def create_variation(self, exercise, term1, term2, term3, result, base): self.questions.append( models.Question(exercise=exercise, type='char', position=1, group='term1', char_value=str(term1))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term1', char_value=str(base))) self.questions.append( models.Question(exercise=exercise, type='char', position=1, group='term2', char_value=str(term2))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term2', char_value=str(base))) self.questions.append( models.Question(exercise=exercise, type='char', position=1, group='term3', char_value=str(term3))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term3', char_value=str(base))) self.answers.append( models.Answer(exercise=exercise, type='exact', position=1, tabindex=1, group='result', value=result)) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=2, group='result', value=base))
def create_exercise(self, term1, term2, result=None): """ Creates exponent exercises. Calculates the intermediary steps so the student may tell the final result and as many steps as the exponent number. E.g.: 2^4 = 2 * 2 * 2 * 2 = 16 Accepts the result as argument or calculates the result otherwise. """ if result is None: result = pow(term1, term2) # Evaluate the exponents if term1 % 10 == 0: tags = 'dezena' else: tags = 'unidade' description = '{0}^{1}'.format(term1, term2) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=term1, filter2=term2, tags=tags) if not created: return # avoid create the exercise again self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term1', char_value=term1)) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term2', char_value=term2)) if term2 > 1: for i, n in enumerate(range(term2)[::-1]): self.answers.append( models.Answer(exercise=exercise, type='exact', position=i, tabindex=n + 1, group='partial', value=term1)) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=len(self.answers) + 1, group='result', value=result))
def get_divisors(self, exercise, *numbers): """ Decomposes one or more numbers into [common] divisors. Attends a decomposition exercise but can also attend a lower common divisor. """ for n, number in enumerate(numbers[::-1]): self.questions.append( models.Question(exercise=exercise, type='char', position=n, group='numbers', char_value=str(number))) primes = list(PRIME_NUMBERS) lines = [] line = list(numbers[:]) # copied end = [1] * len(line) # [1, 1, 1, ...] while line != end: prime = primes[0] new_line = [self.divide_by_prime(x, prime) for x in line] if new_line == line: primes.pop( 0) # ignore this prime as it doesn't divide any number else: line = new_line lines.append((prime, line)) for i, (divisor, steps) in enumerate(lines[::-1]): divisor_tabindex = (len(numbers) + 1) * (len(lines) - i - 1) + 1 self.answers.append( models.Answer(exercise=exercise, type='exact', position=i, tabindex=divisor_tabindex, group='divisors', value=divisor)) for j, step in enumerate(steps[::-1]): position = j + len(numbers) * i tabindex = divisor_tabindex + len(numbers) - j self.answers.append( models.Answer(exercise=exercise, type='exact', position=position, tabindex=tabindex, group='steps', value=step)) return lines
def create_exercise(self, divided, divisor, indivisibles): filter1 = divided filter2 = divisor desc = self.description.format(divided, divisor) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=filter1, filter2=filter2) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term', char_value=str(divisor))) # One correct answer and 9 possible incorrects choices_map = ['+{0}'.format(divided)] random.shuffle(indivisibles) for indivisible in indivisibles[:9]: choices_map.append('-{0}'.format(indivisible)) self.answers.append( models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map='\n'.join(choices_map), choices_sample=5)) return exercise
def create_exercise(self, term): desc = self.description.format(term) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=term) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term', char_value=str(term))) # One correct answer and 9 possible incorrects choices_map = ['+{0}'.format(term)] numbers = [i for i in range(2, 109) if i not in primes.PRIME_NUMBERS] random.shuffle(numbers) for number in numbers[:29]: choices_map.append('-{0}'.format(number)) self.answers.append( models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map='\n'.join(choices_map), choices_sample=9)) return exercise
def create_exercise(self, term): try: result = self.repository[term] except KeyError: raise ValueError('There is no polyhedron {0}'.format(term)) description = self.description.format(term) exercise, created = self.category.exercise_set.get_or_create( description=description) if not created: return # avoid duplications self.questions.append(models.Question(exercise=exercise, type='char', position=0, group='term', char_value=term)) self.answers.append(models.Answer(exercise=exercise, type='exact', position=0, tabindex=1, group='result', value=result)) return exercise
def create_variation(self, term1, term2, inverse=False): if not inverse: description = self.direct_description filter1, filter2 = term1, term2 tags = 'direct' else: description = self.inverse_description filter1, filter2 = term2, term1 tags = 'inverse' description = description.format(term1, term2) exercise, created = self.category.exercise_set.get_or_create( description=description, tags=tags, filter1=filter1, filter2=filter2) if not created: return # avoid create the exercise again self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term1', char_value=str(term1))) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=1, group='term2', value=term2))
def create_exercise(self, term1, term2): desc = self.description.format(term1, term2) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=term1, filter2=term2) if not created: return # avoid duplicate exercise for n, term in enumerate((term2, term1)): # use reverse order self.questions.append( models.Question(exercise=exercise, type='char', position=n, group='fraction', char_value=str(term))) choices_map = ['+{0}/{1}'.format(term1, term2)] for i, j in self.make_choices(term1, term2): choices_map.append('-{0}/{1}'.format(i, j)) # give limit to 5 choices no matter how many was defined self.answers.append( models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map='\n'.join(choices_map), choices_sample=5)) return exercise
def create_exercise(self, base, height): desc = self.description.format(b=base, h=height) filter1 = base filter2 = height exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=filter1, filter2=filter2) if not created: return # avoid duplicate the exercise self.questions.append( models.Question(exercise=exercise, type='char', group='base', char_value=str(base))) self.questions.append( models.Question(exercise=exercise, type='char', group='height', char_value=str(height))) result = (base * height) / 2 self.answers.append( models.Answer(exercise=exercise, type='char', position=0, tabindex=1, group='result', value=result)) return exercise
def create_exercise(self, n): r = roman.toRoman(int(n)) description = '{0} em decimais'.format(r) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=int(n)) if not created: return # avoid duplications self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='number', char_value=r)) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=1, group='result', value=n)) return exercise
def create_exercise(self, term): desc = self.description.format(term) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=term) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='number', char_value='{0}'.format(term))) choices_map = [] for choice in self.make_choices(term): if choice['number'] == term: choices_map.append(u'+{0}'.format(choice['description'])) else: choices_map.append(u'-{0}'.format(choice['description'])) # give limit to 5 choices no matter how many was defined self.answers.append( models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map='\n'.join(choices_map), choices_sample=5)) return exercise
def create_exercise(self, term, sqrt=None): if sqrt is None: # Check if this is a perfect square root. sqrt = math.sqrt(term) orig = pow(sqrt, 2) if orig != term: raise ValueError('Square root must be perfect!') description = u'raíz quadrada de {0}'.format(term) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=term, filter2=term) if not created: return # avoid create the exercise again self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term', char_value=term)) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, group='result', value=int(sqrt))) return exercise
def create_exercise(self, *args): if (args[0] / D(args[1])) != (args[2] / D(args[3])): raise ValueError('The fractions must be equivalent') filter1 = min(args) filter2 = max(args) description = '{0}/{1} = {2}/{3} (irred.)'.format(*args) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=filter1, filter2=filter2) if not created: return # avoid duplicate the exercise for n, i in enumerate(args[0:2][::-1]): self.questions.append( models.Question(exercise=exercise, type='char', position=n, group='term', char_value=str(i))) for n, i in enumerate(args[2:][::-1]): self.answers.append( models.Answer(exercise=exercise, type='exact', position=n, tabindex=2 - n, group='missing', value=i)) return exercise
def create_exercise(self, term): if term not in REGULAR_POLYGONS: raise ValueError('There is no polygon with {0} ' 'sides available'.format(term)) desc = self.description.format(term) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=term) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term', char_value='{0}'.format(term))) choices_map = ['+{0}'.format(term)] for polygon in self.make_choices(term): choices_map.append('-{0}'.format(polygon)) # give limit to 5 choices no matter how many was defined self.answers.append( models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map='\n'.join(choices_map), choices_sample=5)) return exercise
def create_exercise(self, term1): desc = self.description.format(term1) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=term1) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='question', char_value=str(term1))) result = self.get_result(term1) for n, result in enumerate((100, result)): self.answers.append( models.Answer(exercise=exercise, type='exact', position=n, tabindex=2 - n, group='result', value=result)) return exercise
def create_exercise_data(self, exercise, term1, term2): str1, int1, dec1 = self.only_digits(term1) str2, int2, dec2 = self.only_digits(term2) super(Command, self).create_exercise_data(exercise, int(str1), int(str2), sterm1=str1, sterm2=str2) for i in range(1, len(str1)): if i == len(dec1): comma = ',' else: comma = ' ' self.questions.append( models.Question(exercise=exercise, type='char', position=i, group='comma1', char_value=comma)) for i in range(1, len(str2)): if i == len(dec2): comma = ',' else: comma = ' ' self.questions.append( models.Question(exercise=exercise, type='char', position=i, group='comma2', char_value=comma)) result = term1 * term2 result_places = str(result)[::-1].find('.') tabindex = len(self.answers) # creates as many commas as result positions, the position is gotten # from the last answer that is necessary a result last_answer = self.answers[-1] if len(str2) > 1: assert last_answer.group == 'result' else: assert last_answer.group == 'partial1' result_length = last_answer.position + 1 for i in range(1, result_length): if i == result_places: comma = True else: comma = False self.answers.append( models.Answer(exercise=exercise, type='boolean', position=i, tabindex=tabindex + i, group='comma', value=comma))
def create_variation(self, exercise, term1, term2, base1, base2, missing1, missing2): self.questions.append( models.Question(exercise=exercise, type='char', position=1, group='term1', char_value=str(term1))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term1', char_value=str(base1))) self.questions.append( models.Question(exercise=exercise, type='char', position=1, group='term2', char_value=str(term2))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term2', char_value=str(base2))) self.answers.append( models.Answer(exercise=exercise, type='exact', position=1, tabindex=1, group='missing', value=missing1)) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=2, group='missing', value=missing2))
def create_exercise_data(self, exercise, term1, term2): f = '{:.%df}' % self.decimal_places # .2f, .3f and so on int1, dec1 = f.format(term1).split('.') int2, dec2 = f.format(term2).split('.') size = max(len(dec1), len(dec2)) if len(dec2) < size: dec2 = dec2.ljust(size, '0') if len(dec1) < size: dec1 = dec1.ljust(size, '0') str1 = int1 + dec1 str2 = int2 + dec2 # creates the integer addition super(Command, self).create_exercise_data(exercise, int(str1), int(str2)) for i in range(1, len(str1)): if i == self.decimal_places: comma = ',' else: comma = ' ' self.questions.append( models.Question(exercise=exercise, type='char', position=i, group='comma1', char_value=comma)) for i in range(1, len(str2)): if i == self.decimal_places: comma = ',' else: comma = ' ' self.questions.append( models.Question(exercise=exercise, type='char', position=i, group='comma2', char_value=comma)) result = term1 + term2 result_str = f.format(result).replace('.', '') # makes 1.034 be 1034 tabindex = len(self.answers) for i in range(1, len(result_str)): if i == self.decimal_places: comma = True else: comma = False self.answers.append( models.Answer(exercise=exercise, type='boolean', position=i, tabindex=tabindex + i, group='comma', value=comma))
def create_result(self, exercise, numbers, divisors_and_steps): result = self.get_terms_gcd(numbers) self.answers.append( models.Answer(exercise=exercise, type='exact', position=1, tabindex=len(self.answers) + 1, group='result', value=result))
def create_exercise(self, *terms): signals = terms[::2] numbers = terms[1::2] pairs = zip(signals, numbers) description_list = list(self.get_description(pairs)) description = ''.join(description_list) if self.category.exercise_set.filter(description=description).exists(): return # ignore already existent exercises tags = [] if description_list[0] == '-': tags.append('inicio-negat') else: tags.append('inicio-posit') # create a line as "-2+5-3", each digit is a question for n, term in enumerate(description_list): self.questions.append( models.Question(type='char', position=len(description_list) - n, group='exp', char_value=term)) curr_signal, curr_number = pairs.pop(0) for n, (next_signal, next_number) in enumerate(pairs): result = curr_signal * curr_number + next_signal * next_number self.answers.append( models.Answer(type=type, position=len(pairs) - n, tabindex=n + 1, group='result', value=result)) if result < 0: if not 'result-negat' in tags: tags.append('result-negat') curr_signal = -1 else: curr_signal = 1 curr_number = abs(result) if not 'result-negat' in tags: tags.append('result-posit') exercise = self.category.exercise_set.create(description=description, tags=','.join(tags), filter1=min(numbers), filter2=max(numbers)) for answer in self.answers: answer.exercise = exercise for question in self.questions: question.exercise = exercise return exercise
def create_result(self, exercise, numbers, divisors_and_steps): divisors = [divisor for divisor, steps in divisors_and_steps] result = reduce(lambda x, y: x * y, divisors) self.answers.append( models.Answer(exercise=exercise, type='exact', position=1, tabindex=len(self.answers) + 1, group='result', value=result))
def create_exercise(self, a, b, c, d, operator=None): terms = [a, b, c, d] if not operator: operator = random.choice(self.operators) desc = self.description.format(*terms, op=operator) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=min(terms), filter2=max(terms)) if not created: return # avoid duplicate exercise self.create_fraction(exercise, 'fraction1', [a, b]) self.create_fraction(exercise, 'fraction2', [c, d]) comp = a / float(b) - c / float(d) # our comparison tells what is the greater fraction but, if the # operation is lesser than comparison, just invert the comparison term if operator == 'lt': comp = comp * -1 operator_desc = 'menor' else: operator_desc = 'maior' self.questions.append(models.Question(exercise=exercise, type='char', position=0, group='operator', char_value=operator_desc)) choices = [ ['-', u'{0}/{1}'.format(a, b)], ['-', u'{0}/{1}'.format(c, d)], ['-', u'São iguais ou equivalentes'], ] if comp == 0: choices[2][0] = '+' elif comp > 0: choices[0][0] = '+' else: choices[1][0] = '+' choices_map = '\n'.join([(a + b) for a, b in choices]) # give exactly 3 choices self.answers.append(models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map=choices_map, choices_sample=3)) return exercise
def create_exercise_data(self, exercise, term1, term2): str1, int1, dec1 = self.only_digits(term1) self.questions.append(models.Question(exercise=exercise, type='char', position=0, group='term1', char_value='{0},{1}'.format(int1, dec1))) self.questions.append(models.Question(exercise=exercise, type='char', position=1, group='term2', char_value=term2)) result = self.get_result(term1, term2) result_str, result_int, result_dec = self.only_digits(result) result_places = str(result)[::-1].find('.') for i, r in enumerate(result_str): self.answers.append(models.Answer(exercise=exercise, type='char', position=len(result_str) - i, tabindex=i + 1, group='result', value=r)) tabindex = len(self.answers) last_answer = self.answers[0] result_length = last_answer.position for i in range(1, result_length): if i == result_places: comma = True else: comma = False self.answers.append(models.Answer(exercise=exercise, type='boolean', position=i, tabindex=tabindex + i, group='comma', value=comma))
def create_exercise_data(self, exercise, term1, term2): int1, dec1 = str(term1).split('.') int2, dec2 = str(term2).split('.') size = max(len(dec1), len(dec2)) if len(dec2) < size: dec2 = dec2.ljust(size, '0') if len(dec1) < size: dec1 = dec1.ljust(size, '0') str1 = int1 + dec1 str2 = int2 + dec2 super(Command, self).create_exercise_data(exercise, int(str1), int(str2)) decimal_places = max(len(dec1), len(dec2)) for i in range(1, len(str1)): if i == decimal_places: comma = ',' else: comma = ' ' self.questions.append( models.Question(exercise=exercise, type='char', position=i, group='comma1', char_value=comma)) for i in range(1, len(str2)): if i == decimal_places: comma = ',' else: comma = ' ' self.questions.append( models.Question(exercise=exercise, type='char', position=i, group='comma2', char_value=comma)) result = str(int(str1) + int(str2)) tabindex = len(self.answers) for i in range(1, len(result)): if i == decimal_places: comma = True else: comma = False self.answers.append( models.Answer(exercise=exercise, type='boolean', position=i, tabindex=tabindex + i, group='comma', value=comma))
def make_comma_answers(self, exercise, result, decimal_places): # Place the comma according result. result_str = str(result).replace('.', '') # makes 1.034 be 1034 tabindex = len(self.answers) for i in range(1, len(result_str)): if i == decimal_places: comma = True else: comma = False self.answers.append( models.Answer(exercise=exercise, type='boolean', position=i, tabindex=tabindex + i, group='comma', value=comma))
def create_exercise(self, tiles, tilearea, unity): # check if tilearea is defined, if not set 1 if not tilearea: tilearea = 1 result = self.get_result(tiles, tilearea) filter1 = result filter2 = tilearea description = self.description.format(t=tiles, a=tilearea, u=unity) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=filter1, filter2=filter2) if not created: return # avoid duplicate the exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term1', char_value=str(tiles))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='term2', char_value=str(tilearea))) self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='unity', char_value=unity)) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=1, group='result', value=result)) return exercise
def create_exercise(self, point_a, point_b, straight): position_a = self.SEGMENTS[straight][point_a] position_b = self.SEGMENTS[straight][point_b] description = '{a}{b} (medida de segmentos, reta {r})'.format( a=point_a.upper(), b=point_b.upper(), r=straight) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=position_a, filter2=position_b) if not created: return # avoid duplicate the exercise for n, point in enumerate([point_a, point_b]): self.questions.append( models.Question(exercise=exercise, type='char', group='points', position=2 - n, char_value=point)) self.questions.append( models.Question(exercise=exercise, type='char', group='straight', char_value=straight)) # Creates all points sequentially to render the straight in template segments = self.SEGMENTS[straight].values() for n, segment in enumerate(segments): self.questions.append( models.Question(exercise=exercise, type='char', group='segments', position=len(segments) - n, char_value=str(segment))) result = abs(position_a - position_b) self.answers.append( models.Answer(exercise=exercise, type='char', position=0, tabindex=1, group='result', value=result)) return exercise
def create_variation(self, term1, term2, from_unity, to_unity): str1 = str(term1).replace('.', ',') description = '{t1}{fu} = {t2}{tu}'.format(t1=str1, t2=term2, fu=from_unity['unity'], tu=to_unity['unity']) # a tag tells if there is decimal values in the terms or there is only # integers if ',' in description: tags = 'decimal' else: tags = 'integer' exercise, created = self.category.exercise_set.get_or_create( description=description, tags=tags, filter1=term1, filter2=term2) if not created: return # avoid duplications self.questions.append( models.Question(exercise=exercise, type='char', group='question', char_value=str1)) self.questions.append( models.Question(exercise=exercise, type='char', group='question_type', char_value=from_unity['name'])) self.questions.append( models.Question(exercise=exercise, type='char', group='result_type', char_value=to_unity['name'])) self.answers.append( models.Answer(exercise=exercise, type='char', tabindex=1, group='result', value=term2))
def create_exercise(self, n): n = int(n) description = '{0} em romanos'.format(n) exercise, created = self.category.exercise_set.get_or_create( description=description, filter1=n) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='number', char_value=str(n))) # get the numbers between the dozens around the current number, they # will be randomized at execution limit = int(math.ceil(n / 10.)) * 10 + 1 choices = range(limit - 10, limit) # choices exercises are written through a choices_map variable choices_map = [] for c in choices: if c == n: flag = '+' else: flag = '-' r = roman.toRoman(c) choices_map.append(flag + r) # give 10 choices but limit to 5 answers when running the exercise self.answers.append( models.Answer(exercise=exercise, type='radio', position=0, tabindex=1, group='result', choices_map='\n'.join(choices_map), choices_sample=5)) return exercise
def create_exercise(self, *args): if len(set(args)) == 1: polygon_type = 'cube' result = args[0]**3 else: polygon_type = 'rectangular_prism' result = reduce(lambda x, y: x * y, args, 1) desc = self.description.format('Volume({0})'.format(','.join( [str(term) for term in args]))) exercise, created = self.category.exercise_set.get_or_create( description=desc, filter1=max(args), filter2=min(args)) if not created: return # avoid duplicate exercise self.questions.append( models.Question(exercise=exercise, type='char', position=0, group='type', char_value=polygon_type)) for i, term in enumerate(args, start=1): self.questions.append( models.Question(exercise=exercise, type='char', position=(3 - i), group='term', char_value='{0}'.format(term))) self.answers.append( models.Answer(exercise=exercise, type='exact', position=0, tabindex=1, group='result', value=result)) return exercise