Skip to content

Instantly share code, notes, and snippets.

@MarkBaggett
Last active July 31, 2023 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MarkBaggett/9dd4da0807f6b29e7e130381aef0aa00 to your computer and use it in GitHub Desktop.
Save MarkBaggett/9dd4da0807f6b29e7e130381aef0aa00 to your computer and use it in GitHub Desktop.
Base_practice.py allows you to practice converting between bases and binary logic operations. This script goes along with the video lecture that covers the basic concepts. https://youtu.be/qLtCuSTKk4g
import random
#This program will present you with challenges to convert numbers between bases and perform logical operations.
#This program goes along with the following youtube video. https://youtu.be/qLtCuSTKk4g
# Helper function to create conversion functions for different number bases.
def make_conversion_function(choose_from, prompt_text, input_conversion):
def convert_function():
the_number = random.choice(choose_from)
answer = input(eval(prompt_text))
if answer.lower() == input_conversion(the_number).lower():
return True, ""
return False, input_conversion(the_number)
convert_function.operation = prompt_text
return convert_function
# List of numbers close to base 2 for binary to decimal and vice versa conversion exercises.
close_to_base2 = [128, 64, 32, 16, 130, 131, 132, 133, 65, 66, 67, 68, 33, 34, 35, 36, 127, 63, 31, 15]
# Create conversion functions for binary to decimal (bin2dec1) and decimal to binary (dec2bin1) with close-to-base2 numbers.
bin2dec1 = make_conversion_function(
close_to_base2,
'f"What is {the_number:#010b} in decimal? (Answer Format: 999): "',
input_conversion=str
)
dec2bin1 = make_conversion_function(
close_to_base2,
'f"What is {the_number} in binary? (Answer Format: 0b11111111): "',
input_conversion=lambda num: f'{num:#010b}'
)
# Create conversion functions for binary to decimal (bin2dec2) and decimal to binary (dec2bin2) with numbers from 0 to 255.
bin2dec2 = make_conversion_function(
range(256),
'f"What is {the_number:#010b} in decimal? (Answer Format: 999): "',
input_conversion=str
)
dec2bin2 = make_conversion_function(
range(256),
'f"What is {the_number} in binary? (Answer Format: 0b11111111): "',
input_conversion=lambda num: f'{num:#010b}'
)
# Create conversion functions for decimal to hexadecimal (dec2hex) and hexadecimal to decimal (hex2dec) with numbers from 0 to 255.
dec2hex = make_conversion_function(
range(256),
'f"What is {the_number} in hexadecimal? (Answer Format: 0xFF): "',
lambda num: f"{num:#04x}",
)
hex2dec = make_conversion_function(
range(256),
'f"What is {the_number:#04x} in decimal? (Answer Format: 999): "',
str
)
# Create conversion function for hexadecimal to binary (hex2bin) with numbers from 0 to 255.
hex2bin = make_conversion_function(
range(256),
'f"What is {the_number:#04x} in binary? (Answer Format: 0b11111111): "',
lambda num: f"{num:#010b}"
)
# Define logical operation functions for AND, OR, XOR, NAND, NOR, and NXOR.
def logic_operation(op, negate_num2=False):
def op_function(num1=None, num2=None):
num1 = num1 or random.randrange(0,256)
num2 = num2 or random.randrange(0,256)
negate_text = ""
if negate_num2 == True:
negate_text = "NOT"
answer = input(f'\nSolve: {num1:#010b}\n{op+" "+negate_text: >9s} {num2:#010b}\n ==> ')
if negate_num2 == True:
num2 = 0b11111111 - num2
correct = format(eval(f"{num1} {op} {num2}"), '#010b')
if answer == correct:
return True, ''
else:
return False, correct
return op_function
and_operation = logic_operation("&")
or_operation = logic_operation("|")
xor_operation = logic_operation("^")
nand_operation = logic_operation("&", True)
nor_operation = logic_operation("|", True)
nxor_operation = logic_operation("^", True)
# Function to present random conversion or logical operation challenges to the user.
def func_choice(funclist, iterations=20, strikes=3, reset=2):
correct = 0
incorrect = 0
while correct < iterations:
print(f"[{iterations-correct}:{strikes-incorrect}]", end=" ")
choice = random.choice(funclist)
result, ans = choice()
if result:
correct += 1
print(f"\n\nCorrect! Total Correct Answers: {correct} of {iterations}")
print(f"Mistakes before penalty: {strikes - incorrect} remaining.\n")
else:
incorrect += 1
print(f"\n\nIncorrect. The correct answer is {ans}")
print(f"You have {incorrect} strikes {strikes - incorrect} remaining.\n\n")
if incorrect >= strikes:
print("Sorry. You missed too many. Assessing a penalty.")
incorrect = 0
if reset == 0:
print(f"Starting back over from the beginning. You need to get {iterations} answers correct.\n\n")
correct = 0
else:
print(f"You need some more practice. Increasing required challenges by {reset}!\n\n")
iterations += reset
else:
return True
return False
# Main menu and user interaction.
print("Welcome! In information technology, your ability to quickly convert between different bases is very important.")
print("Understanding logical operations is also crucial. Try some challenges to help reinforce your understanding!")
print("The number of labs and mistakes allowed (strikes) change for each lab. Your current status is printed in the square brackets as [# remaining to complete: strikes before penalty]\n")
# Define the menu options and corresponding challenges.
menu_options = {
"Decimal To Binary (easy)": ([dec2bin1], 5, 2),
"Decimal To Binary (hard)": ([dec2bin2], 10, 2, 0),
"Decimal To Hex": ([dec2hex], 5, 2),
"Binary to Decimal (easy)": ([bin2dec1], 5, 2),
"Binary to Decimal (hard)": ([bin2dec2], 10, 2, 0),
"Binary to Hex": ([bin2hex], 5, 2),
"Hex to Binary": ([hex2bin], 5, 2),
"Hex to Decimal": ([hex2dec], 5, 2),
"Random Conversions": ([dec2bin1, dec2hex, bin2dec1, bin2hex, hex2bin, hex2dec], 20, 5, 3),
"AND (&) Operations": ([and_operation], 5, 2),
"OR (|) Operations": ([or_operation], 5, 2),
"XOR (^) Operations": ([xor_operation], 5, 2),
"NOT and AND Operations": ([nand_operation], 10, 2),
"NOT and OR Operation": ([nor_operation], 10, 2),
"NOT and XOR Operation": ([nxor_operation], 10, 2),
"Random Logic": ([and_operation, or_operation, xor_operation, nand_operation, nor_operation, nxor_operation], 20, 5, 3),
}
menu_items = list(menu_options.keys())
menu_text = ""
for position, each_item in enumerate(menu_items):
menu_text += f"{position: >2}) {each_item}\n"
while True:
selection = input(f'Select one of the following exercises to begin\n{menu_text}\n==> ')
if selection.lower() == "q":
break
try:
if not selection.isnumeric() or int(selection) >= len(menu_items):
print("Invalid Menu Option. Enter Q to quit.")
continue
options = menu_options.get(menu_items[int(selection)], "NOT FOUND")
if options == "NOT FOUND":
raise ValueError
except:
print("Invalid Menu Option. Enter Q to quit.")
func_choice(*options)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment