(4 + 8) * (6.5 - 3)

# división
print(11 / 2)

# División entera, el normal en C, por ejemplo, si el tipo es int
print(11 // 2)

"""
Explanation: Operators and control flow
Operators
Pythons tiene siete operadores básicos:
| Operator     | Name           | Description                                            |
    |--------------|----------------|--------------------------------------------------------|
    | a + b    | Suma       | Suma de a y b                                 |
    | a - b    | Resta    | Resta of a y b                          |
    | a * b    | Multiplicación | Producto of a y b                             |
    | a / b    | División  | Cociente de a y b                            |
    | a // b   | División sin resto | Cociente de a y b, sacando la fracción |
    | a % b    | Modulo        | Resto de la división a por b     |
    | a ** b   | Potencia | a a la b potencia                    |
    | -a       | Negación       | El negativo de a                                  |
    | +a       | Suma unaria     | a no cambia (no sé para qué sirve)                          |
End of explanation
"""


bin(16383)

2**9

hex(20)

"""
Explanation: Ops bitwise
El punto fuerte de las compus son las operaciones sobre enteros. Y los enteros están hechos de bits, asi que hay algunas ops que son más faciles que otras. Esta es la lista de los 6 ops de Python que trabajan con enteros a nivel de bits:
| Operator     | Name            | Description                                 |
    |--------------|-----------------|---------------------------------------------|
    | a &amp; b    | Bitwise AND     | Bits en ambos a y b        |
    | <code>a &#124; b</code>| Bitwise OR      | Bits en a o b or both      |
    | a ^ b    | Bitwise XOR     | Bits en a o b pero no en ambos |
    | a &lt;&lt; b   | Bit shift left  | Desplaza bits de a a la izquierda b posiciones     |
    | a &gt;&gt; b   | Bit shift right | Desplaza bits de a a la derecha b posiciones    |
    | ~a       | Bitwise NOT     | Negación de los bits en 1 de a                          |
JvdP dice que estos operadores son usados mucho menos que los de más arriba. Es cierto, sin embargo, las operaciones sobre bits son indispensables cuando hacemos zip, por ejemplo. Para ver cómo actuan estos operadores, tenemos que saber la representación binaria de los números. En Python podemos hacer eso con la función bin(), que toma un entero como argumento, así:
End of explanation
"""


bin(4)

4 | 10

bin(4 | 10)

bin(1)

"""
Explanation: Como ven, el resultado tiene un 0b al principio, que nos dice que el número es binario (0x, para hexa, supongo). El resto the los números indican  que el número 10 se representa como la suma de $1 \cdot 2^3 + 0 \cdot 2^2 + 1 \cdot 2^1 + 0 \cdot 2^0$.
End of explanation
"""


bin(1<<1)

bin(1<<2)

bin(4)

"""
Explanation: Usualmente son ops mas rápidos que los otros (por ejemplo para potencias de 2!)
End of explanation
"""


a = 24
print(a)

a + 2

print(a)

"""
Explanation: Ops de asignación
Ya vimos como las variables se asignan con el ops =, y los valores se guardan para usarlos despues:
End of explanation
"""


a += 2  # equivalent to a = a + 2
print(a)

"""
Explanation: Es decir, también podríamos querer modificar ese valor con uno nuevo sin perder el anterior.
End of explanation
"""


# 25 is odd
25 % 2 == 1

# 66 is odd
66 % 2 == 1

# check if a is between 15 and 30
a = 25
15 < a < 30

-1 == ~0

"""
Explanation: Esta clase de operación (hasta tiene nombre: acumulador) que Python tiene una lista de operadores de "actualización" (no sé si se llaman así en español... traduje literalmente), uno para cada op de los que vimos más arriba.
|||||
    |-|-|
    |a += b| a -= b|a *= b| a /= b|
    |a //= b| a %= b|a **= b|a &amp;= b|
    |<code>a &#124;= b</code>| a ^= b|a &lt;&lt;= b| a &gt;&gt;= b|
Comparison ops
La otra "casta" de operaciones que es vital para programar es la de comparaciones: las que retornan verdadero (True) o falso (False). Los ops de comparación son listados en la siguiente tabla:
| Operación     | Descripción                       || Operación     | Descripción                          |
    |---------------|-----------------------------------||---------------|--------------------------------------|
    | a == b    | a igual a b              || a != b    | a diferente de b             |
    | a &lt; b     | a menor que b             || a &gt; b     | a mayor que b             |
    | a &lt;= b    | a menor o igual a b || a &gt;= b    | a mayor o igual a b |
End of explanation
"""


x = 4
(x < 6) and (x > 2)

(x > 10) or (x % 2 == 0)

not(x < 6)

"""
Explanation: Twos-complement!
Ops booleanos
Cuando trabajamos con valores booleanos (V o F), Python tiene operadores lógicos especiales para compararlos:
End of explanation
"""


a = [1, 2, 3]
b = [1, 2, 3]

a == b

a is b

a is not b

"""
Explanation: Ops de identidad y membresía (!!)
| Operator      | Description                                       |
|---------------|---------------------------------------------------|
    | a is b    | V si a y b son objetos idénticos     |
    | a is not b| V si a y b no son objetos idénticos |
    | a in b    | V si a está en b                |
    | a not in b| V si a no está en b            |
Ops de identidad: is e is not
Estos operadores chequean si dos objetos son los mismos. Ya se van a acordar del ejemplo de un par de clases anteriores.
End of explanation
"""


a = [1, 2, 3]
b = a
a is b

"""
Explanation: And this is what identical objects look like:
End of explanation
"""


1 in [1, 2, 3]

2 not in [1, 2, 3]

"""
Explanation: En el primer ejemplo las variables están apuntando a objetos diferentes. El op is chequea que los punteros sean los mismos. Tengan cuidado entonces cuando usan is, cuando de verdad van a querer decir ==.
Ops de membresía
Los ops de membresía buscan los valores que nos interesan en objetos complejos, por ejemplo:
End of explanation
"""


