Is it possible to define input times, like time, date, currency or that should be verified manually? Like for example:
morning = input('Enter morning Time:')
evening = input('Enter evening Time:')
.. I need (only) time here, how do I make sure that user enters input in xx:xx format where xx are integers only.
input (in Python 2.any) will return the type of whatever expression the user types in. Better (in Python 2.any) is to use raw_input, which returns a string, and do the conversion yourself, catching the TypeError if the conversion fails.
Python 3.any's input works like 2.any's raw_input, i.e., it returns a string.
You can't really force the input function to return a certain type. It's best you write some kind of a wrapper that reads some input from the user and then converts it to an appropriate type for your application (or throw an exception in case of an error).
Also, as Alex said, it's better to use raw_input for user input since it will always return the entered value as a string. Much more manageable.
Related
I am trying to check if my input is a string with try-except block. The function runs without an error. However it checks if the input is an integer, not string. How can I inverse this?
def lexicon(word):
while True:
try:
a=str(input(word))
print("Input is a string. string = ", a)
except ValueError:
print("Oops..Input is not supposed to be a number. Try again!")
return a
b=lexicon("Enter the word you'd like: ")
As discussed with user pavel in the comments to his answer, there are two different styles to code for a problem like this: EAFP ("Easier to Ask for Forgiveness than Permission"), meaning that you make your code work on an assumption and take action if it fails; and LBYL ("Look Before You Leap"), in which you first check whether your assumption is true, and then choose the appropriate action to take.
The try/except route is EAFP, since it just executes the code in the try block without bothering to first check whether it would work. If you want to do it in LYBL style, you would explicitly need to ascertain whether the user input is a string representation of a numeric value, and then act accordingly. I'll provide skeletal code for both approaches below. However, note that Python is a little weird compared to other languages in that it seems to have a certain cultural favour for EAFP.
Also, since you are only asking about checking for integers, I will focus on that here. This means that the code will accept floats as valid inputs.
EAFP: try/except
The problem that presumably trips you up is that input always returns a string, so testing if it is a string is nonsensical and will always yield True. However, note that try/except is only an abrigded version of error handling that you can do in Python; the full version is try/except/else/finally. The else block takes effect if no except blocks are executed, and finally is always run at the end. So you could check whether your input is an integer, and make the program raise a failure if that check succeeds. I admit however that this does seem a bit backwards.
try:
a = int(input())
except ValueError:
# do whatever
else:
raise ValueError("Input must not be an integer")
LBYL: if/else
str objects have several methods to test their contents without having to run into errors. For example, .isalpha() checks if all characters are in the alphabet (which returns False however if you include spaces and special characters); isnumeric() checks whether the string is a representation of a number; etc. See a full list here. So depending on what kind of inputs you want to allow, you would need to use one of these methods, or a combination of them, in an if block. The code below essentially does the same thing as the try/except/else version above, using .isdigit() which returns True if all characters in the string are digits (i.e., the same kind of input for which int(a) would succeed).
Note also that I am making use of the new assignment operator := in this code, which is new to Python 3.8. This way, you don't need to explicitly assign the variable a first, however it's a bit harder to catch where the code actually executes an input() function. If you code for backwards compatibility, or don't like the look of this, you'd have to go with the classical a = input() first.
if (a := input()).isdigit():
raise ValueError("Input must not be an integer")
# do whatever
If you want specifically to check the value type of the string, you're better off using if/else and isinstance:
if not isinstance(word, str):
raise TypeError(f"Expecting a string as a value, not {type(word)}.")
else:
#do something
Ive heard that using "input" was unsafe for password use because it interprets the input as code, and thus someone could bypass the security.
How would you go around doing that? For example, how would you do it to something like this?
password = 1234
pass_true = input("What is the password?")
if password == pass_true:
print("Access granted.")
else:
print ("Access denied.")
It's simple: To get past your check, just type password at the prompt :-) Try it!
What is the password?password
Access granted.
Explanation: input reads what you type, evaluates it as python code, and assigns the result to pass_true. So in the above, I just told it to assign the value of the variable password (which holds the real password) to pass_true.
But this code is broken even for regular use: If you type anything that doesn't look like a valid python expression, it'll trigger an error. Your example uses numbers as "passwords", but you couldn't use the same approach for arbitrary-text passwords: It wouldn't work at all, even with the correct password.
Another kind of problem is typing something damaging like os.remove(".profile") (or something worse and more elaborate) at the prompt. It won't log them in but you can see the damage it can do. Evaluating user input is just wrong, unless you're writing an interactive python interpreter.
Python 2 has raw_input() which just reads input. (In python 3, raw_input() has been renamed to input() and the old input() is gone).
So I was just reading this and if you're using Python 3.x, you'll be fine.
Otherwise, if you use input(), then you could just type password and be done.
Again, if you're using Python 3.x, don't worry.
The idea is not to keep passwords at all. You have to create hash out of input and check whether it's equal to your password's hash. But if you're just a beginner it's okay to do what you do.
The side-channel attack sboutzen mentioned is a real threat, and can be exploited using time(), from linux command-line
This article explains it in more detail
https://blog.sqreen.com/developer-security-best-practices-protecting-against-timing-attacks/
The hash could be compromised by identifying the hash used byte by byte. You would have the hash of the real password instead of the password itself, but that is why dictionary attacks are useful.
Another problem you will have with that approach is that when you compare two strings like that, you leak information and set yourself up for a side-channel attack.
The string comparison will compare the two strings one byte at a time, and if one of the bytes don't match, it returns. However, this means that an attacker knows exactly which part, of the password he is testing, is correct, and which part is not. Therefore he can reduce the entropy of a given password to 2 to the power of the length of the set of characters allowed.
When comparing passwords you should compare the two strings bytewise like so:
result = 0;
for (int i = 0; i < storedUserPass.length; i++) {
result |= storedUserPass[i] ^ incomingPasswordBytes[i];
}
When it is done, if result is equal to 0, all the bytes match, if not, they dont. This is a constant time calculation, which doesn't leak any information
I need to enter a complex string for handling (UTC time code) and breaking down as part of an assignment. I have started the function like this as required:
def convertWmiDateTime(wmiDateTime):
But when I enter this:
convertWmiDateTime(20061122185433.000000+600)
The variable wmiDateTime stores 2.0061122186e+13
If I use raw_input the value 20061122185433.000000+600 will be stored correctly in wmiDateTime, but not when its called as intended above.
Is there a way to preserve what was typed into the input? A way to stop Pythong calculating and simplifying the number? vb. net would be something like (wmiDateTime As String) is there anything like that for Python?
Thanks for looking.
Your function requires a string as its input parameter. You can't call it with a number (as you're doing).
raw_input() returns a string, so the equivalent would be to call
convertWmiDateTime("20061122185433.000000+600")
Your version treats the time code as a floating point number which a) doesn't have the required precision to preserve all the digits and b) will get the timezone info (+600) added, which leads to wrong results as well.
I want to wrap the colour input in quotes within python:
def main():
colour = input("please enter a colour")
So if I enter red into the input box it automatically makes it "red"
I'm not sure how to do this, would it be something along the lines of:
def main():
colour = """ + input("please enter a colour") + """
Kind regards
The issue is that this doesn't pass syntactically, as Python thinks the second " is the end of the string (the syntax highlighting in your post shows how it's being interpreted). The nicest to read solution is to use single quotes for the string: '"'.
Alternatively, you can escape characters (if you wish to, for example, use both types of quote in a string) with a backslash: "\""
A nice way of doing this kind of insertion of a value, rather than many concatenations of strings, is to use str.format:
colour = '"{}"'.format(input("please enter a colour"))
This can do a lot of things, but here, we are simply using it to insert the value we pass in where we put {}. (Note that pre-2.7, you will need to give the number of the argument to insert e.g: {0} in this case. Past that version, if you don't give one, Python will just use the next value).
Do note that in Python 2.x, you will want raw_input() rather than input() as in 2.x, the latter evaluates the input as Python, which could lead to bad things. In 3.x, the behaviour was fixed so that input() behaves as raw_input() did in 2.x.
I currently teach first year university students python, and I was surprised to learn that the seemingly innocuous input function, that some of my students had decided to use (and were confused by the odd behaviour), was hiding a call to eval behind it.
So my question is, why does the input function call eval, and what would this ever be useful for that it wouldn't be safer to do with raw_input? I understand that this has been changed in Python 3, but it seems like an unusual design decision in the first place.
Python 2.x input function documentation
Is it ever useful to use Python 2's input over raw_input?
No.
input() evaluates the code the user gives it. It puts the full power of Python in the hands of the user. With generator expressions/list comprehensions, __import__, and the if/else operators, literally anything Python can do can be achieved with a single expression. Malicious users can use input() to remove files (__import__('os').remove('precious_file')), monkeypatch the rest of the program (setattr(__import__('__main__'), 'function', lambda:42)), ... anything.
A normal user won't need to use all the advanced functionality. If you don't need expressions, use ast.literal_eval(raw_input()) – the literal_eval function is safe.
If you're writing for advanced users, give them a better way to input code. Plugins, user modules, etc. – something with the full Python syntax, not just the functionality.
If you're absolutely sure you know what you're doing, say eval(raw_input()). The eval screams "I'm dangerous!" to the trained eye. But, odds are you won't ever need this.
input() was one of the old design mistakes that Python 3 is solving.
Python Input function returns an object that's the result
of evaluating the expression.
raw_input function returns a string
name = "Arthur"
age = 45
first = raw_input("Please enter your age ")
second = input("Please enter your age again ")
# first will always contain a string
# second could contain any object and you can even
# type in a calculation and use "name" and "age" as
# you enter it at run time ...
print "You said you are",first
print "Then you said you are",second
examples of that running:
Example: 1
Prompt$ python yraw
Please enter your age 45
Please enter your age again 45
You said you are 45 Then you said you are 45
Example: 2
Prompt$ python yraw
Please enter your age 45 + 7
Please enter your age again 45 + 7
You said you are 45 + 7 Then you said you are 52
Prompt$
Q. why does the input function call eval?
A. Consider the scenario where user inputs an expression '45 + 7' in input, input will give correct result as compared to raw_input in python 2.x
input is pretty much only useful as a building block for an interactive python shell. You're certainly right that it's surprising it works the way it does, and is rather too purpose-specific to be a builtin - which I presume is why it got removed from Python 3.
raw_input is better, It always returns the input of the user without changes.
Conversely The input() function will try to convert things you enter as if they were Python code, and it has security problems so you should avoid it.
In real program don't use input(), Parse your input with something that handles the specific input format you're expecting, not by evaluating the input as Python code.