---
jupytext:
  formats: md:myst
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: Python 3
  language: python
  name: python3
---

# Simple types, variables

```{admonition} Education objectives

- `int`, `bool`, `float`, `complex`, `NoneType`
- `True`, `False`, `None`
- Keyword `is`, `and`, `or` and `not`
- Notions of objects and attributes (with `complex`)

```

## `int` (integers)

```{code-cell}
a = 4
c = -10

# binary notation (base 2)
b = 0b010

# octal notation (base 8)
o = 0o011

# hexadecimal (base 16)
h = 0x1CF0

a = int("1")  # base 10
a = int("111", 2)  # base 2
a = int("70", 8)  # base 8
a = int("16", 16)  # base 16
```

```{note}
`int` in Python 3 are impressive! No limit! See
https://docs.python.org/3.1/whatsnew/3.0.html#integers
```

### Arithmetic operations

```{code-cell}
print(10 + 3)
print(10 - 3)
print(10 * 3)
print(10 / 3)  # float division
print(10 // 3)  # integer division
print(10 % 3)
```

## `bool` (booleans)

```{code-cell}
b = bool("1")
b = False
b = True
```

## `None`, NoneType

`None` is defined globally. The type of `None` is `NoneType`. This variable is typically
used to represent something that is irrelevant, not initialized, ....

`None` evaluates to False.

```{code-cell}
# define a variable nb_students that is not yet defined
nb_students = None
# code that update nb_students
```

### Comparison operations (`bool`)

- `==` equal
- `!=` différent
- `<` inferior
- `<=` inferior or equal
- `>` superior
- `>=` superior or equal

### Keyword `is`: check identity

```{code-cell}
a = None
print(a is None)
print(a is not None)
```

### Keywords `and` and `or`

```{code-cell}
True and True
```

```{code-cell}
True and False
```

```{code-cell}
False and False
```

```{code-cell}
True or True
```

```{code-cell}
True or False
```

```{code-cell}
False or False
```

### `float` (real, double precision) and `complex`

```{code-cell}
# float
a = float("1")
a = 1.234
a = 1e2
a = -1e-2
a = 0.2
```

```{code-cell}
# complex (2 floats)
c = complex("1")
c = 1 + 2j
print(c, c.real, c.imag, c.conjugate())
```

```{note}
Notation `var_name.attr_name` to access to an attribute of an object.
```

:::{admonition} Warning about floating-point arithmetic and numerical errors!
:class: warning

```python
b = 1e16
c = 1.2 + b
d = c - b
print(d)
```

gives `2.0`. It's a very general issue (not Python): see
https://en.wikipedia.org/wiki/Floating-point_arithmetic.
:::
