Why does the str.isdigit always output the opposite result - python

def is_valid_zip(zip_code):
"""Returns whether the input string is a valid (5 digit) zip code
"""
if (len(zip_code) == 5) and (str.isnumeric == True):
return True
else :
return False

First of all, it should be str.isnumeric() == True as that's calling the isnumeric function. Second of all you should be really using str.isdigit().
str.isnumeric()
In Python, decimal characters (like: 0, 1, 2..), digits (like: subscript, superscript), and characters having Unicode numeric value property (like: fraction, roman numerals, currency numerators) are all considered numeric characters. Therefore even japanese character for 1, 2 and 3 would pass this check.
str.isdigit()
On the other hand isdigit() will only return True if all characters in a string are digits. If not, it returns False.
source: https://www.programiz.com/python-programming/methods/string/isdigit

A few point to discuss. Regarding your condition:
str.isnumeric == True
That thing on the left side is the function itself, not a call to the function giving a result, the latter would be some_string.isnumeric().
The chances of the function object being equal to true are somewhere between zero and a very, very small number :-)
It's also redundant to compare boolean values against boolean constants since the result of the comparison is just another boolean value. Where do you stop in that case? For example:
(((some_bool_value == True) == True) == True) != False ...
Another point, the code form if cond then return true else return false can be replaced with the much less verbose return cond.
And also keep in mind that isnumeric() allows other things than raw digits, like ¾. If you just want the digits, you're probably better off with another method. You may be tempted to instead use isdigit(), but even that allows other things than just what most would consider "normal" digits, such as allowing "90²10" as a postal code, presumably the much trendier part of Beverly Hills :-).
If you only wanted the raw digits 0-9 (which is probably the case with US postal codes like you seem to be targeting), neither isnumeric() nor isdigit() is really suitable.
An implementation of the function, taking all that into account, could be as follows:
def is_valid_zip(zip_code):
if len(zip_code) != 5:
return False
return all([x in "1234567890" for x in zip_code])

it should be zip_code.isnumeric() not str.isnumeric
Also, why don't you use regex:
import re
RE_ZIP_CODE = re.compile(r'^[0-9]{5}$') # or r'^\d{5}$' for all digit characters
def is_valid_zip(zip_code):
return RE_ZIP_CODE.search(zip_code) is not None

This should work
def is_valid_zip(zip_code):
"""Returns whether the input string is a valid (5 digit) zip code
"""
if len(zip_code) == 5 and zip_code.isnumeric():
return True
else:
return False
print(is_valid_zip("98909"))

Related

I want to distinguish between true digit and a string digit

I want to check a 'x' string whether it is a digit or not in advance.
'1' is naturally a digit.
But and I will use ① what is calld a string number very much.
I don't know the range of string numbers IDE judges as a digit.
'①'.isdigit() returns True.
'⑴'.isdigit() returns True.
'ⅰ' or 'Ⅰ' returns False.
'㈠' returns False. (kanji version of (1) )
'❶' returns True.
I want to do like this.
for s in data:
if s.isdigit():
int_ = int(s)
If I accept '①', int will throw an error. Now, I write try:except for it.
Because I'm a japanese, I often use '①' or '⑴'
How to distinguish isdigit or not isdigit in advance?
Should I rely on try:except or counting all of them in advance?
regular expression?
The main problem is I don't know what is judged as a digit.
data = ["1", "23", "345", "①", "(1)", "(2)"]
This data is dynamic value. It will be changed every time.
Moreover, the string like this may expand in the future.
I hope the string of isdigit() == True is accepted by int().
I don't have an urgent problem because of try: except.
I believe that the str.isdecimal method fits your requirements. It excludes strings like '①', but includes other strings like '١' which are accepted by int.
>>> int('١')
1

Is there a way to check if every character in a string conforms to the set RE conditions?

I've been re-learning python over the last 2 days, and decided to use regular expression [here out referred to as RE] for the first time (in conjunction with tkinter), its exceptionally confusing.
I'm trying to check every character in a string is a number or period, however this has proven difficult for me to wrap my head around.
Here is the code:
def matchFloat(string, search=re.compile(r'[0-9.]').search):
return bool(search(string))
def matchInt(string, search=re.compile(r'[0-9]').search):
return bool(search(string))
def callbackFloat(P):
if matchFloat(P) or P == "":
return True
else:
return False
def callbackInt(P):
if matchInt(P) or P == "":
return True
else:
return False
The first character entered into my enter box [see below] is forced to be a number or . (in the Floats case), however RE search() only requires 1 of the characters to meet the conditions for it to return True.
So in short, Is there a way to only return True if every character in a string conforms to the set RE conditions?
Any help is appreciated, thank you in advanced!
Images:
As you can see, I'm quite new to this.
Disallowed Characters In Box
This thread may be helpful as it covers the topic of tkinter input validation.
However, quick answer to your question:
search(r"^[0-9]+$", string)
would match an integer string. The RE pattern means "one or more digits, extending from the beginning of the string to the end". This can also be shortened to r"^\d+$".
You could also use the re.fullmatch() method:
fullmatch(r"[0-9]+", string)
And for the sake of completeness, I'll point out that you don't need to do this work yourself. You can determine if a string represents an integer with string.isdigit(), string.isdecimal(), or string.isnumeric() methods.
As for checking whether a string is a float, the Pythonic way is to just try converting to a float and catch the exception if it fails:
try:
num = float(string)
except:
print("not a float")

If not... followed by function

I am stuck with this question. I am not too concerned about what each function does, but more importantly how does the IF statement work with functions. From my understanding, the IF.... or statements usually work with a condition, but for this scenario it only involves two functions without any conditions?
def disk_check_usage(disk):
du = shutil.disk_usage(disk)
free = du.free/du.total * 100
return free > 20
def check_cpu_usage():
usage = psutil.cpu_percent(1)
return usage < 75
if not disk_check_usage("/") or not check_cpu_usage():
print("ERROR!")
else:
print("Everything is OK")
I want it to give an 'Error!' message when both conditions (free > 20 and usage < 75) are not True/Satisfied.
Edit: When I run the code, 'free' = 17 which gives 'False' and Usage < 75 which gives 'True'. So my IF statement would mean 'If not False or not True:'. What does that mean and how does the system whether to run 'if' or 'else' statement?
Any help will be appreciated!
They are some operations you can do with booleans.
In particular, (not a) or (not b) is equivalent to not(a and b); at least one of the two have to be False
You just have to inverse your tow statements: if everything is ok, print ok else print error
if disk_check_usage("/") and check_cpu_usage():
print("Everything is OK")
else:
print("Error")
From my understanding, the IF.... or statements usually work with a
condition, but for this scenario it only involves two functions
without any conditions?
There's always a condition. The code you posted is no exception.
What you call a "condition" is really just a boolean expression in a specific context. If the entire expression evaluates to True, you enter the body of the if-statement. Otherwise, if it evaluates to False, you don't.
Example
The following code iterates over the characters in a string, and only prints characters which are both alphabetic and uppercase:
string = "Hell2O]WoR3(Ld"
for char in string:
if char.isalpha() and char.isupper():
print(char)
Output:
H
O
W
R
L
>>>
str.isalpha returns a boolean - True if the string (in this case a string consisting of a single character) contains only alphabetic characters, False otherwise.
str.isupper returns a boolean - True if the string (again, just a single character in this case) contains only uppercase characters, False otherwise.
I picked these two string methods to simulate the two functions you have in your code, since they also return booleans.
Let's take the first character, "H":
>>> char = "H"
>>> char.isalpha()
True
>>> char.isupper()
True
>>> char.isalpha() and char.isupper()
True
>>>
You see, the entire boolean expression char.isalpha() and char.isupper() evaluates to True. In order for the entire expression to be evaluated, both functions need to be called - you can think of their return values effectively "replacing" their respective function calls. When char is "H", after calling the functions, the expression really looks like this:
True and True
Which evaluates to True, so we enter the body of the if-statement.
In your case, you used or instead of and. What I said about boolean expressions collapsing down into a single True or False value still applies, the only difference would be in short-circuiting, which isn't that relevant to your question I think.
Example
Here's something closer to what you have. Imagine a scenario where you want to monitor the temperature and radiation of something. If either the temperature OR the radiation levels are not nominal, we trigger an alarm.
def is_temperature_nominal(temp):
return 70 <= temp <= 100
def is_radiation_nominal(rad):
return rad < 200
if not is_temperature_nominal(250) or not is_radiation_nominal(50):
print("Alarm triggered!")
else:
print("Everything is good.")
Output:
Alarm triggered!
>>>
I picked the nominal ranges arbitrarily, and I picked the arguments 250 and 50 arbitrarily as well. With these two hardcoded values, the boolean expression would look like this after calling the two functions:
not False or not True
Which is another way of saying:
True or False
With an or, only one of the operands has to be True in order for the entire expression to evaluate to True - therefore the entire expression evaluates to True, and we enter the body of the if-statement, triggering the alarm (because only one of the values needs to be not nominal in order for the alarm to trigger. If both values are not nominal it would also trigger the alarm. The only way we enter the body of the else is if both values are nominal).
From my understanding, the IF.... or statements usually work with a
condition, but for this scenario it only involves two functions
without any conditions
if (as well as while) needs an expression that evaluates to a logical (type bool) value (either True or False), or can be typecast to a logical value (for example None is typecast to False).
In your case, the conditions (namely, comparisons) are done inside your functions (see the return statements), so that the functions already return logical values.
When calling a method, it's executed and return a value, which can be use in different manner : directly or stored in a variable, this code is exactly the same as the following, but just not saving in variables and inline the methods in the condition
disck_check = disk_check_usage("/") # True or False
cpu_check = check_cpu_usage() # True or False
if not disk_check or not cpu_check: # Boolean conbination
print("ERROR!")
else:
print("Everything is OK")
You have to use 'and' operator instead the 'or' used by you.
def disk_check_usage(disk):
du = shutil.disk_usage(disk)
free = du.free/du.total * 100
return free > 20
def check_cpu_usage():
usage = psutil.cpu_percent(1)
return usage < 75
if not disk_check_usage("/") and not check_cpu_usage():
print("ERROR!")
else:
print("Everything is OK")

python float is not digit? [duplicate]

This question already has answers here:
How to check if a user input is a float
(6 answers)
Closed 4 years ago.
This code returns False, but when I delete point from float it becomes True and I'm trying to understand why. Explain please
def isDigit(string):
string = string.strip()
if string[:1] == "-":
cuted = string[1:]
if cuted.isdigit():
return True
else:
return False
elif string.isdigit():
return True
else:
return False
print isDigit("-234.4")
also I know my code is not the best and I wonder how can I make it better
isdigit only checks if all the characters are digits (e.g. 0, 1, ... 9).
Therefore the string 234.4 will return False because it also contains a decimal point ., that is not a digit.
help("".isdigit)
will tell you that to be True all characters must be digits and there must be at least one character.
You could use a regular expression to do this kind of checking, for example with something like:
import re
def isnumber(x):
return re.match("-?[0-9]+([.][0-9]+)?$", x) is not None
that will accept an optional minus sign, followed by a sequence of one or more digits optionally followed by a decimal dot and more digits.
Note that floating point numbers can be accepted by a much wider syntax, including scale exponent and missing parts before and after the decimal point so don't be this strict if you're validating output from a computer. Depending on the context it may be however meaningful to refuse things like 1e4 as numbers from a human.
Let's step through your code.
if string[:1] == "-":
string[:1] means "make a string with characters from the start of string up to (but not including) index 1." If your string is "foobar", string[:1] will be "f". In your example, string[:1] will be "-"
cuted = string[1:]
This will do the opposite, producing a string that contains everything but the first character. In this case, cuted would be "234.4"
if cuted.isdigit():
return True
else:
return False
This will test if cuted is made up only of numbers. In our case, this is false, because it contains a decimal point. False is returned.
elif string.isdigit():
return True
else:
return False
If the first character was not "-", this is run instead. If you supplied "234.4", this case would be reached, and the test would fail (because "234.4" contains a decimal point), so False would be returned.
Your code appears to be valid if what you wanted was:
123.3 -> False
-123.3 -> False
123 -> True
-123 -> True
On the other hand, if you want your function to say all four of those are numbers, then you need to modify your code. The one way (probably not the best!) to do that would be to have a test case that does something like this:
If I split this string on ".", do I get two strings?
If so, are both pieces of the string digits?
If so, the string is a number.
It's not clear exactly what behavior you want.

General Python Programming 2.7 data validation

I was wondering what functions should I use for this def function so that the user can only enter strings and not integers -
def GetTextFromUser():
TextFromUser = raw_input('Please enter the text to use: ')
return TextFromUser
raw_input() always returns a string. But ,if by string you meant only alphabets are allowed, then you can use: str.isalpha()
S.isalpha() -> bool
Return True if all characters in S are alphabetic
and there is at least one character in S, False otherwise.
examples:
In [9]: 'foo'.isalpha()
Out[9]: True
In [10]: 'foo23'.isalpha()
Out[10]: False
According to the documentation, raw_input always returns a string. If you never want it to return an integer, I would try to convert it to an integer using int() and catch an exception if it fails. If it doesn't fail, immediately after, return the value. This follows the Pythonic style of "it's better to ask for forgiveness than for permission."

Categories

Resources