def time(is_train): """Questions for calculating start, end, or time differences.""" context = composition.Context() start_minutes = random.randint(1, 24 * 60 - 1) while True: duration_minutes = random.randint(1, 12 * 60 - 1) if train_test_split.is_train(duration_minutes) == is_train: break end_minutes = start_minutes + duration_minutes def format_12hr(minutes): """Format minutes from midnight in 12 hr format.""" hours = (minutes // 60) % 24 minutes %= 60 am_pm = 'AM' if hours < 12 else 'PM' hours = (hours - 1) % 12 + 1 return '{}:{:02} {}'.format(hours, minutes, am_pm) start = format_12hr(start_minutes) end = format_12hr(end_minutes) which_question = random.randint(0, 3) if which_question == 0: # Question: What is start = end - duration? template = random.choice([ 'Berapa {duration} menit sebelum {end}?', ]) return example.Problem(question=example.question( context, template, duration=duration_minutes, end=end), answer=start) elif which_question == 1: # Question: What is end = start + duration? template = random.choice([ 'Berapa {duration} menit setelah {start}?', ]) return example.Problem(question=example.question( context, template, duration=duration_minutes, start=start), answer=end) else: # Question: What is duration = end - start? template = random.choice([ 'Berapa menit antara {start} dan {end}?', ]) return example.Problem(question=example.question(context, template, start=start, end=end), answer=duration_minutes)
def _sub_question_or_entity(context, p, q, is_question): """Generates entity or question for subtraction p - q.""" value = p.value - q.value if is_question: templates = [ '{p} - {q}', 'Work out {p} - {q}.', 'What is {p} minus {q}?', 'What is {p} take away {q}?', 'What is {q} less than {p}?', 'Subtract {q} from {p}.', 'Calculate {p} - {q}.', 'What is {p} - {q}?', ] if sympy.Ge(p.value, q.value): # We calculate p - q, so the difference (|p - q|) is the correct answer. for adjective in ['distance', 'difference']: for pair in ['{p} and {q}', '{q} and {p}']: templates.append('What is the {} between {}?'.format(adjective, pair)) template = random.choice(templates) return example.Problem( question=example.question(context, template, p=p, q=q, problem_type='sub'), answer=value) else: return composition.Entity( context=context, value=value, description='Let {self} = {p} - {q}.', p=p, q=q, problem_type='sub')
def _add_question_or_entity(context, p, q, is_question): """Generates entity or question for adding p + q.""" value = p.value + q.value if is_question: template = random.choice([ '{p} + {q}', '{p}+{q}', 'Work out {p} + {q}.', 'Add {p} and {q}.', 'Put together {p} and {q}.', 'Sum {p} and {q}.', 'Total of {p} and {q}.', 'Add together {p} and {q}.', 'What is {p} plus {q}?', 'Calculate {p} + {q}.', 'What is {p} + {q}?', ]) return example.Problem( question=example.question(context, template, p=p, q=q, problem_type='add'), answer=value) else: return composition.Entity( context=context, value=value, description='Let {self} = {p} + {q}.', p=p, q=q, problem_type='add')
def _conversion_decimal(context, is_train, is_extrapolation): """E.g., "How many grams are in 5kg?".""" dimension = random.choice(DIMENSIONS) while True: base_value, base_unit, target_value, target_unit = ( _sample_conversion_decimal(dimension, is_extrapolation)) if train_test_split.is_train(base_value) == is_train: break templates = [ 'How many {target_name} are there in {base_value} {base_name}?', 'What is {base_value} {base_name} in {target_name}?', 'Convert {base_value} {base_name} to {target_name}.', ] if base_unit.symbol is not None: templates += [ 'How many {target_name} are there in {base_value}{base_symbol}?', 'What is {base_value}{base_symbol} in {target_name}?', 'Convert {base_value}{base_symbol} to {target_name}.', ] template = random.choice(templates) base_name = pluralize(base_unit.name) target_name = pluralize(target_unit.name) question = example.question( context, template, base_name=base_name, base_symbol=base_unit.symbol, base_value=base_value, target_name=target_name) return example.Problem(question=question, answer=target_value)
def is_prime(value, sample_args, context=None): """Questions asking about primality.""" del value # unused for now if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() composite = _semi_prime(entropy) if random.choice([False, True]): # Use the composite integer = composite is_prime_ = False else: # Take the next prime after the composite, to ensure the same distribution # as composites. Do "composite - 4" so we occasionally see "2" as a prime. integer = sympy.ntheory.generate.nextprime(composite - 4) is_prime_ = True (integer_entity, ) = context.sample(sample_args, [integer]) if random.choice([False, True]) and integer != 1: answer = not is_prime_ attribute_name = random.choice(['komposit', 'bilangan komposit']) else: answer = is_prime_ attribute_name = random.choice(['prima', 'bilangan prima']) return example.Problem(question=example.question( context, 'Apakah {integer} {attribute}?', integer=integer_entity.expression_else_handle, attribute=attribute_name), answer=answer)
def compose(value, sample_args, context=None): """E.g., "Let f(x)=2x+1, let g(x)=3x+10. What is f(g(x))?".""" del value # unused if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() entropy_f, entropy_g = entropy * np.random.dirichlet([1, 1]) coeffs_f = polynomials.sample_coefficients([random.randint(1, 2)], entropy_f) coeffs_g = polynomials.sample_coefficients([random.randint(1, 2)], entropy_g) entity_f, entity_g = context.sample( sample_args, [composition.Polynomial(coeffs_f), composition.Polynomial(coeffs_g)]) variable = sympy.var(context.pop()) poly_f = polynomials.coefficients_to_polynomial(coeffs_f, variable) poly_g = polynomials.coefficients_to_polynomial(coeffs_g, variable) poly_f_g = poly_f.sympy().subs(variable, poly_g.sympy()).expand() expression = composition.FunctionHandle(entity_f, entity_g).apply(variable) template = random.choice(_TEMPLATES) return example.Problem(question=example.question(context, template, composed=expression), answer=poly_f_g)
def _conversion_decimal(context, is_train, is_extrapolation): """E.g., "How many grams are in 5kg?".""" dimension = random.choice(DIMENSIONS) while True: base_value, base_unit, target_value, target_unit = ( _sample_conversion_decimal(dimension, is_extrapolation)) if train_test_split.is_train(base_value) == is_train: break templates = [ 'Ada berapa {target_name} di {base_value} {base_name}?', 'Apa {base_value} {base_name} dalam {target_name}?', 'Ubah {base_value} {base_name} to {target_name}.', ] if base_unit.symbol is not None: templates += [ 'Ada berapa {target_name} di {base_value}{base_symbol}?', 'Apa {base_value}{base_symbol} dalam {target_name}?', 'Ubah {base_value}{base_symbol} ke {target_name}.', ] template = random.choice(templates) base_name = base_unit.name # Indonesia no have plural stuff target_name = target_unit.name # Indonesia no have plural stuff question = example.question(context, template, base_name=base_name, base_symbol=base_unit.symbol, base_value=base_value, target_name=target_name) return example.Problem(question=question, answer=target_value)
def base_conversion(min_entropy, max_entropy): """E.g., "What is 17 base 8 in base 10?".""" context = composition.Context() from_base = random.randint(2, 16) while True: to_base = random.randint(2, 16) if to_base != from_base: break # Entropy used up in selecting bases. entropy_used = math.log10(16 * 15) entropy = random.uniform(min_entropy - entropy_used, max_entropy - entropy_used) value = number.integer(entropy, signed=True) template = random.choice([ '{from_str} (basis {from_base}) ke basis {to_base}', 'Ubah {from_str} (basis {from_base}) menjadi basis {to_base}.', 'Apa {from_str} (basis {from_base}) di basis {to_base}?', ]) return example.Problem(question=example.question( context, template, from_str=display.NumberInBase(value, from_base), from_base=from_base, to_base=to_base), answer=display.NumberInBase(value, to_base))
def collect(value, sample_args, context=None): """Collect terms in an unsimplified polynomial.""" is_question = context is None if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() if value is None: entropy_value, entropy = entropy * np.random.dirichlet([2, 3]) degrees = [random.randint(1, 3)] value = composition.Polynomial( polynomials.sample_coefficients(degrees, entropy_value)) assert isinstance(value, composition.Polynomial) coefficients = value.coefficients all_coefficients_are_integer = True for coeff in coefficients.flat: if not number.is_integer(coeff): all_coefficients_are_integer = False break if all_coefficients_are_integer: coefficients = polynomials.expand_coefficients(coefficients, entropy) else: # put back the unused entropy sample_args = composition.SampleArgs(sample_args.num_modules, sample_args.entropy + entropy) num_variables = coefficients.ndim variables = [sympy.Symbol(context.pop()) for _ in range(num_variables)] unsimplified = polynomials.coefficients_to_polynomial( coefficients, variables) simplified = unsimplified.sympy().expand() # Bit of a hack: handle the very rare case where no number constants appearing if not ops.number_constants(unsimplified): unsimplified = ops.Add(unsimplified, ops.Constant(0)) context.sample_by_replacing_constants(sample_args, unsimplified) if is_question: template = 'Sederhanakan {unsimplified}.' return example.Problem(question=example.question( context, template, unsimplified=unsimplified), answer=simplified) else: function_symbol = context.pop() function = sympy.Function(function_symbol)(*variables) return composition.Entity( context=context, value=value, handle=composition.FunctionHandle(function_symbol), expression=unsimplified, polynomial_variables=variables, description='Misalkan {function} = {unsimplified}.', function=function, unsimplified=unsimplified)
def lcm(value, sample_args, context=None): """Question for least common multiple of p and q.""" del value # unused if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() p, q = _pair_with_large_hidden_factor(entropy) answer = sympy.lcm(p, q) if random.choice([False, True]): p, q = context.sample(sample_args, [p, q]) # Ask the question directly. adjective = random.choice( ['paling sedikit', 'paling rendah', 'paling kecil']) template = random.choice([ 'Hitung kelipatan persekutuan {adjective} dari {p} dan {q}.', 'Berapa {adjective} kelipatan persekutuan dari {p} dan {q}?', ]) return example.Problem(question=example.question( context, template, adjective=adjective, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer) else: # Phrase the question as finding the common denominator of two fractions. p = number.integer(2, signed=True, coprime_to=p) / p q = number.integer(2, signed=True, coprime_to=q) / q p, q = context.sample(sample_args, [p, q]) template = random.choice([ 'Berapa penyebut dari {p} dan {q}?', 'Temukan penyebut yang sama dari {p} dan {q}.', 'Hitung penyebut dari {p} dan {q}.', ]) return example.Problem(question=example.question( context, template, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer)
def lcm(value, sample_args, context=None): """Question for least common multiple of p and q.""" del value # unused if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() p, q = _pair_with_large_hidden_factor(entropy) answer = sympy.lcm(p, q) if random.choice([False, True]): p, q = context.sample(sample_args, [p, q]) # Ask the question directly. adjective = random.choice(['least', 'lowest', 'smallest']) template = random.choice([ 'Calculate the {adjective} common multiple of {p} and {q}.', 'What is the {adjective} common multiple of {p} and {q}?', ]) return example.Problem(question=example.question( context, template, adjective=adjective, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer) else: # Phrase the question as finding the common denominator of two fractions. p = number.integer(2, signed=True, coprime_to=p) / p q = number.integer(2, signed=True, coprime_to=q) / q p, q = context.sample(sample_args, [p, q]) template = random.choice([ 'What is the common denominator of {p} and {q}?', 'Find the common denominator of {p} and {q}.', 'Calculate the common denominator of {p} and {q}.', ]) return example.Problem(question=example.question( context, template, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer)
def _kth_biggest_list_question(context, entities, adjective, answer): """Ask for the biggest (or smallest, or second biggest, etc) in a list.""" entity_dict, values_template = _entities_to_list(entities) question = example.question(context, 'Berapa nilai {adjective} dalam ' + values_template + '?', adjective=adjective, **entity_dict) return example.Problem(question=question, answer=answer.handle)
def _kth_biggest_multichoice_question(context, entities, adjective, answer): """Ask for the biggest (or smallest, or second biggest, etc) of choices.""" entity_dict, choices_template, answer_choice = _entities_to_choices( entities, answer) question = example.question(context, 'Manakah nilai {adjective}?' + choices_template, adjective=adjective, **entity_dict) return example.Problem(question=question, answer=answer_choice)
def add(value, sample_args, context=None): """E.g., "Let f(x)=2x+1, g(x)=3x+2. What is 5*f(x) - 7*g(x)?".""" is_question = context is None if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() if value is None: max_degree = 3 degree = random.randint(1, max_degree) entropy -= math.log10(max_degree) entropy_value = entropy / 2 entropy -= entropy_value value = polynomials.sample_coefficients(degree, entropy=entropy_value, min_non_zero=random.randint( 1, 3)) value = composition.Polynomial(value) c1, c2, coeffs1, coeffs2 = polynomials.coefficients_linear_split( value.coefficients, entropy) coeffs1 = polynomials.trim(coeffs1) coeffs2 = polynomials.trim(coeffs2) c1, c2, fn1, fn2 = context.sample(sample_args, [ c1, c2, composition.Polynomial(coeffs1), composition.Polynomial(coeffs2) ]) var = sympy.var(context.pop()) expression = (c1.handle * fn1.handle.apply(var) + c2.handle * fn2.handle.apply(var)) if is_question: answer = polynomials.coefficients_to_polynomial( value.coefficients, var) answer = answer.sympy() template = random.choice(_TEMPLATES) return example.Problem(question=example.question(context, template, composed=expression), answer=answer) else: intermediate_symbol = context.pop() intermediate = sympy.Function(intermediate_symbol)(var) return composition.Entity( context=context, value=value, description='Misalkan {intermediate} = {composed}.', handle=composition.FunctionHandle(intermediate_symbol), intermediate=intermediate, composed=expression)
def _differentiate_polynomial(value, sample_args, context, num_variables): """Generates a question for differentiating a polynomial.""" is_question = context is None if context is None: context = composition.Context() if value is not None: num_variables = value.coefficients.ndim entropy, sample_args = sample_args.peel() max_derivative_order = 3 derivative_order = random.randint(1, max_derivative_order) entropy = max(0, entropy - math.log10(max_derivative_order)) derivative_axis = random.randint(0, num_variables - 1) if value is None: coefficients = _generate_polynomial( num_variables, entropy, derivative_order, derivative_axis) else: coefficients = _sample_integrand( value.coefficients, derivative_order, derivative_axis, entropy) (entity,) = context.sample( sample_args, [composition.Polynomial(coefficients)]) value = coefficients for _ in range(derivative_order): value = polynomials.differentiate(value, axis=derivative_axis) nth = display.StringOrdinal(derivative_order) if entity.has_expression(): polynomial = entity.expression variables = entity.polynomial_variables else: variables = [sympy.Symbol(context.pop()) for _ in range(num_variables)] polynomial = entity.handle.apply(*variables) variable = variables[derivative_axis] if is_question: template = _template(context.module_count, derivative_order, len(variables)) answer = polynomials.coefficients_to_polynomial(value, variables).sympy() return example.Problem( question=example.question( context, template, eq=polynomial, var=variable, nth=nth), answer=answer) else: fn_symbol = context.pop() variables_string = ', '.join(str(variable) for variable in variables) assert len(variables) == 1 # since below we don't specify var we diff wrt return composition.Entity( context=context, value=composition.Polynomial(value), description='Misalkan {fn} ({variables}) menjadi turunan ke-{nth} dari {eq}.', handle=composition.FunctionHandle(fn_symbol), fn=fn_symbol, variables=variables_string, nth=nth, eq=polynomial)
def _closest_in_list_question(context, entities, target, adjective, answer): """Ask for the closest to a given value in a list.""" entity_dict, values_template = _entities_to_list(entities) question = example.question( context, 'Manakah yang {adjective} dari {target} pada ' + values_template + '?', adjective=adjective, target=target, **entity_dict) return example.Problem(question=question, answer=answer.handle)
def evaluate(value, sample_args, context=None): """Entity for evaluating an integer-valued polynomial at a given point.""" is_question = context is None if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() if value is None: entropy_value = random.uniform(1, 1 + entropy / 3) entropy = max(0, entropy - entropy_value) value = number.integer(entropy_value, signed=True) entropy_input = random.uniform(1, 1 + entropy / 3) entropy = max(0, entropy - entropy_input) input_ = number.integer(entropy_input, signed=True) degree = random.randint(1, 3) entropies = entropy * np.random.dirichlet(list(range(1, degree + 1))) # Calculate coefficients in reverse order. target = value coeffs_reversed = [] for i, coeff_entropy in enumerate(entropies): power = degree - i coeff = number.integer(coeff_entropy, signed=True) if input_ != 0: coeff += int(round(target / input_**power)) if coeff == 0 and i == 0: # Don't allow zero in leading coefficient. coeff += random.choice([-1, 1]) coeffs_reversed.append(coeff) target -= coeff * (input_**power) coeffs_reversed.append(target) coefficients = list(reversed(coeffs_reversed)) (polynomial_entity, input_) = context.sample(sample_args, [composition.Polynomial(coefficients), input_]) composed = polynomial_entity.handle.apply(input_.handle) if is_question: template = random.choice(_TEMPLATES) return example.Problem(question=example.question(context, template, composed=composed), answer=value) else: return composition.Entity(context=context, value=value, expression=composed, description='Misalkan {self} be {composed}.', composed=composed)
def _closest_multichoice_question(context, entities, target, adjective, answer): """Ask for the closest to a given value in a set of choices.""" entity_dict, choices_template, answer_choice = _entities_to_choices( entities, answer) question = example.question(context, 'Manakah yang {adjective} dari {target}?' + choices_template, adjective=adjective, target=target, **entity_dict) return example.Problem(question=question, answer=answer_choice)
def coefficient_named(value, sample_args, context=None): """E.g., "Express x^2 + 2x in the form h * x^2 + k * x + t and give h.".""" del value # not used if context is None: context = composition.Context() variable = sympy.Symbol(context.pop()) entropy, sample_args = sample_args.peel() degree = random.randint(1, 4) if random.choice([False, True]): coefficients = polynomials.sample_coefficients( degree, entropy / 2, min_non_zero=random.randint(degree - 1, degree)) expanded = polynomials.expand_coefficients(coefficients, entropy / 2) expression = polynomials.coefficients_to_polynomial(expanded, variable) else: expression = polynomials.sample_with_brackets(variable, degree, entropy) coefficients = list(reversed(sympy.Poly(expression).all_coeffs())) named_coeffs = [sympy.Symbol(context.pop()) for _ in range(degree + 1)] canonical = polynomials.coefficients_to_polynomial(named_coeffs, variable) if random.random() < 0.2: # only small probability of non-zero power power = random.randint(0, degree) else: non_zero_powers = [ i for i in range(degree + 1) if coefficients[i] != 0 ] power = random.choice(non_zero_powers) value = coefficients[power] named_coeff = named_coeffs[power] template = random.choice([ 'Ekspresikan {expression} sebagai {canonical} dan berikan {target}. ' 'Atur ulang {expression} menjadi {canonical} dan berikan {target}.', 'Ekspresikan {expression} dalam bentuk {canonical} dan berikan {target}.', 'Atur ulang {expression} ke bentuk {canonical} dan berikan {target}.', ]) return example.Problem(question=example.question(context, template, expression=expression, canonical=canonical, target=named_coeff), answer=value)
def nearest_integer_root(sample_args): """E.g., "Calculate the cube root of 35 to the nearest integer.".""" context = composition.Context() # With at least 50% probability, pick square or cube root (these are most # important roots!). if random.choice([False, True]): one_over_exponent = random.randint(2, 3) else: one_over_exponent = random.randint(2, 10) entropy, sample_args = sample_args.peel() value = number.integer(entropy, signed=False) answer = int(round(value ** (1 / one_over_exponent))) templates = [ 'What is {value} to the power of 1/{one_over_exponent}, to the nearest' ' integer?', ] if one_over_exponent != 2: # "What is the second root of 4?" never used. ordinal = str() templates += [ 'What is the {ordinal} root of {value} to the nearest integer?', ] if one_over_exponent == 2: templates += [ 'What is the square root of {value} to the nearest integer?', ] elif one_over_exponent == 3: templates += [ 'What is the cube root of {value} to the nearest integer?', ] template = random.choice(templates) ordinal = display.StringOrdinal(one_over_exponent) return example.Problem( question=example.question( context, template, value=value, ordinal=ordinal, one_over_exponent=one_over_exponent), answer=answer)
def expand(value, sample_args, context=None): """E.g., "Expand (x**2 + 1)**2.".""" del value # not used if context is None: context = composition.Context() variable = sympy.Symbol(context.pop()) entropy, sample_args = sample_args.peel() min_order = 1 max_order = 5 order = random.randint(min_order, max_order) entropy -= math.log10(max_order - min_order + 1) expression_ = polynomials.sample_with_brackets(variable, order, entropy) expanded = sympy.expand(expression_) template = random.choice(['Sederhanakan {expression}.']) return example.Problem(question=example.question(context, template, expression=expression_), answer=expanded)
def _sample_without_replacement_probability_question(is_train, event_fn, sample_range): """Question for prob of some event when sampling without replacement.""" def too_big(event_in_space): if isinstance(event_in_space, probability.SequenceEvent): size = len(event_in_space.all_sequences()) else: assert isinstance(event_in_space, probability.FiniteProductEvent) size = np.prod( [len(event.values) for event in event_in_space.events]) return size > int(2e5) allow_trivial_prob = random.random() < _MAX_FRAC_TRIVIAL_PROB while True: distinct_letters, space, random_variable = _swr_space( is_train, sample_range) event, event_description = event_fn(values=distinct_letters, length=space.n_samples, verb='выбрать') event_in_space = random_variable.inverse(event) if too_big(event_in_space): continue answer = space.probability(event_in_space) if answer not in [0, 1] or allow_trivial_prob: break context = composition.Context() template = random.choice([ '{random_variable_capitalize}. Какова вероятность {event}?', '{random_variable_capitalize}. Рассчитайте вероятность {event}.', 'Чему равна вероятность {event} при условии, что {random_variable}?', 'Рассчитайте вероятность {event} при условии, что {random_variable}.', ]) question = example.question(context, template, random_variable=random_variable.description, random_variable_capitalize=(str( random_variable.description).capitalize()), event=event_description) return example.Problem(question, answer)
def simplify_power(value, sample_args, context=None): """E.g., "Simplify ((x**2)**3/x**4)**2/x**3.".""" del value # unused if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() variable = sympy.symbols(context.pop(), positive=True) unsimplified = polynomials.sample_messy_power(variable, entropy) answer = unsimplified.sympy() template = random.choice([ 'Simplify {unsimplified} assuming {variable} is positive.', ]) return example.Problem( example.question( context, template, unsimplified=unsimplified, variable=variable), answer)
def gcd(value, sample_args, context=None): """Question for greatest common divisor of p and q.""" is_question = context is None if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() if value is None: value_entropy = 1 + random.uniform(0, entropy / 3) entropy = max(1, entropy - value_entropy) value = number.integer(value_entropy, False, min_abs=1) p_mult, q_mult = _random_coprime_pair(entropy) p = value * p_mult q = value * q_mult assert sympy.gcd(p, q) == value p, q = context.sample(sample_args, [p, q]) adjective = (random.choice(['pembagi persekutuan', 'faktor umum']) + random.choice([' terbesar', ' tertinggi'])) if is_question: template = random.choice([ 'Hitung {adjective} dari {p} dan {q}.', 'Apa {adjective} dari {p} dan {q}?', ]) return example.Problem(question=example.question(context, template, adjective=adjective, p=p, q=q), answer=value) else: return composition.Entity( context=context, value=value, description='Biarkan {self} menjadi {adjective} dari {p} dan {q}.', adjective=adjective, p=p, q=q)
def gcd(value, sample_args, context=None): """Question for greatest common divisor of p and q.""" is_question = context is None if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() if value is None: value_entropy = 1 + random.uniform(0, entropy / 3) entropy = max(1, entropy - value_entropy) value = number.integer(value_entropy, False, min_abs=1) p_mult, q_mult = _random_coprime_pair(entropy) p = value * p_mult q = value * q_mult assert sympy.gcd(p, q) == value p, q = context.sample(sample_args, [p, q]) adjective = (random.choice(['greatest', 'highest']) + ' common ' + random.choice(['divisor', 'factor'])) if is_question: template = random.choice([ 'Calculate the {adjective} of {p} and {q}.', 'What is the {adjective} of {p} and {q}?', ]) return example.Problem(question=example.question(context, template, adjective=adjective, p=p, q=q), answer=value) else: return composition.Entity( context=context, value=value, description='Let {self} be the {adjective} of {p} and {q}.', adjective=adjective, p=p, q=q)
def place_value(value, sample_args, context=None): """E.g., "Q: What is the tens digit of 31859? A: 5.""" del value # unused for now if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() integer = number.integer(entropy, signed=False, min_abs=1) (entity, ) = context.sample(sample_args, [integer]) integer_as_string = str(integer) num_digits = len(integer_as_string) firsts = ['', 'puluh ', 'ratus '] seconds = [ 'ribu', 'juta', 'milyar', 'triliun', 'kuadriliun ', 'kuintiliun', 'sekstiliun', 'septiliun', 'oktilliun', 'nonilliun', 'desiliun', ] place_names = ['unit', 'ribuan', 'ratusan'] for second in seconds: for first in firsts: place_names.append(first + second) place = random.randint(1, num_digits) # 1 = units, 2 = tens, etc. place_name = place_names[place - 1] answer = sympy.Integer(integer_as_string[num_digits - place]) return example.Problem(question=example.question( context, 'Berapa digit {place_name} dari {integer}?', place_name=place_name, integer=entity.expression_else_handle), answer=answer)
def list_prime_factors(value, sample_args, context=None): """E.g., "What are the prime factors of 36?".""" del value # unused for now if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() entropy = max(1, entropy) integer = number.integer(entropy, signed=False, min_abs=2) (entity, ) = context.sample(sample_args, [integer]) prime_factors = sorted(sympy.factorint(integer).keys()) template = random.choice([ 'Apa faktor prima dari {integer}?', 'Sebutkan faktor prima dari {integer}.', ]) return example.Problem(question=example.question( context, template, integer=entity.expression_else_handle), answer=display.NumberList(prime_factors))
def sort(sample_args, count=None): """Ask to sort numbers in increasing or decreasing order.""" sample_args = sample_args() context = composition.Context() entropy, sample_args = sample_args.peel() # Sometimes just integers, to allow for more terms in a short space. values = _unique_values(entropy, only_integers=random.choice([False, True]), count=count) entities = context.sample(sample_args, values) unsorted_dict, unsorted_template = _entities_to_list(entities) ascending = random.choice([False, True]) templates = [ 'Urutkan ' + unsorted_template + ' dalam urutan {direction}.', 'Taruh ' + unsorted_template + ' dalam urutan {direction}.', ] if ascending: templates.append('Sort ' + unsorted_template + '.') direction = random.choice(['naik', 'meningkat']) else: direction = random.choice(['turun', 'menurun']) template = random.choice(templates) sorted_entities = sorted(entities, key=_entity_sort_key, reverse=(not ascending)) answer = '' for i, entity in enumerate(sorted_entities): if i > 0: answer += ', ' answer += str(entity.handle) return example.Problem(question=example.question(context, template, direction=direction, **unsorted_dict), answer=answer)
def div_remainder(value, sample_args, context=None): """E.g., "What is the remainder when 27 is divided by 5?".""" is_question = context is None if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() if value is None: entropy_value = 1 + random.uniform(0, entropy / 3) entropy = max(0, entropy - entropy_value) value = number.integer(entropy_value, signed=False) entropy_a, entropy_q = entropy * np.random.dirichlet([1, 1]) a = number.integer(entropy_a, signed=False, min_abs=1) q = value + number.integer(entropy_q, signed=False, min_abs=1) p = a * q + value assert p % q == value p, q = context.sample(sample_args, [p, q]) if is_question: template = random.choice([ 'Hitung sisanya ketika {p} dibagi dengan {q}.', 'Berapa sisa jika {p} dibagi dengan {q}?', ]) return example.Problem(question=example.question( context, template, p=p.expression_else_handle, q=q.expression_else_handle), answer=value) else: return composition.Entity( context=context, value=value, description= 'Biarkan {self} menjadi sisa saat {p} dibagi dengan {q}.', p=p, q=q)
def sequence_nth_term(min_entropy, max_entropy): """E.g., "What is the nth term in the sequence 1, 2, 3?".""" entropy = random.uniform(min_entropy, max_entropy) context = composition.Context() variable = sympy.Symbol(context.pop()) sequence = _PolynomialSequence(variable, entropy) min_num_terms = sequence.min_num_terms num_terms = random.randint(min_num_terms, min_num_terms + 3) sequence_sample = [sequence.term(n + 1) for n in range(num_terms)] sequence_sample = display.NumberList(sequence_sample) template = random.choice([ 'Apa suku ke {variable} dari {sequence}?', ]) answer = sequence.sympy return example.Problem(question=example.question(context, template, variable=variable, sequence=sequence_sample), answer=answer)