math / modules /counting /additive_multiplicative.py
Sina Media Lab
Updates
3c35d02
import random
import nltk
from nltk.corpus import words
from nltk.corpus import wordnet
# Ensure the NLTK word corpus is downloaded
nltk.download('words')
nltk.download('wordnet')
title = "Counting and Combinatorial Questions"
description = "This module covers basic counting principles, including additive and multiplicative principles in combinatorial problems."
def get_random_word(length=None):
"""Return a random word from the NLTK words corpus with an optional length."""
word_list = words.words()
if length:
word_list = [word for word in word_list if len(word) == length]
return random.choice(word_list).capitalize()
def get_synonym(word):
"""Return a random synonym for a word using WordNet."""
synonyms = wordnet.synsets(word)
if synonyms:
return random.choice(synonyms).lemmas()[0].name().capitalize()
return word.capitalize()
def generate_question():
question_type = random.choice(["vowels", "ties", "outfits", "combinations"])
if question_type == "vowels":
# Randomly generate two-letter words using vowels
vowel_count = random.randint(3, 5)
vowels = [get_random_word(1) for _ in range(vowel_count)]
num_two_letter_words = len(vowels) * 26
word_type = get_random_word(4)
question = f"How many two-letter {word_type}s can be formed if the first letter must be one of these {vowel_count} vowels: {', '.join(vowels)}?"
correct_answer = num_two_letter_words
explanation = f"There are {vowel_count} choices for the first letter (vowels) and 26 choices for the second letter (any letter). Thus, the total number of two-letter words is {vowel_count} * 26 = {num_two_letter_words}."
step_by_step_solution = [
f"Step 1: Identify the number of choices for the first letter ({vowel_count} vowels).",
"Step 2: Identify the number of choices for the second letter (any letter).",
f"Step 3: Multiply the two values: {vowel_count} * 26 = {num_two_letter_words}.",
f"Step 4: The total number of two-letter words is {num_two_letter_words}."
]
elif question_type == "ties":
# Randomly generate tie names
regular_ties = random.randint(5, 10)
bow_ties = random.randint(3, 7)
tie_name = get_random_word(3)
question = f"You own {regular_ties} {tie_name}s and {bow_ties} bow {tie_name}s. How many choices do you have for your neckwear?"
correct_answer = regular_ties + bow_ties
explanation = f"You have {regular_ties} choices for {tie_name}s and {bow_ties} choices for bow {tie_name}s. Since you can wear either type, you have {regular_ties} + {bow_ties} = {correct_answer} choices for neckwear."
step_by_step_solution = [
f"Step 1: Identify the number of {tie_name}s ({regular_ties}).",
f"Step 2: Identify the number of bow {tie_name}s ({bow_ties}).",
f"Step 3: Add the two values: {regular_ties} + {bow_ties} = {correct_answer}.",
f"Step 4: The total number of neckwear choices is {correct_answer}."
]
elif question_type == "outfits":
# Randomly generate clothing items
shirt_count = random.randint(4, 8)
skirt_count = random.randint(3, 6)
pants_count = random.randint(1, 4)
dress_count = random.randint(2, 5)
clothing_item = get_random_word(5)
question = (f"You have {shirt_count} {clothing_item}s, {skirt_count} skirts, {pants_count} pants, and {dress_count} dresses. "
"You want to select either a shirt to wear with a skirt or pants, or just a dress. How many outfits do you have to choose from?")
outfit_with_shirt = shirt_count * (skirt_count + pants_count)
correct_answer = outfit_with_shirt + dress_count
explanation = (f"You can choose a {clothing_item} ({shirt_count} options) with either a skirt ({skirt_count} options) or pants ({pants_count} options), "
f"giving {shirt_count} * ({skirt_count} + {pants_count}) = {outfit_with_shirt} outfits. "
f"Or you can choose a dress ({dress_count} options), so the total number of outfits is {outfit_with_shirt} + {dress_count} = {correct_answer}.")
step_by_step_solution = [
"Step 1: Calculate the number of outfits with a shirt and either a skirt or pants.",
f"Step 2: Multiply the number of {clothing_item}s ({shirt_count}) by the sum of skirts ({skirt_count}) and pants ({pants_count}): {shirt_count} * ({skirt_count} + {pants_count}) = {outfit_with_shirt}.",
f"Step 3: Add the number of dresses ({dress_count}): {outfit_with_shirt} + {dress_count} = {correct_answer}.",
f"Step 4: The total number of outfits is {correct_answer}."
]
elif question_type == "combinations":
# Randomly generate meal options
appetizers = random.randint(2, 5)
main_courses = random.randint(4, 7)
desserts = random.randint(3, 5)
drinks = random.randint(2, 4)
meal_item = get_random_word(4)
question = (f"A restaurant offers {appetizers} {meal_item}s, {main_courses} main courses, {desserts} desserts, and {drinks} types of drinks. "
"How many different meal combinations can you order if you choose one of each?")
correct_answer = appetizers * main_courses * desserts * drinks
explanation = (f"You have {appetizers} choices for an {meal_item}, {main_courses} choices for a main course, {desserts} choices for a dessert, "
f"and {drinks} choices for a drink. Multiplying these together gives the total number of meal combinations: "
f"{appetizers} * {main_courses} * {desserts} * {drinks} = {correct_answer}.")
step_by_step_solution = [
f"Step 1: Identify the number of choices for each part of the meal: {meal_item}s, main courses, desserts, and drinks.",
f"Step 2: Multiply the number of choices: {appetizers} * {main_courses} * {desserts} * {drinks} = {correct_answer}.",
f"Step 3: The total number of meal combinations is {correct_answer}."
]
options = [correct_answer]
# Generate incorrect answers ensuring they are unique and close to the correct answer
while len(options) < 4:
incorrect_answer = random.randint(correct_answer - random.randint(1, 10), correct_answer + random.randint(1, 10))
if incorrect_answer != correct_answer and incorrect_answer not in options:
options.append(incorrect_answer)
random.shuffle(options)
return {
"question": question,
"options": options,
"correct_answer": correct_answer,
"explanation": explanation,
"step_by_step_solution": step_by_step_solution
}