My goal is to:
take an input (until user enters 0) or quit (if a letter is entered),
run a few checks to throw out non-integers,
add those values to a list, and
then print the sum of list.
I'm trying to capture the boolean value for variable close in main but I'm getting an error.
Error: "close = addToList() TypeError: addToList() missing 1 required
positional argument: 'numberList'."
#function to create a list
def createList():
numberList = []
return numberList
#function to add integers from user to list
def addToList(numberList):
stopAdding = False
close = False
while stopAdding == False:
integerInput = input("Please enter a number [1-9] or '0' to stop: ")
if integerInput.isalpha():
badInput()
close = True
break
elif integerInput == '0':
stopAdding = True
else:
numberList.append(int(integerInput))
if close == True:
return close
else:
return numberList
#function for when invalid number entered
def badInput():
print("Invalid number entered.")
#function to sum the numbers in list
def sumList(numberList):
sumTotal = 0
for number in numberList:
sumTotal = sumTotal + number
return sumTotal
#function to print the list sum
def printSum(sumTotal):
print("The sum is: ", sumTotal)
#the main function
def main():
numberList = createList()
addToList(numberList)
sumTotal = sumList(numberList)
close = addToList()
if close == True:
pass
else:
printSum(sumTotal)
#call main
main()
What would be a better way to exit gracefully if a non-integer was entered? Thanks.
Change you main function to look like this;
def main():
numberList = createList()
close = addToList(numberList)
sumTotal = sumList(numberList)
if not close:
printSum(sumTotal)
Other things you can do to make your code cleaner is to remove the sumList function and just use the builtin sum function, and remove the createList since it really doesn't need to be it's own function. Then your main would look like this;
def main():
numberList = []
close = addToList(numberList)
if not close:
printSum(sum(sumTotal))
You forgot your argument in the second call:
close = addToList(sumTotal)
Thanks guys/gals.
I got rid of my if else at the end of addToList function and returned both close value and numberList value: return (close,numberList)
And then for main use builtin sum function:
close, numberList = addToList(numberList)
#the main function
def main():
numberList = createList()
close, numberList = addToList(numberList)
if not close:
printSum(sum(numberList))
Lastly, for throwing out all non-integer inputs entered, I used:
if not stringname.isdigit():
Works well now.
Related
I'm trying to add values to a list, and stop adding with empty line:
def main():
signal = []
i = 0
print("Enter the data points of the signal. Stop with empty line.\n")
while i != "":
value = float(input())
signal.append(value)
i += 1
print(signal)
main()
However, when I press enter (empty line) I get the following error:
File "C:\Users\Omistaja\Downloads\template_median_filter.py", line 30, in main
value = float(input())
ValueError: could not convert string to float: ''
How to proceed?
You almost got it:
def main():
signal = []
i = 0
print("Enter the data points of the signal. Stop with empty line.\n")
while True:
i += 1
data = input("Data point {}: ".format(i))
if data == "":
break
signal.append(float(data))
print("\nThe signal is: {}".format(signal))
main()
You don't need a counter. Just check if the input is empty
signal = []
while True:
points = input("Enter a data point for the signal. Stop with empty line.\n")
if not points:
break
signal.append(float(points))
print(signal)
I would like to count the number of attempts the user took to guess the correct color sequence. I have been stuck for quite a while as I tried to add a count function but it kept being stuck at 0. I'm new at python so any help is much appreciated (I had to remove some unrelated part of the code because I cant fit it in the box (at compare_list section)
import random
colours = ['PINK', 'BLUE', 'YELLOW', 'RED']
random_colours = []
colours_input = []
#handles the users input and stores in a list (colours_input)
def user_input():
i = 1
while i < 5:
a = input('Please enter your selected colours in sequence, colour ' + str(i) + ': ').upper()
while a not in colours:
print('Please only type the colours in the range (PINK, BLUE, YELLOW, RED) ')
a = input('Please enter a valid colour ' + str(i) + ': ').upper()
colours_input.append(a)
i+=1
print('Your selected colour sequence is: ' + str(colours_input))
#Automatically generate four random colours for the user to guess
def randomize():
for i in range (0,4):
random_colours.append(random.choice(colours))
#To check 2 variables: Correct colour in the correct place and correct colour but in the wrong place
def compare_list():
correct_place = 0
if random_colours[0] == colours_input[0]:
colour_1 = True
correct_place = correct_place + 1
else:
colour_1 = False
if random_colours[1] == colours_input[1]:
colour_2 = True
correct_place = correct_place + 1
else:
colour_2 = False
if random_colours[2] == colours_input[2]:
colour_3 = True
correct_place = correct_place + 1
else:
colour_3 = False
if random_colours[3] == colours_input[3]:
colour_4 = True
correct_place = correct_place + 1
else:
colour_4 = False
print('Correct colour in the correct place: ' + str(correct_place))
while correct_place == 4:
print('Congratulations! You are a master mind')
break
else:
colours_input.clear()
user_input()
compare_list()
You're going to want to have some driver code, that acts as the entry point to your program and orchestrates how functions will be called. Currently you are doing this in your compare_list() function, simply move this code (and change it a bit, there were some mistakes with the while loop structure) to a new function.
Typically this code is placed in a main function. In your case, it could look something like:
def main():
random_colours = []
colours_input = []
randomize() # you forgot to call this in your code
while True:
user_input()
if compare_list():
print('Congratulations! You are a master mind')
break # exit the program
colours_input.clear()
Then, we just need to refactor our compare_list() function so that it only compares the lists, and returns the result of the comparison (I just return a boolean representing whether the comparison was successful, but you could also return the correct_place value for example).
def compare_list():
correct_place = 0
if random_colours[0] == colours_input[0]:
colour_1 = True
correct_place = correct_place + 1
else:
colour_1 = False
if random_colours[1] == colours_input[1]:
...
print('Correct colour in the correct place: ' + str(correct_place))
return correct_place == 4 # returns True, if correct_place equals 4, False otherwise
Now, in our main function, we can count how many times we have run this main loop for each user attempt:
def main():
random_colours = []
colours_input = []
attempts = 0
while True:
attempts += 1
user_input()
randomize()
if compare_list():
print('Congratulations! You are a master mind')
print('It only took you {} attempt{}!'.format(attempts, 's' if attempts > 1 else "")
break # exit
colours_input.clear()
random_colours.clear()
Now we simply call the main() function in our file to run the driver code. Typically this is done in an if block that runs only if your script is being run directly as opposed to being imported by something else:
...
def compare_list():
...
def main():
...
if __name__ == "__main__":
main()
(You can read up about this practice here: What does if __name__ == “__main__”: do?)
A final refactor would be to reduce the use of global variables. You should aim to make your functions units of code that operate on input(s) and return output(s). Designing your functions so that they mutate global variables to produce a result is an anti-pattern.
Here's one way to refactor it:
import random
colours = ('PINK', 'BLUE', 'YELLOW', 'RED') # this is okay since it is a constant. We can make it an immutable tuple to clearly indicate that this is read-only.
# remove the following global variables
# random_colours = []
# colours_input = []
#handles the users input and stores in a list (colours_input)
def user_input():
colours_input = [] # define the variable here. We create a new list that this function will populate, then return it
for i in range(5):
...
print('Your selected colour sequence is: ' + str(colours_input))
return colours_input # return the populated list
def randomize():
random_colours = [] # define the variable here. Similar to above.
for i in range (0,4):
random_colours.append(random.choice(colours))
return random_colours # return it to the caller
# we take in the lists to compare as parameters to the function, rather then getting them from the global scope
def compare_list(colours_input, random_colours):
... # (everything else is the same)
def main():
random_colours = randomize()
# colours_input = []
attempts = 0
while True:
attempts += 1
colours_input = user_input()
if compare_list(colours_input, random_colours): # pass the returned lists in as arguments to this function call
print('Congratulations! You are a master mind')
print('It only took you {} attempt{}!'.format(attempts, 's' if attempts > 1 else "")
break # exit the program
# no need to clear this anymore. We get a new list from each call to user_input()
# colours_input.clear()
This is a training version of Calculator, for some reason I am getting the error:
File "C:/Users/stazc/PycharmProjects/project00/Calculator.py", line 54, in calculate
print(sum(self.numY,self.numX))
TypeError: 'int' object is not iterable
The interesting part is that I am not using the iterator here, even though I wanted to. I executed the code before and run just fine the added some code for looping and it gave this error. Now the looping part is in comments so it should not affect the code although it is still giving me the same error!!
class Calculator:
numX = 0
numY = 0
__sign = ''
def __init__(self):
pass
# self.numX = x
# self.numY = y
# self.__sign = sign
def set_key_values(self):
print("Input numbers and then symbol")
self.numX = int(input("X: "))
self.__sign = input("Input symbol: ")
self.numY = int(input("Y: "))
#functions
def sum(self,numX, numY):
return numX+numY
def minus(self,numX, numY):
return numX-numY
def mult(self,numX, numY):
return numX*numY
def divide(self,numX, numY):
return numX/numY
#setters
def set_x(self,x):
self.numX = x
def set_y(self,y):
self.numY = y
def set_sign(self,sign):
self.__sign = sign
numX = numX
#getters
def get_x(self):
return self.numX
def get_y(self):
return self.numY
def get_sign(self):
return self.__sign
def calculate(self):
if self.__sign == '+':
print(sum(self.numY,self.numX))
elif self.__sign == '-':
print(self.minus(self.numX,self.numY))
elif self.__sign == '*':
print(self.mult(self.numX,self.numY))
elif self.__sign == '/':
print(self.divide(self.numX,self.numY))
else:
print('Incorrect Input, try again!')
c = Calculator()
c.set_key_values()
c.calculate()
Here I tried to add a loop that you can keep adding stuff but this error made my code stop working completely and can't see why?
#
# loop = input("Keep Going? y/n")
# cont = True
# if loop[0] == 'y':
# cont = True
# else:
# cont = False
#
# while cont:
# c = Calculator()
# c.set_key_values()
# c.calculate()
# else:
# quit()
#
The reason why you get this error:
print(sum(self.numY,self.numX))
TypeError: 'int' object is not iterable
Is because you are using Pythons built-in sum(iterable[, start]) method. And the first parameter it takes expects an iterable. Instead you will want to use your defined method self.sum that belongs to your Calculator class.
print(self.sum(self.numY,self.numX))
Replace sum() with self.sum() where you get your error.
You want to do this because python's version is different from yours and needs an iterable as first argument to work. Everything in your calculator is using the self function instead of the python too so thats another reason.
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)
So I have to create a program that asks the user 5 addition questions and they can type the right answer. I am very new at python and functions in general so helpful answers only please. I know how to get random numbers and make it so the question for ex: "What is 4 + 5?" I just do not know how to ask 5 different addition questions within the function. This is what I have.
import random
def add():
num1=random.randint(1,10)
num2=random.randint(1,10)
return num1,num2
def main():
x,y= add()
plus=int(input("What is {} + {} ?".format(x,y)))
main()
I don't get an error when I run your code. Here is an answer for you:
Right now your main() is asking for an input back from the user and each time main() is called it will ask for a different number, so if you like you can do something like this:
for _ in range(5):
main()
But from the sound of it, you want to have the function main() ask all of the questions, namely - something like this:
def main():
for _ in range(5):
x,y = add()
plus = int(input("What is {} + {} ?".format(x,y)))
Simplest is to use a counting loop:
def main():
for i in range(5):
x,y = add()
plus = int(input("What is {} + {} ?".format(x,y)))
The following program demonstrates how to have a program ask five addition questions:
import random
import sys
def main():
for count in range(5):
ask_addition_question()
def ask_addition_question():
numbers = random.randrange(10), random.randrange(10)
answer = get_number('What is {} + {}? '.format(*numbers))
total = sum(numbers)
if answer == total:
print('That is correct!')
else:
print('Actually, the correct answer is {}.'.format(total))
def get_number(query):
while True:
try:
return int(input(query))
except KeyboardInterrupt:
print('Please try again.')
except EOFError:
sys.exit()
except ValueError:
print('You must enter a number.')
if __name__ == '__main__':
main()
Just use a for loop to ask the user 5 times
def main():
for i in range(5):
x,y = add()
plus = int(input("What is {} + {} ?".format(x,y)))
To check if the answer is correct just you can do:
if x + y == plus: print "good"
else: print "bad"