{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Week 1 Python Intro\n",
"\n",
"Welcome to 02402 Statistics (PG)\n",
"\n",
"During the course we will be presenting and working with Python in jupyter notebooks.\n",
"\n",
"Please work through this notebook to get aquainted. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### First steps using python code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A Jupyter notebook is built from **cells**. There are two kinds:\n",
"\n",
"- **Markdown cells** (like this one) contain text: explanations, instructions, questions. They are not code and cannot be \"run\" in the sense of computing something.\n",
"- **Code cells** contain Python code that gets executed by the computer.\n",
"\n",
"To **run** a cell, first click on it to select it, then press one of:\n",
"\n",
"- **Shift + Enter** — run the cell and jump to the next one (most common)\n",
"- **Ctrl + Enter** (**Cmd + Enter** on Mac) — run the cell and stay on it\n",
"\n",
"You can also run a cell using the \"Run\" button/arrow in the toolbar or sidebar of your editor.\n",
"\n",
"**Try it now:** click on the code cell below (the one containing `2+3`) and press **Shift+Enter**. You should see the result, `5`, appear right under the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"2+3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that Jupyter automatically displayed the result (`5`) even though we never asked to \"print\" anything. This happens because Jupyter automatically shows the value of the **last line** in a code cell. This is a Jupyter convenience — it will not happen if you save the same code in a plain `.py` file and run it elsewhere."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Comments\n",
"\n",
"Code cells can also contain **comments** — notes for humans that Python ignores when running the code. A comment starts with a `#` and runs to the end of the line (so a comment can take up a whole line, or follow real code on the same line).\n",
"\n",
"Try running the code cells below:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This is a comment. Nothing will happen if you run this cell\n",
"\n",
"# 3+3 \n",
"# the line above with \"3 + 3\" is also a comment - so nothing will be evaluated"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# this cell contains comments AND code to be evaluated:\n",
"\n",
"10 + 6\n",
"\n",
"# 4 + 5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"20 + 3 # comments can also appear after (to the right of) actual code. \n",
"\n",
"# In this case the stuff before (to the left of) the \"#-sign\" IS evaluated!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Variables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Just like a pocket calculator, Python can evaluate expressions directly. But usually we want to save a result to use again later. For that we use a **variable**: a name that stores a value.\n",
"\n",
"Run the cell below to create a variable called `x` and give it the value `3`. The `=` sign here means \"assign the value on the right to the name on the left\" — it is not the same as mathematical equality."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Define a variable\n",
"x = 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that the cell above produced **no output** — assigning a value to a variable is a silent action. `x` is not automatically shown, because the assignment `x = 3`, not `x` itself, was the last line.\n",
"\n",
"To see the value stored in a variable, we use the `print()` function:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# print out the value of the variable\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Every value in Python has a **data type** — for example a whole number (`int`), a decimal number (`float`), or text (`str`). We can check the type of a variable with the `type()` function:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(type(x))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Try it yourself:** Scroll back up to the cell where you defined `x = 3` (edit it to say `x = 3.8` instead), then re-run that cell followed by the `print(type(x))` cell above (Shift+Enter through them). What type is `x` now?\n",
"\n",
"Try it once more with `x = 'hello'` (note the quotes — this makes `x` a piece of text, a `str`). What type do you get this time?\n",
"\n",
"Use the empty cell below to jot down or test anything else you're curious about."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# use this cell to experiment"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice how jupyter notebooks work in two **modes**: **command** mode and **edit** mode.
\n",
"\n",
"To enter command mode press **esc**
\n",
"\n",
"To enter edit mode press **enter**
\n",
"\n",
"(you can also use the mouse/clicking for most tasks)\n",
"\n",
"**Tip:** the cell border (or a small bar to its left, depending on your editor) usually changes color/appearance depending on the mode — this tells you whether you're about to *type* into the cell (edit mode) or *act on* the cell, e.g. delete it or move it with the arrow keys (command mode). If you ever see letters appearing in strange places instead of a cell being deleted, you're probably in the wrong mode!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Storing several values: lists\n",
"\n",
"So far `x` has stored a single value. In statistics we almost always work with many observations at once (e.g. a sample of measurements). Python's built-in tool for storing several values in one variable is the **list**."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# define a variable of the data-type \"list\", which can contain several values\n",
"x = [1,4,6,2] "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(type(x))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# lists can contain many different types of data\n",
"x = [1,4,'hello',0.232] \n",
"x"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# what happens if we multiply a list by a number?\n",
"print(x*5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# what if we had chosen a non-integer number?\n",
"print(x*1.2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In conclusion: lists do not behave as vectors.
\n",
"For example multiplication does not operate elementwise.
\n",
"We want to work with a variable type that behave more like a vector (or matrix)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using Numpy for vectors (ndarrays)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Numpy is a **library** (also called a *package*) — a collection of ready-made code that we can bring into our notebook with the `import` keyword. Numpy provides a data type well suited for numerical data: the **array** (technically called an `ndarray`, short for *n-dimensional array*).\n",
"\n",
"By convention, almost everyone imports numpy under the short alias `np` — you will see `import numpy as np` at the top of nearly every notebook in this course."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### import the NUMPY package:\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The numpy library gives you access to a lot of ready-made **numpy functions** by typing `np.some_function()`.\n",
"\n",
"An example is the `np.array()` function, which simply creates a new numpy array (a data type that behaves like a vector)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# store data of student height in variable x (which is now an array, not a list)\n",
"x = np.array([168, 161, 167, 179, 184, 166, 198, 187, 191, 179])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(type(x))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Numpy arrays behave like vectors\n",
"\n",
"Unlike lists, numpy arrays support **elementwise** arithmetic — exactly what we need when working with numerical data. \n",
"\n",
"Let's try the same operations that caused trouble for lists:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# multiply the array by 5 (compare this to the list behaviour earlier!)\n",
"x*5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Every element was multiplied by 5 — numpy arrays behave exactly like mathematical vectors under multiplication, unlike lists."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# now try a non-integer number\n",
"x*1.2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This also works — no error this time! We can do the same with addition, subtraction, division, etc."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# elementwise addition (add 10 cm to every measurement)\n",
"x + 10"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# two arrays of the same length can also be combined elementwise\n",
"x + x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Indexing and slicing\n",
"\n",
"Often we need just one value, or a subset of values, from an array. Python uses **zero-based indexing**: the first element has index `0`, not `1`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# the first element of x\n",
"x[0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# the last element (negative indices count from the end)\n",
"x[-1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# a \"slice\": the first three elements (index 0, 1 and 2 - note index 3 is NOT included)\n",
"x[0:3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### A couple of useful properties"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# how many elements does x have?\n",
"len(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# the \"shape\" of the array (10 elements, in one dimension)\n",
"x.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Well done!\n",
"\n",
"You have now:\n",
"\n",
"- learned how Jupyter cells work (markdown vs. code, running cells, edit vs. command mode)\n",
"- created variables and inspected their type with `type()`\n",
"- used Python **lists**, and discovered their quirky behaviour under `*`\n",
"- switched to **numpy arrays**, which behave correctly as vectors under arithmetic operations\n",
"- indexed and sliced arrays, and read off their length/shape\n",
"\n",
"This is all the Python you need to get started. In the next notebook, `descriptive_statistics.ipynb`, we will use numpy arrays like this one to calculate real descriptive statistics (mean, variance, percentiles, ...) and make our first plots.\n",
"\n",
"If you want to explore further on your own:\n",
"\n",
"- Official Python tutorial: https://docs.python.org/3/tutorial/\n",
"- Numpy quickstart: https://numpy.org/doc/stable/user/quickstart.html"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "pernille",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}