Skip to content

Commit 45eebec

Browse files
Merge pull request #5 from neuroinformatics-unit/small-cleanups
2 parents 615c34b + b153629 commit 45eebec

9 files changed

+119
-41
lines changed

index.qmd

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ format:
6060
## Schedule {.smaller}
6161
::: {.incremental}
6262
* Recap and Q&A
63-
* Using third party libraries from pip and conda
6463
* Functions and methods
6564
* Classes and objects
6665
* Errors and exceptions
66+
* Integrated Development Environments (IDEs)
67+
* Virtual environments
68+
* Modules and packages
6769
* Organising your code
6870
* Documenting your code
6971
:::
@@ -82,6 +84,39 @@ format:
8284
Please ask any **questions at any time**!
8385
:::
8486

87+
# Installation
88+
89+
## Install miniforge {.smaller}
90+
91+
[Click here to go to the download page](https://conda-forge.org/download/)
92+
93+
94+
Add Miniforge to PATH when prompted during installation.
95+
96+
![](img/miniforge_window_add_to_path.png){width="25%" fig-align="center"}
97+
98+
Try the below in either your terminal (Mac/Linux) or Miniconda Prompt (Windows):
99+
```bash
100+
conda --version
101+
```
102+
103+
::: {.callout-caution collapse="true"}
104+
## Windows troubleshooting
105+
- Did you had a previous version of Anaconda installed? You might need to uninstall it first.
106+
- `conda not found`? Run `conda init` in your terminal.
107+
:::
108+
109+
## Install an IDE {.smaller}
110+
111+
::: {.fragment .fade-in}
112+
* [Visual Studio Code](https://code.visualstudio.com/download) - customisable, extensible, open source
113+
* [PyCharm](https://www.jetbrains.com/pycharm/download/) - opinionated defaults, not fully free (free for educational use)
114+
:::
115+
116+
## Install a text editor (macOS) {.smaller}
117+
* [Sublime Text](https://www.sublimetext.com/) - lightweight text editor
118+
* Windows can use the built-in Notepad or [Notepad++](https://notepad-plus-plus.org/downloads/)
119+
85120
# Why learn Python?
86121

87122
## Why learn Python? {.smaller}

slides/basics.qmd

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ print(y)
5151
```
5252

5353
## Data types
54-
::: {.fragment .incremental .smaller}
54+
::: {.incremental style="font-size: 80%;"}
5555
* Different kinds of data are stored in different ways in memory
5656
* You can use the `type()` function to find out what type of data a variable contains
5757
:::
@@ -159,6 +159,7 @@ print(1 + 2.1)
159159
::: {.fragment .fade-in}
160160
* What about an **int** and a **str**?
161161
<br/>
162+
162163
```{python}
163164
#| echo: true
164165
#| output-location: fragment
@@ -298,11 +299,21 @@ my_tuple = (1, 2.0, 'cat', 'dog')
298299
299300
print(type(my_tuple))
300301
print(my_tuple[2])
301-
302-
my_tuple[2] = 'rabbit'
303302
```
304303
::::
305304
:::
305+
306+
<br/>
307+
308+
:::: {.fragment .fade-in}
309+
```{python}
310+
#| echo: true
311+
#| output-location: fragment
312+
#| error: true
313+
my_tuple[2] = 'new_element'
314+
print(my_tuple)
315+
```
316+
::::
306317
:::::
307318

308319
## Unpacking {.smaller}
@@ -479,6 +490,10 @@ for i in range(5):
479490
* You can loop over any iterable
480491
* Use `_` if you don't need the loop variable
481492
* `enumerate()` gives you the index and the value
493+
* `range()` generates a sequence of numbers
494+
+ `range(n)` from 0 to n-1
495+
+ `range(a, b)` from a to b-1
496+
+ `range(a, b, step)` from a to b-1 with jumps of step
482497
:::
483498
::: {.column width="45%"}
484499
:::: {.fragment .fade-in}

slides/classes_and_objects.qmd

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,19 @@ file_obj.close()
4444
```{python}
4545
#| echo: true
4646
#| output-location: fragment
47-
#| code-line-numbers: "|1|2,3|5|6|"
47+
#| code-line-numbers: "|1|2,3|5,6|8,9|10|11|"
4848
4949
class Animal():
5050
def __init__(self, species):
5151
self.species = species
5252
53+
def greet(self):
54+
print(f"Hello, I am a {self.species}.")
55+
5356
pingu = Animal("penguin")
57+
print(type(pingu))
5458
print(pingu.species)
59+
pingu.greet()
5560
```
5661
:::::
5762
:::
@@ -73,13 +78,16 @@ pingu.make_noise() # Output: noot
7378
```{python}
7479
#| echo: true
7580
#| output-location: fragment
76-
#| code-line-numbers: "|2|2,4|6,7|"
81+
#| code-line-numbers: "|2|2,4|9,10|"
7782
7883
class Animal():
7984
def __init__(self, species, noise):
8085
self.species = species
8186
self.noise = noise
8287
88+
def greet(self):
89+
print(f"{self.noise}, I am a {self.species}.")
90+
8391
def make_noise(self):
8492
print(self.noise)
8593

slides/errors_and_exceptions.qmd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ a_list[5]
9494
::::
9595

9696
## Tracebacks {.smaller}
97+
::: {.incremental}
9798
* Help you find the source of the error
9899
* Read from the bottom up
99100
* Look for the last line that is *your* code
100101
* [Debugging manifesto](https://wizardzines.com/images/debugging-manifesto.pdf) :bug:
102+
:::
101103

102104
## Tracebacks {.smaller}
103105
```{python}
@@ -115,6 +117,22 @@ def call_func(x):
115117
z = call_func(10)
116118
```
117119

120+
## Tracebacks {.smaller}
121+
```{python}
122+
#| echo: true
123+
#| output-location: fragment
124+
#| error: true
125+
126+
def none_function():
127+
return None
128+
129+
def get_file_name():
130+
return none_function()
131+
132+
file_name = none_function()
133+
open_file = open(file_name)
134+
```
135+
118136
## Handling exceptions {.smaller}
119137
* What if you know an error might happen?
120138

slides/first_script.qmd

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@
66
* `Scripts` (.py)
77
:::
88

9-
::: {.fragment .fade-in}
10-
Demo time! 🧑🏻‍💻👩🏻‍💻
11-
:::
12-
13-
149

1510
## Writing your first Python script
1611

@@ -19,5 +14,5 @@ Demo time! 🧑🏻‍💻👩🏻‍💻
1914
:::
2015

2116
::: {.fragment .fade-in}
22-
![](/img/your_first_script.png){width=70%}
17+
![](/img/your_first_script.png){width=70% fig-align="center"}
2318
:::

slides/functions.qmd

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ print(y)
5353
* Functions allow you to:
5454
+ Reuse code
5555
+ Break problems into smaller pieces
56-
+ Scope defined by indentation
56+
* Scope defined by indentation
5757
* Defined using the `def` keyword
5858
* Can take inputs (arguments) and return outputs
5959
:::
@@ -101,6 +101,7 @@ def is_valid_password(password):
101101
```{python}
102102
#| echo: true
103103
#| output-location: fragment
104+
#| code-line-numbers: "|1|2,3|4,5|"
104105
def is_valid_password(password):
105106
if len(password) >= 8:
106107
return True
@@ -215,7 +216,7 @@ def longer_string(str1, str2=""):
215216
```{python}
216217
#| echo: true
217218
#| output-location: fragment
218-
#| code-line-numbers: "|1|2,4|"
219+
#| code-line-numbers: "|1|2,3|4,5|7|"
219220
220221
def longer_string(str1, str2=""):
221222
if len(str1) > len(str2):
@@ -225,8 +226,8 @@ def longer_string(str1, str2=""):
225226
226227
print(long_str)
227228
228-
print(longer_string("apple", "banana"))
229-
print(longer_string("apple"))
229+
longer_string("apple", "banana")
230+
longer_string("apple")
230231
```
231232

232233
## Using `*` and `**` {.smaller}
@@ -241,26 +242,42 @@ print(longer_string("apple"))
241242
```{python}
242243
#| echo: true
243244
#| output-location: fragment
245+
#| code-line-numbers: "|1|2,3|5,6|8,9|11,12|"
244246
def my_func(*args, **kwargs):
245-
print(f"Unpacking list: {args}")
246-
print(f"Unpacking dictionary: {kwargs}")
247+
print(f"Unpacking positional arguments: {args}")
248+
print(f"Unpacking keyword arguments: {kwargs}")
247249
248250
my_list = [1, 2, 3, 4, 5]
249251
my_dict = {'a': 1, 'b': 2, 'c': 3}
250252
251-
print("Unpacking list:")
252253
my_func(*my_list)
253254
254-
print("Unpacking dictionary:")
255255
my_func(**my_dict)
256256
```
257257
:::
258258

259+
## Using `*` and `**` {.smaller}
260+
261+
::: {.fragment .fade-in}
262+
```{python}
263+
#| echo: true
264+
#| output-location: fragment
265+
def my_func(*args, **kwargs):
266+
print(f"Unpacking positional arguments: {args}")
267+
print(f"Unpacking keyword arguments: {kwargs}")
268+
269+
my_func(1, 'a', 3.14)
270+
my_func(name="John", age=30)
271+
my_func(1, 2, 3, name="Jane", city="New York")
272+
```
273+
:::
274+
259275
## How are `*args` and `**kwargs` useful? {.smaller}
260276
:::: {.columns}
261277
::: {.column width="55%"}
262278
::: {.incremental .smaller}
263-
* `*args` and `**kwargs` are useful when you don't know how many arguments will be passed to the function
279+
* `*args` and `**kwargs` are useful when you don't know which arguments will be passed to the function
280+
* Or when you wrap another function and want to pass all arguments to the wrapped function
264281
:::
265282

266283
:::

slides/interactive_python.qmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ Demo time! 🧑🏻‍💻👩🏻‍💻
1515
:::
1616

1717
::: {.fragment .fade-in}
18-
![](/img/interactive_python.png){width=80%}
18+
![](/img/interactive_python.png){width=70% fig-align="center"}
1919
:::
2020

slides/loading_and_saving.qmd

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ print(contents)
6060
:::::
6161

6262
## Demo
63-
* Write a script that saves the below data to a comma-separated file
63+
* Let's write a script that saves the below data to a comma-separated file
6464

6565
```{python}
6666
#| echo: true
@@ -71,16 +71,17 @@ samples = [(0, 12, 53), (1, 7, 23), (2, 15, 30)]
7171
## Demo
7272
```{python}
7373
#| echo: true
74+
#| code-line-numbers: "|4|5,6|8|9,10|8,11|"
7475
column_labels = "sample_id,speed,distance"
7576
samples = [(0, 12, 53), (1, 7, 23), (2, 15, 30)]
7677
77-
with open("out.csv", "w") as file:
78-
file.write(column_labels)
79-
file.write("\n")
78+
with open("out.csv", "w") as data_file:
79+
data_file.write(column_labels)
80+
data_file.write("\n")
8081
8182
for sample in samples:
8283
for value in sample:
83-
file.write(str(value) + ",")
84-
file.write("\n")
84+
data_file.write(str(value) + ",")
85+
data_file.write("\n")
8586
```
8687

slides/virtual_environments.qmd

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## Scientific Python ecosystem {.smaller}
2-
![Diagram showing the scientific Python ecosystem.](/img/python-ecosystem.png)
2+
![](/img/python-ecosystem.png){alt="Scientific Python ecosystem"}
33

44
::: footer
55
[Aaron Meurer, ‘Python Array API Standard’, SciPy 2023](https://www.youtube.com/watch?v=16rB-fosAWw)
@@ -17,7 +17,7 @@
1717

1818
## Virtual environments {.smaller}
1919

20-
![[Comic from xkcd](https://xkcd.com/1987/)](https://imgs.xkcd.com/comics/python_environment.png){width="20%"}
20+
![[](https://xkcd.com/1987/)](https://imgs.xkcd.com/comics/python_environment.png){width="20%" alt="xkcd comic about Python environments"}
2121

2222
## Virtual environments {.smaller}
2323

@@ -59,17 +59,6 @@
5959
- Future you (HPC, etc...)
6060
:::
6161

62-
## Install miniforge
63-
64-
[Click here to go to the download page](https://conda-forge.org/download/)
65-
66-
::: {.callout-caution collapse="true"}
67-
## Windows troubleshooting
68-
- Did you had a previous version of Anaconda installed? You might need to uninstall it first.
69-
- ![Remember to add Miniforge to your PATH! The installer will say is not required, but it is!](img/miniforge_window_add_to_path.png){width="25%"}
70-
- `conda not found`? Run `conda init` in your terminal.
71-
:::
72-
7362
## Environment management
7463

7564
In your terminal (use Anaconda Prompt on Windows):

0 commit comments

Comments
 (0)