# In Python, is there any way besides `numpy` and `float('nan')` to get the special constant `nan`?

## Question:

I've been reading the Underhanded C Contest website, where the goal is to write subtly malicious code that looks normal at first glance. One of the common techniques mentioned was the use of not a number , or `nan` , a constant that has some special properties; notably, any sort of comparison with `nan` results in `False` .

Thinking about a proof of concept in Python, I arrived at the following:

``````def maior_que_10():
entrada = input('Digite um número: ')
try:
except ValueError:
print('Erro!')
return
print('Maior que 10!')
return
print('Não é maior que 10!')
return

while True:
maior_que_10()
``````

The function correctly handles invalid numeric values ​​by throwing an error and on careless looking, it never seems to get to `print('Inesperado!')` because it checks `> 10` and `<= 10` , but having input "nan" executes the last line:

``````Digite um número: 11
Maior que 10!
Digite um número: 9
Não é maior que 10!
Digite um número: 10
Não é maior que 10!
Digite um número: foobar
Erro!
Digite um número: nan
``````

Theoretically, in less trivial code, malicious code could be hidden after the two `if` . This however depends on having user input passed to the `float` .

Is there any operation between variables that generates a `nan` otherwise?

I thought division by zero or negative number root, but result in exceptions, not `nan` :

``````>>> math.sqrt(-1)
ValueError: math domain error
>>> 1/0
ZeroDivisionError: division by zero
``````

(*rereading the entire question, I saw that I wrote an extensive answer on how to check a decimal point entry, but that doesn't quite answer your specific question – sorry. I'll keep the answer because it might help newbies who fall here because of the title of the question)

In newer versions of Python it is possible to do `from math import nan` – this puts in the namespace the variable `nan` that contains a number `nan` .

In older versions (prior to 3.5 of Python), the recommended thing was to put in your code:

``````nan = float('nan')
``````

same (or use the expression `float('nan')` directly.

Furthermore it is important to keep in mind when dealing with NaN's that one NaN value is never equal to another when compared to `==` (nor is it equal to itself). The best way to tell if a value is a NaN is to use the `isnan` function in the math module:

``````from math import nan, isnam

isnan(nan)
``````

prints `True` .

That said about NaNs – there are more things to consider about using `float` directly on top of a string the user types. In particular, infinite values ​​can be expressed with `float('inf')` (and negative infinity with "-inf"), and numbers with scientific notation are also accepted, where an exponent factor of "10" can be added to the number after of the letter "e":

``````In : float("1e3")
Out: 1000.0
``````

So if you really want to limit the input to positive or negative numbers, with decimal points, it's better to parse them more carefully than simply calling `float(entrada)` .

In general, when we talk about "parse", many people think of regular expressions first. I consider regular expressions to be difficult to read and maintain, and people tend to put simple expressions, which don't match all possible data.

# checking typed data with regular expressions:

Python is a good language for regular expressions because luckily they didn't invent to mix them with the language's syntax – you call normal functions and pass a string with the regular expression you want to compare with your text – there are several functions in the `re` module of regular expressions – for example to "find all occurrences" ( `re.findall` ) or replace ( `re.sub` ). In this case, we simply want to see if an expression matches user input.

And in a hurry one might think "I want to see if the user has typed one or more digits, followed by an optional period, followed by one or more digits" – this expression can be written as `"[0-9]+\.?[0-9]+"` – just look at it and see that it's not good: what if the user types a "-" sign? What if there is only one digit? (the second part expects one more digit after the dot – although the dot is optional) – result – while this expression can match "11", "23.2", "0.1", it will not match "1", "- 1", ".23", etc…

To make a long story short, the regular expression that checks for a decimal number, with optional sign, with at least one valid digit, or no digits if there is a decimal point, and if there is a decimal point at least one digit after it is:

``````c = r"-?(?:[0-9]+|(?=\.))(?:\.[0-9]+)?\$"
``````

(Python regexps documentation is here – https://docs.python.org/3/library/re.html )

And you could do in your code:

``````import re

def maior_que_10():
entrada = input('Digite um número: ')
print('Erro!')
return
...
``````

# Checking Input with Python Code

So, in the name of readability, and knowing what you're doing, it might be worth using Python's string manipulation functions: split, find, count, isdigit to make a function that checks if a string is a decimal well formatted before trying to convert it to float.

You can do something like:

``````verifica_decimal(text):
if not text:  # string vazia
return False
filtered = text.replace('-', '').replace('.', '')
if not filtered.isdigit(): # há caracteres que não são nem dígito nem - nem .
return False
if '-' in text[1:]: # sinal 'perdido' no meio do número.
return False
if text.count('.') > 1 or text[-1] == '.': # Mais de um '.', ou '.' na última casa
return False
return True

def maior_que_10():
entrada = input('Digite um número: ')