Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Python Content #2979

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Types of change:
### Changed
- [Html - Link Relative Paths - Change part of PQ as it wasn't worder properly](https://github.com/enkidevs/curriculum/pull/2985)
- [Python - Format Text Paragraphs With Textwrap - Make the fill method more clear](https://github.com/enkidevs/curriculum/pull/2981)
- [Python - All Applicable Insights - Move single-line commands to a single line, update indentation in codeblocks from 4 to 2 spaces](https://github.com/enkidevs/curriculum/pull/2979)

## January 4th 2022

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ print(ourString[sObject])
Use `slice` to remove every second number in the list of numbers.

```python
nList = ['1', '2', '3', '4', '5',
'6', '7', '8']
nList = ['1', '2', '3', '4', '5', '6', '7', '8']

sObject = ???(???, ???, ???)
print(nList[sObject])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,9 @@ We have three lists, `fnames`, `lnames`, `locations`, which are ordered so that
Fill in the gaps in the code below to achieve this.

```python
locations = ['IT',
'FR',
'FR',
'RU']
fnames = ['italo',
'jean',
'emily',
'katya']
lnames = ['calvino',
'micheal',
'rambert',
'sokolov']
locations = ['IT', 'FR', 'FR', 'RU']
fnames = ['italo', 'jean', 'emily', 'katya']
lnames = ['calvino', 'micheal', 'rambert', 'sokolov']

result = zip(???, ???)
result2 = zip(???, ???)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ Finally, it's good to know that we can pass more than one iterable `input_list`
Let's say we have a list, called `promises`. We want to `make_good` on all our promises, where `make_good` is a previously-defined function that takes a string. Fill in the blanks in the code below to apply `make_good` to all elements in `promises`.

```python
promises = ['learn css', 'learn js',
'buy milk', 'be excellent to each other']
promises = ['learn css', 'learn js','buy milk', 'be excellent to each other']
promises = ???(???, ???)
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ print(sorted([4, 0, 2, 3, 1, 5]))
What is the result of the execution of the following code snippet?

```python
print(sorted([0, 2, 3, 1,
'a', 'b', 'A', 'B']))
print(sorted([0, 2, 3, 1, 'a', 'b', 'A', 'B']))
```

???
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Now if we print cube_dict, we get:

```python
for k, v in cube_dict.items():
print(k, v)
print(k, v)
# output
# 1 1
# 2 8
Expand All @@ -58,17 +58,17 @@ print(lcase_freqs)
# partial output ...

{'u': 0, 'q': 0, 'w': 0, 'o': 0, \
'b': 0, 'c': 0, 't': 0, 'h': 0, \
'b': 0, 'c': 0, 't': 0, 'h': 0, \
...
'g': 0, 'a': 0, 'n': 0}
# Check it is correct:
lfk = list(lcase_freqs.keys())
lfk.sort()
print(lfk)
['a', 'b', 'c', 'd', 'e', 'f', \
'g', 'h', 'i', 'j', 'k', 'l', \
'm', 'n', 'o', 'p','q', 'r', \
's', 't', 'u', 'v', 'w', 'x', \
'y', 'z']
'g', 'h', 'i', 'j', 'k', 'l', \
'm', 'n', 'o', 'p','q', 'r', \
's', 't', 'u', 'v', 'w', 'x', \
'y', 'z']

```
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ Use list comprehension to add one and divide by two [(x + 1) / 2] for all elemen

```python
l = [1,2,3,4,5]
x = [((x+1)/2) ??? x % 2 \
??? x ??? x in ???]
x = [((x+1)/2) ??? x % 2 ??? x ??? x in ???]
```

- if
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,23 @@ Since a list comprehension can take any **expression** as its initial expression
These are often useful, but are often used to work with matrices.

```python
matrix = [[1, 2, 3], [4, 5, 6], \
[7, 8, 9]]

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```

Say we want to create another matrix with values equal to the squares of each element in the original matrix:

```python
matrix2 = [[x**2 for x in row] for \
row in matrix]
#matrix2 = [[1, 4, 9], [16, 25, 36],\
# [49, 64, 81]]
matrix2 = [[x**2 for x in row] for row in matrix]
#matrix2 = [[1, 4, 9], [16, 25, 36], [49, 64, 81]]
```

A more advanced list comprehension with two for clauses and two if clauses:

```python
lc = [ (x, y) for x in \
range(10) if x % 2 == 0 \
for y in range(20) if \
y % 3 == 0 ]
range(10) if x % 2 == 0 \
for y in range(20) if \
y % 3 == 0 ]
# lc
# [(0, 0), (0, 3), (0, 6), \
# (0, 9), (0, 12), (0, 15), (0, 18),\
Expand All @@ -70,7 +66,6 @@ Use nested list comprehension to generate a list of tuples, where the first elem
Ex: (1,1),(1,2),(1,3),...(9,7),(9,8),(9,9).

```python

l = [??? for x in range(10)\
if ??? for y in ???]
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,19 @@ Imagine we have the following list:

```python
my_list = [1, 2, 3, 4, 5, 6, 7, 8]

```

And we need a set containing only even numbers in the list. This can be easily achieved with **set comprehension**:

```python
even_set = {x for x in my_list if x%2 == 0}

```

We can now check the result:

```python
print(even_set)
# {8, 2, 4, 6}

```

Note that the above operation would work even if my_list contained some duplicate values, e.g:
Expand All @@ -67,10 +64,8 @@ since sets by definition do not allow duplicates.
Fill in the following code snippet. It creates a new set that contains elements of list `l` that are even and adds one and divides by two the odd numbers:

```python

l = [10, 11, 13, 14, 18, 19]
new_set = {x ??? x % 2 == 0 else/
??? for x ??? l}
new_set = {x ??? x % 2 == 0 else ??? for x ??? l}
```

- if
Expand All @@ -88,7 +83,6 @@ new_set = {x ??? x % 2 == 0 else/
What will the `odd_set` look like after we run the following code snippet?

```python

l = [1,3,3,2,4,5,5,8,9]
odd_set = {x for x in l if x % 2}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ If you need to lowercase all the input strings:
```python
lower_list = []
for word in input_list:
lower_list.append(word.lower())
lower_list.append(word.lower())
```

Instead, you can use `map()` to push the loop into compiled C code:
Expand All @@ -47,8 +47,7 @@ lower_list = map(str.lower, input_list)
Also, in Python 2.0 or above, there are list comprehensions. List comprehension are the "pythonic" way to approach this situation. `map()` is more often used in JavaScript. We recommend usage of list comprehension:

```python
lower_list = [word.lower() \
for word in input_list]
lower_list = [word.lower() for word in input_list]
```

They are both more efficient than simple `for` loop statement.
Expand All @@ -63,8 +62,7 @@ Use list comprehension to modify a list of characters such that all its elements
```python
strings = ['a', 'e', 'i', 'o', 'u']

lower_list = [word.??? \
for word in ???]
lower_list = [word.??? for word in ???]
```

- upper()
Expand Down
12 changes: 4 additions & 8 deletions python/functional-programming/decorators/decorators-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ def get_fahrenheit(method):
# methods, pass self as a parameter
def wrapper(self):
# "self" argument is passed
return "{0} F"
.format(method(self) * 1.8 + 32)
return "{0} F".format(method(self) * 1.8 + 32)
return wrapper

class Temperature(object):
Expand All @@ -55,8 +54,7 @@ We got it now working for methods. But what if we are looking to decorate method
def get_fahrenheit(method):
# exepect any number of args/named args
def wrapper(*args, **kwargs):
return "{0} F"
.format(method(*args,**kwargs)*1.8+32)
return "{0} F".format(method(*args,**kwargs)*1.8+32)
return wrapper

class Temperature(object):
Expand All @@ -65,10 +63,8 @@ class Temperature(object):

@get_fahrenheit
#two extra arguments expected here
def get_temp(self, extra1, extra2 = 0,
extra3 = 0):
return self.degrees + extra1 + extra2
+ extra3
def get_temp(self, extra1, extra2 = 0, extra3 = 0):
return self.degrees + extra1 + extra2 + extra3
temp = Temperature(15)
# self is passed by default
print(temp.get_temp(3, extra2 = 1))
Expand Down
12 changes: 4 additions & 8 deletions python/functional-programming/decorators/decorators-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ def say_hello(name):
return "Hello, {0}!".format(name)
def h2_decorate(string_function):
def func_wrapper(name):
return "<h2>{0}</h2>"
.format(string_function(name))
return "<h2>{0}</h2>".format(string_function(name))
return func_wrapper
hello_wrapper = h2_decorate(say_hello)
```
Expand All @@ -37,8 +36,7 @@ We can shorten the code and get rid of the variable assignment by introducing th
```python
def h2_decorate(string_function):
def func_wrapper(name):
return "<h2>{0}</h2>"
.format(string_function(name))
return "<h2>{0}</h2>".format(string_function(name))
return func_wrapper

@h2_decorate
Expand All @@ -55,8 +53,7 @@ As you can see, the function is decorated, without the need of an explicit `h2_d
# variable assignment
def say_hello(name):
return "Hello, {0}!".format(name)
long_wrap =
div_decorate(h2_decorate(say_hello))
long_wrap = div_decorate(h2_decorate(say_hello))
print(long_wrap("Mike"))

# @ notation
Expand All @@ -83,8 +80,7 @@ However, this syntax requires an additional enclosing function, as the **decorat
def tags_wrapper(tag):
def func_decorator(string_function):
def name_wrapper(name):
return "<{0}>{1}</{0}>"
.format(tag, string_function(name))
return "<{0}>{1}</{0}>".format(tag, string_function(name))
return name_wrapper
return func_decorator

Expand Down
6 changes: 2 additions & 4 deletions python/functional-programming/decorators/functools-wraps.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ For example, for the code below:
```python
def h2_decorate(string_function):
def func_wrapper(name):
return "<h2>{0}</h2>" \
.format(string_function(name))
return "<h2>{0}</h2>".format(string_function(name))
return func_wrapper

@h2_decorate
Expand All @@ -53,8 +52,7 @@ from functools import wraps
def h2_decorate(string_function):
@wraps(string_function)
def func_wrapper(name):
return "<h2>{0}</h2>"
.format(string_function(name))
return "<h2>{0}</h2>".format(string_function(name))
return func_wrapper

print(say_hello.__name__)
Expand Down
17 changes: 6 additions & 11 deletions python/functional-programming/decorators/what-are-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ You could always define another function that makes use of `say_hello`:

```python
def hello_heading(name):
return "<h2>{0}</h2>"
.format(say_hello(name))
return "<h2>{0}</h2>".format(say_hello(name))
```

Which is perfectly acceptable, but you'd be giving away the opportunity of making your code extensible. What if you are going to need a `say_goodbye` function, formatted in the same way? You'd have to create two more functions:
Expand All @@ -53,17 +52,15 @@ Which is perfectly acceptable, but you'd be giving away the opportunity of makin
def say_goodbye(name):
return "Goodbye, {0}!".format(name)
def goodbye_heading(name):
return "<h2>{0}</h2>"
.format(say_goodbye(name))
return "<h2>{0}</h2>".format(say_goodbye(name))
```

This is not ideal, since all you had done, for each function, was to **decorate** (enhance, manipulate or extend) their output. What if you could write a function that wraps any function's output in `<h2>` tags?

```python
def h2_decorate(string_function):
def func_wrapper(name):
return "<h2>{0}</h2>"
.format(string_function(name))
return "<h2>{0}</h2>".format(string_function(name))
return func_wrapper
```

Expand All @@ -87,7 +84,7 @@ If you couldn't figure it out, consider that `h2_decorate`'s references to the `

## Practice

The number of similar looking functions that can be decorated using the same decorator is
The number of similar-looking functions that can be decorated using the same decorator is

???

Expand All @@ -108,13 +105,11 @@ def say_hello(name):
return "Hello, {0}!".format(name)
# A
def hello_heading(name):
return "<h2>{0}</h2>"
.format(say_hello(name))
return "<h2>{0}</h2>".format(say_hello(name))
# B
def hello_heading(func):
def func_wrapper(name):
return "<h2>{0}</h2>"
.format(func(name))
return "<h2>{0}</h2>".format(func(name))
return func_wrapper
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,14 @@ A comprehension is an expression where the same flow control keywords used in lo
```python
# without comprehension
for element in list:
if condition1(element) and
condition2(element):
if condition1(element) and condition2(element):
collection.append(element)
else:
new = mutate(element)
collection.append(element)

# with comprehension
collection = [e if condition1(e) and
condition2(e) else
modify(e) for e in list]
collection = [e if condition1(e) and condition2(e) else modify(e) for e in list]
```

As you can clearly see, our code instantly becomes much more legible and comprehensible.
Expand Down
Loading