Python script not producing output - python

I have been tasked with reading values inputted by a user(using a while loop) to then store them in a list/array whilst using try: except: to determine if a given input is invalid. In continuation, if the user inputs "done" as a value it will break the loop and print() the total, sum, and average of all the imputed values.
I have gotten this snippet so far:
class Input:
def __init__(self, number_input_value, total_to_be_calculated, main_value):
self.number_input_value = 0
self.total_to_be_calculated = 0.0
self.main_value = input('Enter A Number: ')
self.number_input_value1 = float(self.main_value)
def loop_get_inputs(self):
while True:
self.main_value
if self.main_value == 'done':
break
try :
self.number_input_value1
except :
print('INVAL["VAL"]')
continue
self.number_input_value = self.number_input_value1
self.total_to_be_calculated = self.total_to_be_calculated + self.number_input_value1
print ("Finished successfully!")
print (
self.total_to_be_calculated,
self.number_input_value,
self.total_to_be_calculated/self.number_input_value
)
if __name__ in '__main__':
Input
I have no clue what's wrong, because when it runs it outputs nothing.
Output:
>>>

You need create an instance of the class 'Input' and call the method:
##(self, number_input_value, total_to_be_calculated, main_value)
inp = Input(100, 1000, 10)
#call the method
inp.loop_get_inputs()

Basically:
1 - You have to initialize your class/object before using it.
2 - Having code on the construct is not recommend. You should call a public method of the class to start the "process".
3 - That try-except wasn't doing much. You can, for example, surround the string (from input()) cast to float and print INVALID if the input can't be casted.
4 - You can use += to simplify a = a + b
5 - lower() will convert user input to lowercase, meaning that DONE, done and DoNe (etc) will be considered as "quit" input.
Does this make sense?
class Input:
def __init__(self):
self.number_inputs = 0
self.total = 0.0
def run(self):
self.__get_user_values()
print(f"total: '{self.total}'")
print(f"number_inputs: '{self.number_inputs}'")
print(f"average: '{self.total / self.number_inputs}'")
def __get_user_values(self):
while True:
value = input('Enter A Number: ')
if value.lower() == 'done':
break
if self.__is_valid_input(value):
self.total += float(value)
self.number_inputs += 1
def __is_valid_input(self, value) -> bool:
try:
float(value)
return True
except ValueError:
print('INVAL["VAL"]')
return False
if __name__ in '__main__':
input_wrapper = Input()
input_wrapper.run()

Related

Working on a basic python calculator and can't get my menu to loop properly

Thanks to this site I was able to get this far, being the python novice I am, however I'm kind of stuck. I'm trying to loop 'selection', so after a user does some math, rather than just ending it will give them the option to do something else until they select 0 to quit. I tried a bunch of other try and conditional statements but just end up getting answers and such stuck in an infinite loop.
Also, I'm pretty here, but any help is appreciated, also I'm a python nub. I'm writing this with python 2.7, if that matters.
def sum ( arg1, arg2):
total = a + b
return total;
def subtract ( arg1 , arg2):
total = a - b
return total;
def mult ( arg1, arg2):
total = a * b
return total;
def division ( arg1, arg2):
total = (a / b)
return total;
options = ["1", "2", "3", "4", "5", "0"]
print ("Please choose an option for mathing")
print ("1 for addition")
print ("2 for division")
print ("3 for subtraction")
print ("4 for multiplication")
print ("5 ")
print ("0 to exit")
#this will keep prompting the user to provide an input that is listed in 'options'
while True:
selection = input("Please select choose an option to continue")
if selection in options:
break
else:
print("Please choose a valid option")
#user input for mathing
#input will be validated as follows
a = None
while a is None:
try:
a = int(input("please provide a number for A"))
except ValueError:
print "please use a valid integer"
pass
b = None
while b is None:
try:
b = int(input("please provide a number for B"))
except ValueError:
print "please use a valid integer"
pass
#performing the operations
if selection == '1':
print "The sum is", str(sum(a, b))
elif selection == '2':
print "The quotient is", str(division(a, b))
elif selection == '3':
print "The difference is", str(subtract(a, b))
elif selection == '4':
print "The product is", str(mult(a, b))
elif selection == '0':
exit()
heres a few things I would do to make this more efficient..
options should be a dictionary... your in is a lot more efficient on a dictionary than on a list. the beauty of this is the value for each key can be function methods.
ex. options = {1: 'sum', 2: 'subtract' ..... }
then make a class with your math operations in it
class Calculator(object):
def sum(self, x, y):
return x + y
def subtract(self, x, y):
return x - y
#add more operations here
#staticmethod
def start():
while True:
#prompt for input and the operator
whats nice about this is in your checks for the selection you can dynamically call the class method to clean the code up a lot
if selection in options:
getattr(options[selection], Calculator)(a, b)
if you want me to explain more I can finish the example.
for your loop, you can add a method that starts the action and continues looping and doing more operations each time
here is a basic class you can use using those methods I described
class Calculator(object):
loop = None
calculations = 1
current_value = 0
selection = 0
options = {1: 'add', 2: 'subtract', 3: 'multiply', 4: 'divide'}
def __init__(self, loop=True):
self.loop = loop
print 'Welcome to my basic calculator!'
if not self.loop: # dont loop just execute once
self.run()
else:
while True:
self.run()
#staticmethod
def add(x, y):
return x + y
#staticmethod
def subtract(x, y):
return x - y
#staticmethod
def multiply(x, y):
return x * y
#staticmethod
def divide(x, y):
if y != 0: #cant divide by 0
return x / y
#staticmethod
def quit():
exit(0)
def run(self):
if self.calculations == 1:
self.current_value = self.prompt_user_input('please provide a number: ')
self.prompt_operator('Please choose an operator to continue\n1 for addition\n2 for subtraction\n3 for multiplication \n4 for division\n0 to quit\n')
y = self.prompt_user_input('please provide a number: ')
self.current_value = getattr(Calculator, self.options[self.selection])(self.current_value,y)
self.calculations += 1
print 'New value is: ' + str(self.current_value)
def prompt_operator(self, prompt_message):
while True:
self.selection = input(prompt_message)
if self.selection in self.options:
break
elif self.selection == 0:
self.quit()
else:
print("Please choose a valid option")
def prompt_user_input(self, prompt_message):
val = None
while val is None:
try:
val = int(input(prompt_message))
except ValueError:
print "please use a valid integer"
pass
return val
finally to start your calculator off you can just call it and either pass true to continue loops or pass false to only do one calculation
Calculator(loop=True)
Just put a loop around the prompting and calculation. If they enter 0, break from the outer-most loop:
while True:
#this will keep prompting the user to provide an input that is listed in 'options'
while True:
selection = input("Please select choose an option to continue")
if selection in options:
break
else:
print("Please choose a valid option")
if selection == '0':
break
...
#this will keep prompting the user to provide an input that is listed in 'options'
while True:
selection = input("Please select choose an option to continue")
if selection in options:
if selection == 1:
sum()
if selection == 2:
subtract()
.....
if selection == 'q'
break
Change the logic to what I did above, for option,take some action and do break on the quit character/
Firstly, your code should not work as it is now:
if selection == '1': #should return false
That's because using input you are taking a numeric quantity and then comparing it to a string.
change the input of selection to raw_input
Or change the conditional statements like below:
if selection == 1:
Then add a while True over the entire execution block to go through the execution again and again, until 0 is selected.

What is wrong with my defintion of the function prompt_int?

I have been trying to program a maths quiz that both works and is as efficient as possible. Looking over my code I saw I had a lot of integer inputs and that lead to me having the program to ask the question/exit the system if the criteria isn't met, so to help me I thought that it would be useful to create a new function. Here is my attempt:
def prompt_int(prompt=''):
while True:
if status == prompt_int(prompt=''):
val = input(prompt)
if val in (1,2):
return int(val)
return true
elif status != prompt_int(prompt=''):
val = input(prompt)
if val in (1,2,3):
return int(val)
return true
else:
print("Not a valid number, please try again")
However, when I try to implement this function around my code it doesn't work properly as it says that status isn't defined however, when I do define status it goes into a recursion loop. How can I fix this problem?
Here is my original code before i try to implement this function:
import sys
import random
def get_bool_input(prompt=''):
while True:
val = input(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
sys.exit("Not a valid input (yes/no is expected) please try again")
status = input("Are you a teacher or student? Press 1 if you are a student or 2 if you are a teacher")# Im tring to apply the new function here and other places that require integer inputs
if status == "1":
score=0
name=input("What is your name?")
print ("Alright",name,"welcome to your maths quiz."
"Remember to round all answer to 5 decimal places.")
level_of_difficulty = int(input(("What level of difficulty are you working at?\n"
"Press 1 for low, 2 for intermediate "
"or 3 for high\n")))
if level_of_difficulty not in (1,2,3):
sys.exit("That is not a valid level of difficulty, please try again")
if level_of_difficulty == 3:
ops = ['+', '-', '*', '/']
else:
ops = ['+', '-', '*']
for question_num in range(1, 11):
if level_of_difficulty == 1:
number_1 = random.randrange(1, 10)
number_2 = random.randrange(1, 10)
else:
number_1 = random.randrange(1, 20)
number_2 = random.randrange(1, 20)
operation = random.choice(ops)
maths = round(eval(str(number_1) + operation + str(number_2)),5)
print('\nQuestion number: {}'.format(question_num))
print ("The question is",number_1,operation,number_2)
answer = float(input("What is your answer: "))
if answer == maths:
print("Correct")
score = score + 1
else:
print ("Incorrect. The actual answer is",maths)
if score >5:
print("Well done you scored",score,"out of 10")
else:
print("Unfortunately you only scored",score,"out of 10. Better luck next time")
class_number = input("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
while class_number not in ("1","2","3"):
print("That is not a valid class, unfortunately your score cannot be saved, please try again")
class_number = input("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
else:
filename = (class_number + "txt")
with open(filename, 'a') as f:
f.write("\n" + str(name) + " scored " + str(score) + " on difficulty level " + str(level_of_difficulty))
with open(filename, 'a') as f:
f = open(filename, "r")
lines = [line for line in f if line.strip()]
f.close()
lines.sort()
if get_bool_input("Do you wish to view previous results for your class"):
for line in lines:
print (line)
else:
sys.exit("Thanks for taking part in the quiz, your teacher should discuss your score with you later")
if status == "2":
class_number = input("Which classes scores would you like to see? Press 1 for class 1, 2 for class 2 or 3 for class 3")
if class_number not in (1,2,3):
sys.exit("That is not a valid class")
filename = (class_number + "txt")
with open(filename, 'a') as f:
f = open(filename, "r")
lines = [line for line in f if line.strip()]
f.close()
lines.sort()
for line in lines:
print (line)
Well, just a part:
def prompt_int(prompt=""):
while True:
val = input(prompt)
if val in ("1", "2"):
return int(val), True
Will ask again and again. And return when the user enter "1" or "2"!
But better: "if val in "12":
def prompt_int(prompt=""):
while True:
val = input(prompt)
if val.isdigit():
return int(val)
Hi if you dont want to have valid values send to your you could change your code as the function above.
But you could also change it to do the system exits:
def prompt_int(prompt="", authorized=()):
while True:
val = raw_input(prompt)
if val.isdigit():
if int(val) in authorized:
return int(val)
else:
sys.exit("Bla bla bla too bad")
def prompt_int(prompt=''):
while True:
if status == prompt_int(prompt=''):
This line will look for the name "status" in the global namespace (module's namespace), and raise a NameError if there's no global variable named 'status'.
If there's one, it will then recursively calls prompt_int without any possible termination, resulting theoretically in an endless recursion, but practically (in CPython at least) in a RuntimeError when it will hit the maximum recursion depth.
There are also quite a few other things that won't work as you expect:
val = input(prompt)
if val in (1,2):
In Python 3.x, val will be a string, so it will never compare equal to an int. In Python 2.x, input() is a shortcut for eval(raw_input()), which might return an int, but is also a huge security flaw since it unconditionnally execute untrusted code.
return int(val)
return true
The second return statement will never be executed, obviously, since the function will exit at the first one.
A simpler implementation might look like this:
# rebinds raw_input to input for python < 3
import sys
if sys.version_info.major < 3:
input = raw_input
def prompt_int(prompt='', choices=None):
while True:
val = input(prompt)
try:
val = int(val)
if choices and val not in choices:
raise ValueError("{} is not in {}".format(val, choices))
return val
except (TypeError, ValueError) as e:
print(
"Not a valid number ({}), please try again".format(e)
)
While we're at it, there's room for improvement in other parts of your code. Let's start with this:
def get_bool_input(prompt=''):
while True:
val = input(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
sys.exit("Not a valid input (yes/no is expected) please try again")
First point: your naming is not consistent. If your other function is named prompt_int, this one should be named prompt_bool. Also, you have one function (prompt_int) looping forever and the other one exiting the whole program on invalid input, which is another inconsistency. If you want to allow the user to exit on any prompt, provide an explicit option for it, ie:
def prompt_bool(prompt, quit='Q'):
prompt += " (hit '{}' to exit) : ".format(quit)
while True:
val = input(prompt).strip().upper()
if val == quit:
sys.exit("Goodbye")
elif val == 'yes':
return True
elif val == 'no':
return False
else:
print "Invalid input '{}', please try again".format(val)
Of course you then want to provide the same option in prompt_int(), which leads to a more generic function:
def get_input_or_quit(prompt, quit="Q"):
prompt += " (hit '{}' to exit) : ".format(quit)
val = input(prompt).strip()
if val.upper() == quit:
sys.exit("Goodbye")
return val
def prompt_bool(prompt):
while True:
val = get_input_or_quit(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
print "Invalid input '{}', please try again".format(val)
And of course you also replace the call to input by a call to get_input_or_quit in prompt_int.
We could go on for long - splitting all your code in distinct, self-contained function, writing a "main()" function to drive them (instead of having the "main" part at the top level), and obviously using the operator module instead of eval().

Python input restriction and repromoting

I wanted to restrict the user input from 1 - 223 excluding " 3 , 7 , 10 , 12 "
and when the user enter one of these numbers i want to print an error and ask to re-promote the entry from the user .. I have the problem in listing the excluded numbers and in the repromoting code ..
This is where i have stopped
for i in range(numRan):
ranNums.append(int(raw_input( "Range %d Number ? (1-223)\n" % (i+1) )))
if i in []:
print "Rang is not allowed!"
This works- including retaking the input if it is not valid:
allowed_nums = set(range(1,224)) - {3,7,10,12}
for i in range(numRan):
while True:
inpt = int(raw_input("Range %d Number? (1-223)\n" % (i+1)))
if inpt in allowed_nums:
ranNums.append(inpt)
break
print "Range is not allowed!"
So the way this basically works is that for every iteration, or input we create an infinite loop that only breaks to thus move onto the next input iteration when the input is valid.
I usually write a function for inputs that have to re-prompt the user
def limited_input(prompt="",include_only=None,not_allowed=None,not_allowed_err="",cast=None,wrongcasterr=""):
if not_allowed is None:
not_allowed = set()
in_ = None
while in_ is None:
in_ = raw_input(prompt)
if cast:
try: in_ = cast(in_)
except ValueError:
print wrongcasterr
in_ = None
continue
if (include_only and in_ not in include_only) or in_ in not_allowed:
print not_allowed_err
in_ = None
return in_
Then you can use it as usual:
for i in range(numRan):
ranNums.append(limited_input(prompt="Range %d Number ? (1-223)\n" % (i+1),
include_only = range(1,224),
not_allowed = {3,7,10,12},
not_allowed_err = "You cannot use 3,7,10,12"
cast = int
wrongcasterr = "You must enter an integer"))
This solution is highly portable, and I usually include it in some module or another in my python lib. On this system it's in utils.inpututils but YMMV
It might be easier for you to separate the function which asks for the function, and creating a list of numbers layer, like so:
restrict = [3,7,10,12]
# This function returns an input number with the right
# characteristics.
def strictInput():
v = int(raw_input('Number?'))
if v >0 and v<224 and v not in restrict: return v
print 'Illegal number ..., try again'
return strictInput()
# Now call this function however many times you need ...
inputNumbers = [strictInput() for i in range(numRan)]
Try this:
not_allowed = {3,7,10,12}
for i in range(numRan):
while True: # to repeat raw_input if the input is not_allowed
val = int(raw_input( "Range %d Number ? (1-223)\n" % (i+1) )))
if val in not_allowed or val < 1 or val > 223:
print "Rang is not allowed!"
else:
ranNums.append(val)
break

Python - Input Validation

I'm looking to create code which requires an integer greater than 2 to be input by a user before continuing. I'm using python 3.3. Here's what I have so far:
def is_integer(x):
try:
int(x)
return False
except ValueError:
print('Please enter an integer above 2')
return True
maximum_number_input = input("Maximum Number: ")
while is_integer(maximum_number_input):
maximum_number_input = input("Maximum Number: ")
print('You have successfully entered a valid number')
What I'm not sure about is how best to put in the condition that the integer must be greater than 2. I've only just started learning python but want to get into good habits.
This should do the job:
def valid_user_input(x):
try:
return int(x) > 2
except ValueError:
return False
maximum_number_input = input("Maximum Number: ")
while valid_user_input(maximum_number_input):
maximum_number_input = input("Maximum Number: ")
print("You have successfully entered a valid number")
Or even shorter:
def valid_user_input():
try:
return int(input("Maximum Number: ")) > 2
except ValueError:
return False
while valid_user_input():
print('You have successfully entered a valid number')
My take:
from itertools import dropwhile
from numbers import Integral
from functools import partial
from ast import literal_eval
def value_if_type(obj, of_type=(Integral,)):
try:
value = literal_eval(obj)
if isinstance(value, of_type):
return value
except ValueError:
return None
inputs = map(partial(value_if_type), iter(lambda: input('Input int > 2'), object()))
gt2 = next(dropwhile(lambda L: L <= 2, inputs))
def take_user_in():
try:
return int(raw_input("Enter a value greater than 2 -> ")) # Taking user input and converting to string
except ValueError as e: # Catching the exception, that possibly, a inconvertible string could be given
print "Please enter a number as" + str(e) + " as a number"
return None
if __name__ == '__main__': # Somethign akin to having a main function in Python
# Structure like a do-whole loop
# func()
# while()
# func()
var = take_user_in() # Taking user data
while not isinstance(var, int) or var < 2: # Making sure that data is an int and more than 2
var = take_user_in() # Taking user input again for invalid input
print "Thank you" # Success
def check_value(some_value):
try:
y = int(some_value)
except ValueError:
return False
return y > 2
Hope this helps
import str
def validate(s):
return str.isdigit(s) and int(s) > 2
str.isdidig() will eliminate all strings containing non-integers, floats ('.') and negatives ('-') (which are less than 2)
int(user_input) confirms that it's an integer greater than 2
returns True if both are True
This verifies that the input is an integer, but does reject values that look like integers (like 3.0):
def is_valid(x):
return isinstance(x,int) and x > 2
x = 0
while not is_valid(x):
# In Python 2.x, use raw_input() instead of input()
x = input("Please enter an integer greater than 2: ")
try:
x = int(x)
except ValueError:
continue
The problem with using the int() built-in shown in other answers is that it will convert float and booleans to integers, so it's not really a check that your argument was an integer.
It's tempting to use the built-in isinstance(value, int) method on its own, but unfortunately, it will return True if passed a boolean. So here's my short and sweet Python 3.7 solution if you want strict type checking:
def is_integer(value):
if isinstance(value, bool):
return False
else:
return isinstance(value, int)
Results:
is_integer(True) --> False
is_integer(False) --> False
is_integer(0.0) --> False
is_integer(0) --> True
is_integer((12)) --> True
is_integer((12,)) --> False
is_integer([0]) --> False
etc...

Syntax error in python, need help for a project

I'm trying to find a way to fix this syntax error. I can't seem to find it to make the program run correctly.
This is my code below
wrong = 0
test = raw_input("Please enter a 4 digit integer:")
def start(test):
if test.isdigit():
if wrong(test)==True:
print 'Invalid input. Four integers must be entered.'
else:
numbers = []
for a in test:
digits.append(a)
a=calc(int(digits[0]))
b=calc(int(digits[1]))
c=calc(int(digits[2]))
d=calc(int(digits[3]))
code = str(c)+str(d)+str(a)+str(b)
print 'The encrypted integer is:',code
else:
print 'You input wrong. Use numbers only.'
def calc(num):
num+=7
num%=10
return num
def error(test):
if len(test)<4 or len(test)>4:
return True
else:
return False
start(test)
AND the fixed is ...
digits = 0
wrong = 0
test = raw_input("Please enter a 4 digit integer:")
def start(test):
if test.isdigit():
if wrong(test)==True:
print 'Invalid input. Four integers must be entered.'
else:
numbers = []
for a in test:
digits.append(a)
a=calc(int(digits[0]))
b=calc(int(digits[1]))
c=calc(int(digits[2]))
d=calc(int(digits[3]))
code = str(c)+str(d)+str(a)+str(b)
print 'The encrypted integer is:',code
else:
print 'You input wrong. Use numbers only.'
def calc(num):
num+=7
num%=10
return num
def wrong(test):
if len(test)<4 or len(test)>4:
return True
else:
return False
start(test)
You've called a function named wrong() but defined a function named error(). Is that the problem you're seeing?
Don't you mean if error(test)? 'wrong' is not a function.

Categories

Resources