Sina Media Lab commited on
Commit
c9ca893
·
1 Parent(s): a26033f
app.py CHANGED
@@ -1,37 +1,13 @@
1
  import streamlit as st
2
  import importlib
 
3
  from fpdf import FPDF
4
  import uuid
5
 
6
- # List of available modules with shorter names and icons
7
- module_names = {
8
- "Bases": "presentation_bases",
9
- "Validity": "valid_invalid_numbers",
10
- "Conversion": "conversion_bases",
11
- "Grouping": "grouping_techniques",
12
- "Addition": "addition_bases",
13
- "2's Complement": "twos_complement",
14
- "Negative Numbers": "negative_binary",
15
- "Subtraction": "subtraction_bases",
16
- }
17
-
18
- # Module descriptions
19
- module_descriptions = {
20
- "Bases": "This module covers the presentation of numbers in various bases, including binary, octal, decimal, and hexadecimal.",
21
- "Validity": "This module helps determine the validity of numbers in different bases.",
22
- "Conversion": "This module covers conversion techniques between different bases, including with and without fractions.",
23
- "Grouping": "This module focuses on grouping techniques for conversion between bases such as binary and hexadecimal.",
24
- "Addition": "This module covers addition operations in bases like binary, octal, and hexadecimal.",
25
- "2's Complement": "This module explains the 2's complement method for representing negative numbers.",
26
- "Negative Numbers": "This module covers negative binary numbers and their representation.",
27
- "Subtraction": "This module focuses on subtraction operations in binary using the 2's complement method.",
28
- }
29
-
30
- # Initialize unique session state
31
  if 'session_id' not in st.session_state:
32
  st.session_state.session_id = str(uuid.uuid4())
33
 
34
- # Initialize session state variables
35
  if 'questions' not in st.session_state:
36
  st.session_state.questions = []
37
  if 'current_index' not in st.session_state:
@@ -41,9 +17,9 @@ if 'current_module' not in st.session_state:
41
  if 'correct_count' not in st.session_state:
42
  st.session_state.correct_count = 0
43
  if 'module_correct_count' not in st.session_state:
44
- st.session_state.module_correct_count = {name: 0 for name in module_names}
45
  if 'module_question_count' not in st.session_state:
46
- st.session_state.module_question_count = {name: 0 for name in module_names}
47
  if 'pdf_data' not in st.session_state:
48
  st.session_state.pdf_data = None
49
 
@@ -58,12 +34,11 @@ def generate_pdf_report():
58
  pdf.cell(200, 10, txt="Quiz Report", ln=True, align="C")
59
  pdf.ln(10)
60
 
61
- for module in module_names.keys():
62
- pdf.set_text_color(0, 0, 0)
 
63
  pdf.cell(200, 10, txt=f"Module: {module}", ln=True, align="L")
64
  pdf.ln(5)
65
- correct_count = st.session_state.module_correct_count[module]
66
- total_count = st.session_state.module_question_count[module]
67
  pdf.cell(200, 10, txt=f"Correct Answers: {correct_count}/{total_count}", ln=True, align="L")
68
  pdf.ln(5)
69
 
@@ -100,21 +75,29 @@ def generate_pdf_report():
100
 
101
  return pdf.output(dest='S').encode('latin1', 'replace')
102
 
103
- def load_module(module_name):
104
- module_file = module_names[module_name]
105
- module = importlib.import_module(f'modules.{module_file}')
106
- return module
107
-
108
- def generate_new_question(module_name):
109
- module = load_module(module_name)
110
- question_data = module.generate_question()
 
 
 
 
 
 
 
 
111
  # Ensure 'answered' is initialized to False and add the 'module' and 'selected' keys
112
  question_data['answered'] = False
113
  question_data['module'] = module_name # Add the module name to the question data
114
  question_data['selected'] = None # Initialize 'selected' to None
115
- # Ensure there are 5 options
116
- if len(question_data['options']) != 5:
117
- st.warning(f"Question does not have 5 options. Found {len(question_data['options'])}.")
118
  return question_data
119
 
120
  def navigate_question(direction):
@@ -125,30 +108,30 @@ def navigate_question(direction):
125
  st.session_state.current_index += 1
126
  else:
127
  # Generate a new question if at the end of the list
128
- new_question = generate_new_question(st.session_state.current_module)
129
  st.session_state.questions.append(new_question)
130
  st.session_state.current_index += 1
131
 
 
 
 
132
  # Streamlit interface
133
  st.sidebar.title("Quiz Modules")
134
- module_name = st.sidebar.radio("Choose a module:", list(module_names.keys()), index=0)
135
 
136
  if module_name != st.session_state.current_module:
137
  st.session_state.current_module = module_name
138
  st.session_state.current_index = 0
139
- st.session_state.questions = [generate_new_question(module_name)]
 
 
140
 
141
  # Load the current module's question
142
- if st.session_state.current_index < len(st.session_state.questions):
143
- current_question = st.session_state.questions[st.session_state.current_index]
144
- else:
145
- current_question = generate_new_question(st.session_state.current_module)
146
- st.session_state.questions.append(current_question)
147
- st.session_state.current_index = len(st.session_state.questions) - 1
148
 
149
  # Display module title and description
150
- st.title(module_name)
151
- st.write(module_descriptions.get(module_name, "No description available for this module."))
152
  st.write(current_question["question"])
153
 
154
  # Use a form to prevent rerun on option selection
 
1
  import streamlit as st
2
  import importlib
3
+ import os
4
  from fpdf import FPDF
5
  import uuid
6
 
7
+ # Initialize session state variables
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  if 'session_id' not in st.session_state:
9
  st.session_state.session_id = str(uuid.uuid4())
10
 
 
11
  if 'questions' not in st.session_state:
12
  st.session_state.questions = []
13
  if 'current_index' not in st.session_state:
 
17
  if 'correct_count' not in st.session_state:
18
  st.session_state.correct_count = 0
19
  if 'module_correct_count' not in st.session_state:
20
+ st.session_state.module_correct_count = {}
21
  if 'module_question_count' not in st.session_state:
22
+ st.session_state.module_question_count = {}
23
  if 'pdf_data' not in st.session_state:
24
  st.session_state.pdf_data = None
25
 
 
34
  pdf.cell(200, 10, txt="Quiz Report", ln=True, align="C")
35
  pdf.ln(10)
36
 
37
+ for module, data in st.session_state.module_question_count.items():
38
+ correct_count = st.session_state.module_correct_count.get(module, 0)
39
+ total_count = data
40
  pdf.cell(200, 10, txt=f"Module: {module}", ln=True, align="L")
41
  pdf.ln(5)
 
 
42
  pdf.cell(200, 10, txt=f"Correct Answers: {correct_count}/{total_count}", ln=True, align="L")
43
  pdf.ln(5)
44
 
 
75
 
76
  return pdf.output(dest='S').encode('latin1', 'replace')
77
 
78
+ def load_modules():
79
+ modules = {}
80
+ module_dir = "modules"
81
+ for filename in os.listdir(module_dir):
82
+ if filename.endswith(".py") and filename != "__init__.py":
83
+ module_name = filename[:-3]
84
+ module = importlib.import_module(f"{module_dir}.{module_name}")
85
+ modules[module_name] = {
86
+ "title": getattr(module, "title", module_name),
87
+ "description": getattr(module, "description", "No description available."),
88
+ "generate_question": module.generate_question
89
+ }
90
+ return modules
91
+
92
+ def generate_new_question(module_name, module):
93
+ question_data = module['generate_question']()
94
  # Ensure 'answered' is initialized to False and add the 'module' and 'selected' keys
95
  question_data['answered'] = False
96
  question_data['module'] = module_name # Add the module name to the question data
97
  question_data['selected'] = None # Initialize 'selected' to None
98
+ # Ensure there are exactly 4 options
99
+ if len(question_data['options']) != 4:
100
+ st.warning(f"Question in module '{module_name}' does not have 4 options. Found {len(question_data['options'])}.")
101
  return question_data
102
 
103
  def navigate_question(direction):
 
108
  st.session_state.current_index += 1
109
  else:
110
  # Generate a new question if at the end of the list
111
+ new_question = generate_new_question(st.session_state.current_module, modules[st.session_state.current_module])
112
  st.session_state.questions.append(new_question)
113
  st.session_state.current_index += 1
114
 
115
+ # Load all modules dynamically
116
+ modules = load_modules()
117
+
118
  # Streamlit interface
119
  st.sidebar.title("Quiz Modules")
120
+ module_name = st.sidebar.radio("Choose a module:", list(modules.keys()), index=0)
121
 
122
  if module_name != st.session_state.current_module:
123
  st.session_state.current_module = module_name
124
  st.session_state.current_index = 0
125
+ st.session_state.questions = [generate_new_question(module_name, modules[module_name])]
126
+ st.session_state.module_question_count[module_name] = 0
127
+ st.session_state.module_correct_count[module_name] = 0
128
 
129
  # Load the current module's question
130
+ current_question = st.session_state.questions[st.session_state.current_index]
 
 
 
 
 
131
 
132
  # Display module title and description
133
+ st.title(modules[module_name]["title"])
134
+ st.write(modules[module_name]["description"])
135
  st.write(current_question["question"])
136
 
137
  # Use a form to prevent rerun on option selection
modules/addition_bases.py CHANGED
@@ -1,46 +1,44 @@
1
- import random
 
 
 
2
 
3
  def generate_question():
4
- base = random.choice([2, 8, 10, 16])
5
- num1 = random.randint(1, 15)
6
- num2 = random.randint(1, 15)
7
 
8
- if base == 10:
9
- num1_rep = str(num1)
10
- num2_rep = str(num2)
11
- elif base == 2:
12
- num1_rep = bin(num1)[2:]
13
- num2_rep = bin(num2)[2:]
14
- elif base == 8:
15
- num1_rep = oct(num1)[2:]
16
- num2_rep = oct(num2)[2:]
17
- elif base == 16:
18
- num1_rep = hex(num1)[2:].upper()
19
- num2_rep = hex(num2)[2:].upper()
20
 
21
- sum_decimal = num1 + num2
22
- if base == 10:
23
- correct_answer = str(sum_decimal)
24
- elif base == 2:
25
- correct_answer = bin(sum_decimal)[2:]
26
- elif base == 8:
27
- correct_answer = oct(sum_decimal)[2:]
28
- elif base == 16:
29
- correct_answer = hex(sum_decimal)[2:].upper()
30
 
31
- steps = [
32
- f"Convert {num1_rep} and {num2_rep} to decimal if needed.",
33
- f"Add the numbers: {num1} + {num2} = {sum_decimal} in decimal.",
34
- f"Convert {sum_decimal} from decimal to base {base}.",
35
- f"The result in base {base} is {correct_answer}."
36
- ]
37
 
38
- question_data = {
39
- "question": f"Add the numbers {num1_rep} and {num2_rep} in base {base}.",
40
- "options": [correct_answer] + [str(random.randint(1, 30)) for _ in range(3)],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  "correct_answer": correct_answer,
42
- "explanation": f"The sum of {num1_rep} and {num2_rep} in base {base} is {correct_answer}.",
43
- "step_by_step_solution": steps
44
  }
45
-
46
- return question_data
 
1
+ # modules/addition_bases.py
2
+
3
+ title = "Addition in Various Bases"
4
+ description = "This module covers addition operations in bases like binary, octal, and hexadecimal."
5
 
6
  def generate_question():
7
+ import random
 
 
8
 
9
+ base = random.choice([2, 8, 16])
10
+ num1 = ''.join(random.choice('0123456789ABCDEF') for _ in range(3))
11
+ num2 = ''.join(random.choice('0123456789ABCDEF') for _ in range(3))
 
 
 
 
 
 
 
 
 
12
 
13
+ def add_numbers(num1, num2, base):
14
+ return hex(int(num1, base) + int(num2, base))[2:].upper() if base == 16 else \
15
+ oct(int(num1, base) + int(num2, base))[2:] if base == 8 else \
16
+ bin(int(num1, base) + int(num2, base))[2:] if base == 2 else \
17
+ str(int(num1) + int(num2))
 
 
 
 
18
 
19
+ correct_answer = add_numbers(num1, num2, base)
20
+ options = [correct_answer]
 
 
 
 
21
 
22
+ # Generate incorrect answers
23
+ while len(options) < 4:
24
+ invalid_answer = ''.join(random.choice('0123456789ABCDEF') for _ in range(4))
25
+ if invalid_answer != correct_answer:
26
+ options.append(invalid_answer)
27
+
28
+ random.shuffle(options)
29
+
30
+ question = f"Add the numbers {num1} and {num2} in base {base}."
31
+ explanation = f"The sum of {num1} and {num2} in base {base} is {correct_answer}."
32
+ step_by_step_solution = [
33
+ f"Step 1: Convert the numbers {num1} and {num2} to base 10.",
34
+ "Step 2: Add the numbers in base 10.",
35
+ f"Step 3: Convert the sum back to base {base}."
36
+ ]
37
+
38
+ return {
39
+ "question": question,
40
+ "options": options,
41
  "correct_answer": correct_answer,
42
+ "explanation": explanation,
43
+ "step_by_step_solution": step_by_step_solution
44
  }
 
 
modules/conversion_bases.py CHANGED
@@ -1,41 +1,51 @@
1
- import random
 
 
 
2
 
3
  def generate_question():
4
- base_from = random.choice([2, 8, 10, 16])
5
- base_to = random.choice([2, 8, 10, 16])
6
- number = random.randint(1, 255)
7
 
8
- if base_from == 10:
9
- number_rep = str(number)
10
- elif base_from == 2:
11
- number_rep = bin(number)[2:]
12
- elif base_from == 8:
13
- number_rep = oct(number)[2:]
14
- elif base_from == 16:
15
- number_rep = hex(number)[2:].upper()
16
 
17
- if base_to == 10:
18
- correct_answer = str(int(number_rep, base_from))
19
- elif base_to == 2:
20
- correct_answer = bin(int(number_rep, base_from))[2:]
21
- elif base_to == 8:
22
- correct_answer = oct(int(number_rep, base_from))[2:]
23
- elif base_to == 16:
24
- correct_answer = hex(int(number_rep, base_from))[2:].upper()
 
 
 
 
25
 
26
- steps = [
27
- f"Convert the number {number_rep} from base {base_from} to decimal.",
28
- f"Result: {int(number_rep, base_from)} in decimal.",
29
- f"Now, convert {int(number_rep, base_from)} from decimal to base {base_to}.",
30
- f"Final result: {correct_answer}."
31
- ]
32
 
33
- question_data = {
34
- "question": f"Convert the number {number_rep} from base {base_from} to base {base_to}.",
35
- "options": [correct_answer] + [str(random.randint(1, 255)) for _ in range(3)],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  "correct_answer": correct_answer,
37
- "explanation": f"The number {number_rep} in base {base_from} is {correct_answer} in base {base_to}.",
38
- "step_by_step_solution": steps
39
  }
40
-
41
- return question_data
 
1
+ # modules/conversion_bases.py
2
+
3
+ title = "Conversion Between Bases"
4
+ description = "This module covers conversion techniques between different bases, including with and without fractions."
5
 
6
  def generate_question():
7
+ import random
 
 
8
 
9
+ from_base = random.choice([2, 8, 10, 16])
10
+ to_base = random.choice([2, 8, 10, 16])
11
+ number = ''.join(random.choice('0123456789ABCDEF') for _ in range(4))
 
 
 
 
 
12
 
13
+ def convert_number(number, from_base, to_base):
14
+ # Convert from `from_base` to base 10
15
+ base_10 = int(number, from_base)
16
+ # Convert from base 10 to `to_base`
17
+ if to_base == 10:
18
+ return str(base_10)
19
+ elif to_base == 16:
20
+ return hex(base_10)[2:].upper()
21
+ elif to_base == 8:
22
+ return oct(base_10)[2:]
23
+ elif to_base == 2:
24
+ return bin(base_10)[2:]
25
 
26
+ correct_answer = convert_number(number, from_base, to_base)
27
+ options = [correct_answer]
 
 
 
 
28
 
29
+ # Generate incorrect answers
30
+ while len(options) < 4:
31
+ invalid_number = ''.join(random.choice('0123456789ABCDEF') for _ in range(4))
32
+ if invalid_number != correct_answer:
33
+ options.append(invalid_number)
34
+
35
+ random.shuffle(options)
36
+
37
+ question = f"Convert the number {number} from base {from_base} to base {to_base}."
38
+ explanation = f"The number {number} in base {from_base} is {correct_answer} in base {to_base}."
39
+ step_by_step_solution = [
40
+ f"Step 1: Convert the number {number} from base {from_base} to base 10.",
41
+ f"Step 2: Convert the base 10 number to base {to_base}.",
42
+ f"Step 3: The correct answer is {correct_answer}."
43
+ ]
44
+
45
+ return {
46
+ "question": question,
47
+ "options": options,
48
  "correct_answer": correct_answer,
49
+ "explanation": explanation,
50
+ "step_by_step_solution": step_by_step_solution
51
  }
 
 
modules/grouping_techniques.py CHANGED
@@ -1,30 +1,49 @@
1
- import random
2
 
3
- title = "Grouping Techniques for Base Conversion"
4
- description = "This module covers the techniques used for converting binary numbers to octal and hexadecimal by grouping bits."
5
 
6
  def generate_question():
7
- binary_num = bin(random.randint(1, 63))[2:]
8
- padded_binary = binary_num.zfill(len(binary_num) + (3 - len(binary_num) % 3) % 3)
9
-
10
- octal = ''.join([str(int(padded_binary[i:i+3], 2)) for i in range(0, len(padded_binary), 3)])
11
-
12
- question = f"Group the binary number {binary_num} into octal."
13
- correct_answer = octal
 
 
 
 
 
 
 
 
 
 
 
14
  options = [correct_answer]
15
-
16
- # Generate incorrect options
17
- while len(options) < 5:
18
- fake_option = ''.join([str(random.randint(0, 7)) for _ in range(len(octal))])
19
- if fake_option not in options:
20
- options.append(fake_option)
21
 
22
  random.shuffle(options)
23
- explanation = (
24
- f"The binary number {binary_num} is grouped into octal as {octal}."
25
- "\n\n**Step-by-step solution:**\n"
26
- "1. Pad the binary number with leading zeros to make its length a multiple of 3.\n"
27
- "2. Group the binary digits in groups of three, starting from the right.\n"
28
- "3. Convert each group to its octal equivalent."
29
- )
30
- return question, options, correct_answer, explanation
 
 
 
 
 
 
 
 
 
1
+ # modules/grouping_techniques.py
2
 
3
+ title = "Grouping Techniques for Conversion"
4
+ description = "This module focuses on grouping techniques for conversion between bases such as binary and hexadecimal."
5
 
6
  def generate_question():
7
+ import random
8
+
9
+ from_base = random.choice([2, 8, 16])
10
+ to_base = 8 if from_base == 2 else 2
11
+ number = ''.join(random.choice('01') for _ in range(8))
12
+
13
+ def group_conversion(number, from_base, to_base):
14
+ # Group the binary digits for conversion
15
+ if from_base == 2 and to_base == 8:
16
+ return oct(int(number, 2))[2:]
17
+ elif from_base == 2 and to_base == 16:
18
+ return hex(int(number, 2))[2:].upper()
19
+ elif from_base == 8 and to_base == 2:
20
+ return bin(int(number, 8))[2:]
21
+ elif from_base == 16 and to_base == 2:
22
+ return bin(int(number, 16))[2:]
23
+
24
+ correct_answer = group_conversion(number, from_base, to_base)
25
  options = [correct_answer]
26
+
27
+ # Generate incorrect answers
28
+ while len(options) < 4:
29
+ invalid_number = ''.join(random.choice('01234567') for _ in range(4))
30
+ if invalid_number != correct_answer:
31
+ options.append(invalid_number)
32
 
33
  random.shuffle(options)
34
+
35
+ question = f"Convert the binary number {number} from base {from_base} to base {to_base} using grouping technique."
36
+ explanation = f"The number {number} in base {from_base} is {correct_answer} in base {to_base} using grouping technique."
37
+ step_by_step_solution = [
38
+ "Step 1: Group the binary digits in sets of 3 (for base 8) or 4 (for base 16).",
39
+ "Step 2: Convert each group to the corresponding digit in the target base.",
40
+ "Step 3: Combine the digits to form the final answer."
41
+ ]
42
+
43
+ return {
44
+ "question": question,
45
+ "options": options,
46
+ "correct_answer": correct_answer,
47
+ "explanation": explanation,
48
+ "step_by_step_solution": step_by_step_solution
49
+ }
modules/negative_binary.py CHANGED
@@ -1,29 +1,39 @@
1
- import random
2
 
3
- title = "Negative Numbers in Binary"
4
- description = "This module focuses on the binary representation of negative numbers using 2's complement and other methods."
5
 
6
  def generate_question():
7
- num = random.randint(-8, -1)
8
- bit_length = 4
9
- binary = bin((1 << bit_length) + num)[2:]
10
-
11
- question = f"What is the binary representation of {num} using 4 bits?"
12
- correct_answer = binary
 
 
 
13
  options = [correct_answer]
14
-
15
- # Generate incorrect options
16
- while len(options) < 5:
17
- fake_option = bin(random.randint(-8, -1) & 0xF)[2:]
18
- if fake_option not in options:
19
- options.append(fake_option)
20
 
21
  random.shuffle(options)
22
- explanation = (
23
- f"The binary representation of {num} using 4 bits is {binary}."
24
- "\n\n**Step-by-step solution:**\n"
25
- "1. Convert the absolute value of the negative number to binary.\n"
26
- "2. Find the 2's complement of the binary number to represent the negative number.\n"
27
- "3. The result is the binary representation of the negative number."
28
- )
29
- return question, options, correct_answer, explanation
 
 
 
 
 
 
 
 
1
+ # modules/negative_binary.py
2
 
3
+ title = "Negative Binary Numbers"
4
+ description = "This module covers negative binary numbers and their representation."
5
 
6
  def generate_question():
7
+ import random
8
+
9
+ number = ''.join(random.choice('01') for _ in range(8))
10
+
11
+ def calculate_negative_binary(number):
12
+ # Example logic: return a simple 2's complement representation
13
+ return bin(int(number, 2) * -1)[3:].zfill(len(number))
14
+
15
+ correct_answer = calculate_negative_binary(number)
16
  options = [correct_answer]
17
+
18
+ # Generate incorrect answers
19
+ while len(options) < 4:
20
+ invalid_number = ''.join(random.choice('01') for _ in range(8))
21
+ if invalid_number != correct_answer:
22
+ options.append(invalid_number)
23
 
24
  random.shuffle(options)
25
+
26
+ question = f"What is the negative representation of the binary number {number}?"
27
+ explanation = f"The negative binary representation of {number} is {correct_answer}."
28
+ step_by_step_solution = [
29
+ "Step 1: Determine the 2's complement of the binary number.",
30
+ "Step 2: The result is the negative binary representation."
31
+ ]
32
+
33
+ return {
34
+ "question": question,
35
+ "options": options,
36
+ "correct_answer": correct_answer,
37
+ "explanation": explanation,
38
+ "step_by_step_solution": step_by_step_solution
39
+ }
modules/presentation_bases.py CHANGED
@@ -1,20 +1,35 @@
1
- import random
2
 
3
- def generate_question():
4
- number = random.randint(1, 15)
5
- binary_rep = bin(number)[2:].zfill(4)
6
 
7
- question_data = {
8
- "question": f"What is the binary representation of the decimal number {number}?",
9
- "options": [bin(i)[2:].zfill(4) for i in random.sample(range(1, 16), 4)],
10
- "correct_answer": binary_rep,
11
- "explanation": f"The decimal number {number} is represented as {binary_rep} in binary.",
12
- "step_by_step_solution": [
13
- f"1. Start with the decimal number {number}.",
14
- "2. Divide the number by 2 and note the quotient and remainder.",
15
- "3. Continue dividing the quotient by 2 until you reach 0.",
16
- "4. The binary representation is formed by reading the remainders from bottom to top."
17
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
-
20
- return question_data
 
1
+ # modules/presentation_bases.py
2
 
3
+ title = "Bases"
4
+ description = "This module covers the presentation of numbers in various bases, including binary, octal, decimal, and hexadecimal."
 
5
 
6
+ def generate_question():
7
+ import random
8
+ # Generate a random base
9
+ base = random.choice([2, 8, 10, 16])
10
+ # Generate a valid number in that base
11
+ number = ''.join(random.choice('0123456789ABCDEF') for _ in range(4))
12
+ # Generate incorrect answers
13
+ correct_answer = number
14
+ options = [correct_answer]
15
+ while len(options) < 4:
16
+ invalid_number = ''.join(random.choice('0123456789ABCDEF') for _ in range(4))
17
+ if invalid_number != correct_answer:
18
+ options.append(invalid_number)
19
+ random.shuffle(options)
20
+
21
+ question = f"What is the representation of {number} in base {base}?"
22
+ explanation = f"The number {number} in base {base} is {correct_answer}."
23
+ step_by_step_solution = [
24
+ "Step 1: Identify the digits.",
25
+ "Step 2: Convert each digit based on the base.",
26
+ "Step 3: Combine the digits to form the final answer."
27
+ ]
28
+
29
+ return {
30
+ "question": question,
31
+ "options": options,
32
+ "correct_answer": correct_answer,
33
+ "explanation": explanation,
34
+ "step_by_step_solution": step_by_step_solution
35
  }
 
 
modules/subtraction_bases.py CHANGED
@@ -1,46 +1,44 @@
1
- import random
 
 
 
2
 
3
  def generate_question():
4
- base = random.choice([2, 8, 10, 16])
5
- num1 = random.randint(10, 15)
6
- num2 = random.randint(1, 9)
7
 
8
- if base == 10:
9
- num1_rep = str(num1)
10
- num2_rep = str(num2)
11
- elif base == 2:
12
- num1_rep = bin(num1)[2:]
13
- num2_rep = bin(num2)[2:]
14
- elif base == 8:
15
- num1_rep = oct(num1)[2:]
16
- num2_rep = oct(num2)[2:]
17
- elif base == 16:
18
- num1_rep = hex(num1)[2:].upper()
19
- num2_rep = hex(num2)[2:].upper()
20
 
21
- difference_decimal = num1 - num2
22
- if base == 10:
23
- correct_answer = str(difference_decimal)
24
- elif base == 2:
25
- correct_answer = bin(difference_decimal)[2:]
26
- elif base == 8:
27
- correct_answer = oct(difference_decimal)[2:]
28
- elif base == 16:
29
- correct_answer = hex(difference_decimal)[2:].upper()
30
 
31
- steps = [
32
- f"Convert {num1_rep} and {num2_rep} to decimal if needed.",
33
- f"Subtract the numbers: {num1} - {num2} = {difference_decimal} in decimal.",
34
- f"Convert {difference_decimal} from decimal to base {base}.",
35
- f"The result in base {base} is {correct_answer}."
36
- ]
37
 
38
- question_data = {
39
- "question": f"Subtract {num2_rep} from {num1_rep} in base {base}.",
40
- "options": [correct_answer] + [str(random.randint(1, 10)) for _ in range(3)],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  "correct_answer": correct_answer,
42
- "explanation": f"The result of subtracting {num2_rep} from {num1_rep} in base {base} is {correct_answer}.",
43
- "step_by_step_solution": steps
44
  }
45
-
46
- return question_data
 
1
+ # modules/subtraction_bases.py
2
+
3
+ title = "Subtraction in Bases"
4
+ description = "This module focuses on subtraction operations in binary using the 2's complement method."
5
 
6
  def generate_question():
7
+ import random
 
 
8
 
9
+ base = random.choice([2, 8, 16])
10
+ num1 = ''.join(random.choice('0123456789ABCDEF') for _ in range(3))
11
+ num2 = ''.join(random.choice('0123456789ABCDEF') for _ in range(3))
 
 
 
 
 
 
 
 
 
12
 
13
+ def subtract_numbers(num1, num2, base):
14
+ return hex(int(num1, base) - int(num2, base))[2:].upper() if base == 16 else \
15
+ oct(int(num1, base) - int(num2, base))[2:] if base == 8 else \
16
+ bin(int(num1, base) - int(num2, base))[2:] if base == 2 else \
17
+ str(int(num1) - int(num2))
 
 
 
 
18
 
19
+ correct_answer = subtract_numbers(num1, num2, base)
20
+ options = [correct_answer]
 
 
 
 
21
 
22
+ # Generate incorrect answers
23
+ while len(options) < 4:
24
+ invalid_answer = ''.join(random.choice('0123456789ABCDEF') for _ in range(4))
25
+ if invalid_answer != correct_answer:
26
+ options.append(invalid_answer)
27
+
28
+ random.shuffle(options)
29
+
30
+ question = f"Subtract the number {num2} from {num1} in base {base}."
31
+ explanation = f"The result of subtracting {num2} from {num1} in base {base} is {correct_answer}."
32
+ step_by_step_solution = [
33
+ f"Step 1: Convert the numbers {num1} and {num2} to base 10.",
34
+ "Step 2: Subtract the numbers in base 10.",
35
+ f"Step 3: Convert the result back to base {base}."
36
+ ]
37
+
38
+ return {
39
+ "question": question,
40
+ "options": options,
41
  "correct_answer": correct_answer,
42
+ "explanation": explanation,
43
+ "step_by_step_solution": step_by_step_solution
44
  }
 
 
modules/twos_complement.py CHANGED
@@ -1,28 +1,41 @@
1
- import random
 
 
 
2
 
3
  def generate_question():
4
- binary_number = bin(random.randint(1, 15))[2:].zfill(4)
5
 
6
- def twos_complement(binary_str):
7
- n = len(binary_str)
8
- ones_complement = ''.join('1' if bit == '0' else '0' for bit in binary_str)
9
- twos_complement_result = bin(int(ones_complement, 2) + 1)[2:].zfill(n)
10
- return twos_complement_result[-n:]
11
 
12
- correct_answer = twos_complement(binary_number)
 
 
 
 
13
 
14
- steps = [
15
- f"Start with the binary number: {binary_number}.",
16
- f"Find the 1's complement by flipping each bit: {''.join('1' if bit == '0' else '0' for bit in binary_number)}.",
17
- f"Add 1 to the 1's complement to get the 2's complement: {correct_answer}.",
18
- ]
19
 
20
- question_data = {
21
- "question": f"What is the 2's complement of the binary number {binary_number}?",
22
- "options": [correct_answer] + [bin(random.randint(1, 15))[2:].zfill(4) for _ in range(3)],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  "correct_answer": correct_answer,
24
- "explanation": f"The 2's complement of the binary number {binary_number} is {correct_answer}.",
25
- "step_by_step_solution": steps
26
  }
27
-
28
- return question_data
 
1
+ # modules/twos_complement.py
2
+
3
+ title = "2's Complement Questions"
4
+ description = "This module explains the 2's complement method for representing negative numbers."
5
 
6
  def generate_question():
7
+ import random
8
 
9
+ number = ''.join(random.choice('01') for _ in range(8))
 
 
 
 
10
 
11
+ def calculate_twos_complement(number):
12
+ n = len(number)
13
+ ones_complement = ''.join('1' if bit == '0' else '0' for bit in number)
14
+ twos_complement = bin(int(ones_complement, 2) + 1)[2:]
15
+ return twos_complement.zfill(n)
16
 
17
+ correct_answer = calculate_twos_complement(number)
18
+ options = [correct_answer]
 
 
 
19
 
20
+ # Generate incorrect answers
21
+ while len(options) < 4:
22
+ invalid_number = ''.join(random.choice('01') for _ in range(8))
23
+ if invalid_number != correct_answer:
24
+ options.append(invalid_number)
25
+
26
+ random.shuffle(options)
27
+
28
+ question = f"What is the 2's complement of the binary number {number}?"
29
+ explanation = f"The 2's complement of {number} is {correct_answer}."
30
+ step_by_step_solution = [
31
+ "Step 1: Find the 1's complement by flipping all bits.",
32
+ "Step 2: Add 1 to the 1's complement to get the 2's complement."
33
+ ]
34
+
35
+ return {
36
+ "question": question,
37
+ "options": options,
38
  "correct_answer": correct_answer,
39
+ "explanation": explanation,
40
+ "step_by_step_solution": step_by_step_solution
41
  }
 
 
modules/valid_invalid_numbers.py CHANGED
@@ -1,40 +1,45 @@
1
- import random
 
 
 
2
 
3
  def generate_question():
 
 
4
  base = random.choice([2, 8, 10, 16])
5
  length = random.randint(3, 5)
6
 
7
  def generate_valid_number():
8
  return ''.join([str(random.randint(0, base - 1)) for _ in range(length)])
9
-
10
  def generate_invalid_number():
11
- if base <= 9:
12
- valid_digits = ''.join([str(random.randint(0, base - 1)) for _ in range(length - 1)])
13
- invalid_digit = str(random.randint(base, 9))
14
- return valid_digits + invalid_digit
15
- else:
16
- # For bases higher than 9 (base 10 and base 16), generate an invalid number differently.
17
- valid_digits = [str(random.randint(0, base - 1)) for _ in range(length - 1)]
18
- invalid_digit = chr(random.randint(65, 70)) # Use A-F for invalid hex digits
19
- valid_digits[random.randint(0, length - 2)] = invalid_digit
20
- return ''.join(valid_digits)
21
 
22
  correct_answer = generate_invalid_number()
23
- options = [correct_answer] + [generate_valid_number() for _ in range(3)]
24
- random.shuffle(options)
25
 
26
- steps = [
27
- f"Check if all digits are within the valid range for base {base}.",
28
- f"In base {base}, valid digits are 0 to {base-1}.",
29
- f"The number {correct_answer} contains a digit outside this range, so it is invalid."
 
 
 
 
 
 
 
 
 
 
30
  ]
31
-
32
- question_data = {
33
- "question": f"Which of the following is an invalid number in base {base}?",
34
  "options": options,
35
  "correct_answer": correct_answer,
36
- "explanation": f"The number {correct_answer} is invalid in base {base} because it contains a digit outside the range 0-{base-1}.",
37
- "step_by_step_solution": steps
38
  }
39
-
40
- return question_data
 
1
+ # modules/valid_invalid_numbers.py
2
+
3
+ title = "Validity of Numbers in Bases"
4
+ description = "This module helps determine the validity of numbers in different bases like binary, octal, decimal, and hexadecimal."
5
 
6
  def generate_question():
7
+ import random
8
+
9
  base = random.choice([2, 8, 10, 16])
10
  length = random.randint(3, 5)
11
 
12
  def generate_valid_number():
13
  return ''.join([str(random.randint(0, base - 1)) for _ in range(length)])
14
+
15
  def generate_invalid_number():
16
+ valid_digits = ''.join([str(random.randint(0, base - 1)) for _ in range(length - 1)])
17
+ invalid_digit = str(random.randint(base, 9))
18
+ return valid_digits + invalid_digit
 
 
 
 
 
 
 
19
 
20
  correct_answer = generate_invalid_number()
21
+ options = [correct_answer]
 
22
 
23
+ # Generate valid options
24
+ while len(options) < 4:
25
+ valid_option = generate_valid_number()
26
+ if valid_option not in options:
27
+ options.append(valid_option)
28
+
29
+ random.shuffle(options)
30
+
31
+ question = f"Which of the following is an invalid number in base {base}?"
32
+ explanation = f"The number {correct_answer} is invalid in base {base} because it contains a digit outside the range 0-{base-1}."
33
+ step_by_step_solution = [
34
+ "Step 1: Identify the valid digits for the base.",
35
+ "Step 2: Check each option to see if it contains any invalid digits.",
36
+ "Step 3: The correct answer will have a digit that is not allowed in the specified base."
37
  ]
38
+
39
+ return {
40
+ "question": question,
41
  "options": options,
42
  "correct_answer": correct_answer,
43
+ "explanation": explanation,
44
+ "step_by_step_solution": step_by_step_solution
45
  }