Created
August 25, 2021 00:13
-
-
Save Mathsmaniac/eae6497e23e86e65eea92870f5ebb0b6 to your computer and use it in GitHub Desktop.
Fully working program v2 with differences to quitting the program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Elements Quiz project-fully working program combining all 4.5 components v2 | |
Includes post usability testing changes: | |
Differences to quitting the program | |
Written by Nathan Smith | |
25/08/21""" | |
import ast | |
import random | |
def search_dict(value, dictionary): | |
for thing in dictionary: | |
if dictionary[thing] == value: | |
return thing | |
# Raises ValueError if the value is not found in the dict | |
raise ValueError | |
# Making sure that the input is valid and | |
# getting the values that correspond to the difficulty level selected | |
def checkinput(): | |
global quitting | |
while True: | |
difficulty = input("\nPlease enter '1' for easiest, '2' for medium, " | |
"'3' for hard, '4' for very hard, or '5' fo" | |
"r extremely hard: ") | |
if difficulty == 'q': | |
quitting = 1 | |
break | |
try: | |
difficulty = int(difficulty) | |
except ValueError: | |
# Prints "Oops!" and skips the rest of the loop | |
# so that the loop starts again | |
print("Oops!, try again!") | |
continue | |
if MIN_DIFFICULTY <= difficulty <= MAX_DIFFICULTY: | |
break | |
else: | |
print("Oops!, try again!") | |
continue | |
return difficulty | |
def check_spell(correct_answer, user_answer): | |
correct_list = [] | |
checking_list = [] | |
errors = 0 | |
# Putting all the words into lists so that I can manage them easier | |
for letter in correct_answer: | |
correct_list.append(letter.lower()) | |
for letter in user_answer: | |
checking_list.append(letter.lower()) | |
# If the length is not the right length or is not 1 | |
# over the right length, the word must have more than 1 | |
# error in it so it is automatically returning bad | |
# If the word is 1 letter over then that's fine because the spell | |
# checker lets through 1 mistake and an added letter is a mistake | |
if len(checking_list)-1 == len(correct_list) or\ | |
len(checking_list) == len(correct_list): | |
pass | |
else: | |
return "bad" | |
# If the word is the right length then it does this bit of code | |
if len(checking_list) == len(correct_list): | |
# Goes through every letter of the word and | |
# checks it against the exemplar | |
for a in range(len(checking_list)): | |
if correct_list[a] == checking_list[a]: | |
pass | |
else: | |
try: | |
# This means that if the letters are mixed up it only | |
# gives 1 error in total, not 2 | |
if (correct_list[a] == checking_list[a-1] and | |
correct_list[a-1] == checking_list[a]) or \ | |
(correct_list[a] == checking_list[a+1] and | |
correct_list[a+1] == checking_list[a]): | |
errors += 0.5 | |
else: | |
errors += 1 | |
except IndexError: | |
errors += 1 | |
# This bit sees if the extra letter is the only mistake in the word | |
else: | |
for e in range(len(checking_list)-1): | |
if correct_list[e] == checking_list[e]: | |
pass | |
else: | |
if len(checking_list) == len(correct_list)+1: | |
del checking_list[e] | |
errors += 1 | |
if errors > 1: | |
return "bad" | |
else: | |
return "fine" | |
def make_question(): | |
# If foo is 1, the question will be about the element | |
# (Asking what the element with a particular symbol is) | |
# If it is 2, it's the opposite | |
foo = random.randint(1, 2) | |
# Randomly chooses a symbol from the using_dict | |
bar = random.choice(list(using_dict.values())) | |
if foo == 1: | |
question_element = bar | |
# Searches the dict for the element that corresponds to the symbol | |
answer_element = (search_dict(question_element, my_dict)) | |
question = "\nWhat is the name of the element with the chemical " \ | |
"symbol: {}? ".format(question_element) | |
return [question, answer_element, "element"] | |
else: | |
# Same as above, sets the question and answer | |
question_element = (search_dict(bar, using_dict)) | |
answer_element = bar | |
question = "\nWhat is the chemical symbol of the " \ | |
"element: {}? ".format(question_element) | |
return [question, answer_element, "symbol"] | |
def ask_question(question, answer, question_type): | |
# Makes these variables so that the function can edit | |
# them throughout the program | |
global right_answers | |
global wrong_answers | |
global quitting | |
# Makes it so that it only spell checks if it is asking for the element | |
if question_type == "element": | |
tries = 0 | |
# Gets the input | |
user_answer = input(question) | |
while True: | |
# Makes it so that it is not case sensitive | |
if user_answer.lower() == answer.lower(): | |
print("Correct!") | |
right_answers += 1 | |
break | |
# If the user inputs 'q' then it will quit the program | |
elif user_answer.lower() == "q": | |
# Sets quitting to 1 and stops the function | |
quitting = 1 | |
return | |
else: | |
# If it is wrong, run it through the spell checking function | |
foo = check_spell(answer, user_answer) | |
if foo == "bad": | |
print("Sorry, that was not the correct answer, " | |
"\nThe correct answer was: {}\n".format(answer)) | |
wrong_answers += 1 | |
break | |
else: | |
# Makes it so that once they have spelt it wrong once | |
# they can only have one more try to get it right | |
if tries < MAX_TRIES: | |
print("Are you sure you've spelt that" | |
" correctly?\nHave another go: \n") | |
user_answer = input(question) | |
tries += 1 | |
continue | |
else: | |
print("Sorry, that was not the correct answer, " | |
"\nThe correct answer was: {}\n".format(answer)) | |
wrong_answers += 1 | |
break | |
else: | |
# The part for if it is asking about a symbol | |
user_answer = input(question) | |
if user_answer == answer: | |
print("Correct!") | |
right_answers += 1 | |
# Makes it so that if the error is in the case | |
# then it tells the user that | |
elif user_answer.lower() == 'q': | |
# Sets quitting to one and stops the function | |
quitting = 1 | |
return | |
elif user_answer.lower() == answer.lower(): | |
print("Sorry, that's incorrect, remember" | |
" that the symbols are case sensitive") | |
wrong_answers += 1 | |
else: | |
print("Sorry, that was not the correct answer, " | |
"\nThe correct answer was: {}\n".format(answer)) | |
wrong_answers += 1 | |
def make_dict(): | |
# Gets the difficulty and takes off the required amounts of elements | |
# from the end of the dictionary | |
global dif | |
dif = checkinput() | |
if quitting == 0: | |
if MIN_DIFFICULTY <= dif <= 4: | |
for i in range(100 - (dif * 20) + 18): | |
using_dict.popitem() | |
else: | |
pass | |
# Opens the file "Elements.txt" and makes it into dictionary form | |
file = open("Elements.txt", "r") | |
contents = file.read() | |
my_dict = ast.literal_eval(contents) | |
file.close() | |
# Making a copy of the dictionary for the elements I'm actually going to use | |
using_dict = my_dict.copy() | |
# Defining some variables and constants | |
counter = 0 | |
MIN_DIFFICULTY = 1 | |
MAX_DIFFICULTY = 5 | |
ALL_ELEMENT_NUMBER = 118 | |
right_answers = 0 | |
wrong_answers = 0 | |
MAX_TRIES = 1 | |
dif = 0 | |
quitting = 0 | |
print("Welcome to the elements quiz! A few notes before you start:") | |
print("The symbols (e.g Na) are case sensitive but the names for the" | |
" elements (e.g sodium), are not") | |
print("Difficulty 1 is the first 20 elements, 2 is the first 40, 3 is the fi" | |
"rst 60, 4 is the first 80, and 5 is all of them") | |
print("At any point, you can just type 'q' and press enter to quit the quiz") | |
print("Ready?") | |
make_dict() | |
if quitting == 0: | |
while True: | |
# This is the main program | |
quest = make_question() | |
ask_question(quest[0], quest[1], quest[2]) | |
if quitting == 1: | |
break | |
else: | |
dif = "<unspecified>" | |
print("Goodbye! This session you got {} correct, and {} incorrect" | |
". You were on difficulty leve" | |
"l {}".format(right_answers, wrong_answers, dif)) | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment