MCS 260 Fall 2020
Emily Dumas
Python is a computer programming language.
Learning Python (version 3.6 or higher) is a key focus of MCS 260.
Most of our discussion of general computer science concepts will be based on the way they are seen and used in Python.
In this course we only use Python 3.
The transition from Python 2 to Python 3 was a major milestone, with incompatible changes.
Python 2 support ended in January 1, 2020.
Humans usually use the decimal number system, also known as base $10$.
In this system there is a $10^0=1$s place, a $10^1=10$s place, a $10^2=100$s place, etc.
There are $10$ digits with values $0, 1, \ldots, 9$.
In decimal, $312$ means: \[ {\color{red}3 \color{green} 1 \color{orange} 2} = {\color{red} 3} \times 10^2 + {\color{green} 1} \times 10^1 + {\color{orange} 2} \times 10^0 \]
For any whole number $b>1$ there is a number system called base $b$ where the place values are $b^0$, $b^1$, $b^2$, etc.
In base $b$ there are $b$ digits with values $0, 1, \ldots, b-1$.
In mathematics, it is common to use a subscript to indicate the base.
So $201_5$ means the base $5$ number with digits $2,0,1$.
In computer science, three non-decimal number systems are often encountered.
The digits are $0$ and $1$. A binary digit is called a bit.
The place values are $1$, $2$, $4$, $8$, $16$, etc.
Example: $1001_2$ means \[ 1\times 8 + 0 \times 4 + 0 \times 2 + 1 \times 1 = 9\]
In Python, binary numbers are indicated by preceding the digits with $\texttt{0b}$.
So the previous example would be written $\texttt{0b1001}$.
We can convert to binary using integer division and remainder.
Integer division
$x /\!/ 2$ means $x$ divided by $2$, discarding the remainer.
e.g.
$7 /\!/ 2 = 3$, $6 /\!/ 2 = 3$.
Remainder
$x \texttt{%} 2$ means the remainder when $x$ is divded by $2$.
$7 \texttt{%}2 = 1$, $6 \texttt{%} 2 = 0$.
To convert a number to binary, just keep track of the remainders when you repeatedly integer-divide by $2$.
$x$ | $x /\!/ 2$ | $x \texttt{%} 2$ |
---|---|---|
$312$ | $156$ | $\color{#F0F}0$ |
$156$ | $78$ | $\color{#F0E}0$ |
$78$ | $39$ | $\color{#F0C}0$ |
$39$ | $19$ | $\color{#F0A}1$ |
$19$ | $9$ | $\color{#F08}1$ |
$9$ | $4$ | $\color{#F06}1$ |
$4$ | $2$ | $\color{#F04}0$ |
$2$ | $1$ | $\color{#F02}0$ |
$1$ | $0$ | $\color{#F00}1$ |
So $312 = \texttt{0b}\color{#F00}{\texttt{1}}\color{#F02}{\texttt{0}}\color{#F04}{\texttt{0}}\color{#F06}{\texttt{1}}\color{#F08}{\texttt{1}}\color{#F0A}{\texttt{1}}\color{#F0C}{\texttt{0}}\color{#F0E}{\texttt{0}}\color{#F0F}{\texttt{0}}$, i.e. $312 = 256 + 32 + 16 + 8$.
Binary is not ideal for human consumption because of its low information density.
e.g. $9754 = \texttt{0b10011000011010}$.
Hexadecimal addresses this, giving a more condensed way of expressing a sequence of bits.
Hexadecimal or hex is a condensed representation of binary, with one symbol for each $4$-bit block.
Each $4$-bit block is just a number between $\texttt{0b0000}=0$ and $\texttt{0b1111}=15$. We use hex digits $0\ldots9$,$A \ldots F$:
Digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Bit block | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
Digit | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|
Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Bit block | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
Hexadecimal or hex is a condensed representation of binary, with one symbol for each $4$-bit block.
Each $4$-bit block is just a number between $\texttt{0b0000}=0$ and $\texttt{0b1111}=15$. We use hex digits $0\ldots9$,$A \ldots F$:
Digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Bit block | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
Digit | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|
Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Bit block | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
In Python notation, hexadecimal numbers begin with $\texttt{0x}$, followed by the digits.
So $\texttt{0x3e}$ means
3 | e | ||
0011 | 1110 | $\longrightarrow$ | $\texttt{0b00111110} = 62$ |
Hexadecimal is also base $16$. Another way to see $\texttt{0x3e}$: \[ \begin{align}\texttt{0x3e} &= \texttt{3} \times 16^1 + \texttt{e} \times 16^0 \\ &= 3 \times 16 + 14 \times 1 = 62 \end{align} \]
Aside: In decimal we sometimes separate groups of digits with punctuation for easier reading.
e.g. in the USA one million is often written "$1,\!000,\!000$".
In Python notation the underscore "$\texttt{_}$" can be used as a separator.
\[ \begin{align}\texttt{0b1111_0100_0010_0100_0000} &= \texttt{0xf4240}\\ &= \texttt{1_000_000} \end{align}\]
When converting binary to hex, the number of bits may not be a multiple of $4$ at first. In this case we need to add some zeros on the left:
\[\texttt{0b10101} = \texttt{0b00010101} = \texttt{0b0001_0101} = \texttt{0x15}\]
To convert a decimal number to hex, one way is to convert to binary and group bits.
An alternative is to repeatedly integer-divide by $16$ and use the remainders:
$x$ | $x /\!/ 16$ | $x \texttt{%} 16$ |
---|---|---|
$62$ | $3$ | $\color{#F0F}{14}$ |
$3$ | $0$ | $\color{#F00}3$ |
Therefore $62 = \texttt{0x}\color{#F00}{\texttt{3}}\color{#F0F}{\texttt{e}}$
Octal or base $8$ is similar but we divide a binary number into blocks of $3$ bits, to using $0, \ldots, 7$ to represent blocks of $3$ bits.
In Python notation, octal numbers begin with $\texttt{0o}$ followed by the digits.
(That's numeral zero followed by lower case letter o.)
Example: $\texttt{0o775} = \texttt{0b111_111_101} = 509$
Octal is most commonly seen when setting file permissions on unix/Linux, where $9$ bits are naturally divided into $3$ groups of $3$.
e.g.
chmod 600 secrets.dat