How write User Input Data to External Text File? - python

I would like to be able to take the test scores the user inputs and write to an external text file. Then have the application read off the values from the and calculate the average. However, I am unsure as to how to implement the python syntax within the loop and the functions. I've attempted to utilize my resources to get a better idea of how to do this, but I've been having some trouble understanding how python handles external files. In addition, would using append be better than write in this scenario?
Current Syntax:
def testAvgCalculation():
#Variables
total = 0
total_quiz = 0
while True:
#User Input and Variable to stop loop
inpt = input("Enter score: ")
if inpt.lower()== 'stop':
break
#Data Validation
try:
if int(inpt) in range(1,101):
total += int(inpt)
total_quiz += 1
else:
print("Score too small or Big")
except ValueError:
print("Not a Number")
return total, total_quiz
def displayAverage(total, total_quiz):
average = total / total_quiz
print('The Average score is: ', format(average, '.2f'))
print('You have entered', total_quiz, 'scores')
#Main Function
def main():
total, total_quiz = testAvgCalculation()
displayAverage(total, total_quiz)
#Run Main Function
main()

This is hacky as heck, but I tried to work with what was already there. I split the data validation section of the original function off into a separate function. In main() it returns its value counter, which keeps track of how many values were entered, to calculate_average(), which then reads the file line by line until counter becomes 0, which means it's about to read the word "stop" (which allows EOF recognition via the 'and' in the if statement), performs the calculation and returns its values.
def write_file():
#Variables
counter = 0
file = open("Scores.txt", "w")
while True:
#User Input and Variable to stop loop
inpt = input("Enter score: ")
file.write(inpt + "\n")
if inpt.lower()== 'stop':
file.close()
break
counter += 1
return counter
def calculate_average(counter):
total = 0
total_quiz = counter
scores = open("Scores.txt", "r")
s = ""
try:
while counter > 0 and s != 'stop':
s = int(scores.readline())
if int(s) in range(1,101):
total += int(s)
counter -= 1
else:
print("Invalid data in file.")
except ValueError:
print("Invalid data found")
return total, total_quiz
def displayAverage(total, total_quiz):
average = total / total_quiz
print('The Average score is: ', format(average, '.2f'))
print('You have entered', total_quiz, 'scores')
#Main Function
def main():
total, total_quiz = calculate_average(write_file())
displayAverage(total, total_quiz)
#Run Main Function
main()
NOTE: the file is created initially in write mode which overwrites the file each time so you never need a new one. if you want to keep a record you might like to change it to append, though you'll need to manage extracting the proper lines from among old input.
Not pretty at all, but should give you an idea of how to accomplish what you were going for.

Related

How to pass a local list of lists to a global outside outside function? And how can i check if csv file DNE or is empty?

I know that moving the information in the file_open into global would fix my issue but my professor insisted that I move it all that code into a function which is why I'm having problems.
def file_open():
my_data = open('vgsales.csv')
data = csv.reader(my_data)
data_list = list(data)
my_data.close()
def year_release_count()->None:
"""
Tells the user how many games in a specific
year was released
"""
count = 0
year = input("Enter Year: ")
for index in range(len(data_list)):
if(data_list[index][3] == year):
count += 1
print(count)
def info()->None:
print("Which function would you like to run?")
print("Enter 1, to see the number of games released in specific year")
value = int(input("Enter: "))
if(value == 1):
year_release_count()
if __name__ == "__main__":
file_open()
info()

How to sort a .txt file numerically

I am having trouble sorting my .txt file by a numerical value. I have attached the code and am trying to get it to sort by score,
I also cant get it to print each new score to a new line from the txt file.
def Highscore():
name = input("What is your name for the scoreboard?")
newhighscore =(name, highscore)
newline = ("\n")
HighscoreWrite = open ("highscore.txt", "a")
HighscoreWrite.write(highscore )
HighscoreWrite.write(name )
HighscoreWrite.write("\n")
HighscoreWrite.close()
HighscoreRead = open("highscore.txt", "r" )
ordered = sorted(HighscoreRead)
print (ordered)
print (HighscoreRead.read())
#print (newhighscore)
HighscoreRead.close()
retry = "Yes"
while retry == "Yes":
print ("Welcome to this quiz.\n")
score = 0
attempt = 0
while score < 10:
correct = Question()
if correct:
score += 1
attempt += 1
print ("Well done, You got it right")
else:
print ("Good try but maybe next time")
attempt += 1
highscore = score, ("/") ,attempt
highscore = str(highscore)
message = print ("You scored", (score), "out of ",(attempt))
Highscore();
retry = input("Would you like to try again? Yes/No")
In order to sort a file numerically, you must create a key(line) function that takes a line as parameter and returns the numeric value of the score.
Assuming that highscore.txt is a text file where each line starts with a numerical value followed with a space, the key function could be:
def key_func(line):
return int(line.lstrip().split(' ')[0])
You can then use ordered = sorted(HighscoreRead, key = key_func)
As it is a one line function, you can also use a lambda:
ordered = sorted(HighscoreRead, key= (lambda line: int(line.lstrip().split(' ')[0])))

Python function not running, interpreter not giving any errors

I'm very new to Python and having a problem with a program I'm doing for a class. main() and create_file work, but when it gets to read_file, the interpreter just sits there. The program is running but nothing is happening.
The answer is probably something very simple, but I just can't see it. Thanks in advance for any help.
I'm using IDLE (Python and IDLE v. 3.5.2)
Here's the code:
import random
FILENAME = "randomNumbers.txt"
def create_file(userNum):
#Create and open the randomNumbers.txt file
randomOutput = open(FILENAME, 'w')
#Generate random numbers and write them to the file
for num in range(userNum):
num = random.randint(1, 500)
randomOutput.write(str(num) + '\n')
#Confirm data written
print("Data written to file.")
#Close the file
randomOutput.close()
def read_file():
#Open the random number file
randomInput = open(FILENAME, 'r')
#Declare variables
entry = randomInput.readline()
count = 0
total = 0
#Check for eof, read in data, and add it
while entry != '':
num = int(entry)
total += num
count += 1
#Print the total and the number of random numbers
print("The total is:", total)
print("The number of random numbers generated and added is:", count)
#Close the file
randomInput.close()
def main():
#Get user data
numGenerate = int(input("Enter the number of random numbers to generate: "))
#Call create_file function
create_file(numGenerate)
#Call read_file function
read_file()
main()
You have an infinite while loop in the function, since entry never changes during the loop.
The Pythonic way to process all the lines in a file is like this:
for entry in randomInput:
num = int(entry)
total += num
count += 1

Issue with creating new file

I'm trying to make a new file at the end of a program to append info into, however the file isn't being created for some reason (the place in my code to look at is the #curve area). My best guess is that the variable "filename" established at the beginning of the program, isn't carrying all the way down to where I establish the new file name. My code is as follows:
import statistics
# input
filename = input("Enter a class to grade: ")
try:
# open file name
open(filename+".txt", "r")
print("Succesfully opened", filename,".txt", sep='')
print("**** ANALYZING ****")
with open(filename+".txt", 'r') as f:
counter1 = 0
counter2 = 0
right = 0
answerkey = "B,A,D,D,C,B,D,A,C,C,D,B,A,B,A,C,B,D,A,C,A,A,B,D,D"
a = []
# validating files
for line in f:
if len(line.split(',')) !=26:
print("Invalid line of data: does not contain exactly 26 values:")
print(line)
counter2 += 1
counter1 -= 1
if line.split(",")[0][1:9].isdigit() != True:
print("Invalid line of data: wrong N#:")
print(line)
counter2 += 1
counter1 -= 1
if len(line.split(",")[0]) != 9:
print("Invalid line of data: wrong N#:")
print(line)
counter2 += 1
counter1 -= 1
counter1 += 1
#grading students
score = len(([x for x in zip(answerkey.split(","), line.split(",")[1:]) if x[0] != x[1]]))
score1 = 26 - score
score2 = score1 / 26
score3 = score2 * 100
a.append(score3)
sscore3 = str(score3)
# results file
results = open(filename+"_grades.txt", "a")
results.write(line.split(",")[0])
results.write(",")
results.write(sscore3[:2])
results.write("\n")
results.close()
# in case of no errors
if counter2 == 0:
print("No errors found!")
# calculating
number = len(a)
sum1 = sum(a)
max1 = max(a)
min1 = min(a)
range1 = max1 - min1
av = sum1/number
# turn to int
av1 = int(av)
max2 = int(max1)
min2 = int(min1)
range2 = int(range1)
# median
sort1 = sorted(a)
number2 = number / 2
number2i = int(number2)
median = a[number2i]
median1 = int(median)
# mode
from statistics import mode
mode = mode(sort1)
imode = int(mode)
# printing
print ("**** REPORT ****")
print ("Total valid lines of data:", counter1)
print ("Total invalid lines of data:", counter2)
print ("Mean (average) score:", av1)
print ("Highest score:", max2)
print("Lowest score:", min2)
print("Range of scores:", range2)
print("Median Score:", median1)
print("Mode score(s):", imode)
# curve
part = input("Would you like to apply a curve to the scores? (y)es or (n)o?")
if part == "y":
newmean = input("Enter desired mean score:")
part1 = newmean - av1
part2 = sscore3 + part1
results = open(filename+"_grades_with_curve.txt", "a")
results.write(line.split(",")[0])
results.write(",")
results.write(sscore3[:2])
results.write(",")
results.write(part2)
results.write("\n")
results.close()
except:
print("File cannot be found.")
and It skips to the except block when I enter "y" at the end to try and create the new list, meaning the issue is within creating this new list.
The code is too long and requires reorganization.
It is likely, there are other problems with your code and you are trying to fix wrong one.
Few hints:
Do not open file without assigning the file object to a variable
open(filename+".txt", "r")
You open the file and have no chance to close it as you ignore the returned
file object.
Use with block to open/close your files
with open(input_fname, 'r'):
# work with the file
Learn doing so everywhere.
Do not reopen file for writing results
Your code repeatedly opens the result file (in "a" mode). You have better opening it only once.
You may even open multiple files within one context block:
with open(input_fname, 'r') as f, open(output_fname, "a") as results:
# work with the files
Reuse once calculated result
In many places you split the line: line.split(",").
You shall put the result into variable and reuse it.
rec = line.split(",")
Never ignore exceptions!!! (most serious problem)
The final block is catching all exceptions without giving you any sign, what went wrong (or even
worse, it tells you probably wrong information that the file was not found).
So instead of:
try:
# some code
except:
print("File not found.")
at least reraise the exception to learn from it:
try:
# some code
except:
print("File not found.") # this is probably to be removed as misleading message
raise
In fact, you can completely ignore complete top level try - except block and let the exception show
up telling you what went wrong.
Split your code into smaller chunks.
Having the code split to smaller functions shall simplify debugging and usage

Difficulties with an unruly program

I have been working on this code for a couple of hours now, and I am rather unsure what the problem is.
import random#imports random
import os#Imports os
print("Welcome to the maths quiz") # Welcomes user to quiz
score = (0)
def details():
plr_name = input ("Please Input Name:") # Asks user for name
plr_class = input("Input class number: ") # Asks the user for class numer
return (plr_name, plr_class)
def Q():
while qno < 10: # loops while qno is under 10
ran_num1 = random.randint(1,99) # Generates the first random number
ran_num2 = random.randint(1,99) # Generates the second random number
ran_fun = random.choice("X-+") # Picks a random function
print(ran_num1,ran_fun,ran_num2,"=") # Prints the Sum for the user
if ran_fun == "X":
sum_ans = ran_num1 * ran_num2 # Does the sum if it is a multiplication
if ran_fun == "+":
sum_ans = ran_num1 + ran_num2 # Does the sum if it is a addition
if ran_fun == "-":
sum_ans = ran_num1 - ran_num2 # Does the sum if it is a subtraction
plr_ans = int(input()) # Gets the user's answer
if plr_ans == sum_ans:
print("Correct!") # Prints correct
score = score + 1 # Adds 1 to score
else:
print("Incorrect!")
qno = qno + 1 # Adds 1 to qno
def plr_list_make(lines, listoreder):
index = 0
plr_names =[]
plr_scores =[]
for line in lines:
if listorder == 1:
column =0
rev = False
else:
column = 1
rev = True
return sorted(zip(plr_names, plr_scores),key = lambda x:(x[column]),reverse = rev)
def fileUP(plr_name, score, line ):
found = False
index = 0
for line in lines:
if line.startswith(plr_name):
line = line.strip("\n") + ","+str(score+"\n")
lines[index] = line
found = True
index = index + 1
if not found:
lines.append(plr_name+"|" +str(score)+"\n")
return lines
def save (plr_name, plr_class, score):
filename = "QuizScore_"+plr_class+".txt"
try:
fileI = open(filename)
except IOError:
fileI = open(filename, "w+")
fileI = open(filename)
lines = fileI.readlines()
fileI.close
lines = FileUP(plr_name, score, lines)
fileO = open(filename, "w")
fileO.writelines(lines)
fileO.close
def disp_list(): ## intialise_list
student_list=[]
filename = "QuizScore_"+plr_class+".txt"
try:
## open file read into list "lines"
input_file = open(filename)
lines = input_file.readlines() ## read file into list "lines"
input_file.close
student_list = create_student_list(lines, listorder) ### update "lines" with student list as requested by user
## output sorted list
for counter in range(len(student_list)):
print ("Name and Score: ", student_list[counter][0], student_list[counter][1])
except IOError:
print ("no class file!!!")
def menu():
print ("1 Test")
print ("2 Alphabetical")
print ("3 Highscore")
print ("4 Avg Score")
def Run():
selection = 0
while selection != 5:
menu()
option = int(input("Please select option: "))
if option == 1:
name, plr_class = details()
save(name, plr_class, Q())
else:
plr_class = input("input class ")
disp_list(plr_class, option-1)
Run()
Errors:
Traceback (most recent call last):
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 117, in
Run()
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 113, in Run
save(name, plr_class, Q())
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 74, in save
lines = FileUP(plr_name, score, lines)
NameError: global name 'FileUP' is not defined
Line 110:
name, plr_class = details()
But the details function does not return anything - so Python tries to assign the default return value None to the tuple name, plr_class. It can't do this, because None is not an iterable (you can't assign two things to it). To fix it, add the following line to your details function:
return (plr_name, plr_class)
(I haven't tested this.)
I like your game but it's buggy as a mofo :P
score and qno aren't properly defined. Define them in the functions that need them, define them globally or pass them to the relevant functions as arguments.
details() doesn't return anything but you still attempt to use its output to define two other variables. Add return (plr_name, plr_class) to details()
Every time you cast user input to int without checking its value, your program will crash if an int can't be cast. This applies here:
option = int(input("Please select option: "))
here
plr_ans = int(input())#Gets the user's answer
and elsewhere.
Since your program is input-heavy you could make a a function to which you pass the expected datatype and an optional string to display to the user. This way you wouldn't have to write try/except 10 times and your program wouldn't crash on unexpected input.
In def fileUP(plr_name, score, line ): you have for line in lines: but lines isn't defined. Thus, the save() function that calls FileUP() also fails. Also, FileUP and fileUP are not the same thing. You call the function with a capital "f" but the defintion of the function calls it fileUP with a lower case "f".
While we're at it, the file handling in def save (plr_name, plr_class, score):looks weird. The standard way of opening files for simple reading and writing in Python is via with open().
disp_list() should take one or two arguments but it doesn't at the moment so this error is raised:
TypeError: disp_list() takes 0 positional arguments but 2 were given
These 2 positional arguments were given here:
disp_list(plr_class, option-1)

Categories