Running the following on python - python

trying to get a program to enter a students name and score, test it to make sure score is a vaule >=0 and <=100 and save results to a file and loop back
gradeFile = open("grade.dat","a")
Score = "0"
while Score>=0:
Name = raw_input("What is the students's name?: ")
Score = float(raw_input("What is the students's score?: "))
while Score <0 or Score >100 :
print("ERROR: the grade cannot be less than 0 or more than 100")
Score = float(raw_input("What is the students's score?: "))
gradeFile.write(Name+"\n")
gradeFile.write(Score+"\n")
gradeFile.close()
print("Data saved to grade.dat")

You need to have a way to exit the loop. For your outer loop, you automatically go in. Then you loop again until you get a valid score, via your inner loop, and you repeat. In your current configuration, there's no way to exit the loop.
Additionally, score should be a number, but you enter it as a string in Score = "0". When outputting, you're going to want to write str(Score) so that you can concatenate it with "\n".
I suggest that your outer loop have something like while Score >= 0 and userWantsToContinue. You can handle userWantsToContinue in whatever way you see fit.

Your datatpe doesn't match
Score = "0" # So, score is a string
while Score >= 0: # Oh, thenm it's a integer?

Related

My code freezes and stops, what's wrong with it?

I'm new to python so don't be surprised it if is something really basic, but i've been trying to write this code that asks math questions and then saves the scores in order to show them again at the start of the loop, but it doesn't save the scores. what should i change?
this is the code
scores = []
names = []
while True:
f = open("highscore.txt", "r")
for line in f:
line = line.strip("\n")
line = line.split(" ")
names.append(line[0])
scores.append(int(line[1]))
print(f.read())
for pos in range(len(names)) :
print(pos + 1, names[pos], scores[pos])
f.close()
score = 0
print("hello, welcome to maths game")
print("\nQuestion 1: what is 2 x 2 x 2?")
answer = int(input("your answer >"))
if answer == 8:
print("correct")
score = score + 1
print("your score is ", score)
else:
print("incorrect")
print("the score is ", score)
print("\nQuestion 2: what is 34 x 2?")
answer = int(input("your answer >"))
if answer == 68:
print("correct")
score = score + 1
print("your score is", score)
else:
print("incorrect")
print("the score is", score)
name = input("what is your name?")
position = 0
for compare_score in scores :
if score < compare_score:
position = position + 1
scores.insert(position, score)
names.insert(position, name)
scores = scores[:5]
names = names[:5]
f = open("highscore.txt", "w")
for pos in range (len(names)):
f.write(names[pos] + " " + scores[pos])
it doesn't give any kind of error message, just loops back and doesn't save the names, neither the scores
You have a for-loop on scores that adds a new item to the scores list at each iteration. The for-loop will never reach the end of the list because there is always 'one more'.
Alain T.'s answer has already stated the root cause that you experienced. The loop never stops which appears to you as "freezing" since there are no outputs or indicators that you (as a user/developer) see that the loop still runs. So actually nothing freezes here .. it just runs forever.
For that reason I wanted to add a short note how to drill down the problem your own the next times..
Keyword here is clearly: debugging.
Debugging means: "finding out what your code does while being executed"
A very simple but (at least for small programs) quite effective approach is using one or more print() statements. These can be used to display the value of variables, the property of an object or just some statement like print("I am before the loop") to know where execution runs/stops..
A possible would be: (look at the print statements)
while True:
print("in while") #<-- this one
...
print("before loop") #<-- this one
for compare_score in scores :
print("in loop") #<-- this one repeats....
if score < compare_score:
position = position + 1
scores.insert(position, score)
names.insert(position, name)
scores = scores[:5]
names = names[:5]
print("After loop") #<-- never see this one
f = open("highscore.txt", "w")
for pos in range (len(names)):
f.write(names[pos] + " " + scores[pos])
Running your program again should print out:
in while
before loop
in loop
in loop
in loop
in loop
in loop
in loop
in loop
...
and so on... So what you know now is:
Everything before the loop at least executed
The loop runs forever .
So now it would be time to dig a little deeper inside the loop.
Most interesting would be to examine the variable on which the loop exit
depends.
In your case that is the length of the scores list:
for compare_score in scores:
So the loop runs until there are no more scores to compare left in the scores list.
So it might be a good idea to print() the length of the list to check if and how it decreases until there are no more scores to compare.
So add something like this:
Check the two print() statements containing len(scores)
for compare_score in scores:
print("in loop")
if score < compare_score:
position = position + 1
scores.insert(position, score)
names.insert(position, name)
scores = scores[:5]
names = names[:5]
print(len(scores)) #<--- this one
# or a bit nicer as f-string:
print(f"len score: {len(scores)}") #<--- this one
print("After loop")
Both are displaying the length of the scores list.
The former one just does it a little nicer.
There is a lot more to debugging. Many tools like VSCode, Pycharm, etc. support a lot more sophisticated methodologies to step through code, set breakpoints, inspect objects and variables ..
But for small ans simple projects and when the focus is on learning, instant feedback and repeating. At least to my mind. Print() debugging gives you a lot of insight in a very easy and simple manner.
Oh, and if you read until here:
"Welcome to the community" Just jokin', welcome !! ;)"

My Python code is looping at the wrong place

I have written this code for an assignment and it not working as it should. I want my program to validate user input for 3 users when they enter the names and grades for 3 test. my program just check the first input and then asks for the other user name and skips asking the user for an input or validating the input.
validInput1 = False
validInput2 = False
validInput3 = False
studentnames = []
studentMarkTest1 = []
studentMarkTest2 = []
studentMarkTest3 = []
totalScores = []
sum = 0
for i in range(3):
sname = input("Enter Student name:")
while not validInput1:
score1 = int(input("What did {} get on their test 1?".format(sname)))
if score1 < 0 or score1 >20:
print("Invalid input")
else:
validInput1 = True
while not validInput2:
score2 = int(input("What did {} get on their test 2?".format(sname)))
if score2 < 0 or score2 >25:
print("Invalid input")
else:
validInput2 = True
while not validInput3:
score3 = int(input("What did {} get on their test 3?".format(sname)))
if score3 < 0 or score3 >35:
print("Invalid input")
else:
validInput3 = True
totalScore = score1+ score2+ score3
sum = sum + totalScore
AverageTestScore = sum / 3
# saving name and grade
studentnames.append(sname)
studentMarkTest1.append(score1)
studentMarkTest2.append(score2)
studentMarkTest3.append(score3)
totalScores.append(totalScore) for i in range(3):
print(studentnames[i],"total Test score",totalScores[i]) print("class average", AverageTestScore)
here what happens when i run the program
>>>
Enter Student name:g
What did g get on their test 1?44
Invalid input
What did g get on their test 1?33
Invalid input
What did g get on their test 1?44
Invalid input
What did g get on their test 1?22
Invalid input
What did g get on their test 1?20
What did g get on their test 2?34
Invalid input
What did g get on their test 2?23
What did g get on their test 3?55
Invalid input
What did g get on their test 3?44
Invalid input
What did g get on their test 3?32
Enter Student name:e
Enter Student name:e
g total Test score 75
e total Test score 75
e total Test score 75
class average 75.0
>>>
How can I get the highest test score value stored in totalscore and then print out the highest score with the name of the student with the highest score?
its easy to get confused when you have a big chunk of code like this ... instead try and split your problem into smaller parts
start with a function to get the details of only one student
def get_student_detail(num_tests): # get the detail for just 1 student!
student_name = input("Enter Student Name:")
scores = []
for i in range(1,num_tests+1):
scores.append(float(input("Enter Score on test %s:"%i)))
return {'name':student_name,'scores':scores,'avg':sum(scores)/float(num_tests)}
now just call this for each student
student_1 = get_student_detail(num_tests=3)
student_2 = get_student_detail(num_tests=3)
student_3 = get_student_detail(num_tests=3)
print("Student 1:",student_1)
print("Student 2:",student_2)
print("Student 3:",student_3)
or better yet implement a function that lets you keep going as long as you want
def get_students():
resp="a"
students = []
while resp[0].lower() != "n":
student = get_student_detail(num_tests=3)
students.append(student)
resp = input("Enter another students details?")
return student
you may want to split out get_student_details even further writing a method to get a single test score and validate that its actually a number (this will crash as is if you enter something that isnt a number as a test score), or to keep asking for test scores until an empty response is given, etc
def get_number(prompt):
while True:
try:
return float(input(prompt))
except ValueError:
print ("That is not a valid number!")
def get_test_score(prompt):
while True:
score = get_number(prompt)
if 0 <= score <= 100:
return score
print("Please enter a value between 1 and 100!")
test_score = get_test_score("Enter test score for test 1:")
print(test_score)
Let's take a look at the while-loops you have:
while not validInput1:
The first time that your application runs, validInput1 is False, so this block evaluates. However, on subsequent loops (from for i in range(3):), validInput1 is already true, so this block is entirely skipped.
You can fix this by changing validInput1, validInput2 and validInput3 to False at the beginning of your for-loop.
That is because validInput1, validInput2 and validInput3 variables were set to True at first iteration but were not set to false for the second iteration.
Therefore for after first iteration your while conditions are always false due to "not True" i.e. False
Can set them to false again after each iteration i.e. at the end of the loop
You need to put validInput back to False after the while loops or even better replace them to the beginning of the for loop.

NameError after using input in Python 2

I am learning Python this semester and this is my homework.
Can anyone tell me why my code is wrong?
QUESTION:
You want to know your grade in Computer Science, so write a program that continuously takes grades between 0 and 100 to standard input until you input "stop", at which point it should print your average to standard output.
MY CODE:
total=0
count=0
while True:
grade=input("Enter Your Grades between 0 and 100 [put 'stop' when done]:")
if grade<0 or grade>100:
print("Invalid Input")
continue
elif grade=="stop":
break
else:
count+=1
total+=grade
print "Your Average Grade is:"+format(total/count,'.2f')
When I run the code, the Python keeps giving me this messages:
Change input to raw_input
grade = raw_input("Enter Your Grades between 0 and 100 [put 'stop' when done]:")
You are using Python 2.7, so use raw_input instead of input. The latter evaluates the input, so 5 + 2 will return 7 instead of the string '5 + 2'. Entering stop tries to evaluate stop as a variable, which doesn't exist.
Another note, total and count are both integers, so total/count performs integer division in Python 2 (Python 3 gives a float result). If you want a floating point average, use float(total)/count. One of the variables must be float to get a float answer.
You'll also find that grade is a string, so test for 'stop' first, then convert it to an int to test the grade grade = int(grade). You might want to think about handling errors. What if the user types 10a?
You can evaluate first the string stop, try capture the input with raw_input:
total = 0
count = 0
while True:
grade = raw_input("Enter Your Grades between 0 and 100 [put 'stop' when done]:")
if grade == "stop":
break
if grade.isdigit():
grade = int(grade)
if grade < 0 or grade > 100:
print("Invalid Input")
continue
else:
count += 1
total += grade
if count == 0:
print "Empty values"
else:
print "Your Average Grade is: %.2f" % (float(total)/count)
I added different conditions for correct execution, check the lines, for example if grade.isdigit(): for verify that the input value is a numeric value, when this evaluation we can work normally with any math calculation.
count == 0: for the error division by zero if the user write stop in first iteration.
In the last line you can use two different ways to print the values:
print "Your Average Grade is: %.2f" % (float(total)/count)
or
print "Your Average Grade is: {:.2f}".format(float(total)/count)
You're running this program in Python 2 where input evaluates the user input. So if you enter "stop", Python tries to find the variable stop which doesn't exist and raises the NameError.
There are more problems and you need to restructure the code. The first thing you should do is to change input to raw_input which just returns the user input as a string. Then you need to check if the user entered "stop" and break, otherwise convert the input string to an int and then increment the count and total.
total = 0
count = 0
while True:
grade = raw_input("Enter Your Grades between 0 and 100 [put 'stop' when done]:")
if grade == "stop":
break
# Skip if the string can't be converted to an int.
if not grade.isdigit():
print("Invalid Input")
continue
# Now convert the grade to an int.
grade = int(grade)
if grade < 0 or grade > 100:
print("Invalid Input")
continue
else:
count += 1
total += grade
# Convert total to a float for true division.
print "Your Average Grade is: {:.2f}".format(float(total)/count)

Printing min and max function from input of a list

Every time I run the code I get "TypeError: 'int' object is not iterable".
So my question is: How do I print/use the min and max function at the end? So if someone let's say types 5,7,10, and -1. How do I let the user know that the highest score is 10 and the lowest score would be 5? (And then I guess organizing it from highest numbers to lowest.)
def fillList():
myList = []
return myList
studentNumber = 0
myList = []
testScore = int(input ("Please enter a test score "))
while testScore > -1:
# myList = fillList()
myList.append (testScore)
studentNumber += 1
testScore = int(input ("Please enter a test score "))
print ("")
print ("{:s} {:<5d}".format("Number of students", studentNumber))
print ("")
print ("{:s} ".format("Highest Score"))
print ("")
high = max(testScore)
print ("Lowest score")
print ("")
print ("Average score")
print ("")
print ("Scores, from highest to lowest")
print ("")
Your problem is that testScore is an integer. What else could it be? Each time through the list, you reassign it to the next integer.
If you want to, say, append them to a list, you have to actually do that:
testScores = []
while testScore > -1:
testScores.append(testScore)
# rest of your code
And now it's easy:
high = max(testScores)
And, in fact, you are doing that in the edited version of your code: myList has all of the testScore values in it. So, just use it:
high = max(myList)
But really, if you think about it, it's just as easy to keep a "running max" as you go along:
high = testScore
while testScore > -1:
if testScore > high:
high = testScore
# rest of your code
You will get different behavior in the case where the user never enters any test scores (the first one will raise a TypeError about asking for the max of an empty list, the second will give you -1), but either of those is easy to change once you decide what you actually want to happen.
If all your scores are in a array.
print("The max was: ",max(array))
print("The min was: ",min(array))

For loop only executes 1 time, though given a range of 5

This question already has answers here:
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed 2 days ago.
I have the following code:
def input_scores():
scores = []
y = 1
for num in range(5):
score = int(input(print('Please enter your score for test %d: ' %y)))
while score < 0 or score > 100:
print ('Error --- all test scores must be between 0 and 100 points')
score = int(input('Please try again: '))
scores.append(score)
y += 1
return scores
When I run it, the output is as follows:
Please enter your score for test 1:
None
Then I'll enter the test score next to None, as, say 95
It then runs through the rest of the program without prompting me for the next test score to add to the scores list. I'm really curious why that is
Thanks in advance for taking the time to help
Sincerely,
~Dustin
You return from inside the loop. Move return scores one indent left.
your return statement is indented too much, causing the function to return on the first iteration. It needs to be outside of the for block. This code works:
def input_scores():
scores = []
y = 1
for num in range(5):
score = int(input('Please enter your score for test %d: ' %y))
while score < 0 or score > 100:
print ('Error --- all test scores must be between 0 and 100 points')
score = int(input('Please try again: '))
scores.append(score)
y += 1
return scores
You indentation of the code seems whacky. It looks like the return statement is inside the scope of the for loop. So after the first iteration the return statement takes you out of the function completely.
You're returning scores at the end of each loop iteration (so in other words, after the first loop iteration finishes, you return all the scores thereby exiting the function, and the loop).
Change your code to be:
for num in range(5):
# ...
return scores # Note the indentation is one tab less than the loop's contents
Others have correctly pointed out that the indentation of your return statement was causing the problem. Also, you might want to try it like this, using len(scores) to control the loop, as #max suggested:
def input_scores(num_tests=5, max=100, min=0):
scores = []
while len(scores) < num_tests:
score = int(input('Please enter your score for test {0}: '.format(len(scores)+1)))
if score < min or score > max:
print ('Error --- all test scores must be between 0 and 100 points.')
else:
scores.append(score)
return scores

Categories

Resources