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;









4















$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:



enter image description here




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










share|improve this question











$endgroup$










  • 2




    $begingroup$
    nice apple icons
    $endgroup$
    – RomanPerekhrest
    Oct 16 at 15:25

















4















$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:



enter image description here




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










share|improve this question











$endgroup$










  • 2




    $begingroup$
    nice apple icons
    $endgroup$
    – RomanPerekhrest
    Oct 16 at 15:25













4













4









4


2



$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:



enter image description here




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










share|improve this question











$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:



enter image description here




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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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












  • 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










3 Answers
3






active

oldest

votes


















4

















$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.





share|improve this answer










$endgroup$














  • $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


















3

















$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 Nones 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.')





share|improve this answer










$endgroup$






















    1

















    $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+)?$





    share|improve this answer










    $endgroup$










    • 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













    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
    );



    );














    draft saved

    draft discarded
















    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









    4

















    $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.





    share|improve this answer










    $endgroup$














    • $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















    4

















    $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.





    share|improve this answer










    $endgroup$














    • $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













    4















    4











    4







    $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.





    share|improve this answer










    $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.






    share|improve this answer













    share|improve this answer




    share|improve this answer










    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 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















    $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













    3

















    $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 Nones 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.')





    share|improve this answer










    $endgroup$



















      3

















      $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 Nones 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.')





      share|improve this answer










      $endgroup$

















        3















        3











        3







        $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 Nones 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.')





        share|improve this answer










        $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 Nones 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.')






        share|improve this answer













        share|improve this answer




        share|improve this answer










        answered Oct 16 at 16:46









        CarcigenicateCarcigenicate

        10.3k1 gold badge20 silver badges49 bronze badges




        10.3k1 gold badge20 silver badges49 bronze badges
























            1

















            $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+)?$





            share|improve this answer










            $endgroup$










            • 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
















            1

















            $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+)?$





            share|improve this answer










            $endgroup$










            • 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














            1















            1











            1







            $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+)?$





            share|improve this answer










            $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+)?$






            share|improve this answer













            share|improve this answer




            share|improve this answer










            answered Oct 17 at 0:57









            user211527user211527

            111 bronze badge




            111 bronze badge










            • 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













            • 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








            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



















            draft saved

            draft discarded















































            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.




            draft saved


            draft discarded














            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





















































            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









            Popular posts from this blog

            Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

            Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

            Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її