You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 01-Fundamentals.qmd
+10-18Lines changed: 10 additions & 18 deletions
Original file line number
Diff line number
Diff line change
@@ -220,6 +220,16 @@ You can add more key-value pairs via `my_dict[new_key] = new_value` syntax. If t
220
220
sentiment['dog'] = 5
221
221
```
222
222
223
+
### Dictionary vs. List
224
+
225
+
Both data types help you organize values, and they differ how you access the values. You access a list's values via a numerical index, and you access a dictionary's values via a key.
Suppose that you want to do some data recoding. You want to look at the "case_control" column of `simple_df` and change "case" to "experiment" and "control" to "baseline". This correspondence relationship can be stored in a dictionary. You can use the `.replace()` method for Series objects with a dictionary as an input argument.
@@ -314,21 +324,3 @@ isinstance(simple_df, list)
314
324
## Exercises
315
325
316
326
Exercise for week 1 can be found [here](https://colab.research.google.com/drive/1nskVV4XFDVjkN_6OIQJDtDettOEr-n5W?usp=sharing).
317
-
318
-
## Appendix: Why Dictionaries?
319
-
320
-
If we didn't have a tool such as Dictionary, we could have tried to implement the following via Pandas Dataframes:
Besides the cumbersome syntax, it is not very fast: the program has to find which row "joy" is at. Whereas, in the dictionary data structure, the lookup is immediate. The time it takes for dictionary to take a key and retrieve a value *does not depend on the size of the dictionary,* whereas it does for the Dataframe implementation.
Copy file name to clipboardExpand all lines: 02-Iteration.qmd
+49-76Lines changed: 49 additions & 76 deletions
Original file line number
Diff line number
Diff line change
@@ -27,7 +27,7 @@ It turns out that we can iterate over *many* types of data structures in Python.
27
27
28
28
- DataFrame
29
29
30
-
- Ranges (to be introduced in exercises)
30
+
- Ranges
31
31
32
32
- Dictionary
33
33
@@ -62,7 +62,7 @@ for rate in heartrates:
62
62
print("Current heartrate:", rate)
63
63
```
64
64
65
-
Here is what the Python interpretor is doing:
65
+
Here is what the Python interpreter is doing:
66
66
67
67
1. Assign `heartrates` as a list.
68
68
2. Enter For-Loop: `rate` is assigned to the next element of `heartrates`. If it is the first time, `rate` is assigned as the first element of `heartrates`.
@@ -142,110 +142,83 @@ Let's see this example step by step:
142
142
143
143
If it doesn't load properly, here is the [link](https://pythontutor.com/render.html#code=import%20math%0Aheartrates%20%3D%20%5B68,%2054,%2072,%2066,%2090,%20102,%2049%5D%0Aprint%28%22Before%3A%22,%20heartrates%29%0A%0Afor%20index,%20m%20in%20enumerate%28heartrates%29%3A%0A%20%20print%28%22Index%3A%22,%20index,%20%22%20%20%20m%3A%22,%20m%29%0A%20%20heartrates%5Bindex%5D%20%3D%20math.log%28m%29%0A%20%20%23heartrates%5Bindex%5D%20%3D%20math.log%28heartrates%5Bindex%5D%29%20%23this%20is%20okay%20also.%0A%20%20%0Aprint%28%22After%3A%22,%20heartrates%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false).
144
144
145
-
## Conditional Statements
145
+
## For-Loops on other iterable data structures
146
146
147
-
As we iterate through values in a data structure, it is quite common to want to have your code do different things depending on the value. For instance, suppose you are recoding `heartrates`, and the numerical values should be "low" if it is between 0 and 60, "medium" if it is between 60 and 100, "high" if it is above 100, and "unknown" otherwise (when it is below 0 or other data type).
147
+
### Tuple
148
148
149
-
Stepping back, we have been working with a *linear* way of executing code - we have unconditionally executing every line of code in our program. Here, we are create a "control flow" via **conditional statements** in which the your code will run a certain section *if* some conditions are met.
149
+
You can loop through a Tuple just like you did with a List, but remember that you can't modify it!
150
150
151
-
Here is how the syntax looks like for conditional statements:
151
+
### String
152
152
153
-
```
154
-
if <expression1>:
155
-
block of code 1
156
-
elif <expression2>:
157
-
block of code 2
158
-
else:
159
-
block of code 3
160
-
161
-
block of code 4
162
-
```
153
+
You can loop through a String by iterating on each letter within the String.
163
154
164
-
There are three possible ways the code can run:
155
+
```{python}
156
+
message = "I am hungry"
157
+
for text in message:
158
+
print(text)
159
+
```
165
160
166
-
1. If `<expression1>` is evaluated as `True`, then `block of code 1` will be run. When done, it will continue to `block of code 4`.
167
-
2. If `<expression1>` is evaluated as `False`, then it will ask if `<expression2>` is `True` or not. If `True`, then `block of code 2` will be run. When done, it will continue to `block of code 4`.
168
-
3. If `<expression1>` and `<expression2>` are both evaluated as `False`, then `block of code 3` is run. When done, it will continue to `block of code 4`.
161
+
However, Strings are **immutable**, similar to Tuples. So if you iterate via `enumerate()`, you won't be able to modify the original String.
169
162
170
-
An important takeaway is that *only one block of code can be run*.
163
+
### Dictionary
171
164
172
-
Let's see how this apply to the data recoding example. Let's just assume the data we want to recode is just a single value in a variable `rate`, not the entire list `heartrates`:
165
+
When you loop through a Dictionary, you loop through the Keys of the Dictionary:
You don't always need multiple `if`, `elif`, `else` statements when writing conditional statements. In its simplest form, a conditional statement requires only an `if` clause:
173
+
The `.items()` method for Dictionary is similar to the `enumerate()` function: it returns a list of tuples, and within each tuple the first element is a key, and the second element is a value.
191
174
192
175
```{python}
193
-
x = -12
176
+
sentiment.items()
177
+
```
194
178
195
-
if x < 0:
196
-
x = x * -1
197
-
198
-
print(x)
179
+
```{python}
180
+
for key, value in sentiment.items():
181
+
print(key, "corresponds to ", value)
199
182
```
200
183
201
-
Then, you can add an `elif` or `else` statement, if you like. Here's `if`-`elif`:
184
+
### Ranges
202
185
203
-
```{python}
204
-
x = .25
186
+
**Ranges** are a collection of sequential numbers, such as:
205
187
206
-
if x < 0:
207
-
x = x * -1
208
-
elif x >= 0 and x < 1:
209
-
x = 1 / x
210
-
211
-
print(x)
188
+
- 1, 2, 3, 4, 5
212
189
213
-
```
190
+
- 1, 3, 5
214
191
215
-
Here's `if`-`else`. The `in` statement asks whether an element (102) is found in an iterable data structure `heartrates`, and returns `True` if so:
192
+
- 10, 15, 20, 25, 30
216
193
217
-
```{python}
218
-
if 102 in heartrates:
219
-
print("Found 102.")
220
-
else:
221
-
print("Did not find 102.")
222
-
```
194
+
It seems natural to treat Ranges as Lists, but the neat thing about them is that only the bare minimum information is stored: the start, end, and step size. This could be a huge reduction in memory...if you need a sequence of numbers between 1 and 1 million, you can either store all 1 million values in a list, or you can just have a Range that holds the start: 1, the end: 1 million, and the step size: 1. That's a big difference!
223
195
224
-
Finally, let's put the data recoding example within a For-Loop:
196
+
You can create a Range via the following ways:
225
197
226
-
```{python}
227
-
heartrates = [68, 54, 72, 66, 90, 102]
198
+
-`range(stop)` which starts at 0 and ends in `stop` - 1.
199
+
200
+
-`range(start, stop)` which starts at `start` and ends in `stop` - 1
201
+
202
+
-`range(start, stop, step)` which starts at `start` and ends in `stop` - 1, with a step size of `step`.
203
+
204
+
When you create a Range object, it just tells you what the input values you gave it.
To use Ranges in a For-Loop, it's straightforward:
247
217
248
-
If it doesn't load properly, you can find it [here](https://pythontutor.com/render.html#code=heartrates%20%3D%20%5B68,%2054,%2072,%2066,%2090,%20102%5D%0A%0Afor%20index,%20rate%20in%20enumerate%28heartrates%29%3A%0A%20%20if%20rate%20%3E%200%20and%20rate%20%3C%3D%2060%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22low%22%0A%20%20elif%20rate%20%3E%2060%20and%20rate%20%3C%3D%20100%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22medium%22%0A%20%20elif%20rate%20%3E%20100%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22high%22%0A%20%20else%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22unknown%22%0A%20%20%20%20%0Aprint%28heartrates%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false)
As we develop more complex code, it is quite common to want to have your code do different things depending on the value. For instance, suppose you are recoding `heartrates`, and the numerical values should be "low" if it is between 0 and 60, "medium" if it is between 60 and 100, "high" if it is above 100, and "unknown" otherwise (when it is below 0 or other data type).
4
+
5
+
Stepping back, we have been working with a *linear* way of executing code - we have unconditionally executing every line of code in our program. Here, we are create a "control flow" via **conditional statements** in which the your code will run a certain section *if* some conditions are met.
6
+
7
+
Here is how the syntax looks like for conditional statements:
8
+
9
+
```
10
+
if <expression1>:
11
+
block of code 1
12
+
elif <expression2>:
13
+
block of code 2
14
+
else:
15
+
block of code 3
16
+
17
+
block of code 4
18
+
```
19
+
20
+
There are three possible ways the code can run:
21
+
22
+
1. If `<expression1>` is evaluated as `True`, then `block of code 1` will be run. When done, it will continue to `block of code 4`.
23
+
2. If `<expression1>` is evaluated as `False`, then it will ask if `<expression2>` is `True` or not. If `True`, then `block of code 2` will be run. When done, it will continue to `block of code 4`.
24
+
3. If `<expression1>` and `<expression2>` are both evaluated as `False`, then `block of code 3` is run. When done, it will continue to `block of code 4`.
25
+
26
+
An important takeaway is that *only one block of code can be run*.
27
+
28
+
Let's see how this apply to the data recoding example. Let's just assume the data we want to recode is just a single value in a variable `rate`, not the entire list `heartrates`:
29
+
30
+
```{python}
31
+
heartrates = [68, 54, 72, 66, 90, 102, 49]
32
+
33
+
rate = heartrates[0]
34
+
print(rate)
35
+
36
+
if rate > 0 and rate <= 60:
37
+
rate = "low"
38
+
elif rate > 60 and rate <= 100:
39
+
rate = "medium"
40
+
elif rate > 100:
41
+
rate = "high"
42
+
else:
43
+
rate = "unknown"
44
+
45
+
print(rate)
46
+
```
47
+
48
+
You don't always need multiple `if`, `elif`, `else` statements when writing conditional statements. In its simplest form, a conditional statement requires only an `if` clause:
49
+
50
+
```{python}
51
+
x = -12
52
+
53
+
if x < 0:
54
+
x = x * -1
55
+
56
+
print(x)
57
+
```
58
+
59
+
Then, you can add an `elif` or `else` statement, if you like. Here's `if`-`elif`:
60
+
61
+
```{python}
62
+
x = .25
63
+
64
+
if x < 0:
65
+
x = x * -1
66
+
elif x >= 0 and x < 1:
67
+
x = 1 / x
68
+
69
+
print(x)
70
+
71
+
```
72
+
73
+
Here's `if`-`else`. The `in` statement asks whether an element (102) is found in an iterable data structure `heartrates`, and returns `True` if so:
74
+
75
+
```{python}
76
+
if 102 in heartrates:
77
+
print("Found 102.")
78
+
else:
79
+
print("Did not find 102.")
80
+
```
81
+
82
+
Finally, let's put the data recoding example within a For-Loop:
If it doesn't load properly, you can find it [here](https://pythontutor.com/render.html#code=heartrates%20%3D%20%5B68,%2054,%2072,%2066,%2090,%20102%5D%0A%0Afor%20index,%20rate%20in%20enumerate%28heartrates%29%3A%0A%20%20if%20rate%20%3E%200%20and%20rate%20%3C%3D%2060%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22low%22%0A%20%20elif%20rate%20%3E%2060%20and%20rate%20%3C%3D%20100%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22medium%22%0A%20%20elif%20rate%20%3E%20100%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22high%22%0A%20%20else%3A%0A%20%20%20%20heartrates%5Bindex%5D%20%3D%20%22unknown%22%0A%20%20%20%20%0Aprint%28heartrates%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false)
107
+
108
+
## Exercises
109
+
110
+
Exercise for week 3 can be found [here](https://colab.research.google.com/drive/1kPVyALVVn7__x0q6kfE9PKRpGNQgtu0a?usp=sharing).
0 commit comments