PhoneValue=0
if (condition== "new"):
PhoneValue=int(PhoneValue+10)
else:
PhoneValue=int(PhoneValue+9)
if GPS==bool(input("true")):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
if WiFi==eval(bool(input("true"))):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
if camera==eval(bool(input("true"))):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
global PhoneValue
This is my code. I am supposed to be able to input the condition, GPS, camera, and WiFi and the code evaluates the input and gives points for each condition. If the phone is new it gets ten points and if used it gets nine. For GPS, Camera, and WiFi it wants me to use boolean to either give it a point for true or no points for false. I am wondering how do I convert the input string into boolean in order to add it to phone value?
There's a lot wrong in this code. Firstly, the input() command is defined
input([prompt])
If the prompt argument is present, it is written to standard output without a trailing newline.
which means your call to input("true") prints "true" on the console and waits for a line of input. That's not what you were hoping for.
Your use of eval is bad. Almost every use of eval on user input is a problem. But you saved yourself here by accident: eval(bool(text)) is superfluous. The only thing that bool() can return True or False neither of which is dangerous to eval, but since you already had a boolean in hand, eval'ing it didn't do anything.
Converting the result of integer addition to an int() is useless, and your if / else clauses can be more clearly written as:
if input("Is there a GPS? "):
PhoneValue += 1
with no else clause needed. Unfortunately, this has almost no chance of getting correct input. If I type "True" the if block will trigger. It will also trigger if I write "no", "false", or "JosEduSol", those will be evaluated as True also. The declaration at the end
global PhoneValue
does absolutely nothing as the last line. In fact, you should probably just forget that global exists because most everybody uses it incorrectly.
There are more faults in the code, and you should really get assistance from a teacher or get a better learning resource.
Related
For context, I am new to Python, and somewhat new to programming in general. In CS50's "Little Professor" problem (details here, but not needed: https://cs50.harvard.edu/python/2022/psets/4/professor/) my program passes all correctness checks; but, unfortunately, programs aren't checked for efficiency, style or "cleanliness", making those details harder to learn... Therefore, using the function below as an example, I am trying to grasp how to think about choosing an implementation when there are multiple options.
In the code below, I have a function that prompts the user to input an int(). If the user inputs 1, 2 or 3, return that value. Otherwise, if the user does not input 1, 2 or 3, or the input is not even an int(), re-prompt the user.
The first includes the conditional within the try block, and breaks if the condition is met, returning the value once out of the loop.
def get_level():
while True:
try:
level = int(input("Level: "))
if 0 < level <= 3:
break
except ValueError:
pass
return level
In the second, once the input has met the int() condition, if the value is 1, 2 or 3, it breaks out of the loop by returning the value of level, similarly re-prompting if not. (Note: I noticed the below also works without the "else:" statement, which is a little confusing to me as well, why isn't it needed?)
def get_level():
while True:
try:
level = int(input("Level: "))
except ValueError:
pass
else:
if 0 < level <= 3:
return level
Is one of these examples better to use than the other, and if so, why? Any help is greatly appreciated, but if there is not a specific answer here, thoughts on the overall concept would be incredibly helpful as well!
Generally, you should put as little code as possible inside a try, so that you don't misconstrue an unrelated error as the one you're expecting. It also makes sense to separate the code that obtains the level from the code that acts on it, so that level has known validity for as much code as possible. Both of these points favor the second approach (the second moreso in a larger example), although in this case you could also write it as
def get_level():
while True:
try:
level = int(input("Level: "))
except ValueError:
continue
if 0 < level <= 3:
return level
which avoids the else indentation. (You do need that else as given, since otherwise if the first input attempt doesn't parse you'll read level before assigning to it.)
Meanwhile, the question of break vs. return is really just one of style or conceptualization: do you see the value being in the desired range as meaning "we should stop asking" (break) or "we have the answer" (return)?
I'm trying to create a function in Python that, using recursion, saves a certain number if it is greater than or equal to another previously provided in input (and saved on another variable).
a = 6
def attempts(k):
n = int(input("How many attempts do you want to make? "))
if n>=k:
return n
else:
print("You must make at least {} attempts to play!".format(k))
attempts(k)
b = attempts(a)
The problem is that, if I don't immediately insert the "correct" number, the variable "b" becomes a NoneType. How can I solve this problem?
Sorry for any typos, I'm not a native speaker.
Change your last line of the function to:
return attempts(k)
Currently, results starting from the first recursive call (if it occurs) are thrown away, which results in None being returned by the outermost call.
In the else statement, you are not returning anything, setting b equal to nothing. Add a return statement in the else statement and return whatever you want b to equal to if the else statement comes up.
The way your code works right now, you should add return attempts(k) in your else statement and remove the current last line, attempts(k) This will work the same, except b will have a value.
In the else case you evaluate attempts(k) but don't return it. So it's evaluated as a None. Change
attempts(k)
To
return attempts(k)
Let me preface this by saying I am a total newbie to Python programming. Sorry to bother anyone with a possibly trivial question. But I am creating a program that calculates the user's BMI and displays their info along with their calculated BMI. I must create a function for the following:
1. BMI calculation
2. Retrieve user's weight
3. Retrieve user's height
4. Display user's weight, height, and calculated BMI
Here is my code:
BMI Calculator Code
These are my results:
Code Results
I'm supposed to show the calculated results too, but I'm doing one step at a time, making sure I can at least print the inputs first which is not happening. I'm so confused and don't know what to do to fix it. Any feedback is appreciated. Thanks.
use return
your input in function do not return any value to w, h, name in main code.
so, function need to be
def get_weight():
return int(input('message'))
return pass value to caller, now w can get value returned by get_weight function
w = get_weight()
Problem & Solution
You are getting the user input correctly, but you need to actually return the user input from the function for the value to accessible outside of the function. Currently in your code you are simply getting your user input, converting it to an integer, and immediately throwing away the values by letting them be garbage collected.
To return the value from the functions, use the return keyword:
def get_weight():
return int(input(...))
def get_height():
return int(input(...))
Improvements
Along with the solution above, there are some general improvements you can make to your code:
Follow PEP8. Put spaces between parameter, a newline at the end of the source file.
Use newline characters, rather than extra calls to print, for whitespace around displayed text. For example, use:
print('\nBMI calculator\n')
Rather than:
print()
print('BMI calculator')
print()
Here is my code that solves a quadratic equation given user inputs a, b, c. However, I want to check for incorrect user inputs. If a user inputs anything but a float, the user is confronted with print "Not a valid input. Try again.\n" followed by a loop of the function quadratic2(). However, this program is part of a larger program, so I want the user to have the option of typing in "next" to terminate this function and move on. My issue is that I am calling for 3 user inputs, but I want the "next" input to be the first input, a. This works perfectly well until the user types in a random string, causing a ValueError. Once this happens, my code does not want to loop back to check for if the input is next. Please help me! I think something about the way this code is nested is messing me up.
def retest3():
print "Type in another a, b, and c. Or type \"Next\" to move on."
def quadratic1():
print ("This program calculates the zeroes of a quadratic equation."
"\nPlease enter a, b, and c, hitting \"Enter\" after each one: ")
def quadratic2():
while 1 == 1:
a = (raw_input())
if "next" == a.lower():
ontonextthing()
return 1 == 0
else:
try:
a = float(a)
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
c = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
if b**2-4*a*c>0:
root1=(-b+math.sqrt(b**2-4*a*c))/(2*a)
root2=(-b-math.sqrt(b**2-4*a*c))/(2*a)
print ("First Root: {0}\nSecond Root: {1}".format(root1,root2))
else:
print ("The discriminant is negative, so your"
" roots will contain \"i\".")
disc1=(b**2-4*a*c)
disc2=-disc1
sqrtdisc2=(math.sqrt(disc2))/(2*a)
b2=(-b)/(2*a)
print ("{0} + {1}i".format(b2, sqrtdisc2))
print ("{0} - {1}i\n".format(b2, sqrtdisc2))
retest3()
quadratic1()
quadratic2()
This works perfectly well until the user types in a random string, causing a ValueError. Once this happens, my code does not want to loop back to check for if the input is next.
Seems like you want the continue statement:
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
continue
The continue statement takes you back to the beginning of your while loop (the next iteration). Currently you are calling quadratic2() which makes your function recursive, and not what you want.
Because it's recursive, when you receive your Exception it exits the current function, but because you were using recursion, you simply return back to the previous function you were in the middle of (which is the same function). Therefore the next input you type could be parsed by
b = float(raw_input())
instead of
a = (raw_input())
The "real" solution for your problem is not to use deeply nested constructs in the first place. Deeply nested statements make your code hard to read, hard to test, hard to maintain and hard to reuse. Also, you will tend to duplicate code, which is bad. Especially in Python, deep nesting will cause you to count spaces to get the indentation right, which is really a pain in the neck.
Break your code into functions, and follow the "single responsibility principle" by letting one function do exactly one thing. This has several advantages:
You don't have to keep too many things in your mind. Focus on one small problem, and be done with it.
You can always return early in a function, so you can avoid nesting in many cases.
You can reuse the code in your function.
You don't have duplicate code: If you want to change a particular behavior, change one function instead of several places in one function.
You can test your functions in isolation, making sure that they do the right thing.
In your case, the quadratic2 function does a lot of things:
It runs a "main loop"
It reads user input for commands
It dispatches the command
It reads user input for values
It handles invalid user input
It does computations
It displays the result back to the user
Now I don't say that you need one function for every detail listed above, but it is rather obvious that this function does too much.
Examples on how you could break it up:
Make one function for the main loop and for dispatching commands. Let the commands (such as "next") be handled in separate functions.
Write one function to read in a float from the user, and call this three times instead of repeating the try...except code three times. This has the added benefit that you can enhance this function to run in a loop, so that the user is asked to repeat the input for one value, instead of having to start all over again as your current solution does.
Other tips:
Don't use else after return, raise, break, or continue. It is not necessary, since the next statement will not be reached anyway, and you can save one nesting level.
Don't use confusing expressions like 1==1 or 1==0. This is just a complicated way of writing True and False. In your example, it should read while True and return False instead.
I know this is a data object but I'm new to python and I don't understand what user_output is doing. Trying to understand all this.
def user_output(self,check): #data object
output = ""
#loop of all the info for __user_arr
for user in self.__user_arr:
if user.user_bot == str(check):
output += '''
<div class='about'>
<h1>{user.user_name}</h1>
<h2>My favorite band is: {user.user_band} </h2>
<div class='business'>
<p>Why I want the tickets:<br /> {user.user_business}</p>
</div>
</div>
'''
return output.format(**locals())
else: #this will spit an error if the user do not answer the last question correctly.
output = '''<div class='error'><h2>Turns out you are a robot. No tickets for you </h2></div>'''
return output
It will generate for each user a div block with some favorite bands etc. , provided that, the user flag user_bot is equal to check (as far as I can understand a kind of bot check). If the user is a bot (does not pass the check) the program will generate the Turns out you are a robot.. block.
This looks like a function, not an object. It checks whether your user is a robot. It does so by checking if your user (for every user) has their user_bot as the string you get as input, probably a string identifying robots. Then you write something I know nothing about to the output string, probably selling the ticket.
This function seems to do this only for the first user, though because it returns in the first if else clause.
user_output() seems to be a method in some class. It is using a "poor man's" tempting facility to output an HTML fragment.
It appears to use a loop, for user in self.__user_arr:, but this is a bit of a sham. It uses this construct to pick the first item out of self.__user_arr. Because it soon returns from the function under all conditions, it will never return to the head of the loop to check subsequent users (if any).
Also note that the double-understore prefix to self.__user_arr marks it as a private part of the implementation of the object. A deeply private part. A single underscore usually indicates "private." Double underscores don't have a super-precise definition, but "very private" or "very implementation dependent" would be my guess.
If the user_bot property of that first user is a string equal to the check value (as stringified), then the template is instantiated. It does this first by setting a string variable (output) which has embedded in tt the variable markers ({a_variable}) compatible with str's format method. Calling output.format(**locals()) does the string formatting operation using locals() (which is a lookup dictionary of all current variable assignments, a.k.a. a symbol table). The **locals() construction means "use this dict (or dict-like) object as though it were a set of keyword arguments." The effect is that substrings in output like {user.user_band} are directly interpolated into the output string. Then the filled-in string is returned.
If, instead, the user.user_bot == str(check) test fails, a simple error string is returned.
In either case, a string is returned, and the method exits.
The only other case worth considering is what if there are no users in the self.__user_arr collection? Then the loop would never run, and the method would return None implicitly.