Writing Data to a .txt File - python

I am trying to write data to a text file in python and I am trying to get the user to choose the name of the file as a string. However when it comes to actually writing the data, it shows an error.
import random
name = input("Please enter your name: ")
clas = input("Please enter what class you are in: ")
#Uses a list to show the 3 operators I want to use
ops = ['+', '-', '*']
#Defines two variables as 1 and 0
x = 1
score = 0
#While the variable x is less than or equal to 10, the loop will continue
while x <= 10:
#Selects 2 random integers from 1 to 10
num1 = random.randint(1,10)
num2 = random.randint(1,10)
#Choses the operation from the list `ops`
operation = random.choice(ops)
#Prints the 2 numbers and operation in an arithmetic question layout
print(num1,operation,num2)
maths = int(eval(str(num1) + operation + str(num2)))
#Gets the user to input there answer to the question
answer = int(input("What is the answer to that arithmetic question? "))
#If the answer the user input is equal to the correct answer the user scores a point and is told it is correct
#Otherwise, the answer must be wrong so the user is told his score is incorrect and that no points are scored
if answer == maths:
print ("Correct")
score += 1
else:
print ("Incorrect Answer")
#Add one onto the score that the while loops depends on to make sure it only loops 10 times
x = x + 1
#Leaves the iteration after 10 loops and prints the users final score
print ("You scored", score, " out of 10 points")
score2 = str(score)
score = str(name + score2 + "\n")
with open(clas."txt", "a") as scorefile:
scorefile.write(score)

To write to a file:
f = open("filename.txt","w")
f.write("Writing to a file!")
# writes "Writing to a file!" as a new line in filename.txt
f.close()
To read a file:
f = open("filename.txt","r")
lines = f.readlines()
f.close()
print lines
# prints array
Make sure to use f.close(), otherwise bad things will happen.

Related

Using Python to make a quiz from a text file

I'm learning Python, and I need to make a mini quiz. The questions and answers are in a text file (called textfile.txt), each on its own line. At the end of the quiz, it will tell the user their score out of three.
I can get my quiz to print out the first question, and when I try inputting an answer no matter what I put (correct answer or incorrect answer), it'll tell me it's incorrect.
In the text file I have the following:
whats 1+1
2
whats 2+2
4
whats 3+3
6
And here is what I have in my .py file:
questions = open("textfile.txt", "r")
content = questions.readlines()
userScore = 0
for i in range(1):
print(content[0])
answer = input("What's the answer: ")
if answer == content[1]:
print("Correct")
userScore + 1
else:
print("Incorrect")
print(content[2])
answer = input("What's the answer: ")
if answer == content[3]:
print("Correct")
userScore + 1
else:
print("Incorrect")
print(content[4])
answer = input("What's the answer: ")
if answer == content[5]:
print("Correct")
userScore + 1
else:
print("Incorrect")
questions.close()
print("You're done the quiz, your score is: ")
print(userScore)
How do I make it read the correct answer and keep track of the users score?
First of all, use .strip() to remove the newline characters. The answers comparison might not always work because of them.
To ask every even row you can use the modulo (%) operator to get the remainder of the current line index after dividing it by two.
If the answer is correct we add 1 to the corrent_answer_count variable that we print in the end.
questions = open(r"textfile.txt", "r")
content = [line.strip() for line in questions.readlines()]
questions.close()
corrent_answer_count = 0
for i in range((len(content))):
if i % 2 == 0:
print(content[i])
answer = input("What's the answer: ")
if answer == content[i + 1]:
print("Correct")
corrent_answer_count += 1
else:
print("Incorrect")
print("Correct answer count: " + str(corrent_answer_count))

How to extract numbers from csv file into variable

I want to make a highscore in a game on python - todo this i've realised I have to use an external file. I want it to extract the numbers located in the file and save them as a variable. It will then compare it to the users score and if it's bigger it will write the new high score to the file
I've been googling for days with no luck.
while theo >= 0 and theo <=9:
theo = theo + 1
x = (random.randint(0, 12))
y = (random.randint(0, 12))
print("Your sum is: " ,y,"x ",x)
answer = input("What is the answer?: ")
while len(answer) == 0:
answer = input("What is the answer?: ")
an = (x*y)
if int(answer) == (an):
print("Well done - you were correct ")
score = score + 1
elif int(answer) != (an):
print("Sorry, you were wrong. The correct answer was " ,an)
if theo == (10):
print("The quiz has finished. your score is ",score)
again = input("Do you want to play again? (Y/N)")
gamesplayed = gamesplayed + 1
if again == ("Y") or again == ("y"):
theo = 0
timesplayed = timesplayed + 1
elif again!=("y") or again!=("Y"):
print("well done your final score was ",score," you played ",timesplayed," times")
I want it to do above
I personally prefer to use dataclass CSV whenever I work with CSV files. You just need to type the column as integer (you do that by typing dataclass attribute as int)
It is a nice clean way to convert CSV rows to python objects. The only restriction is that you need to use python3.7 or higher.

How do I sort a list if there is an integer tied to a string by the smallest number?

I am quite new to programming and I am trying to make a leader board for a number guessing game in python 3 where you have the score then the name sorted by the lowest score first:
leaderboard_list = [0,0,0,0,0]
while True:
leaderboard_list.sort()
print("This in the leaderboard",leaderboard_list)
name = ("What is your name?")
while user_num != answer:
user_num = input("Guess a number: ")
if user_num = answer:
print("YAY")
else:
score = score + 1
leaderboard_list.append(score+" "+name)
I have tried many different ways and have figured out that if you get a score of 11, then it will say you are higher in the leader board than someone with a score of 2, which it shouldn't. I have also tried to change the score to an int type however you can't have an int and a string in the same list. How can I get around this?
Dictionary solution
dictionaries are well suited for the task of storing the scores and linking them to the user name. Dictionaries can't be directly sorted. However, there is an easy solution in this other post.
Moreover, in the OP, the name declaration is wrong, as it is not getting any value from the user. With the following code, it works perfectly. A condition for ending the while loop should added as well.
import operator
#Store the names and scores in a dictionary
leaderboard_dict = {}
#Random number
answer = 3
while True:
#Sort the dictionary elements by value
sorted_x = sorted(leaderboard_dict.items(), key=operator.itemgetter(1))
#Rewrite the leaderboard_dict
leaderboard_dict = dict(sorted_x)
print("This in the leaderboard",leaderboard_dict)
name = input("What is your name?")
#initialize score and user_num for avois crashes
user_num = -1
score = 0
while user_num != answer:
user_num = input("Guess a number: ")
if user_num is answer:
print("YAY")
else:
score += 1
leaderboard_dict[name] = score
NumPy array solution
EDIT: In case that you want to store more than one score for each player, I would user NumPy arrays, as they let you do plenty of operations, like ordering indexes by slicing and getting their numeric order, that is the request of the OP. Besides, their syntax is very understandable and Pythonic:
import numpy as np
#Random number
answer = 3
ranking = np.array([])
while True:
name = input("What is your name?")
user_num = -1
score = 1
while user_num != answer:
user_num = input("Guess a number: ")
if user_num is answer:
print("YAY")
else:
score += 1
#The first iteration the array is created
if not len(ranking):
ranking = np.array([name, score])
else:
ranking = np.vstack((ranking, [name,score]))
#Get the index order of the scores
order = np.argsort(ranking[:,1])
#Apply the obtained order to the ranking array
ranking = ranking[order]
And an example of its use:
>> run game.py
What is your name?'Sandra'
Guess a number: 3
YAY
What is your name?'Paul'
Guess a number: 6
Guess a number: 3
YAY
What is your name?'Sarah'
Guess a number: 1
Guess a number: 5
Guess a number: 78
Guess a number: 6
Guess a number: 3
YAY
What is your name?'Sandra'
Guess a number: 2
Guess a number: 4
Guess a number: 3
YAY
What is your name?'Paul'
Guess a number: 1
Guess a number: 3
YAY
Being the output:
print ranking
[['Sandra' '1']
['Paul' '2']
['Paul' '2']
['Sandra' '3']
['Sarah' '5']]
The leaderboard itself should store more structured data; use strings only to display the data.
# Store a list of (name, score) tuples
leaderboard = []
while True:
# Print the leaderboard
print("This in the leaderboard")
for name, score in leaderboard:
print("{} {}".format(score, name))
name = ("What is your name?")
score = 0
while user_num != answer:
user_num = input("Guess a number: ")
if user_num == answer:
print("YAY")
else:
score = score + 1
# Store a new score
leaderboard.append((name, score))
# Sort it
leaderboard = sorted(leaderboard, key=lambda x: x[1], reverse=True)
# Optional: discard all but the top 5 scores
leaderboard = leaderboard[:5]
Note that there are better ways to maintain a sorted list than to resort the entire leaderboard after adding a new score to the end, but that's beyond the scope of this answer.

Python while loop + check if integer or not, then saving to a file

I've been stuck on this for some time now. I'm making a quiz app, and I need to save the users score. The app will ask the users to enter a number from 1 to 3 so that they can save their score into a file, that will either save it in file 1, 2 or 3 (for 3 different classes).
If the user enters a letter then they will be asked to enter a number, and if the number isn't between 1 and 3 then it will ask them again until there's input is valid. Then it will save their score into the file.
classname = int(input("\nEnter [1] for class 1 \nEnter [2] for class 2 \nEnter [3] for class 3"))
invalid = True
while invalid = True:
classname = int(raw_input("Please enter a number in the range 1 to 3: "))
if int(classname) >= 1 and int(classname) <= 3:
invalid = False:
while invalid = False:
if int(classname) == 1:
score = str(score)
f = open("class 1.txt", "a")
f.write(str(name+': '))
f.write(str(score))
f.write('\n')
f.close()
elif int(classname) == 2:
score = str(score)
f = open("class 2.txt", "a")
f.write(str(name+': '))
f.write(str(score))
f.write('\n')
f.close()
elif int(classname) == 3:
score = str(score)
f = open("class 3.txt", "a")
f.write(str(name+': '))
f.write(str(score))
f.write('\n')
f.close()
else: #not sure what to put here
I didn't know what to put for else. I am new to Python and I really need help with this as I just want to complete it. If someone could fix my code that would be greatly appreciated.
I think I need to use type(classname) but I'm not sure.
You don't need an else statement.
Since you are taking the classname as an integer, you can catch the all errors with try-except. So basically you will check the input is an integer or not.
try:
classname = int(input("\nEnter [1] for class 1 \nEnter [2] for class 2 \nEnter [3] for class 3"))
except:
print ("It's not a number, please try again.")
continue
if 3 < classname or classname < 1:
print ("Please enter a number between 1 and 3.")
continue
The continue statement will pass all over the things until the user enter a number, then it will check is the number between 1 and 3. If it's not between 1 and 3, then it will pass all over the things until user enter an acceptable number.
you should learn about regular expressions and the re module:
import re
only_numbers=re.compile("^[0-9]+$")
good_one=re.compile("^[1-3]$")
usr_input=str(raw_input("Please enter a number in the range 1 to 3: ")
while True:
while not only_numbers.match(usr_input):
usr_input=str(raw_input("a NUMBER in the range 1 to 3: ")
if good_one.match(usr_input):
break
else:
usr_input=str(raw_input("in the RANGE 1 to 3: ")
outint=int(usr_input)
For your example, you don't even need to check if it is a letter. I am assuming that if the answer given is anything but a 1, 2, or 3, you will reject it. So, all you need is an else statement, and just put the code that you want to do if they enter an invalid response.
If you really want to check the type of the answer, you can either check if the input is a letter:
if isalpha(classname):
//Do stuff here
Or check if it is not an integer in general:
if type(classname) != int:
//Do stuff here
However, if the user enters a letter, your program will not even get to this conditional to check it, because you immediately attempt to convert the input to an integer at the top. If the input is a letter, this will immediately throw an error. Therefore, GLHF's answer above would be an ideal solution to fix your code.

The program will not let me get the last three scores of each student

print("Hello, and welcome to the Maths quiz!")
#Asks user for name
name = input("What is your name? ")
class_number = input("What is your class number? Class 1, 2 or 3? Please enter an integer, no letters.")
#This will import random to generate random functions
import random
#This is a variable for score
#It has been set to 0 at the start of the program
score = 0
scores={}
scores[name]=[]
#This creates an array containing the mathematical operators
#that this quiz will use
ops = ['+','-','*']
#A loop has been set for 0 - 10
for x in range(10):
#This is variable has been set to the operator of the equation that
#uses the random function and will choose a random operator from the
#array containing the operators made earlier
op = random.choice(ops)
#The if statement checks if the operation is an addition operation
if op == '+':
#This will generate a random number between 1 and 100
#for the first integer
first1 = random.randint(1,100)
#This will generate a random number between 1
#and 100 for the first integer
second1 = random.randint(1,100)
#This print function will generate a mathematical question
print ("What is " + (str(first1) + op + str(second1) + "?"))
#This eval function will generate the answer to the mathematical
#question asked and store it in the answer variable
answer = eval(str(first1) + op + str(second1))
#This will loop the try statement until an integer is entered as the guess variable
while True:
#The try statement will see if the guess variable is given an integer value,
#if not then it will print "You did not enter an integer. This is not a
#valid answer
try:
#This will allow the user to enter their answer and
#store it in the guess variable
guess = int(input(""))
#This will break the while loop if an integer is entered as the guess variable
break
except ValueError:
print("You did not enter an integer. This is not a valid answer. Please enter a valid integer")
print("Answer the quesiton appropiately. " + "What is " + (str(first1) + op + str(second1)) + "?")
if guess == answer:
#If the guess1 variable is equal to the answer1 variable, then
#"Correct!" will be printed and one point would be
#added to the score
print("Correct!")
score += 1
else:
#If the guess variable is equal to the answer variable, then
#"Correct!" will be printed and one point would be
#added to the score
#Else "Incorrect" would be printed
print("Incorrect")
#The elif statement checks if the operation is a subtraction operation
elif op == '-':
#This will generate a random number between 1 and 20 (because over 20 could be too hard for the students)
#for the first integer and stores it as the left2 variable
first2 = random.randint(1,20)
#This will generate a random number between 1
#and 20 (because over 20 could be too hard for the students) for the second integer and stores it as the right2 variable
second2 = random.randint(1,20)
#This print function will generate a mathematical question
print ("What is " + (str(first2) + op + str(second2) + "?"))
#This eval function will generate the answer to the mathematical
#question asked and store it in the answer1 variable
answer1 = eval(str(first2) + op + str(second2))
#This will loop the try statement until an integer is entered as the guess1 variable
while True:
#The try statement will see if the guess variable is given an integer value,
#if not then it will print "You did not enter an integer. This is not a
#valid answer
try:
#This will allow the user to enter their answer and
#store it in the guess1 variable
guess1 = int(input(""))
#This will break the while loop if an integer is entered as the guess1 variable
break
except ValueError:
print("You did not enter an integer. This is not a valid answer. Please enter a valid integer")
print("Answer the question appropiately. " + "What is " + (str(first2) + op + str(second2)) + "?")
if guess1 == answer1:
#If the guess1 variable is equal to the answer1 variable, then
#"Correct!" will be printed and one point would be
#added to the score
print("Correct!")
score += 1
else:
#Else "Incorrect" would be printed
print ("Incorrect")
#The second elif statement checks if the operation is a multiplication
#operation
elif op == '*':
#This generates the first number as a random number between
#1 and 12 (because the students would be tested on their multiplication table)
#used in the multiplication calculation
#and stores it as the left3 variable
first3 = random.randint(1,12)
#This generates the second number as a random number between
#1 and 12 (because the students would be tested on their multiplication table)
#used in the multiplication calculation
#and stores it as the left3 variable
second3 = random.randint(1,12)
#This generates the multiplcation question
print ("What is " + (str(first3) + op + str(second3) + "?"))
#This creates the answer for the multiplication question and
#stores it as the answer2 variable
answer2 = eval(str(first3) + op + str(second3))
#This will loop the try statement until an integer is entered as the guess2 variable
while True:
#The try statement will see if the guess variable is given an integer value,
#if not then it will print "You did not enter an integer. This is not a
#valid answer
try:
#This allows the user to enter their own answer and store it as
#the guess2 variable
guess2 = int(input(""))
#This will break the while loop if an integer is entered as the guess2 variable
break
except ValueError:
print("You did not enter an integer. This is not a valid answer. Please enter a valid integer.")
print("Answer the quesiton appropiately. " + "What is " + (str(first3) + op + str(second3)) + "?")
#The if statement checks if the answer the user entered is equal
#to the answer of the question
if guess2 == answer2:
#If the guess2 variable is equal to the answer2 variable, then
#"Correct!" will be printed and one point would be
#added to the score
print("Correct!")
score += 1
else:
#Else "Incorrect" would be printed
print ("Incorrect")
else:
#Else if the operation is not an addition, subtration or multiplcation
#operation then the break statement would be enacted and the
#the whole if statement would stop. However, this
#will be unlikely to happen since an operation would be chosen
#by the program
break
#This will print out the user's score out of 10
print ("You got " + str(score) + "/10, " + name + " " + "from class " + class_number)
#This will create a new variable that connects both the class_number variable and
#the "Class" string so it would come out as "Class class_number".
class_tag = "Class "+ class_number
#This will create and open a new text file under the name
#of the class_tag variable.
file = open(class_tag + ".txt", "a")
#This will write down the user's name and their score
file.write(str(name) + " scored " + str(score))
#This will create a new line for each user
file.write("\n")
#This will close the file.
file.close()
user_scores = {}
user_scores[name].append(score)
for line in scores:
name, score = line.rstrip('\n').split(' - ')
score = int(score)
if name not in user_scores or user_scores[name] < score:
user_scores[name] = score
for name in sorted(user_scores):
print(name, '-', user_scores[name])
print(user_scores[name][-3:])
I have created a program that allows students to do a quiz and their scores are stored in a text file that is based on their class. I'm trying to use the text files to get data from it and order their scores in the terms of the their last three, so the user can use it. However, when I tried:
user_scores = {}
#This adds to the list of names
user_scores[name].append(score)
for line in scores:
name, score = line.rstrip('\n').split(' - ')
score = int(score)
if name not in user_scores or user_scores[name] < score:
user_scores[name] = score
for name in sorted(user_scores):
print(name, '-', user_scores[name])
print(user_scores[name][-3:])
The IDLE shell came back with:
user_scores[name].append(score)
KeyError: 'student'
The Class 0 text file's data is:
student scored 3
student scored 8
student scored 0
student scored 4
student scored 10
student scored 3
student scored 0
student scored 4
Class 3 text file's data is:
katy scored 0
katy scored 2
katy scored 0
katy scored 6
user_scores will be a list full of lists, so one list of scores per name.
UPDATE:
I tried:
user_scores = []
user_scores[name].append(score)
for line in scores:
name, score = line.rstrip('\n').split(' - ')
score = int(score)
if name not in user_scores or user_scores[name] < score:
user_scores[name] = score
for name in sorted(user_scores):
print(name, '-', user_scores[name])
print(user_scores[name][-3:])
But the IDLE shell stated:
user_scores[name].append(score)
TypeError: list indices must be integers, not str
So how would I get the program to get the last three score's of the student based on their name? I tried using many other methods and none of them have worked.
Here:
user_scores = {}
user_scores[name].append(score)
You are trying to append an item to a list, but user_scores[name] is not a list, because user_scores is an empty dictionary.
If you want something quick and dirty that will do what you want, then:
user_scores = {}
for line in scores:
name, score = line.rstrip('\n').split(' scored ')
score = int(score)
if name not in user_scores:
user_scores[name] = []
user_scores[name].append(score)
for name in sorted(user_scores.keys()):
print(name + '-' + user_scores[name])
print(user_scores[name][-3:])
There are multiple problems with your code, but something like this at least would give you the output that you want. I kept the print syntax you used earlier in the code for consistency, but as mentioned you should use other techniques.

Categories