diff --git a/index.qmd b/index.qmd
index 06d0966..de9f2d3 100644
--- a/index.qmd
+++ b/index.qmd
@@ -60,10 +60,12 @@ format:
## Schedule {.smaller}
::: {.incremental}
* Recap and Q&A
-* Using third party libraries from pip and conda
* Functions and methods
* Classes and objects
* Errors and exceptions
+* Integrated Development Environments (IDEs)
+* Virtual environments
+* Modules and packages
* Organising your code
* Documenting your code
:::
@@ -82,6 +84,39 @@ format:
Please ask any **questions at any time**!
:::
+# Installation
+
+## Install miniforge {.smaller}
+
+[Click here to go to the download page](https://conda-forge.org/download/)
+
+
+Add Miniforge to PATH when prompted during installation.
+
+{width="25%" fig-align="center"}
+
+Try the below in either your terminal (Mac/Linux) or Miniconda Prompt (Windows):
+```bash
+conda --version
+```
+
+::: {.callout-caution collapse="true"}
+## Windows troubleshooting
+- Did you had a previous version of Anaconda installed? You might need to uninstall it first.
+- `conda not found`? Run `conda init` in your terminal.
+:::
+
+## Install an IDE {.smaller}
+
+::: {.fragment .fade-in}
+* [Visual Studio Code](https://code.visualstudio.com/download) - customisable, extensible, open source
+* [PyCharm](https://www.jetbrains.com/pycharm/download/) - opinionated defaults, not fully free (free for educational use)
+:::
+
+## Install a text editor (macOS) {.smaller}
+* [Sublime Text](https://www.sublimetext.com/) - lightweight text editor
+* Windows can use the built-in Notepad or [Notepad++](https://notepad-plus-plus.org/downloads/)
+
# Why learn Python?
## Why learn Python? {.smaller}
diff --git a/slides/basics.qmd b/slides/basics.qmd
index 5ae84ca..41e8e1f 100644
--- a/slides/basics.qmd
+++ b/slides/basics.qmd
@@ -51,7 +51,7 @@ print(y)
```
## Data types
-::: {.fragment .incremental .smaller}
+::: {.incremental style="font-size: 80%;"}
* Different kinds of data are stored in different ways in memory
* You can use the `type()` function to find out what type of data a variable contains
:::
@@ -159,6 +159,7 @@ print(1 + 2.1)
::: {.fragment .fade-in}
* What about an **int** and a **str**?
+
```{python}
#| echo: true
#| output-location: fragment
@@ -298,11 +299,21 @@ my_tuple = (1, 2.0, 'cat', 'dog')
print(type(my_tuple))
print(my_tuple[2])
-
-my_tuple[2] = 'rabbit'
```
::::
:::
+
+
+
+:::: {.fragment .fade-in}
+```{python}
+#| echo: true
+#| output-location: fragment
+#| error: true
+my_tuple[2] = 'new_element'
+print(my_tuple)
+```
+::::
:::::
## Unpacking {.smaller}
@@ -479,6 +490,10 @@ for i in range(5):
* You can loop over any iterable
* Use `_` if you don't need the loop variable
* `enumerate()` gives you the index and the value
+* `range()` generates a sequence of numbers
+ + `range(n)` from 0 to n-1
+ + `range(a, b)` from a to b-1
+ + `range(a, b, step)` from a to b-1 with jumps of step
:::
::: {.column width="45%"}
:::: {.fragment .fade-in}
diff --git a/slides/classes_and_objects.qmd b/slides/classes_and_objects.qmd
index 45b2e79..40f2377 100644
--- a/slides/classes_and_objects.qmd
+++ b/slides/classes_and_objects.qmd
@@ -44,14 +44,19 @@ file_obj.close()
```{python}
#| echo: true
#| output-location: fragment
-#| code-line-numbers: "|1|2,3|5|6|"
+#| code-line-numbers: "|1|2,3|5,6|8,9|10|11|"
class Animal():
def __init__(self, species):
self.species = species
+ def greet(self):
+ print(f"Hello, I am a {self.species}.")
+
pingu = Animal("penguin")
+print(type(pingu))
print(pingu.species)
+pingu.greet()
```
:::::
:::
@@ -73,13 +78,16 @@ pingu.make_noise() # Output: noot
```{python}
#| echo: true
#| output-location: fragment
-#| code-line-numbers: "|2|2,4|6,7|"
+#| code-line-numbers: "|2|2,4|9,10|"
class Animal():
def __init__(self, species, noise):
self.species = species
self.noise = noise
+ def greet(self):
+ print(f"{self.noise}, I am a {self.species}.")
+
def make_noise(self):
print(self.noise)
diff --git a/slides/errors_and_exceptions.qmd b/slides/errors_and_exceptions.qmd
index 22a1b3d..b2bd0c7 100644
--- a/slides/errors_and_exceptions.qmd
+++ b/slides/errors_and_exceptions.qmd
@@ -94,10 +94,12 @@ a_list[5]
::::
## Tracebacks {.smaller}
+::: {.incremental}
* Help you find the source of the error
* Read from the bottom up
* Look for the last line that is *your* code
* [Debugging manifesto](https://wizardzines.com/images/debugging-manifesto.pdf) :bug:
+:::
## Tracebacks {.smaller}
```{python}
@@ -115,6 +117,22 @@ def call_func(x):
z = call_func(10)
```
+## Tracebacks {.smaller}
+```{python}
+#| echo: true
+#| output-location: fragment
+#| error: true
+
+def none_function():
+ return None
+
+def get_file_name():
+ return none_function()
+
+file_name = none_function()
+open_file = open(file_name)
+```
+
## Handling exceptions {.smaller}
* What if you know an error might happen?
diff --git a/slides/first_script.qmd b/slides/first_script.qmd
index c99fc28..60672f2 100644
--- a/slides/first_script.qmd
+++ b/slides/first_script.qmd
@@ -6,11 +6,6 @@
* `Scripts` (.py)
:::
-::: {.fragment .fade-in}
-Demo time! π§π»βπ»π©π»βπ»
-:::
-
-
## Writing your first Python script
@@ -19,5 +14,5 @@ Demo time! π§π»βπ»π©π»βπ»
:::
::: {.fragment .fade-in}
-{width=70%}
+{width=70% fig-align="center"}
:::
\ No newline at end of file
diff --git a/slides/functions.qmd b/slides/functions.qmd
index 626dc57..15ed1a4 100644
--- a/slides/functions.qmd
+++ b/slides/functions.qmd
@@ -53,7 +53,7 @@ print(y)
* Functions allow you to:
+ Reuse code
+ Break problems into smaller pieces
- + Scope defined by indentation
+* Scope defined by indentation
* Defined using the `def` keyword
* Can take inputs (arguments) and return outputs
:::
@@ -101,6 +101,7 @@ def is_valid_password(password):
```{python}
#| echo: true
#| output-location: fragment
+#| code-line-numbers: "|1|2,3|4,5|"
def is_valid_password(password):
if len(password) >= 8:
return True
@@ -215,7 +216,7 @@ def longer_string(str1, str2=""):
```{python}
#| echo: true
#| output-location: fragment
-#| code-line-numbers: "|1|2,4|"
+#| code-line-numbers: "|1|2,3|4,5|7|"
def longer_string(str1, str2=""):
if len(str1) > len(str2):
@@ -225,8 +226,8 @@ def longer_string(str1, str2=""):
print(long_str)
-print(longer_string("apple", "banana"))
-print(longer_string("apple"))
+longer_string("apple", "banana")
+longer_string("apple")
```
## Using `*` and `**` {.smaller}
@@ -241,26 +242,42 @@ print(longer_string("apple"))
```{python}
#| echo: true
#| output-location: fragment
+#| code-line-numbers: "|1|2,3|5,6|8,9|11,12|"
def my_func(*args, **kwargs):
- print(f"Unpacking list: {args}")
- print(f"Unpacking dictionary: {kwargs}")
+ print(f"Unpacking positional arguments: {args}")
+ print(f"Unpacking keyword arguments: {kwargs}")
my_list = [1, 2, 3, 4, 5]
my_dict = {'a': 1, 'b': 2, 'c': 3}
-print("Unpacking list:")
my_func(*my_list)
-print("Unpacking dictionary:")
my_func(**my_dict)
```
:::
+## Using `*` and `**` {.smaller}
+
+::: {.fragment .fade-in}
+```{python}
+#| echo: true
+#| output-location: fragment
+def my_func(*args, **kwargs):
+ print(f"Unpacking positional arguments: {args}")
+ print(f"Unpacking keyword arguments: {kwargs}")
+
+my_func(1, 'a', 3.14)
+my_func(name="John", age=30)
+my_func(1, 2, 3, name="Jane", city="New York")
+```
+:::
+
## How are `*args` and `**kwargs` useful? {.smaller}
:::: {.columns}
::: {.column width="55%"}
::: {.incremental .smaller}
-* `*args` and `**kwargs` are useful when you don't know how many arguments will be passed to the function
+* `*args` and `**kwargs` are useful when you don't know which arguments will be passed to the function
+* Or when you wrap another function and want to pass all arguments to the wrapped function
:::
:::
diff --git a/slides/interactive_python.qmd b/slides/interactive_python.qmd
index 9c143f6..ebbd283 100644
--- a/slides/interactive_python.qmd
+++ b/slides/interactive_python.qmd
@@ -15,6 +15,6 @@ Demo time! π§π»βπ»π©π»βπ»
:::
::: {.fragment .fade-in}
-{width=80%}
+{width=70% fig-align="center"}
:::
diff --git a/slides/loading_and_saving.qmd b/slides/loading_and_saving.qmd
index 7dcec8f..73b41e5 100644
--- a/slides/loading_and_saving.qmd
+++ b/slides/loading_and_saving.qmd
@@ -60,7 +60,7 @@ print(contents)
:::::
## Demo
-* Write a script that saves the below data to a comma-separated file
+* Let's write a script that saves the below data to a comma-separated file
```{python}
#| echo: true
@@ -71,16 +71,17 @@ samples = [(0, 12, 53), (1, 7, 23), (2, 15, 30)]
## Demo
```{python}
#| echo: true
+#| code-line-numbers: "|4|5,6|8|9,10|8,11|"
column_labels = "sample_id,speed,distance"
samples = [(0, 12, 53), (1, 7, 23), (2, 15, 30)]
-with open("out.csv", "w") as file:
- file.write(column_labels)
- file.write("\n")
+with open("out.csv", "w") as data_file:
+ data_file.write(column_labels)
+ data_file.write("\n")
for sample in samples:
for value in sample:
- file.write(str(value) + ",")
- file.write("\n")
+ data_file.write(str(value) + ",")
+ data_file.write("\n")
```
diff --git a/slides/virtual_environments.qmd b/slides/virtual_environments.qmd
index dfef719..06bcaf4 100644
--- a/slides/virtual_environments.qmd
+++ b/slides/virtual_environments.qmd
@@ -1,5 +1,5 @@
## Scientific Python ecosystem {.smaller}
-
+{alt="Scientific Python ecosystem"}
::: footer
[Aaron Meurer, βPython Array API Standardβ, SciPy 2023](https://www.youtube.com/watch?v=16rB-fosAWw)
@@ -17,7 +17,7 @@
## Virtual environments {.smaller}
-](https://imgs.xkcd.com/comics/python_environment.png){width="20%"}
+](https://imgs.xkcd.com/comics/python_environment.png){width="20%" alt="xkcd comic about Python environments"}
## Virtual environments {.smaller}
@@ -59,17 +59,6 @@
- Future you (HPC, etc...)
:::
-## Install miniforge
-
-[Click here to go to the download page](https://conda-forge.org/download/)
-
-::: {.callout-caution collapse="true"}
-## Windows troubleshooting
-- Did you had a previous version of Anaconda installed? You might need to uninstall it first.
-- {width="25%"}
-- `conda not found`? Run `conda init` in your terminal.
-:::
-
## Environment management
In your terminal (use Anaconda Prompt on Windows):