TangibleAI/mathtext-fastapi
1
1import random2from typing import Literal3 4 5def generate_question_data(level: Literal["easy", "medium", "hard"] = "easy"):6 """generate question, its numbers and proper answer"""7 8 nums = generate_numbers_by_level(level)9 cur_num = nums['current_number'] # current number10 ord_num = nums['ordinal_number'] # ordinal number11 seq_up_by_one = generate_number_sequence(cur_num, ord_num=1, times=1) # sequence with ord_num = 1, times = 112 13 count_up_by_one_questions = [14 {15 "question": f"Let's practice counting. After {cur_num}, what number is next?\n{seq_up_by_one}",16 "current_number": cur_num,17 "ordinal_number": 1,18 "times": 1,19 "answer": cur_num + 120 }21 ]22 seq_up_by_ord = generate_number_sequence(cur_num, ord_num, times=1) # sequence with times = 123 count_up_by_ord_questions = [24 {25 "question": f"What number comes {ord_num} number after {cur_num}?\n{seq_up_by_ord}",26 "current_number": cur_num,27 "ordinal_number": ord_num,28 "times": 1,29 "answer": cur_num + ord_num 30 },31 {32 "question": f"If we count up {ord_num} from {cur_num}, what number is next?\n{seq_up_by_ord}",33 "current_number": cur_num,34 "ordinal_number": ord_num,35 "times": 1,36 "answer": cur_num + ord_num37 }38 ]39 times = 1 if level == "easy" else nums['times']40 times_ord_seq = generate_number_sequence(cur_num, ord_num, times)41 times_ord_questions = [42 {43 "question": f"We're counting up by {times}s. What number is {ord_num} after {cur_num}?\n{times_ord_seq}",44 "current_number": cur_num,45 "ordinal_number": ord_num,46 "times": times,47 "answer": cur_num + ord_num * times48 }49 ]50 times_only_seq = generate_number_sequence(cur_num, 1, times) # sequence with ordinal number = 151 times_only_questions = [52 {53 "question": f"Let's count up by {times}s. What number is next if we start from {cur_num}?\n{times_only_seq}",54 "current_number": cur_num,55 "ordinal_number": 1,56 "times": times,57 "answer": cur_num + times58 }59 ]60 questions = [*count_up_by_one_questions, *count_up_by_ord_questions, *times_only_questions, *times_ord_questions]61 random_choice = random.choice(questions)62 return random_choice63 64 65def generate_numbers_by_level(level: Literal["easy", "medium", "hard"] = "easy"):66 """generate current number, ordinal number and times parameter67 68 returns69 dict with params:70 :param current_number: current number71 :param ordinal numebr: the number we count up by72 :param times: the number of times we count up by ordinal number"""73 74 if level == "easy":75 cur_num = random.randint(1, 8)76 ord_num = random.randint(1, 2)77 times = 178 elif level == "medium":79 cur_num = random.randint(1, 94)80 ord_num = random.randint(1, 3)81 times = random.randint(1, 2)82 elif level == "hard":83 cur_num = random.randint(1, 488)84 ord_num = random.randint(1, 4)85 times = random.randint(1, 2)86 87 return {88 "current_number": cur_num,89 "ordinal_number": ord_num,90 "times": times91 }92 93 94def generate_number_sequence(cur_num, ord_num, times=1):95 """generate one of 2 sequences. For example we want 55 to be a right answer, then sequences can be:96 52 53 54 ...97 ... 56 57 5898 99 parameters100 :cur_num: current number101 :ord_num: ordinal number102 :times: times"""103 max_num = cur_num + times * ord_num104 105 seq_before = [str(num) for num in range(max_num - times, 0, -times)][:3][::-1]106 seq_after = [str(num) for num in range(max_num + times, max_num + 4 * times, times)]107 seq_before.append("...")108 seq_after.insert(0, "...")109 110 seqs = []111 if len(seq_before) == 4:112 seqs.append(seq_before)113 if len(seq_after) == 4:114 seqs.append(seq_after)115 rand_seq = " ".join(random.choice(seqs))116 return rand_seq117 