LeetCode 65: Valid Number (Python)LeetCode 65: Valid Number (C++)Test if a string is a palindromeLeetcode 125. Valid PalindromeLeetcode 125. Valid Palindrome (better performance?)Leetcode number of atoms solution using stackIdentify fraudulent bank transactionsPython program to get the first word(Leetcode) Valid parenthesesPapers, Please - Kata from CodeWars - PythonObject-oriented calculatorLeetCode #494: Target Sum (Python)
Why are rain clouds darker?
Why are there so many binary systems?
N-Dimensional Cartesian Product
Beautiful planar geometry theorems not encountered in high school
What does Yoda's species eat?
Contradictory parts of D&D Beyond: which is official?
Prove that the equation has only one real root.
Car imitates dead battery but comes back to life ~30 minutes later and lets me start it
Uniqueness principle for functions types in the HoTT book
Why does it not make sense to define addition on points in geometry?
Can a UK passport valid for two months travel to Germany post-brexit?
SSH host identification changes on one wireless network
Curl of electric field
Cage Length (Rear Derallieur) and Total Capacity
Can the Protection fighting style be used in this way?
How to capitalize letter (using uppercase) that has been assigned to let (or to def)?
Should I re-install Windows 10 on my failing hard drive?
How to get rid of vertical white lines in a table?
How should I handle a player attacking from the top of a tree?
Are there any dishes that can only be cooked with a microwave?
Would a warhorse allow its rider to approach a Dragon at all?
Are these numbers Madelung constants?
Evaluating a definite Integral with a constant n
Why do we use the particular magnitude of a force to calculate work?
LeetCode 65: Valid Number (Python)
LeetCode 65: Valid Number (C++)Test if a string is a palindromeLeetcode 125. Valid PalindromeLeetcode 125. Valid Palindrome (better performance?)Leetcode number of atoms solution using stackIdentify fraudulent bank transactionsPython program to get the first word(Leetcode) Valid parenthesesPapers, Please - Kata from CodeWars - PythonObject-oriented calculatorLeetCode #494: Target Sum (Python)
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
$begingroup$
Problem
Validate if a given string can be interpreted as a decimal or scientific number.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
Code
I've solved the valid number LeetCode problem using Python re
module. If you'd like to review the code and provide any change/improvement recommendations, please do so and I'd really appreciate that.
import re
from typing import Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers and input string can be string or None
"""
if input_string is None:
return False
expression_d_construct = r"^[+-]?(?:d*.d+|d+.d*|d+)[Ee][+-]?d+$|^[+-]?(?:d*.d+|d+.d*|d+)$|^[+-]?d+$"
expression_char_class = r"^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)[Ee][+-]?[0-9]+$|^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)$|^[+-]?[0-9]+$"
if re.match(expression_d_construct, input_string.strip()) is not None and re.match(expression_char_class, input_string.strip()) is not None:
return True
return False
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
if is_numeric(string):
print(f'GREEN_APPLE Test int(count + 1): string is a valid number.')
else:
print(f'RED_APPLE Test int(count + 1): string is an invalid number.')
count += 1
Output
--------------------------------------------------
🍎 Test 1: None is an invalid number.
--------------------------------------------------
🍏 Test 2: 0 is a valid number.
--------------------------------------------------
🍏 Test 3: 0.1 is a valid number.
--------------------------------------------------
🍎 Test 4: abc is an invalid number.
--------------------------------------------------
🍎 Test 5: 1 a is an invalid number.
--------------------------------------------------
🍏 Test 6: 2e10 is a valid number.
--------------------------------------------------
🍏 Test 7: -90e3 is a valid number.
--------------------------------------------------
🍎 Test 8: 1e is an invalid number.
--------------------------------------------------
🍎 Test 9: e3 is an invalid number.
--------------------------------------------------
🍏 Test 10: 6e-1 is a valid number.
--------------------------------------------------
🍎 Test 11: 99e2.5 is an invalid number.
--------------------------------------------------
🍏 Test 12: 53.5e93 is a valid number.
--------------------------------------------------
🍎 Test 13: --6 is an invalid number.
--------------------------------------------------
🍎 Test 14: -+3 is an invalid number.
--------------------------------------------------
🍎 Test 15: 95a54e53 is an invalid number.
RegEx Circuit
jex.im visualizes regular expressions:
RegEx Demo 1
RegEx Demo 2
If you wish to explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
Source
LeetCode Valid Number
python beginner algorithm strings regex
$endgroup$
add a comment
|
$begingroup$
Problem
Validate if a given string can be interpreted as a decimal or scientific number.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
Code
I've solved the valid number LeetCode problem using Python re
module. If you'd like to review the code and provide any change/improvement recommendations, please do so and I'd really appreciate that.
import re
from typing import Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers and input string can be string or None
"""
if input_string is None:
return False
expression_d_construct = r"^[+-]?(?:d*.d+|d+.d*|d+)[Ee][+-]?d+$|^[+-]?(?:d*.d+|d+.d*|d+)$|^[+-]?d+$"
expression_char_class = r"^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)[Ee][+-]?[0-9]+$|^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)$|^[+-]?[0-9]+$"
if re.match(expression_d_construct, input_string.strip()) is not None and re.match(expression_char_class, input_string.strip()) is not None:
return True
return False
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
if is_numeric(string):
print(f'GREEN_APPLE Test int(count + 1): string is a valid number.')
else:
print(f'RED_APPLE Test int(count + 1): string is an invalid number.')
count += 1
Output
--------------------------------------------------
🍎 Test 1: None is an invalid number.
--------------------------------------------------
🍏 Test 2: 0 is a valid number.
--------------------------------------------------
🍏 Test 3: 0.1 is a valid number.
--------------------------------------------------
🍎 Test 4: abc is an invalid number.
--------------------------------------------------
🍎 Test 5: 1 a is an invalid number.
--------------------------------------------------
🍏 Test 6: 2e10 is a valid number.
--------------------------------------------------
🍏 Test 7: -90e3 is a valid number.
--------------------------------------------------
🍎 Test 8: 1e is an invalid number.
--------------------------------------------------
🍎 Test 9: e3 is an invalid number.
--------------------------------------------------
🍏 Test 10: 6e-1 is a valid number.
--------------------------------------------------
🍎 Test 11: 99e2.5 is an invalid number.
--------------------------------------------------
🍏 Test 12: 53.5e93 is a valid number.
--------------------------------------------------
🍎 Test 13: --6 is an invalid number.
--------------------------------------------------
🍎 Test 14: -+3 is an invalid number.
--------------------------------------------------
🍎 Test 15: 95a54e53 is an invalid number.
RegEx Circuit
jex.im visualizes regular expressions:
RegEx Demo 1
RegEx Demo 2
If you wish to explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
Source
LeetCode Valid Number
python beginner algorithm strings regex
$endgroup$
2
$begingroup$
nice apple icons
$endgroup$
– RomanPerekhrest
Oct 16 at 15:25
add a comment
|
$begingroup$
Problem
Validate if a given string can be interpreted as a decimal or scientific number.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
Code
I've solved the valid number LeetCode problem using Python re
module. If you'd like to review the code and provide any change/improvement recommendations, please do so and I'd really appreciate that.
import re
from typing import Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers and input string can be string or None
"""
if input_string is None:
return False
expression_d_construct = r"^[+-]?(?:d*.d+|d+.d*|d+)[Ee][+-]?d+$|^[+-]?(?:d*.d+|d+.d*|d+)$|^[+-]?d+$"
expression_char_class = r"^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)[Ee][+-]?[0-9]+$|^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)$|^[+-]?[0-9]+$"
if re.match(expression_d_construct, input_string.strip()) is not None and re.match(expression_char_class, input_string.strip()) is not None:
return True
return False
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
if is_numeric(string):
print(f'GREEN_APPLE Test int(count + 1): string is a valid number.')
else:
print(f'RED_APPLE Test int(count + 1): string is an invalid number.')
count += 1
Output
--------------------------------------------------
🍎 Test 1: None is an invalid number.
--------------------------------------------------
🍏 Test 2: 0 is a valid number.
--------------------------------------------------
🍏 Test 3: 0.1 is a valid number.
--------------------------------------------------
🍎 Test 4: abc is an invalid number.
--------------------------------------------------
🍎 Test 5: 1 a is an invalid number.
--------------------------------------------------
🍏 Test 6: 2e10 is a valid number.
--------------------------------------------------
🍏 Test 7: -90e3 is a valid number.
--------------------------------------------------
🍎 Test 8: 1e is an invalid number.
--------------------------------------------------
🍎 Test 9: e3 is an invalid number.
--------------------------------------------------
🍏 Test 10: 6e-1 is a valid number.
--------------------------------------------------
🍎 Test 11: 99e2.5 is an invalid number.
--------------------------------------------------
🍏 Test 12: 53.5e93 is a valid number.
--------------------------------------------------
🍎 Test 13: --6 is an invalid number.
--------------------------------------------------
🍎 Test 14: -+3 is an invalid number.
--------------------------------------------------
🍎 Test 15: 95a54e53 is an invalid number.
RegEx Circuit
jex.im visualizes regular expressions:
RegEx Demo 1
RegEx Demo 2
If you wish to explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
Source
LeetCode Valid Number
python beginner algorithm strings regex
$endgroup$
Problem
Validate if a given string can be interpreted as a decimal or scientific number.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
Code
I've solved the valid number LeetCode problem using Python re
module. If you'd like to review the code and provide any change/improvement recommendations, please do so and I'd really appreciate that.
import re
from typing import Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers and input string can be string or None
"""
if input_string is None:
return False
expression_d_construct = r"^[+-]?(?:d*.d+|d+.d*|d+)[Ee][+-]?d+$|^[+-]?(?:d*.d+|d+.d*|d+)$|^[+-]?d+$"
expression_char_class = r"^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)[Ee][+-]?[0-9]+$|^[+-]?(?:[0-9]*.[0-9]+|[0-9]+.[0-9]*|[0-9]+)$|^[+-]?[0-9]+$"
if re.match(expression_d_construct, input_string.strip()) is not None and re.match(expression_char_class, input_string.strip()) is not None:
return True
return False
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
if is_numeric(string):
print(f'GREEN_APPLE Test int(count + 1): string is a valid number.')
else:
print(f'RED_APPLE Test int(count + 1): string is an invalid number.')
count += 1
Output
--------------------------------------------------
🍎 Test 1: None is an invalid number.
--------------------------------------------------
🍏 Test 2: 0 is a valid number.
--------------------------------------------------
🍏 Test 3: 0.1 is a valid number.
--------------------------------------------------
🍎 Test 4: abc is an invalid number.
--------------------------------------------------
🍎 Test 5: 1 a is an invalid number.
--------------------------------------------------
🍏 Test 6: 2e10 is a valid number.
--------------------------------------------------
🍏 Test 7: -90e3 is a valid number.
--------------------------------------------------
🍎 Test 8: 1e is an invalid number.
--------------------------------------------------
🍎 Test 9: e3 is an invalid number.
--------------------------------------------------
🍏 Test 10: 6e-1 is a valid number.
--------------------------------------------------
🍎 Test 11: 99e2.5 is an invalid number.
--------------------------------------------------
🍏 Test 12: 53.5e93 is a valid number.
--------------------------------------------------
🍎 Test 13: --6 is an invalid number.
--------------------------------------------------
🍎 Test 14: -+3 is an invalid number.
--------------------------------------------------
🍎 Test 15: 95a54e53 is an invalid number.
RegEx Circuit
jex.im visualizes regular expressions:
RegEx Demo 1
RegEx Demo 2
If you wish to explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
Source
LeetCode Valid Number
python beginner algorithm strings regex
python beginner algorithm strings regex
edited Oct 16 at 15:30
Emma
asked Oct 16 at 15:10
EmmaEmma
1,3912 gold badges2 silver badges21 bronze badges
1,3912 gold badges2 silver badges21 bronze badges
2
$begingroup$
nice apple icons
$endgroup$
– RomanPerekhrest
Oct 16 at 15:25
add a comment
|
2
$begingroup$
nice apple icons
$endgroup$
– RomanPerekhrest
Oct 16 at 15:25
2
2
$begingroup$
nice apple icons
$endgroup$
– RomanPerekhrest
Oct 16 at 15:25
$begingroup$
nice apple icons
$endgroup$
– RomanPerekhrest
Oct 16 at 15:25
add a comment
|
3 Answers
3
active
oldest
votes
$begingroup$
Instead of diving into cumbersome and lengthy regex expressions consider the following improvement/correction:
The main thesis for the underlying aspect is:
Numeric literals containing a decimal point or an exponent sign
yield floating point numbers.
https://docs.python.org/3.4/library/stdtypes.html#numeric-types-int-float-complex
Therefore Python treats values like 53.5e93
, -90e3
as float type numbers.
Eventually I would proceed with the following approach (retaining those cute icons) including additional small optimizations:
from typing import TypeVar, Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
if input_string is None:
return False
try:
input_string = input_string.strip()
float(input_string)
except ValueError:
return False
return True
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
count += 1
if is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
The output:
--------------------------------------------------
🍎 Test 1: `None` is not a valid number.
--------------------------------------------------
🍏 Test 2: `0 ` is a valid number.
--------------------------------------------------
🍏 Test 3: `0.1` is a valid number.
--------------------------------------------------
🍎 Test 4: `abc` is not a valid number.
--------------------------------------------------
🍎 Test 5: `1 a` is not a valid number.
--------------------------------------------------
🍏 Test 6: `2e10` is a valid number.
--------------------------------------------------
🍏 Test 7: `-90e3` is a valid number.
--------------------------------------------------
🍎 Test 8: `1e` is not a valid number.
--------------------------------------------------
🍎 Test 9: `e3` is not a valid number.
--------------------------------------------------
🍏 Test 10: `6e-1` is a valid number.
--------------------------------------------------
🍎 Test 11: `99e2.5` is not a valid number.
--------------------------------------------------
🍏 Test 12: `53.5e93` is a valid number.
--------------------------------------------------
🍎 Test 13: `--6` is not a valid number.
--------------------------------------------------
🍎 Test 14: `-+3` is not a valid number.
--------------------------------------------------
🍎 Test 15: `95a54e53` is not a valid number.
$endgroup$
$begingroup$
The.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit theNone
check and catch bothValueError
andTypeError
.
$endgroup$
– Wombatz
Oct 17 at 11:03
add a comment
|
$begingroup$
I'd just go with @Roman's suggestion. You should just leave it up to the language to decide what is and isn't valid.
I'd make two further suggestions though:
I don't think the parameter to is_numeric
should be Optional
; either conceptually, or to comply with the challenge. None
will never be a valid number, so why even check it? I don't think dealing with invalid data should be that function's responsibility. Make it take just a str
, then deal with None
s externally. I also don't really think it's is_numeric
's responsibility to be dealing with trimming either; and that isn't even required:
print(float(" 0.1 ")) # prints 0.1
I'd also return True
from within the try
. The behavior will be the same, but I find it makes it clearer the intent of the try
.
After the minor changes, I'd go with:
def is_numeric(input_string: str) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
try:
parsed = float(input_string)
return True
except ValueError:
return False
if string is not None and is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
$endgroup$
add a comment
|
$begingroup$
That regex visualisation you provided is really neat. It shows that there is a lot of potential overlap in the conditions.
You should be able to reduce it down to something similar to this:
^[+-]?d+(.d+)?([Ee][+-]?d+)?$
$endgroup$
1
$begingroup$
Your regex doesn't match1.
or.5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.
$endgroup$
– JAD
Oct 17 at 8:39
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f230848%2fleetcode-65-valid-number-python%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Instead of diving into cumbersome and lengthy regex expressions consider the following improvement/correction:
The main thesis for the underlying aspect is:
Numeric literals containing a decimal point or an exponent sign
yield floating point numbers.
https://docs.python.org/3.4/library/stdtypes.html#numeric-types-int-float-complex
Therefore Python treats values like 53.5e93
, -90e3
as float type numbers.
Eventually I would proceed with the following approach (retaining those cute icons) including additional small optimizations:
from typing import TypeVar, Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
if input_string is None:
return False
try:
input_string = input_string.strip()
float(input_string)
except ValueError:
return False
return True
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
count += 1
if is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
The output:
--------------------------------------------------
🍎 Test 1: `None` is not a valid number.
--------------------------------------------------
🍏 Test 2: `0 ` is a valid number.
--------------------------------------------------
🍏 Test 3: `0.1` is a valid number.
--------------------------------------------------
🍎 Test 4: `abc` is not a valid number.
--------------------------------------------------
🍎 Test 5: `1 a` is not a valid number.
--------------------------------------------------
🍏 Test 6: `2e10` is a valid number.
--------------------------------------------------
🍏 Test 7: `-90e3` is a valid number.
--------------------------------------------------
🍎 Test 8: `1e` is not a valid number.
--------------------------------------------------
🍎 Test 9: `e3` is not a valid number.
--------------------------------------------------
🍏 Test 10: `6e-1` is a valid number.
--------------------------------------------------
🍎 Test 11: `99e2.5` is not a valid number.
--------------------------------------------------
🍏 Test 12: `53.5e93` is a valid number.
--------------------------------------------------
🍎 Test 13: `--6` is not a valid number.
--------------------------------------------------
🍎 Test 14: `-+3` is not a valid number.
--------------------------------------------------
🍎 Test 15: `95a54e53` is not a valid number.
$endgroup$
$begingroup$
The.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit theNone
check and catch bothValueError
andTypeError
.
$endgroup$
– Wombatz
Oct 17 at 11:03
add a comment
|
$begingroup$
Instead of diving into cumbersome and lengthy regex expressions consider the following improvement/correction:
The main thesis for the underlying aspect is:
Numeric literals containing a decimal point or an exponent sign
yield floating point numbers.
https://docs.python.org/3.4/library/stdtypes.html#numeric-types-int-float-complex
Therefore Python treats values like 53.5e93
, -90e3
as float type numbers.
Eventually I would proceed with the following approach (retaining those cute icons) including additional small optimizations:
from typing import TypeVar, Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
if input_string is None:
return False
try:
input_string = input_string.strip()
float(input_string)
except ValueError:
return False
return True
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
count += 1
if is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
The output:
--------------------------------------------------
🍎 Test 1: `None` is not a valid number.
--------------------------------------------------
🍏 Test 2: `0 ` is a valid number.
--------------------------------------------------
🍏 Test 3: `0.1` is a valid number.
--------------------------------------------------
🍎 Test 4: `abc` is not a valid number.
--------------------------------------------------
🍎 Test 5: `1 a` is not a valid number.
--------------------------------------------------
🍏 Test 6: `2e10` is a valid number.
--------------------------------------------------
🍏 Test 7: `-90e3` is a valid number.
--------------------------------------------------
🍎 Test 8: `1e` is not a valid number.
--------------------------------------------------
🍎 Test 9: `e3` is not a valid number.
--------------------------------------------------
🍏 Test 10: `6e-1` is a valid number.
--------------------------------------------------
🍎 Test 11: `99e2.5` is not a valid number.
--------------------------------------------------
🍏 Test 12: `53.5e93` is a valid number.
--------------------------------------------------
🍎 Test 13: `--6` is not a valid number.
--------------------------------------------------
🍎 Test 14: `-+3` is not a valid number.
--------------------------------------------------
🍎 Test 15: `95a54e53` is not a valid number.
$endgroup$
$begingroup$
The.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit theNone
check and catch bothValueError
andTypeError
.
$endgroup$
– Wombatz
Oct 17 at 11:03
add a comment
|
$begingroup$
Instead of diving into cumbersome and lengthy regex expressions consider the following improvement/correction:
The main thesis for the underlying aspect is:
Numeric literals containing a decimal point or an exponent sign
yield floating point numbers.
https://docs.python.org/3.4/library/stdtypes.html#numeric-types-int-float-complex
Therefore Python treats values like 53.5e93
, -90e3
as float type numbers.
Eventually I would proceed with the following approach (retaining those cute icons) including additional small optimizations:
from typing import TypeVar, Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
if input_string is None:
return False
try:
input_string = input_string.strip()
float(input_string)
except ValueError:
return False
return True
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
count += 1
if is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
The output:
--------------------------------------------------
🍎 Test 1: `None` is not a valid number.
--------------------------------------------------
🍏 Test 2: `0 ` is a valid number.
--------------------------------------------------
🍏 Test 3: `0.1` is a valid number.
--------------------------------------------------
🍎 Test 4: `abc` is not a valid number.
--------------------------------------------------
🍎 Test 5: `1 a` is not a valid number.
--------------------------------------------------
🍏 Test 6: `2e10` is a valid number.
--------------------------------------------------
🍏 Test 7: `-90e3` is a valid number.
--------------------------------------------------
🍎 Test 8: `1e` is not a valid number.
--------------------------------------------------
🍎 Test 9: `e3` is not a valid number.
--------------------------------------------------
🍏 Test 10: `6e-1` is a valid number.
--------------------------------------------------
🍎 Test 11: `99e2.5` is not a valid number.
--------------------------------------------------
🍏 Test 12: `53.5e93` is a valid number.
--------------------------------------------------
🍎 Test 13: `--6` is not a valid number.
--------------------------------------------------
🍎 Test 14: `-+3` is not a valid number.
--------------------------------------------------
🍎 Test 15: `95a54e53` is not a valid number.
$endgroup$
Instead of diving into cumbersome and lengthy regex expressions consider the following improvement/correction:
The main thesis for the underlying aspect is:
Numeric literals containing a decimal point or an exponent sign
yield floating point numbers.
https://docs.python.org/3.4/library/stdtypes.html#numeric-types-int-float-complex
Therefore Python treats values like 53.5e93
, -90e3
as float type numbers.
Eventually I would proceed with the following approach (retaining those cute icons) including additional small optimizations:
from typing import TypeVar, Optional
def is_numeric(input_string: Optional[str]) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
if input_string is None:
return False
try:
input_string = input_string.strip()
float(input_string)
except ValueError:
return False
return True
if __name__ == "__main__":
# ---------------------------- TEST ---------------------------
DIVIDER_DASH = '-' * 50
GREEN_APPLE = 'U0001F34F'
RED_APPLE = 'U0001F34E'
test_input_strings = [None, "0 ", "0.1", "abc", "1 a", "2e10", "-90e3",
"1e", "e3", "6e-1", "99e2.5", "53.5e93", "--6", "-+3", "95a54e53"]
count = 0
for string in test_input_strings:
print(DIVIDER_DASH)
count += 1
if is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
The output:
--------------------------------------------------
🍎 Test 1: `None` is not a valid number.
--------------------------------------------------
🍏 Test 2: `0 ` is a valid number.
--------------------------------------------------
🍏 Test 3: `0.1` is a valid number.
--------------------------------------------------
🍎 Test 4: `abc` is not a valid number.
--------------------------------------------------
🍎 Test 5: `1 a` is not a valid number.
--------------------------------------------------
🍏 Test 6: `2e10` is a valid number.
--------------------------------------------------
🍏 Test 7: `-90e3` is a valid number.
--------------------------------------------------
🍎 Test 8: `1e` is not a valid number.
--------------------------------------------------
🍎 Test 9: `e3` is not a valid number.
--------------------------------------------------
🍏 Test 10: `6e-1` is a valid number.
--------------------------------------------------
🍎 Test 11: `99e2.5` is not a valid number.
--------------------------------------------------
🍏 Test 12: `53.5e93` is a valid number.
--------------------------------------------------
🍎 Test 13: `--6` is not a valid number.
--------------------------------------------------
🍎 Test 14: `-+3` is not a valid number.
--------------------------------------------------
🍎 Test 15: `95a54e53` is not a valid number.
answered Oct 16 at 15:44
RomanPerekhrestRomanPerekhrest
1,8994 silver badges10 bronze badges
1,8994 silver badges10 bronze badges
$begingroup$
The.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit theNone
check and catch bothValueError
andTypeError
.
$endgroup$
– Wombatz
Oct 17 at 11:03
add a comment
|
$begingroup$
The.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit theNone
check and catch bothValueError
andTypeError
.
$endgroup$
– Wombatz
Oct 17 at 11:03
$begingroup$
The
.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit the None
check and catch both ValueError
and TypeError
.$endgroup$
– Wombatz
Oct 17 at 11:03
$begingroup$
The
.strip()
part is not necessary, because python allows optional leading and trailing whitespace. Also, you can omit the None
check and catch both ValueError
and TypeError
.$endgroup$
– Wombatz
Oct 17 at 11:03
add a comment
|
$begingroup$
I'd just go with @Roman's suggestion. You should just leave it up to the language to decide what is and isn't valid.
I'd make two further suggestions though:
I don't think the parameter to is_numeric
should be Optional
; either conceptually, or to comply with the challenge. None
will never be a valid number, so why even check it? I don't think dealing with invalid data should be that function's responsibility. Make it take just a str
, then deal with None
s externally. I also don't really think it's is_numeric
's responsibility to be dealing with trimming either; and that isn't even required:
print(float(" 0.1 ")) # prints 0.1
I'd also return True
from within the try
. The behavior will be the same, but I find it makes it clearer the intent of the try
.
After the minor changes, I'd go with:
def is_numeric(input_string: str) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
try:
parsed = float(input_string)
return True
except ValueError:
return False
if string is not None and is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
$endgroup$
add a comment
|
$begingroup$
I'd just go with @Roman's suggestion. You should just leave it up to the language to decide what is and isn't valid.
I'd make two further suggestions though:
I don't think the parameter to is_numeric
should be Optional
; either conceptually, or to comply with the challenge. None
will never be a valid number, so why even check it? I don't think dealing with invalid data should be that function's responsibility. Make it take just a str
, then deal with None
s externally. I also don't really think it's is_numeric
's responsibility to be dealing with trimming either; and that isn't even required:
print(float(" 0.1 ")) # prints 0.1
I'd also return True
from within the try
. The behavior will be the same, but I find it makes it clearer the intent of the try
.
After the minor changes, I'd go with:
def is_numeric(input_string: str) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
try:
parsed = float(input_string)
return True
except ValueError:
return False
if string is not None and is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
$endgroup$
add a comment
|
$begingroup$
I'd just go with @Roman's suggestion. You should just leave it up to the language to decide what is and isn't valid.
I'd make two further suggestions though:
I don't think the parameter to is_numeric
should be Optional
; either conceptually, or to comply with the challenge. None
will never be a valid number, so why even check it? I don't think dealing with invalid data should be that function's responsibility. Make it take just a str
, then deal with None
s externally. I also don't really think it's is_numeric
's responsibility to be dealing with trimming either; and that isn't even required:
print(float(" 0.1 ")) # prints 0.1
I'd also return True
from within the try
. The behavior will be the same, but I find it makes it clearer the intent of the try
.
After the minor changes, I'd go with:
def is_numeric(input_string: str) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
try:
parsed = float(input_string)
return True
except ValueError:
return False
if string is not None and is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
$endgroup$
I'd just go with @Roman's suggestion. You should just leave it up to the language to decide what is and isn't valid.
I'd make two further suggestions though:
I don't think the parameter to is_numeric
should be Optional
; either conceptually, or to comply with the challenge. None
will never be a valid number, so why even check it? I don't think dealing with invalid data should be that function's responsibility. Make it take just a str
, then deal with None
s externally. I also don't really think it's is_numeric
's responsibility to be dealing with trimming either; and that isn't even required:
print(float(" 0.1 ")) # prints 0.1
I'd also return True
from within the try
. The behavior will be the same, but I find it makes it clearer the intent of the try
.
After the minor changes, I'd go with:
def is_numeric(input_string: str) -> bool:
"""
Returns True for valid numbers. Acceptable types of items: str or None
"""
try:
parsed = float(input_string)
return True
except ValueError:
return False
if string is not None and is_numeric(string):
print(f'GREEN_APPLE Test count: `string` is a valid number.')
else:
print(f'RED_APPLE Test count: `string` is not a valid number.')
answered Oct 16 at 16:46
CarcigenicateCarcigenicate
10.3k1 gold badge20 silver badges49 bronze badges
10.3k1 gold badge20 silver badges49 bronze badges
add a comment
|
add a comment
|
$begingroup$
That regex visualisation you provided is really neat. It shows that there is a lot of potential overlap in the conditions.
You should be able to reduce it down to something similar to this:
^[+-]?d+(.d+)?([Ee][+-]?d+)?$
$endgroup$
1
$begingroup$
Your regex doesn't match1.
or.5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.
$endgroup$
– JAD
Oct 17 at 8:39
add a comment
|
$begingroup$
That regex visualisation you provided is really neat. It shows that there is a lot of potential overlap in the conditions.
You should be able to reduce it down to something similar to this:
^[+-]?d+(.d+)?([Ee][+-]?d+)?$
$endgroup$
1
$begingroup$
Your regex doesn't match1.
or.5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.
$endgroup$
– JAD
Oct 17 at 8:39
add a comment
|
$begingroup$
That regex visualisation you provided is really neat. It shows that there is a lot of potential overlap in the conditions.
You should be able to reduce it down to something similar to this:
^[+-]?d+(.d+)?([Ee][+-]?d+)?$
$endgroup$
That regex visualisation you provided is really neat. It shows that there is a lot of potential overlap in the conditions.
You should be able to reduce it down to something similar to this:
^[+-]?d+(.d+)?([Ee][+-]?d+)?$
answered Oct 17 at 0:57
user211527user211527
111 bronze badge
111 bronze badge
1
$begingroup$
Your regex doesn't match1.
or.5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.
$endgroup$
– JAD
Oct 17 at 8:39
add a comment
|
1
$begingroup$
Your regex doesn't match1.
or.5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.
$endgroup$
– JAD
Oct 17 at 8:39
1
1
$begingroup$
Your regex doesn't match
1.
or .5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.$endgroup$
– JAD
Oct 17 at 8:39
$begingroup$
Your regex doesn't match
1.
or .5
, both of which are matched by the regex in the OP. Your regex assumes that there will always be a leading digit before a period, and that a period will always be followed by decimals. Neither is true.$endgroup$
– JAD
Oct 17 at 8:39
add a comment
|
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f230848%2fleetcode-65-valid-number-python%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
$begingroup$
nice apple icons
$endgroup$
– RomanPerekhrest
Oct 16 at 15:25