Kinki University Advent Calendar 2019 Day 10 I was very surprised that the Advent calendar, which I started with a light feeling, was filled all day. I am very grateful to everyone who participated, thank you.

In this article, I'll show you what I've done with Python. Also, I will leave what I investigated when I was addicted to NaN. I would like to look back on myself and become a teacher on the other hand.

After getting used to Python, while trying to write Pythonic, an acquaintance said, "In Python, it is more fashionable to judge equivalence with ʻis`!", And I have replaced all `

==` with ʻis`

. ..
Then it seems to work right, but ...

== Difference in behavior between is and is == determines if the values are equal is determines if the object ids are equal

Even if the Python strings and lists have the same value, the object id may be different. (If Japanese is entered in the character string, I feel that it will be strange in ʻis`), so if you judge with ʻis`

, False will be returned even if the value is the same, and you will be addicted to it.

```
left = "python"
# ==Judgment
left == "python"
# > True
#is judgment
left is "python"
# > False
```

Python can multiply strings and arrays with `*`

.

```
"Ora" * 10
# 'Ora Ora Ora Ora Ora Ora Ora Ora Ora'
[0] * 10
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
```

However, if you generate it as a two-dimensional array with this, you will fall into the trap of reference copy. I didn't notice this and it melted for a long time ... I think it's better to write in list comprehension, etc. without wearing it sideways.

```
two_d_list = [[0] * 10] * 10
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0,0]I want to add only the value of
two_d_list[0][0] += 1
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
```

Unlike Python's C etc., the for statement is a mechanism that iterates over sequence types. So, I'm addicted to doing the following.

- Even if the target list such as ʻi` is changed in the middle, it is not reflected.
- Append to a sequence object in a loop from the inside, resulting in an infinite loop

I think I have to give up on the first one ... The second can be solved by using slice notation

```
num_list = list(range(1, 4))
#There is no point in playing with the target list in the middle
for i in num_list:
print(i)
i += 1
# 1
# 2
# 3
#Append in a loop using slices
for i in num_list[:]:
num_list.append(i)
# [1, 2, 3, 1, 2, 3]
```

If you have a little math or something you want to try, you often call a Python interprinter from your terminal. However, once you press enter, you cannot go back and often say, "Oh, I made a mistake in the variable name" or "Oh, I made a mistake in indentation." So I started using ʻipython`. ipython is recommended because it is superior to the default interprinter as an interactive environment where you can execute commands in an environment where you execute code in cells that you are familiar with in jupyter notebook.

This is mainly related to AtCoder, but if the Python version is 3.4 or lower, the `gcd`

function is not in the math module (the current Python3 version of AtCoder is 3.4).

The `gcd`

function is placed in the math module since 3.5, and earlier versions have it in the fractions module and must be used. It may be a trivial matter, but it was quite a bit of a challenge for a competitive professional who missed a minute and a second.

```
# 3.This cannot be used for 4 or less
from math import gcd
# 3.Use this before 4(3.Not recommended after 5)
from fractions import gcd
```

NaN

a bit pattern of a single-precision or double-precision real number data type that is a result of an invalid floating point operation. Translation: Bit patterns of single-precision or double-precision real data types that are the result of invalid floating-point operations From IEEE 754

I've always thought that the function that determines NaN in Pandas is `df.isnan ()`

(?)
It's actually `df.isnull ()`

. `math.isnan ()`

and `numpy.isnan ()`

are also valid for individual determination.

np.nan == np.nan # is always False! Use special numpy functions instead.

NaN has a characteristic that it returns False in numerical comparison and equivalent operation with everything (it is also from this characteristic that it returns False in comparison with itself), but is compared by reference is not a numerical comparison. , This principle does not apply. However, Python has two types of NaN, math.nan and numpy.nan, which have different object ids.

```
#Comparison between NaNs using is
math.nan is math.nan
# True
#math module NaN
id(math.nan)
# 4538852576
#NaN in the numpy library
id(np.nan)
# 4569389960
```

However, these are able to correctly determine each NaN with a function in a separate library.

```
#Each isnan()NaN can be judged correctly by the function
math.isnan(np.nan) and np.isnan(math.nan)
# True
```

I was curious about what kind of implementation it was, so I checked it.

The implementation of math.nan seems to follow the implementation of C from cpython. I referred to this site for the implementation of C.

- https://ja.cppreference.com/w/c/numeric/math/isnan)

```
#define Py_IS_NAN(X) isnan(X)
```

From NumPy core libraries you can see that it follows the C99 implementation.

.. c:function:: int npy_isnan(x) This is a macro, and is equivalent to C99 isnan: works for single, double and extended precision, and return a non 0 value is x is a NaN.

In other words, the object id is different, but the original implementation is the same in C, so it works the same. Somehow I was expecting it, but I'm glad if I can actually confirm it!

I've reached the limit of the ad-care deadline, but iCould is bad because it also hindered backups and took 3 days to back up about 25G.

Recommended Posts