Program ignoring if elif statements - python

I'm stumped, I have no idea why this is not working. It just ignores everything except for the else statement. No idea what could be causing this, help!
The program is just too simple to mess up, and yet, here it is, not working.
def main(): #the main function, where the program is held.
print("Opening Account List now...\n")#flavor tx to add user context for the list of numbers to be displayed.
infile = open('CHarge Accounts.txt', 'r')#opens the 'CHarge Accounts' text file in read-only mode,
#and saves it to the variable 'infile'.
numbers = infile.readlines()#The '.readlines()' command opens the text file stored in the 'infile'
#variable and and reads every single line of text in the file.
#It then saves the data that has been read to the variable 'numbers'.
infile.close()#This closes the text file being within the 'infile' variable, preventing data from being los,
#and causing errors in the program
index = 0#control value for the number of values to be inserted into the 'numbers' list.
#
while index < len(numbers): #while the index value is less than the number of values within numbers.
#This means that as long as index is less than however many account numbers
#that are within the 'numbers' list, the loop will continue.
numbers[index] = int(numbers[index])#While the loop runs, the values in the numbers index will be
#converted to integer values
index += 1 #controlling value increments for every number read
print (numbers, '\n')
x = 0 #control value for the while loop.
while x == 0: #Loop begins.
accnumber = int(input("Please type in the account number you'd like to change, or type in -1 to exit."))
if accnumber not in numbers and not -1:#Checks if account number is not in the saved txt file data, and
#if the user has inputted the 'kill' value.
print("The account number you have typed in is invalid.")#informs user data is invalid
elif accnumber in numbers and not -1:#Checks if the account number is within the saved text file data, and
#if the user has inputted the 'kill' value.
print("The account number you have selected is valid.")#text informs user that data is valid
elif accnumber == -1:#Checks if the account number value is -1
print("Goodbye!")#Flavor for the user
x = 1 #activates the control variable to break the loop
main()

if accnumber not in numbers and not -1:
# ^^^^^^
When evaluated as a truth-statement, 0 is False and any other integer is True. So -1 is True, not -1 is False, and (anything) and not -1 is always False.
Therefore your if and elif clauses always get skipped.
Try
if accnumber not in numbers and accnumber != -1:
instead.
Also:
your commenting is overdone to the point of obscuring your program. I presume this is some sort of class requirement, ie commenting every line?
your use of while loops and index variables is very non-idiomatic and could be replaced by a list comprehension as follows:
.
def main():
print("Opening Account List now...\n")
with open('Charge Accounts.txt') as inf:
numbers = [int(line) for line in inf]
print(numbers, '\n')
while True:
accnumber = int(input("Please enter an account number (or -1 to exit): "))
if accnumber == -1:
print("Goodbye!")
break
elif accnumber not in numbers:
print("The account number you have typed in is invalid.")
else:
print("The account number you have selected is valid.")
main()

Your code is a bit messy. When you are adding comments, please try to make it reader friendly. Also, spend more time on basic syntax!
def main():
print("Opening Account List now...\n")
infile = open('CHarge Accounts.txt', 'r')
numbers = infile.readlines()
infile.close()
index = 0
while index < len(numbers):
numbers[index] = int(numbers[index])
index += 1
print (numbers, '\n')
x = 0 #control value for the while loop.
while x == 0:
accnumber = int(input("Please type in the account number you'd like to change, or type in -1 to exit."))
if (accnumber not in numbers) and (accnumber !=-1):
print("The account number you have typed in is invalid.")
elif (accnumber in numbers) and (accnumber !=-1):
print("The account number you have selected is valid.")#text informs user that data is valid
elif accnumber == -1:#Checks if the account number value is -1
print("Goodbye!")#Flavor for the user
x = 1 #activates the control variable to break the loop
main()

Related

How to count and store an unknown number of inputs Python

I need to take in an unknown number of strings, each on a new line, count them and determine if they were entered in alphabetical order.
I have to do this without using lists or dictionaries.
I’m lost. I tried assigning each to a variable but realized that without knowing the number of inputs that was not going to work without a loop of some kind that ends when there is no additional input. I have tried that but can’t figure out how to assign a new variable in the loop
try this one:
count = 0
prev = ''
isAlphabetical = True
while True:
curr = input('Enter string:')
if curr == '': # this is the ending condition. you may want to change it.
break
count+=1
if curr < prev:
isAlphabetical = False
prev = curr
print('count =',count)
if isAlphabetical:
print('they are in alphabetical order')
else:
print('they are not in alphabetical order')
the above code takes the inputs until the user enters nothing and press the enter button. it takes track of the order of the inputs and the number of them.

list index out of range for while loop

def main():
infile = open('charge_accounts.txt', 'r')
chargeAccounts = infile.readlines()
index = 0
while index < len(chargeAccounts):
chargeAccounts[index] = chargeAccounts[index].rstrip('\n')
index += 1
userAccount = input("Please enter a charge account number: ")
count = 0
while userAccount != chargeAccounts[count] or chargeAccounts[count] == chargeAccounts[17]:
count += 1
if chargeAccounts[index] == userAccount:
print("The account number", userAccount, "is in the list.")
else:
print("The account number", userAccount, "in not in the list.")
main()
I'm trying to make a code in python that has the user input a number and checks to see if that number is in a list. When I try to run this code, I get an error that says that the list index is out of range in the while loop. There are only 18 items in the list, and I have the while loop set to terminate at 17(which should be 18 in the list).
Edit: It also doesn't work if the while loop is set to chargeAccounts[count] != chargeAccounts[17]:
Here's the exact error code:
Traceback (most recent call last):
File "F:/CPT 168/Ch 7/AndrewBroughton_Chapter7_Excersizes/7-5/7-5.py", line 23, in <module>
main()
File "F:/CPT 168/Ch 7/AndrewBroughton_Chapter7_Excersizes/7-5/7-5.py", line 13, in main
while userAccount != chargeAccounts[count] or chargeAccounts[count] != chargeAccounts[17]:
IndexError: list index out of range
Here's the content of the original text file:
5658845
4520125
7895122
8777541
8451277
1302850
8080152
4562555
5552012
5050552
7825877
1250255
1005231
6545231
3852085
7576651
7881200
4581002
A while loop will keep looping as long as its condition is True.
count = 0
while userAccount != chargeAccounts[count] or chargeAccounts[count] == chargeAccounts[17]:
count += 1
If I enter an invalid userAccount to your program, the first part of the condition userAccount != chargeAccounts[count] is always going to be True. That makes the entire condition True, since you're using or logic.
Furthermore, if you want to check to see if you've reached the end of a list, you don't have to check the contents of the last list element (chargeAccounts[count] == chargeAccounts[17]). Check the length instead (count == len(chargeAccounts)).
To fix this, change that loop condition to something like
while count < len(chargeAccounts) and userAccount != chargeAccounts[count]:
(I'm not sure if this is exactly what you need, because I don't really follow the logic of your program. This should get you past the current error, though.)
You get the error at the string if chargeAccounts[index] == userAccount: because index is already bigger than the index of the last element of the list (because you left the loop with this index above).
I would recommend you to follow a few rules to work with lists that could save you from similar errors with indices.
Use for-loop instead of while-loop, if you lineary go through each element.
Use break if you want to leave the loop and keep the index
So you code may look like this:
with open('charge_accounts.txt', 'r') as infile:
chargeAccounts = infile.readlines()
for index in range(len(chargeAccounts)):
chargeAccounts[index] = chargeAccounts[index].strip()
userAccount = input("Please enter a charge account number: ")
found = False
for chargeAccount in chargeAccounts:
if chargeAccount = userAccount:
found = True
break
if found:
print("The account number", userAccount, "is in the list.")
else:
print("The account number", userAccount, "in not in the list.")

changing data from printing line by line to a list (in a text file)

I'm using python, idle version 3.4.2
My code when it prints, print 3 scores per name but they print like this:
Maya: 3
Maya:2
Maya: 4
I was wondering if there was any way to get it to print like this in a list/dictionary so i can call upon the scores later for sorting
Maya = [3,2,4]
Here is my code.
students_names = []
import random #import module
print("What is your name?") #prints writing in brackets
name = input().title() #Capitalizes the first letter of the word inputted
students_names.append(name)
print("What class are you in? (Enter 1, 2 or 3)") #asks the user to input a number
while True:
try:
class_number = int(input()) #asks for an integer input from user
except ValueError:
print("Sorry, I didn't understand that, please try again") #print statement
continue
if class_number > 3: #if input is more than 3
print("SORRY but that class isn't recognised, try again") #print statement
continue
else:
print ("Hello,", name, "from class", class_number, "welcome to my quiz") #prints writing in brackets and anything saved in the variable "name" and "class_number"
break #break out of loop
score = 0 #sets the variable "score" to zero
question = 0 # sets the variable "question" to zero
print(class_number)
while question < 3:#If questions (intitally set to 0) is smaller than 10, carry out this function
question +=1 # add one to the value of "question"
maths = random.randint(1,3) #randomly generate a number from 1-3 and store as "maths"
num1 = random.randint(1,10)#randomly generate an integer from 1-10 and store as "num1"
num2 = random.randint(1,10)#randomly generate a second integer from 1-10 and store as "num2"
if maths == 1: #if the number generated is 1
print(num1, "+", num2) #prints num1 + num2
ans = num1 + num2 #sets "ans" to equal the value of num1 added to num2
elif maths == 2: #if the number generated is 1
print(num1, "*", num2) #print num1 multiplied by num2
ans = num1 * num2 #sets "ans" to equal the value of num1 multiplied by num2
else: #else run this part of code
print(num1, "-", num2) #print num1 subtracted by num2
ans = num1 - num2 #sets "ans" to equal the value of num1 subtracted by num2
while True:
try:
user_ans = int(input()) #user inputs answer to question
except ValueError: #runs when the user input is no an integer
print ("SORRY but that answer isn't recognised, try again")
else:
break
if user_ans == ans:
score+=1
print("Well done, you are CORRECT")
else:
print("SORRY, you are INCORRECT") #print writing in brackets
print("The correct answer was", ans)
if score == 10: #run this part of code if "score" equals 10
print("fantastic", name, "you got full marks!")#print statement and name
elif score >= 6: #run this part of code if "score" is larger than or equal to 6
print("well done, there's some improvement to be done here though", name, "you got", score, "/10")# then print statement and score
elif score <=5: #run this part of code if "score" is smaller than or equal to 5
print("hmm, maybe some more practise would be beneficial", name, "you got", score, "/10") #then print statement and score
class_number = str(class_number) + ".txt" #this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
file = open(class_number, 'a') #opens the file in 'append' mode so you don't delete all the information
file.write(str(students_names))
file.write(str(name + " : ")) #writes the name and ":" to file
file.write(str(score)) #writes the score to file
file.write('\n')#writes the score to the file
file.close()#safely closes the file to save the information
Sure simply add the score values foreach person to a new dictionary.
name_dict = {}
if name in name_dict:
name_dict[name].append(new_score)
else:
name_dict[name] = [new_score]
It is a little bit hard to follow up on your code. Therefore I was not completely able to integrate it.
Ok, I think I get what you're looking for. But to simplify my answer to that, we first need to simplify your example. A good way to do so, is to cut your code into functions:
How to store your results?
First we'll look at where you need help on, which is the last bit of your code, which fits in a function we'll call store_results():
def store_results(...):
class_number = str(class_number) + ".txt" # this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
file = open(class_number, 'a') # opens the file in 'append' mode so you don't delete all the information
file.write(str(students_names))
file.write(str(name + " : ")) # writes the name and ":" to file
file.write(str(score)) # writes the score to file
file.write('\n') # writes the score to the file
file.close() # safely closes the file to save the information
I used here ... for the arguments of the function, which is not python, to have a thought about it. What arguments does that function needs to work as is?
class_number: the class the student answering the QA is in
name: the score the student had on the QA
student_names
What you're doing here, is that when you run that code, you're appending name
into student_names, which will always contain one, and only one name. So when
you write file.write(str(students_names)), for a user whose name is John, you'll
end up writing:
...
['John']
John : 5
...
Which is not something I believe you're expecting. You actually do not need that list at all.
So as a first update, you should do:
def store_results(class_number, name, score):
class_file = "{}.txt".format(class_number) # this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
with open(class_file, 'a') as f: # opens the file in 'append' mode so you don't delete all the information
f.write("{}: {}\n".format(name, score) # outputs the user's score to the file
Other changes in that snippet are:
- you shall not use file as a variable as it already exists as a global type, and using it in
your code is considered bad practice called "shadowing" which can lead to hard to find bugs
(not in this case, but if you don't take the good habits now, it's bite you in a future code).
- you shall use with open() as f: construct instead of opening and closing the file manually,
because in your existing code, if there's an exception thrown between open and close your
file won't be properly closed, ending up in possible lost writes.
- you shall use format strings instead of direct string concatenation, which makes the code
easier to read and to modify.
Now, that being said, you'll still have your issue having the result of each test taken
by an user being shown as:
John: 2
John: 4
John: 5
The right way to solve this is to not use "blinded" appending to the file, but instead
use the file as some sort of very basic database. The most simple option would be to
write your scores within a JSON file, which is syntactically compatible with python
(pretty useful for manual testing):
import os
import json
def store_results(class_number, name, score):
# this adds '.json' to the end of the file (therefore creating a json file)
class_file = "{}.json".format(class_number)
# first step: load the existing data
# first test if the file exists, and if not, use an empty score dictionary
if not os.path.exists(class_file):
scores = {}
# otherwise populate the dictionary
else:
# open as read only, because we just want the data out of it
with open(class_file, 'r') as f:
# load contents of the json file "f" as object "scores"
scores = json.load(f)
# second step: update the data
scores.setdefault(name, []).append(score)
# third step: update the file
# use 'w' when opening the file to overwrite all data within it
with open(class_file, 'w') as f:
# dump object "scores" within file "f"
json.dump(scores, f)
Within this code, I used a trick to do insertion of the score in one line:
scores.setdefault(name, []).append(score)
which is equivalent to:
# if the user's "name" is not already in the dictionary
if name not in scores.keys():
# add it as a new key containing an empty list
scores[name] = []
# append the "score" to the list indexed by the user's "name"
scores[name].append(score)
Then the results within a file would look like:
{"John":[3,5,10],"Jane":[2],"Bob":[1,0,2]}
To make the output file more readable you can change the json.dump line into:
json.dump(scores, f, sort_keys=True, indent=4, separators=(',', ': '))
which will output:
{
"Bob": [
1,
0,
2
],
"Jane": [
2
],
"John": [
3,
5,
10
]
}
How to run the QA?
Finally you want to create another function that handles the QA process, within which
you call the function we just defined
# add the following import at the start of your script if you're running python2 and not python3
from __future__ import print_function
def run_qa():
print("What is your name?") # prints writing in brackets
name = input().title() # Capitalizes the first letter of the word inputted
print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
while True:
try:
class_number = int(input()) # asks for an integer input from user
except ValueError:
print("Sorry, I didn't understand that, please try again") # print statement
continue
if class_number > 3: # if input is more than 3
print("SORRY but that class isn't recognised, try again") # print statement
continue
else:
break # break out of loop
# prints writing in brackets and anything saved in the variables "name" and "class_number"
print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))
score = 0 # sets the variable "score" to zero
question = 0 # sets the variable "question" to zero
while question < 3: # If questions (initially set to 0) is smaller than 10, carry out this function
question += 1 # add one to the value of "question"
maths = random.randint(1,3) # randomly generate a number from 1-3 and store as "maths"
num1 = random.randint(1,10) # randomly generate an integer from 1-10 and store as "num1"
num2 = random.randint(1,10) # randomly generate a second integer from 1-10 and store as "num2"
if maths == 1: # if the number generated is 1
print("{} + {} = ?".format(num1, num2)) # prints num1 + num2
ans = num1 + num2 # sets "ans" to equal the value of num1 added to num2
elif maths == 2: # if the number generated is 1
print("{} * {} = ?".format(num1, num2)) # print num1 multiplied by num2
ans = num1 * num2 # sets "ans" to equal the value of num1 multiplied by num2
else: # else run this part of code
print("{} - {} = ?".format(num1, num2)) # print num1 subtracted by num2
ans = num1 - num2 # sets "ans" to equal the value of num1 subtracted by num2
while True:
try:
# print a nice little prompt for the user to enter his answer
print("> ", end="")
user_ans = int(input()) # user inputs answer to question
# if an exception is raised by "int()" the break is not being called
# here you achieve the same as a single line, as you're doing in two
# lines with your try/except/else clause, making your code more readable.
break
except ValueError: # runs when the user input is no an integer
print ("SORRY but that answer isn't recognised, try again")
if user_ans == ans:
score += 1
print("Well done, you are CORRECT")
else:
print("SORRY, you are INCORRECT") # print writing in brackets
print("The correct answer was {}".format(ans))
if score == 10: # run this part of code if "score" equals 10
print("Fantastic {}, you got full marks!".format(name))# print statement and name
elif score >= 6: # run this part of code if "score" is larger than or equal to 6
print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))# then print statement and score
elif score <=5: # run this part of code if "score" is smaller than or equal to 5
print("hmm, maybe some more practice would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score
# return the results
return class_number, name, score
Finally, to call your code, you just need to add the following at the end of your script:
if __name__ == "__main__":
class_number, name, score = run_qa()
store_results(class_number, name, score):
the reason for the if statement is to make it possible to later include your code as
a module in another module without running it, which is considered good practice!
as another improvement I'd avoid repeating the same code several times to check input
from the user, but use a function instead:
def get_integer_input(maxval=None):
while True:
try:
# print a nice prompt
print("> ", eol="")
i = int(input()) # asks for an integer input from user
if maxval:
if i >= maxval:
continue
print("Sorry, input shall be inferior than {}, try again".format(maxval))
break
except ValueError:
print("Sorry, I didn't understand that, please try again") # print statement
return i
Then in your code you use it that way:
...
class_number = get_integer_input(maxval=3)
...
BTW, as an improvement, I'd actually split the run_qa in two functions: one that
generates the questions, and the other that does the interactive process.
so that you would do:
if __name__ == "__main__":
questions = generate_qa()
class_number, name, score = run_qa(questions)
store_results(class_number, name, score)
with generate_qa() being something like:
def generate_qa():
questions = []
while len(questions) < 3: # add a question until we have three generated
op = random.randint(0,2) # randomly generate a number from 1-3 and store as "maths"
num1 = random.randint(1,10) # randomly generate an integer from 1-10 and store as "num1"
num2 = random.randint(1,10) # randomly generate a second integer from 1-10 and store as "num2"
questions.append( (op, num1, num2) )
return questions
and then:
def run_qa(questions):
print("What is your name?") # prints writing in brackets
name = input().title() # Capitalizes the first letter of the word inputted
print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
class_number = get_integer_input(maxval=3)
# prints writing in brackets and anything saved in the variables "name" and "class_number"
print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))
score = 0 # sets the variable "score" to zero
for op, left, right in questions:
if op == 0: # if the number generated is 0
op("{} + {} = ?".format(left, right)) # prints 'left' + 'right'
ans = left + right # sets "ans" to equal the value of num1 added to 'right'
elif op == 1: # if the number generated is 1
print("{} * {} = ?".format(left, right)) # print 'left' multiplied by 'right'
ans = left * right # sets "ans" to equal the value of num1 multiplied by 'right'
else: # the only possible value is: op == 2
print("{} - {} = ?".format(left, right)) # print 'left' subtracted by 'right'
ans = left - right # sets "ans" to equal the value of num1 subtracted by 'right'
user_ans = get_integer_input()
if user_ans == ans:
score += 1
print("Well done, you are CORRECT")
else:
print("SORRY, you are INCORRECT") # print writing in brackets
print("The correct answer was {}".format(ans))
if score == 10: # run this part of code if "score" equals 10
print("Fantastic {}, you got full marks!".format(name))# print statement and name
elif score >= 6: # run this part of code if "score" is larger than or equal to 6
print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))# then print statement and score
elif score <=5: # run this part of code if "score" is smaller than or equal to 5
print("hmm, maybe some more practise would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score
return class_number, name, score
Finally, a last improvement that could be done to your code is to use a dict containing the operators:
import operator
operations = {
'+': operator.add,
'*': operator.mul,
'-': operator.sub
}
and then you'd simplify run_qa as follows:
def run_qa(questions):
print("What is your name?") # prints writing in brackets
name = input().title() # Capitalizes the first letter of the word inputted
print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
class_number = get_integer_input(maxval=3)
# prints writing in brackets and anything saved in the variables "name" and "class_number"
print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))
score = 0 # sets the variable "score" to zero
for op, left, right in questions:
# convert from index value into symbol (the "list()" is a needed trick for python3
op = list(operations.keys())[op]
print("{} {} {} = ?".format(left, op, right))
# calculate the operation with operator 'op' using 'left' and 'right'
ans = operations[op](left, right)
user_ans = get_integer_input()
if user_ans == ans:
score += 1
print("Well done, you are CORRECT")
else:
print("SORRY, you are INCORRECT") # print writing in brackets
print("The correct answer was {}".format(ans))
if score == 10: # run this part of code if "score" equals 10
print("Fantastic {}, you got full marks!".format(name))# print statement and name
elif score >= 6: # run this part of code if "score" is larger than or equal to 6
print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))# then print statement and score
elif score <=5: # run this part of code if "score" is smaller than or equal to 5
print("hmm, maybe some more practice would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score
return class_number, name, score
Nota Bene: I have not tested my code locally, it's been live coding within the answer box
of stackoverflow, so there might be syntax errors and maybe minor bugs. The goal of
my answer is to emphasize what you're doing wrong and show you how to do better. So,
please do not take it "as is" to copy/paste, but read it through, understand what I'm
showing to you, and update your code with what I given you as an improvement.
Here's a full example I just tested:
# make the script both py2 and py3 compatible
from __future__ import print_function
import sys
if sys.version_info.major == 2:
input = raw_input
import operator
import random
import json
import os
def store_results(class_number, name, score):
# this adds '.json' to the end of the file (therefore creating a json file)
class_file = "{}.json".format(class_number)
# first step: load the existing data
# first test if the file exists, and if not, use an empty score dictionary
if not os.path.exists(class_file):
scores = {}
# otherwise populate the dictionary
else:
# open as read only, because we just want the data out of it
with open(class_file, 'r') as f:
# load contents of the json file "f" as object "scores"
scores = json.load(f)
# second step: update the data
scores.setdefault(name, []).append(score)
# third step: update the file
# use 'w' when opening the file to overwrite all data within it
with open(class_file, 'w') as f:
# dump object "scores" within file "f"
json.dump(scores, f, sort_keys=True, indent=4, separators=(',', ': '))
def get_integer_input(maxval=None):
while True:
try:
# print a nice prompt
print("> ", end="")
i = int(input()) # asks for an integer input from user
if maxval:
if i >= maxval:
continue
print("Sorry, input shall be inferior than {}, try again".format(maxval))
break
except ValueError:
print("Sorry, I didn't understand that, please try again") # print statement
return i
operations = {
'+': operator.add,
'*': operator.mul,
'-': operator.sub
}
def generate_qa():
questions = []
while len(questions) < 3: # add a question until we have three generated
op = random.randint(0,2) # randomly generate a number from 1-3 and store as "maths"
num1 = random.randint(1,10) # randomly generate an integer from 1-10 and store as "num1"
num2 = random.randint(1,10) # randomly generate a second integer from 1-10 and store as "num2"
questions.append( (op, num1, num2) )
return questions
def run_qa(questions):
print("What is your name?") # prints writing in brackets
name = input().title() # Capitalizes the first letter of the word inputted
print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
class_number = get_integer_input(maxval=3)
# prints writing in brackets and anything saved in the variables "name" and "class_number"
print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))
score = 0 # sets the variable "score" to zero
for op, left, right in questions:
# convert from index value into symbol (the "list()" is a needed trick for python3
op = list(operations.keys())[op]
print("{} {} {} = ?".format(left, op, right))
# calculate the operation with operator 'op' using 'left' and 'right'
ans = operations[op](left, right)
user_ans = get_integer_input()
if user_ans == ans:
score += 1
print("Well done, you are CORRECT")
else:
print("SORRY, you are INCORRECT") # print writing in brackets
print("The correct answer was {}".format(ans))
if score == 10: # run this part of code if "score" equals 10
print("Fantastic {}, you got full marks!".format(name))# print statement and name
elif score >= 6: # run this part of code if "score" is larger than or equal to 6
print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))# then print statement and score
elif score <=5: # run this part of code if "score" is smaller than or equal to 5
print("hmm, maybe some more practise would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score
return class_number, name, score
if __name__ == "__main__":
questions = generate_qa()
class_number, name, score = run_qa(questions)
store_results(class_number, name, score)
HTH

Continually prompting user for input in Python

Objective: * Write a python program that repeatedly prompts for input of a positive number until the sum of the numbers is greater than 179. Use at least three modules/functions in your solution.
* The largest number entered cannot exceed 42.
* When the sum of the numbers exceeds 179, print the sum of the numbers, the largest number entered and smallest number entered.
I just need some guidance, specifically for the "input_numbers" module. There must be an easier way to do this than to make a variable for each number. The code is not complete. I haven't even started on the two other modules yet. Thanks in advance.
def input_numbers():
while True:
num1 = raw_input("Enter a positive integer no greater than 42 ")
if num1 <= 0:
print "That is not a positive integer. Try again "
elif num1 > 42:
print "The number cannot exceed 42. Try again "
num2 = raw_input("Enter another positive integer ")
if num2 <= 0:
print "That is not a positive integer. Try again "
elif num2 > 42:
print "The number cannot exceed 42. Try again "
num3 = raw_input("Enter another positive integer ")
if num3 <= 0:
print "That is not a positive integer. Try again "
elif num3 > 42:
print "The number cannot exceed 42. Try again "
num4 = raw_input("Enter another positive integer ")
if num4 <= 0:
print "That is not a positive integer. Try again "
elif num4 > 42:
print "The number cannot exceed 42. Try again "
num5 = raw_input("Enter another positive integer ")
if num5 <= 0:
print "That is not a positive integer. Try again "
elif num5 > 42:
print "The number cannot exceed 42. Try again "
elif sum(num1, num2, num3, num4, num5) > 179:
print_numbers()
add_numbers()
def add_numbers():
print_numbers()
def print_numbers():
input_numbers()
You can knock out all three function requirements by encapsulating each step of your program. Rather than having your loop inside of a function, we'll let main control the loop, and we'll control the flow by passing data into and out of function calls.
Let's rework your input_numbers() function a bit.
def get_input_number():
num = int(raw_input("Enter a positive integer no greater than 42 "))
if num <= 0 or num > 42:
print "Invalid input. Try again "
get_input_number()
else:
return num
So, instead of having input_numbers control the loop as well as the input handling and validation, we have it do just what its name implies: It asks for input, validates it, and then, if it's good, it returns the value to the caller, but if it's bad, it writes a message, and calls itself again to the user can enter good input.
The next function we'll set up is straight from your list of requirements. From all of the numbers that the user enters, we need to find the biggest one. From the language alone, we can determine that we're looking through a set of numbers, and thus, this is a good place to break out a list. Assuming we store all of the users input in a list, we can then pass that list to a function and perform operations on it, like so.
def get_greatest_number(input_list):
highest = input_list[0]
for i in input_list:
if i > highest:
highest = i
return highest
We set the first element of the list to a variable highest and then check all other elements in the list against that initial value. If we find one that's bigger, we then reassign the highest variable to the element that was bigger. Once we do this for each element in the list, the number inside of highest will now be, just that, the highest number, and so, we'll return it to the main program.
Similarly, we can do the same for finding the smallest.
def get_smallest_number(input_list):
smallest = input_list[0]
for i in input_list:
if i < smallest:
smallest = i
return smallest
Finally, we get to our main loop. Here we declare an empty list, number_list to store all the numbers in. And we use the sum of that as our loop condition.
if __name__ == '__main__':
number_list = []
while sum(number_list) < 179:
number_list.append(get_input_number())
In the body of the loop, we call our get_input_number() and append its result to the list we made. Once the sum of the numbers in the list exceed 179, the while loop will exit and we can finally show the user the results.
print
print '-------------------------'
print 'total of numbers entered: %d' % sum(number_list)
print 'greatest number entered: %d' % get_greatest_number(number_list)
print 'smallest number entered: %d' % get_smallest_number(number_list)
Here we can the get_greatest_number and get_smallest_number we made, and we give them the list of numbers as an argument. They'll loop though the lists, and then return the appropriate values to the print statements.
Yes, of course there's a better way than making a variable for each number. Store them in a list. Storing them in a list also makes finding their sum and the highest and lowest value easy (there are built-in functions for this).
As a further hint, you'll want to use two loops, one inside the other. The outer loop keeps the user entering numbers until their sum exceeds 179. The inner loop keeps the user entering a single number until it's between 1 and 42 inclusive.
def get_int(prompt=''):
while True:
try:
return int(raw_input(prompt))
except ValueError:
pass
def get_values():
values = []
total = 0
while total <= 179:
val = get_int('Enter a positive integer <= 42: ')
if 0 <= val <= 42:
values.append(val)
total += val
return values
def print_info(values):
print 'Sum is {}'.format(sum(values))
print 'Largest value is {}'.format(max(values))
print 'Smallest value is {}'.format(min(values))
def main():
values = get_values()
print_info(values)
if __name__=="__main__":
main()
You can repeatedly poll the number in a loop, and add the inputs into a list, e.g.
def input_numbers():
user_inputs = [] # a list of all user's inputs
while True:
num = raw_input("Enter a positive integer no greater than 42 ")
try:
num = int(num) # convert input string to integer
if num <= 0:
print "That is not a positive integer. Try again "
elif num > 42:
print "The number cannot exceed 42. Try again "
user_inputs.append(num)
except ValueError: # conversion to integer may fail (e.g. int('string') ?)
print 'Not a Number:', num
if some_condition_regarding(user_inputs):
break # eventually break out of infinite while loop
here some well-known tricks:
def min_and_max(your_num_list)
min=your_num_list[0]
max=your_num_list[0]
for num in your_num_list:
if num < min:
min=num
if max > num
max=num
return min,max
When you're writing a standalone Python program, it’s a good practice to use a main function. it allows you to easily add some unit tests, use your functions or classes from other modules (if you import them), etc.
And as others already said, it is a good idea to create a list and append a new element to it each time the user enters a valid number (until the sum of the numbers axceeds 179). If user entered an incorrect value, then just don’t append anything to the list and skip to the next iteration (so the user will be asked to enter a number again).
So basically it could look like this:
def validate_entered_number(num):
"""
Checks if the number is positive and is less or equal to 42.
Returns True if the number matches these conditions,
otherwise it returns False.
"""
if num < 0:
print "That is not a positive integer."
return False
if num > 42:
print "The number cannot exceed 42."
return False
return True
def main():
entered_numbers = []
while True:
try:
num = int(raw_input("Enter a positive integer less or equal to 42: "))
except ValueError:
print "You should enter a number"
continue
if validate_entered_number(num):
entered_numbers.append(num)
if sum(entered_numbers) > 179:
print "The sum of the numbers is %s" % sum(entered_numbers)
print "The smallest number entered is %s" % min(entered_numbers)
print "The largest number entered is %s" % max(entered_numbers)
return
if __name__ == "__main__":
main()
In fact, I can imagine a situation where you would want to just store the sum of the numbers, the smallest number and the largest number in three variables and update these variables in each iteration (add current number to the sum and compare it to the currently known smallest and larger numbers and update the corresponding variables when necessary), but in this case the longest list you can possibly have is only 180 elements (if all numbers are 1 and the user doesn’t enter 0 or you have modified the program to deny entering 0), which is very small amount of elements for a list in Python. But if you had to deal with really big amounts of numbers, I’d recommend to switch to a solution like this.
Thanks to everyone who answered. I've written the following code and it works nearly perfectly except the last module. If you exit the program after the first run (by pressing 0) it will exit, but if you run it a second time pressing 0 won't make it exit. It'll just go back to the beginning of the program. I don't know why.
Note: The assignment has various requirements that I had to incorporate in my code. Hence the unnecessary modules, global variables, and comments.
maxNum = 42 # declares global variable maxNum
target = 179 # declares global variable target
def user_input(): # prompts user to input a number 42 or less until all add up to 179
x = 0
nums = []
while sum(nums) <= target:
nums.append(int(raw_input("Enter a number: ")))
if int(nums[x]) > int(maxNum):
print "Number cannot exceed 42."
user_input()
else:
x += 1
print_nums(nums,x)
def print_nums(nums,x): # prints the sum of the numbers, the smallest, and the largest
print "Sum of all numbers is", sum(nums)
nums.sort()
x -= 1
print "Largest number entered is", nums[x]
print "Smallest number entered is", nums[0]
decide()
def decide(): # allows user to continue the program or exit
exit = raw_input("<9 to enter a new set of number. 0 to exit.> ")
while True:
if int(exit) == 0:
return
elif int(exit) == 9:
user_input()
user_input()

Using random.randint help in python

The following code is my attempt at simulating a lottery.
import random
def lottery(numbers):
lottoNumbers = [randint('0,100') for count in range(3)]
if numbers == lottoNumbers:
print('YOU WIN $10,000')
else:
print('YOU LOSE,DUN DUN DUNNN!')
return numbers
def main():
numbers = int(input('Enter a number: '))
if numbers == lottoNumbers:
numbers = lottery(numbers)
else:
numbers = lottery(numbers)
main()
Hey guys I've gotten this far with the help you've given me. I'm trying to write the code so that 3 lotto numbers at random will be chosen. Then the user must enter 3 of his/her own lotto numbers. If they get all 3 correct then they win the whole prize, if they get the 3 numbers but not in the correct order they win some of the prize. Obviously if they guess all wrong then a print statement would state that. What I'm confused about is how can I write the code so that the user can enter 3 numbers to try matching the random lottery numbers. I also want to print the 3 lottery numbers after the user inputs his/her choices. Any ideas guys?
Thanks for your help everyone.
You seem a bit confused about what the role of the arguments in a function are. You've said that your randm function takes the argument "number", but then you haven't actually used it anywhere. The next time number appears, you've assigned it a completely new value, so any value passed to randm isn't actually being used.
Also, the function is trying to return x, when x hasn't been assigned within the function. Either you already have a global variable called x already defined, in which case the function will just return that variable, or the function will just fail because it can't find the variable x.
Here's a quick example I've done where you pass their three numbers as a list as an argument to the function.
import random
theirNumbers=[5,24,67]
def checkNumbers(theirNumbers):
lottoNumbers = []
for count in range(3)
lottoNumbers.append(random.randint(0,100))
winning = True
for number in theirNumbers:
if not each in lottoNumbers: winning=False
if winning == True: print("Winner!")
There are a few things wrong with your implementation, to name a few:
if you are trying to compare the output of the function randm to x, you will need to include a return value in the function, like so:
def randm():
return return_value
You appear to be printing all the values but not storing them, in the end you will only end up with the final one, you should attempt to store them in a list like so:
list_name = [randint(0,100) for x in range(x)]
This will generate randint(0,100) x times in a list, which will allow you to access all the values later.
To fix up your code as close to what you were attempting as possible I would do:
import random
def randm(user_numbers):
number = []
for count in range(3):
number.append(random.randint(0, 100))
print(number)
return user_numbers == number
if randm(x):
print('WINNER')
If you are looking for a very pythonic way of doing this task,
you might want to try something like this:
from random import randint
def doLotto(numbers):
# make the lotto number list
lottoNumbers = [randint(0,100) for x in range(len(numbers))]
# check to see if the numbers were equal to the lotto numbers
if numbers == lottoNumbers:
print("You are WinRar!")
else:
print("You Lose!")
I'm assuming from your code (the print() specifically) that you are using python 3.x+
Try to post your whole code. Also mind the indentation when posting, there it looks like the definition of your function would be empty.
I'd do it like this:
import random
def lottery():
win = True
for i in range(3):
guess = random.randint(1,100)
if int(raw_input("Please enter a number...")) != guess:
win = False
break
return win
Let so do this in few steps.
First thing you should learn in writing code is to let separate pieces of code( functions or objects) do different jobs.
First lets create function to make lottery:
def makeLottery(slotCount, maxNumber):
return tuple(random.randint(1,maxNumber) for slot in range(slotCount))
Next lets create function to ask user's guess:
def askGuess(slotCount, maxNumber):
print("take a guess, write {count} numbers separated by space from 1 to {max}".format(count = self.slotCount, max = self.maxNumber))
while True: #we will ask user until he enter sumething suitable
userInput = raw_input()
try:
numbers = parseGuess(userInput,slotCount,maxNumber)
except ValueError as err:
print("please ensure your are entering integer decimal numbers separated by space")
except GuessError as err:
if err.wrongCount: print("please enter exactly {count} numbers".format(count = slotCount))
if err.notInRange: print("all number must be in range from 1 to {max}".format(max = maxNumber))
return numbers
here we are using another function and custom exception class, lets create them:
def parseGuess(userInput, slotCount,maxNumber):
numbers = tuple(map(int,userInput.split()))
if len(numbers) != slotCount : raise GuessError(wrongCount = True)
for number in numbers:
if not 1 <= number <= maxNumber : raise GuessError(notInRange = True)
return numbers
class GuessError(Exception):
def __init__(self,wrongCount = False, notInRange = False):
super(GuessError,self).__init__()
self.wrongCount = wrongCount
self.notInRange = notInRange
and finally function to check solution and conratulate user if he will win:
def checkGuess(lottery,userGuess):
if lottery == userGuess : print "BINGO!!!!"
else : print "Sorry, you lost"
As you can see many functions here uses common data to work. So it should suggest you to collect whole code in single class, let's do it:
class Lottery(object):
def __init__(self, slotCount, maxNumber):
self.slotCount = slotCount
self.maxNumber = maxNumber
self.lottery = tuple(random.randint(1,maxNumber) for slot in range(slotCount))
def askGuess(self):
print("take a guess, write {count} numbers separated by space from 1 to {max}".format(count = self.slotCount, max = self.maxNumber))
while True: #we will ask user until he enter sumething suitable
userInput = raw_input()
try:
numbers = self.parseGuess(userInput)
except ValueError as err:
print("please ensure your are entering integer decimal numbers separated by space")
continue
except GuessError as err:
if err.wrongCount: print("please enter exactly {count} numbers".format(count = self.slotCount))
if err.notInRange: print("all number must be in range from 1 to {max}".format(max = self.maxNumber))
continue
return numbers
def parseGuess(self,userInput):
numbers = tuple(map(int,userInput.split()))
if len(numbers) != self.slotCount : raise GuessError(wrongCount = True)
for number in numbers:
if not 1 <= number <= self.maxNumber : raise GuessError(notInRange = True)
return numbers
def askAndCheck(self):
userGuess = self.askGuess()
if self.lottery == userGuess : print "BINGO!!!!"
else : print "Sorry, you lost"
finally lets check how it works:
>>> lottery = Lottery(3,100)
>>> lottery.askAndCheck()
take a guess, write 3 numbers separated by space from 1 to 100
3
please enter exactly 3 numbers
1 10 1000
all number must be in range from 1 to 100
1 .123 asd
please ensure your are entering integer decimal numbers separated by space
1 2 3
Sorry, you lost
>>> lottery = Lottery(5,1)
>>> lottery.askAndCheck()
take a guess, write 5 numbers separated by space from 1 to 1
1 1 1 1 1
BINGO!!!!

Categories

Resources