Python: Saving numbers error when saved as string - python

I'm having an issue with my code, here:
correct = 0
grade_book = {}
File = open('Test.txt', 'r')
for line in File:
name, scores = line.split(':')
grade_book[name] = scores.strip()
File.close()
print(grade_book)
name = input("Name: ")
if name in grade_book.keys():
grade_book[name] += ',' + correct
else:
grade_book[name] = correct
File = open('Test.txt', 'w')
for name, scores in grade_book.items():
out_line = str(name) + ':' + str(scores) + "\n"
File.write(out_line)
File.close()
The problem is that it gives an error stating:
TypeError: Can't convert 'int' object to str implicitly
This happens in the program when it tries to save 'correct' to an existing name in the file. I've tried to fix the problem with the following:
name = input("Name: ")
if name in grade_book.keys():
grade_book[name] += ',' + str(correct)
else:
grade_book[name] = correct
But the problem with this is that the number printed to file is always 0, despite 'correct' being assigned to numbers more than 0, such as 8. On the other hand it doesent give an error like before, just the problem above.
Any solutions to this?
Yeah, Im probably missing something really obvious here.
Code for 'correct':
def mainLoop():
global count
global correct
Num1 = randint(1, 10)
Num2 = randint(1,10)
Operand= randint(1,3)
if Operand == 1:
question = str(Num1) + " + " + str(Num2) + " = "
answer = Num1 + Num2
elif Operand == 2:
question = str(Num1) + " - " + str(Num2) +" = "
answer = Num1 - Num2
else:
question = str(Num1) + " x " + str(Num2) + " = "
answer = Num1 * Num2
userAnswer = int(input(question))
if userAnswer == answer:
correct += 1
Guess I'll post the whole code for reference:
from random import randint
import time
count = 0
correct = 0
def mainLoop():
global count
global correct
Num1 = randint(1, 10)
Num2 = randint(1,10)
Operand= randint(1,3)
if Operand == 1:
question = str(Num1) + " + " + str(Num2) + " = "
answer = Num1 + Num2
elif Operand == 2:
question = str(Num1) + " - " + str(Num2) +" = "
answer = Num1 - Num2
else:
question = str(Num1) + " x " + str(Num2) + " = "
answer = Num1 * Num2
userAnswer = int(input(question))
if userAnswer == answer:
correct += 1
grade_book = {}
File = open('Test.txt', 'r')
for line in File:
name, scores = line.split(':')
grade_book[name] = scores.strip()
File.close()
print(grade_book)
name = input("Name: ")
if name in grade_book.keys():
grade_book[name] += ',' + str(correct)
else:
grade_book[name] = str(correct)
File = open('Test.txt', 'w')
for name, scores in grade_book.items():
out_line = str(name) + ':' + str(scores) + "\n"
File.write(out_line)
File.close()
while count < 10:
mainLoop()
count += 1
Did the indends fast, may be wrong
Text File Exmple:
Test:1,5
John:1,0

You are running mainLoop after writing the scores to your file, so the file will not contain the correct scores. Just move the code that asks the questions 10 times (while count < 10 etc.) to above the code that writes the scores to the grade_book (if name in grade_book.keys(): etc.).
You may find it helpful to avoid using global variables. Instead, you could have a question function that returns True or False depending on whether the user responds correctly or not, and then we just use sum to count up the right and wrong responses.
from random import randint
import time
def question():
a = randint(1, 10)
b = randint(1,10)
operand= randint(1,3)
if operand == 1:
sign = '+'
answer = a + b
elif operand == 2:
sign = '-'
answer = a - b
else:
sign = 'x'
answer = a * b
user_answer = int(input('{} {} {} = '.format(a, sign, b)))
return user_answer == answer # returns True if correct, False if not
grade_book = {}
with open('Test.txt', 'r') as file:
for line in file:
name, scores = line.split(':')
grade_book[name] = scores.strip()
print(grade_book)
name = input("Name: ")
# Ask a question 10 times and sum up the correct responses
# (This works because sum counts True as 1 and False as 0)
correct = sum(question() for _ in range(10))
if name in grade_book.keys():
grade_book[name] += ',' + str(correct)
else:
grade_book[name] = str(correct)
with open('Test.txt', 'w') as file:
for name, scores in grade_book.items():
file.write('{}:{}\n'.format(name, scores))

In grade_book[name] = correct You assign integer value correct. So it should be:
name = input("Name: ")
if name in grade_book.keys():
grade_book[name] += ',' + str(correct)
else:
grade_book[name] = str(correct)
And You are not doing anything with "correct". It is always 0.

Related

My Python 3 file code is not appending nor reading right to a file

I did a calculator code which works perfectly fine, but I need to append the results on a text file and/or read from the text file. I've done most of it but I'm having some errors which I need help with
-When I append the result, it just prints "5.098.042.0..." and it is supposed to be printing like this
"5 + 3 = 8
7 * 3 =43..."
It does show it in the code, but for some reason it just prints the result in the text
Please help, any suggestions to save work in the future or anything will be appreciated, thanks!
def menu():
print("\t1. Addition")
print("\t2. Substraction")
print("\t3. Multiplication")
print("\t4. Division")
print("\t5. Show")
print("\t6. Quit")
def option(min, max, exi):
option= -1
menu()
option= int(input("\n\t-> What would you like to calculate?: "))
while (option < min) or (option > max):
print("\n\t>>> Error. Invalid option.")
menu()
option= int(input("\n\t-> What would you like to calculate?: "))
return option
def add():
num1 = float(input("\tEnter a number: "))
num2 = float(input("\tEnter a number: "))
answer = num1 + num2
print("\n\t-> The result of " + str(num1) + " + " + str(num2) + "= ", answer)
return answer
def subs():
num1 = float(input("\tEnter a number: "))
num2 = float(input("\tEnter a number: "))
answer = num1 - num2
print("\n\t-> The result of " + str(num1) + " - " + str(num2) + "= ", answer)
return answer
def mult():
num1 = float(input("\tFirst number: "))
num2 = float(input("\tSecond number: "))
answer = num1 * num2
print("\n\t-> The result of " + str(num1) + " * " + str(num2) + "= ", answer)
return answer
def div():
num1 = float(input("\tFirst number: "))
num2 = float(input("\tSecond number: "))
if num2 != 0:
answer = num1 / num2
print("\n\t-> The result of " + str(num1) + " / " + str(num2) + "= ", answer)
else:
print("\n\t>>> Error. Division by zero.")
answer= "Error. Division by zero."
return answer
def result(r):
print("\n\t The last result was" , r)
def ex():
print("Goodbye")
def main():
solution = 0
op= -1
while op != 6:
op = option(0, 6, 0)
if op == 1:
solution = str(add())
with open ("myResultt.txt","a") as f:
f.write(solution)
elif op == 2:
solution = str(subs())
with open ("myResultt.txt","a") as f:
f.write(solution)
elif op == 3:
solution = str(mult())
with open ("myResultt.txt","a") as f:
f.write(solution)
elif op == 4:
solution = str(div())
with open ("myResultt.txt","a") as f:
f.write(solution)
elif op == 5:
with open ("myResultt.txt","r") as f:
for line in f:
print(line)
else:
solution = ex()
with open ("myResultt.txt","r") as f:
f.close()
main()
You prompt for the operands in the sum and etc... functions. If you want those operands to appear in the result file, you either have to return them along with the answer, or do the write in the function itself. For example,
def add():
num1 = float(input("\tEnter a number: "))
num2 = float(input("\tEnter a number: "))
answer = num1 + num2
result = "{} + {} = {}".format(num1, num2, answer)
print("\n\t-> The result of " + result)
with open ("myResultt.txt","a") as f:
f.write(result + "\n")
return answer

Problems with python math

I'm creating program which will teach my little brother math. But for example, when program is saying 2 + 2, and I enter 4 it's saying "Incorrect!". What am I doing wrong?
import random
import math
def addition():
num1 = random.randint(1, 100)
num2 = random.randint(1, 100)
result = num1 + num2
guess = input(str(num1) + " + " + str(num2) + " = ")#this is the line with problem
if guess == result:
print("Correct!")
if guess != result:
print("Incorrect!")
addition()
result is an integer (e.g., 4), and the inputed guess is a string (e.g., '4'). You need to convert them to the same type in order to compare them. E.g.:
result = str(num1 + num2)
Wrap the answer to int
guess = int(input(str(num1) + " + " + str(num2) + " = "))
typecast the input to int:
import random
import math
def addition():
num1 = random.randint(1, 5)
num2 = random.randint(1, 5)
result = num1 + num2
guess = input(str(num1) + " + " + str(num2) + " = ")
guess = int(guess) #input is string and it must be typecast to int
if guess == result:
print("Correct!")
if guess != result:
print("Incorrect!")
addition()

how to add an ordered score table with names

import random
number_correct = 0
def scorer():
global number_correct
if attempt == answer:
print("Correct.")
number_correct = number_correct + 1
else:
print('Incorrect. The correct answer is ' + str(answer))
name = input("Enter your name: ")
for i in range(10):
num1 = random.randrange(1, 100)
num2 = random.randrange(1, 100)
operation = random.choice(["*", "-", "+", "%", "//"])
print("What is the answer?", num1, operation, num2)
attempt = int(input(" "))
if operation == "+":
answer = num1 + num2
scorer()
elif operation == "-":
answer = num1 - num2
scorer()
elif operation == "*":
answer = num1 * num2
scorer()
elif operation == "%":
answer = num1 % num2
scorer()
elif operation == "//":
answer = num1 // num2
scorer()
print(name + ", you got " + str(number_correct) + " out of 10.")
I have made the quiz above and now want it to make a high-score table with the names and scores next to each other from highest to smallest.
I am trying to sort the scores first and this is what I have come up with:
scores = []
names = []
file = open("scores.txt","a")
addedline = number_correct
file.write('%d' % addedline)
file.close()
file = open("scores.txt","r")
for eachline in file:
scores.append(eachline)
x = scores.sort()
print(x)
file.close()
I don't think this works and am not sure how i will combine the names and scores at the end (making sure that the correct score is next to the correct name). Please help.
thanks
I'm not sure how exactly your textfile looks but I would suggest using a dictionary (as long as you do not have the same score more than once). Like this you could make the key your score and the value could be the name and the dictionary would automatically sort itself in order of the keys.
I would recommend storing the names and scores as a csv, then you could read the names with the scores and then sort with the score as a key.
with open("scores.txt", "a") as file:
file.write("%s, %s\n" % (name, number_correct))
with open("scores.txt", "r") as file:
data = [line.split(", ") for line in file.read().split("\n")]
data = sorted(data, key = lambda x: -int(x[1]))
print("\n".join(["%s\t%s" % (i[0], i[1]) for i in data]))

How to store last three scores

I have been doing a school project recently which which is about a school maths quiz. I successfully done two of the three tasks of my project. However the third task is seeming quite difficult.
I'm currently trying to store the last three scores of that student. However I can't quite get it to work. I did have a look at this thread: Displaying only the highest of a person's 3 most recent scores, saved in a .txt file. However I am having an error in my code for the for:
scores = file.readlines()
Which gives me an error saying that it's not readable. So unfortunately I couldn't get that code to work.
So what I'm trying to do is score the last three scores of the student. Then if there is more then 3, then I want to delete the least recent score.
This is my code:
import random
import csv
import operator
import os.path
import sys
user_scores = {}
validclass = "No"
classfile = "Class"
studentteacher = "None"
while studentteacher == "None":
studentteacherinput = input("Are you a Teacher or a Student?")
if studentteacherinput == "Teacher":
studentteacher = "Teacher"
print(studentteacher)
elif studentteacherinput == "Student":
studentteacher = "Student"
print(studentteacher)
else:
print("Please enter the one applicable ' Student ' or ' Teacher '.")
while validclass == "No":
pupilclass = input("What class are you in or what class would you like to see??")
print(pupilclass)
if pupilclass == "1":
if os.path.exists("class1scores.txt") and studentteacher == "Teacher":
file = open("class1scores.txt", "r")
validclass = "Yes"
elif os.path.exists("class1scores.txt") and studentteacher == "Student":
file = open("class1scores.txt", "a")
classfile = "class1scores.txt"
validclass = "Yes"
else:
file = open("class1scores.txt", "w")
validclass = "Yes"
elif pupilclass == "2":
if os.path.exists("class2scores.txt") and studentteacher == "Teacher":
file = open("class2scores.txt", "r")
validclass = "Yes"
elif os.path.exists("class2scores.txt") and studentteacher == "Student":
file = open("class2scores.txt", "a")
classfile = "class2scores.txt"
validclass = "Yes"
else:
file = open("class1scores.txt", "w")
validclass = "Yes"
elif pupilclass == "3":
if os.path.exists("class3scores.txt") and studentteacher == "Teacher":
file = open("class3scores.txt", "r")
validclass = "Yes"
elif os.path.exists("class3scores.txt") and studentteacher == "Student":
file = open("class3scores.txt", "a")
classfile = "class3scores.txt"
validclass = "Yes"
else:
file = open("class1scores.txt", "w")
validclass = "Yes"
file.seek(0)
scores = file.readline()
if studentteacher == "Teacher":
teacherinput = input("How would you like to sort the list? ' Alphabetically ' to sort it alphabetically with the students highest score, ' Highest ' for the highest scores with highest to lowest or ' Average ' for average scores with highest to lowest")
if teacherinput == "Alphabetically":
print("alphabetically")
csv1 = csv.reader(file, delimiter = ",")
sort = sorted(csv1, key = operator.itemgetter(0))
for eachline in sort:
print(eachline)
sys.exit()
if teacherinput == "Highest":
print("Highest")
if teacherinput == "Average":
print("Average")
namecheck = "invalid"
while namecheck == "invalid":
name = input("Please enter your name?")
if name.isalpha():
print("Your name is valid.")
namecheck = "valid"
#file.write(name + ",")
else:
print("Please enter a valid name, only containing letters.")
operation = input("Hello %s! Would you like to do Addition, Subtraction or Multiplication" % (name))
score = 0
if operation == "Addition":
for i in range(0, 10):
number1 = random.randint(1, 20)
number2 = random.randint(1, 20)
answer = number1 + number2
question = input("What is " + str(number1) + " + " + str(number2))
if question.isdigit() == True:
int(question)
else:
question = input("Please enter a answer with digits only. What is " + str(number1) + " + " + str(number2))
if int(question) == answer:
score += 1
print("Correct!")
else:
print("Wrong!")
elif operation == "Subtraction":
for i in range(0, 10):
number1 = random.randint(1, 20)
number2 = random.randint(1, 20)
answer = number1 - number2
if number2 >= number1:
answer = number2 - number1
question = input("What is " + str(number2) + " - " + str(number1))
else:
question = input("What is " + str(number1) + " - " + str(number2))
if question.isdigit() == True:
int(question)
else:
if number2 >= number1:
answer = number2 - number1
question = input("Please enter a positive answer with digits only. What is " + str(number2) + " - " + str(number1))
else:
question = input("Please enter a positive answer with digits only. What is " + str(number1) + " - " + str(number2))
if int(question) == answer:
score += 1
print("Correct!")
else:
print("Wrong!")
elif operation == "Multiplication":
for i in range(0, 10):
number1 = random.randint(1, 20)
number2 = random.randint(1, 20)
answer = number1 * number2
question = input("What is " + str(number1) + " x " + str(number2))
if question.isdigit() == True:
int(question)
else:
question = input("Please enter a answer with digits only. What is " + str(number1) + " + " + str(number2))
if int(question) == answer:
score += 1
print("Correct!")
else:
print("Wrong!")
print("Your final score is %s/10, Well Done!" % (score))
#file.write(str(score) + "\n")
#This is the code which I was trying to use to get the last 3 scores.
user_scores = {}
for line in scores:
name, score = line.rstrip('\n').split(',')
score = int(score)
if name not in user_scores:
user_scores[name] = [] # Initialize score list
user_scores[name].append(score) # Add the most recent score
if len(user_scores[name]) > 3:
user_scores[name].pop(0) # If we've stored more than 3, get rid of the oldest
file.close()
Sorry for the inefficient method, but it's just the way I like to think. And thanks for your time.
#This is the code which I was trying to use to get the last 3 scores.
user_scores = {}
for line in scores:
name, score = line.rstrip('\n').split(',')
score = int(score)
if name not in user_scores:
user_scores[name] = [] # Initialize score list
user_scores[name].append(score) # Add the most recent score
if len(user_scores[name]) > 3:
user_scores[name].pop(0) # If we've stored more than 3, get rid of the oldest
So I took that from the link mentioned above. My aim is to try and only get three scores, and not above 3.
As you seem to know, there are different modes you can open()(2/3) a file in. If you use "a" or "w", you can't read from the file. You can add a "+", to allow reading, too, though:
open("file.txt","a+")
Also, I'm not sure what version of Python you're using, but file() is a built-in type and function in Python 2, so you shouldn't use it as a variable name if that's the version you're using.
Implement a queue - https://docs.python.org/2/library/collections.html#collections.deque
from collections import deque
for line in scores:
name, score = line.rstrip('\n').split(',')
score = int(score)
if name not in user_scores:
user_scores[name] = deque(maxlen=3)
temp_q = user_scores[name]
temp_q.append(str(score))
user_scores[name] = temp_q
Now user scores is a dict with key as name, and values as a deque object with just 3 scores. You need to iterate through them, cast the queue to list and join the elements to write them to file.
filehandle = open('outputfile.csv' ,'w')
for key, values in user_scores.iteritems():
filehandle.write(name + ',')
filehandle.write(','.join(list(values)) + '\n')
filehandle.close()

Defining Functions, TypeError

Probably obvious, but for some reason, this code:
import random
import time
def tables():
global tablesUsed
tablesUsed = [int(x) for x in input("Please choose which multiplication tables you wish\nto practice, then type them like this: 2 5 10.\n").split()]
return tablesUsed
def timer():
timer = input("Do you wish to play with the timer? (yes or no)\n")
if timer == "yes":
withTimer()
else:
withoutTimer()
def withTimer():
playAgain = "yes"
total = 0
correct = 0
while playAgain == "yes":
total = total + 1
random1 = random.choice(tablesUsed)
random2 = random.randint(1, 12)
realAnswer = random1 * random2
start = time.time()
humanAnswer = int(input("What is the answer to this multiplication sum?\n" + str(random1) + " * " + str(random2) + "\n"))
if realAnswer == humanAnswer:
elapsed = round((time.time() - start), 1)
correct = correct + 1
score = str(int(correct / total * 100)) + "%"
if elapsed < 2:
print("Congratulations, you got it correct in " + str(elapsed) + " seconds!\nThat is a very good time!\nScore: " + score)
else:
print("Congratulations, you got it correct in " + str(elapsed) + " seconds!\nNow work on your time.\nScore: " + score)
else:
score = str(int(correct / total * 100)) + "%"
print("Unforunately, you got this one incorrect, the actual answer was " + str(realAnswer) + ".\nScore: " + score)
playAgain()
def withoutTimer():
playAgain = "yes"
total = 0
correct = 0
while playAgain == "yes":
total = total + 1
random1 = random.choice(tablesUsed)
random2 = random.randint(1, 12)
realAnswer = random1 * random2
humanAnswer = int(input("What is the answer to this multiplication sum?\n" + str(random1) + " * " + str(random2) + "\n"))
if realAnswer == humanAnswer:
correct = correct + 1
score = str(int(correct / total * 100)) + "%"
print("Congratulations, you got it correct!\nScore: " + score)
else:
score = str(int(correct / total * 100)) + "%"
print("Unforunately, you got this one incorrect, the actual answer was " + str(realAnswer) + ".\nScore: " + score)
playAgain()
def playAgain():
playAgain = input("Do you wish to play again? (yes or no)\n")
if playAgain == "yes":
settings()
else:
print("Thank you for practising your multiplication tables with me. Your final score was " + score + " and your average time was " + averageTime)
def settings():
settings = input("Do you wish to edit settings? (yes or no)\n")
if settings == "yes":
tables()
timer()
tables()
timer()
returns an error saying:
TypeError: 'str' object is not callable, line 66, line 10, line 35
Please could someone help and tell me what I'm doing wrong?
I gather that it's probably to do with defining functions incorrectly, but I can't find anything on that solves my problem.
You defined playAgain both as a function and a local variable in the withTimer function:
def withTimer():
playAgain = "yes"
# ...
while playAgain == "yes":
# ....
playAgain() # this is now a string, not the function
Don't do that, use meaningful names that don't shadow your function names.

Categories