Please see the code below -
def add(a, b):
print "ADDING %d + %d" % (a, b)
return a + b
print "Let's do some math with just functions!"
age = add(float(raw_input("Add this:")), float(raw_input("To this:")))
Is there anyway, I can shorten the last line? Or, is there another way of getting user input?
Thanks
Applying "don't repeat yourself", we can take the repeated code and make a function out of it:
def add(a, b):
print "ADDING %d + %d" % (a, b)
return a + b
print "Let's do some math with just functions!"
def getf(prompt_mesg):
s = raw_input(prompt_mesg)
return float(s)
age = add(getf("Add this:"), getf("To this:"))
And then if you want you can make the input function handle errors better. Instead of raising an exception that takes down the whole program, you can handle errors gracefully:
def getf(prompt_mesg):
while True:
try:
s = raw_input(prompt_mesg)
return float(s)
except ValueError:
print("Could not convert that input. Please enter a number.")
This will loop forever until the user enters a valid input (or terminates the program).
I see you're using p2.x. First thing - I'd recommend switching to p3.x (it has many enhancements, but in this case you'll be happy to see that raw_input() became input() and input () with evaluation is gone).
Other way to shorten this stuff is using input() instead of raw_input(). If user gives you anything that is not a number, you'll get some sort of exception at addition, if he gives you a number (float, int, whatever) - your program will work.
==EDIT==
As glglgl pointed out - second part is dangerous and warning here is appriopriate. Using input() is basically the same as eval(raw_input()). Unfortunately, I forgot about the fact, that it doesnt take locals and globals parameters like eval - if it would, you could make it safe. For real-life applications it shouldnt be used, because some rogue user could evaluate anything he wants, causing program (or even computer) to crash. For simple apps like that, I stand my ground, and keep saying that it is useful.
Related
The question I want to solve is to input two numbers and output the sum until the user finishes.(until the user inputs ctrl+d) Of course, I can solve the problem using sys.stdin, but I want to solve it using while.
The two codes below are my codes, the first one works well, but the second one doesn't work well. I don't know the difference between two codes. If anybody knows about the reason, please explain why..
from sys import stdin
# in this code, when I input ctrl d, program is finished
try:
while True:
a,b = map(int, stdin.readline().split())
print(a+b)
except:
exit()
from sys import stdin
# in this code, when I input ctrl d, 0 is printed out
try:
while 1:
print(sum(map(int, stdin.readline().split())))
except:
exit()
readline() doesn’t fail at EOF; it just returns an empty string. Splitting an empty string is fine. mapping int across an empty list is fine. Summing an empty iterable is fine (and results in zero).
In the first version, it’s the a, b unpacking that fails, but there’s no way to tell the difference when you throw away all the exception information and catch an overly broad class of exceptions at the same time.
Never use except; use except Exception to avoid catching low-level flow control exceptions. And if you feel the need to catch an exception you will otherwise ignore, consider logging the fact that you caught it for debugging purposes.
If you want to use sys.stdin, a for loop is better (line will continue to end with \n):
for line in stdin:
print(sum(map(int, line.split())))
If you want to use a while loop, input is better:
while True:
try:
line = input()
except EOFError:
break
print(sum(map(int, line.split())))
I am doing a python course where they suggested a try and except block in a while loop in order to keep asking for input until the condition is satisfied. Intuitively I feel it is shorter to just call the function again in the "except" block like this:
def exceptiontest():
try:
print(int(input("number 1: "))+int(input("number 2:")))
except:
print("a mistake happened")
exceptiontest()
exceptiontest()
When asking on the forum on the course I got the reply that it is not the same. I am a bit confused now. Anyone that can clarify for me? Thanks in advance!
Calling the function in the except will eventually raise a RecursionError: maximum recursion depth exceeded error if you keep entering bad inputs. Generally must humans won't be entering that many bad data to hit the error before they give up, but you are unnecessarily putting function calls on a stack.
A while loop is better since it's one function call, waiting for a valid input. IT doesn't waste any more resources than it needs.
while loop, for two reasons
it's clearer to read: while not success, try again
recursion is not free. It leaves the previous function stack open. it could run out of memory (probably won't, in this case, but in principle, avoid it)
Another reason to use the while loop which has not yet been mentioned is that you could leverage the assignment expressions coming with Python 3.8.
The function add encapsulates getting two numbers and trying to add them.
def add():
'try to add two numbers from user input, return None on failure'
x = input('number 1: ')
y = input('number 2: ')
try:
return float(x) + float(y)
except TypeError, ValueError:
return None
The following while loop runs as long as there is no result.
while (result := add()) is None:
print('you made a mistake, make sure to input two numbers!')
# use result
I'm still kind of learning Python, but my friend who has programmed in Python before says this should work fine, but it wont?
All code before this was the beginning story for this basic "escape the room" game I'm making. The code up until here works, (basic print functions describing the game).
I give the player the scenario that they're in a room and they can do one of two things:
def intro_room_input():
intro_action = input("What would you like to do? (Please enter either: 1 or 2) ")
return intro_action;
These two functions are for when they choose 1 or 2, the next if/elif function runs these functions
If they choose 1:
def intro_room_result1():
print(
"""
(Story stuff for the result of option 1. Not important to the code)
""")
return;
This function will play out if they choose 2
def intro_room_result2():
print(
"""
(Story stuff for the result of option 2. Not important to the code)
""")
return;
This will be the function for taking the player's input and continuing the story from there.
def intro_action_if(string):
if string == "1":
intro_room_result1()
elif string == "2":
intro_room_result2()
else:
print("I'm sorry, that wasn't one of the options that was available..."+'\n'+
"For this action, the options must be either '1' or '2'"+'\n'+
"Let me ask again...")
intro_room_input()
intro_action_if(string)
return;
that last intro_room_input runs fine, it re-runs the previous input, but when you actually enter 1 or 2, it doesn't do anything with them. It doesn't want to re-run the if/elif/else function to give the results.
finally I have a main that runs everything:
def main():
string = intro_room_input()
intro_action_if(string)
return;
main()
Please help, I have no idea what's wrong with this code!?
The problem is in your intro_action_if(). When you are calling the function to get values again, you forgot to change the string value.
ie,
#intro_room_input() #wrong
string = intro_room_input() #right
intro_action_if(string)
As you can see, even though in your code you asked for the user input and returned it, you forgot to reassign string with the returned value. Hence it kept the same input you had given previously and passed that old value to intro_action_if().
I am new to python,trying to write program for finding amstrong and modulus . But I have problem in finding amstrong no,it will not go to end state,hang in the middle. However,modulus is working fine. It will not throw any error. Here is my code:
try:
def check(s):
if(s==1):
print 'enter the no'
v=[]
s=int(raw_input())
print s
for x in str(s):
print x
v.append(x)
print v
x=len(v)
i=0
y1=0
print v[0]
while(i<x):
y=int(v[i])
y=y**3
y1=y1+y
print y1
if(y1==s):
print "given no",s,"is amstrong no"
else:
print "given no",s,"is not a amstrong no"
elif(s==2):
print 'enter the 1st no'
s=int(raw_input())
print 'enter the 2nd no'
s1=int(raw_input())
ans=s%s1
print 'modulus ans is',ans
finally:
print "bye bye"
try:
print "1.amstrong 2.modulus"
x=int(raw_input())
if(x>=1 and x<=2):
check(x)
finally:
print 'bye bye'
Please help me on this.
The reason it's hanging in the middle is that you enter into the while loop while(i<x):, but you never change the value of either i or x. (You do change y and y1, but your conditional doesn't involve either.) The condition never ends up being false, and can't ever end up being false, so it continues to execute forever.
Note also that you're not really using try blocks correctly. There's no point in using try unless you're using except to handle any exceptions. (On a different level, you shouldn't be wrapping the entirety of your code in a try block in the first place - exceptions are useful information that make it easier to discover ways your program isn't working correctly, and ignoring them can lead to unpredictable, difficult-to-debug states.)
Last piece of advice - recognizing and fixing your problems is almost universally made easier (for both of us) by using distinct, pertinent names to your variables - it's very difficult to figure out what you're doing when every single variable is a single letter, and some are just a letter you've already used with a number appended.
You can check if a number is a 3-digit ammstrong using the function coded below.
This however is restricted to only 3 digits, but using loops correctly this will work of a greater number of digits as well. Almost in the way you have done. But always remember to increment or decrement the loop counter to prevent infinite loop. Otherwise the loop "will not go to end state,hang in the middle".
def Ammstrong(s):
n1=s/100
#n1 contains the 1st digit of number, s.
n2=s%100
n2=n2/10
#n2 contains the 2nd digit of number, s.
n3=s%10
#n3 contains the 3rd digit of number, s.
number=(n1**3)+(n2**3)+(n3**3)
if number==s:
print number,"is an Ammstron Number"
#return number
else:
print number,"is not an Ammstron Number"
#return number
num=input(Enter a number: ")
Ammstrong(num)
#use this if return is uesd:
#number=Ammstrong(num)
This function will print the answer. So, there wont be any need to use the print function in the main function to print your answer.
If you wish to perform further calculations, use 'return'. This is illustrated in the coded using comments. But, as soon as the return execution is executed, the program in which the statement is executed, terminates. Meaning the function will terminate not the main program. So, use the return function after the print function.
If you do use the return function u'll have to store the returned value in a variable.
One thing more:
You have made use of the variable x before initiating it.
And, instead of using (s==2) statement use (s!=0). "!=" is the symbol for "not equal"
Best of luck with learning python. It is a very interesting language.
http://pythontutor.com will show you the execution of the code step by step.
Basically, I want my throw raw input variable to be skipped so that it can still be accessed and referred to later on, but doesn't need a user input to continue, so what happens is if you type "throw brick" within 5 seconds, it will bring you to the outcome print "good job!"
throw = raw_input()
throw_command = ["throw brick"]
import time
me.sleep(5)
if throw in throw_command:
print "good job!"
if throw not in throw_command:
print "GAME OVER"
restart
I know such thing as a goto or jump don't exist in such a structure-based code. So, if anyone could happen to provide an alternative, your assistance would be much appreciated.
I'm not sure I understand what you're trying to do, but it sounds to me like this:
Ask the user for input, but timeout after 5 seconds (your time.sleep(5))
Repeat over and over again (your restart)
If so, it looks like this would be one way to do it: Keyboard input with timeout in Python
I modified the select-based answer with the details of your code:
import sys
import select
throw_command = ["throw brick"]
while True:
print "\nEnter command:"
i, o, e = select.select( [sys.stdin], [], [], 5 ) # times out after 5 seconds
if i: # If input was provided
throw = sys.stdin.readline().strip()
if throw in throw_command:
print "good job!"
break
else:
print "GAME OVER"
else:
print "You didn't enter anything!"
The use of select is a little advanced (ideally, raw_input should have an optional timeout argument) but it's easier than using threads which is the only way I could think of doing this with raw_input.
The use of a while loop instead of your restart attempt at a go-to should be self-explanatory.