Created
August 24, 2021 22:58
-
-
Save Mathsmaniac/76e2932621fb0087749db87799e890e7 to your computer and use it in GitHub Desktop.
First version of fully working program, not tested for usability
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 | |
First version of fully working program, not tested for usability | |
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(): | |
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: ") | |
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 = "What 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 = "What is the chemical symbol of the " \ | |
"element: {}?".format(question_element) | |
return [question, answer_element, "symbol"] | |
def ask_question(question, answer, question_type): | |
global right_answers | |
global wrong_answers | |
# 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 | |
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() == 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 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("Ready?") | |
make_dict() | |
while True: | |
quest = make_question() | |
ask_question(quest[0], quest[1], quest[2]) | |
# The first while loop will have the main routine in it, | |
# and the second one is just to get the input | |
while True: | |
user_input = input("Would you like to quit?\nType in the 'q' button " | |
"and press enter to quit," | |
" or just press enter to go another round: ") | |
print() | |
# Makes it run the main program again if just <enter> is put in | |
if user_input.lower() == "": | |
break | |
# Makes it exit this while loop then change a variable so that it | |
# quits the other while loop | |
elif user_input == "q": | |
quitting = 1 | |
break | |
else: | |
print("Sorry, I didn't quite understand that\n") | |
if quitting == 1: | |
break | |
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