├── 03_05.py ├── 03_06.py ├── 03_02.py ├── 03_04.py ├── 04_03.py ├── 03_03.py ├── 02_02.py ├── 02_06.py ├── 02_04.py ├── 02_01.py ├── 02_03.py ├── 02_05.py ├── 04_02.py ├── 03_09.py ├── 03_07.py ├── 03_08.py └── higher-order-functions.py /03_05.py: -------------------------------------------------------------------------------- 1 | numbers_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 | 3 | doubled = [x * 2 for x in numbers_list] 4 | print(doubled) 5 | 6 | evens = [x for x in numbers_list if x % 2 == 0] 7 | print(evens) -------------------------------------------------------------------------------- /03_06.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | numbers_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 4 | 5 | def get_sum(acc, x): 6 | print(f'acc is {acc}, x is {x}') 7 | return acc + x 8 | 9 | sum = reduce(get_sum, numbers_list) 10 | print(sum) -------------------------------------------------------------------------------- /03_02.py: -------------------------------------------------------------------------------- 1 | numbers_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 | 3 | doubled_list = [] 4 | for x in numbers_list: 5 | doubled_list.append(x * 2) 6 | 7 | print(doubled_list) 8 | 9 | def double(x): 10 | return x * 2 11 | 12 | doubled_list_functional = list(map(double, numbers_list)) 13 | print(doubled_list_functional) -------------------------------------------------------------------------------- /03_04.py: -------------------------------------------------------------------------------- 1 | numbers_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 | 3 | add = lambda x, y: x + y 4 | 5 | print(add(2, 3)) 6 | 7 | doubled_numbers = list(map(lambda x: x * 2, numbers_list)) 8 | print(doubled_numbers) 9 | 10 | def create_multiplier(a): 11 | return lambda x: x * a 12 | 13 | double = create_multiplier(2) 14 | print(double(5)) -------------------------------------------------------------------------------- /04_03.py: -------------------------------------------------------------------------------- 1 | def count_down(x): 2 | if x < 0: 3 | print('Done!') 4 | return 5 | print(x) 6 | count_down(x - 1) 7 | 8 | count_down(10) 9 | 10 | def count_up(x, maximum): 11 | if x > maximum: 12 | print('Done!') 13 | return 14 | print(x) 15 | count_up(x + 1, maximum) 16 | 17 | count_up(0, 10) -------------------------------------------------------------------------------- /03_03.py: -------------------------------------------------------------------------------- 1 | numbers_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 | 3 | even_numbers = [] 4 | for x in numbers_list: 5 | if (x % 2 == 0): 6 | even_numbers.append(x) 7 | 8 | print(even_numbers) 9 | 10 | def is_even(x): 11 | return x % 2 == 0 12 | 13 | even_numbers_functional = list(filter(is_even, numbers_list)) 14 | print(even_numbers_functional) -------------------------------------------------------------------------------- /02_02.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def double(x): 4 | return x * 2 5 | 6 | def minus_one(x): 7 | return x - 1 8 | 9 | def squared(x): 10 | return x * x 11 | 12 | function_list = [ 13 | squared, 14 | double, 15 | minus_one, 16 | math.sqrt, 17 | ] 18 | 19 | my_number = 3 20 | 21 | for func in function_list: 22 | my_number = func(my_number) 23 | 24 | print(my_number) -------------------------------------------------------------------------------- /02_06.py: -------------------------------------------------------------------------------- 1 | def divide(x, y): 2 | return x / y 3 | 4 | def second_argument_isnt_zero(func): 5 | def safe_version(*args): 6 | if args[1] == 0: 7 | print('Warning: second argument is zero') 8 | return 9 | return func(*args) 10 | 11 | return safe_version 12 | 13 | divide_safe = second_argument_isnt_zero(divide) 14 | 15 | print(divide_safe(10, 2)) -------------------------------------------------------------------------------- /02_04.py: -------------------------------------------------------------------------------- 1 | def create_printer(): 2 | def printer(): 3 | print('Hello functional!') 4 | 5 | return printer 6 | 7 | my_printer = create_printer() 8 | my_printer() 9 | 10 | def create_multiplier(a): 11 | def multiplier(x): 12 | return x * a 13 | 14 | return multiplier 15 | 16 | double = create_multiplier(2) 17 | triple = create_multiplier(3) 18 | quadruple = create_multiplier(4) 19 | 20 | print(double(5)) 21 | print(triple(6)) 22 | print(quadruple(7)) -------------------------------------------------------------------------------- /02_01.py: -------------------------------------------------------------------------------- 1 | def say_hello(name): 2 | print(f'Hello {name}') 3 | 4 | say_hello_2 = say_hello 5 | say_hello_2('Johnny') 6 | 7 | ENVIRONMENT = 'prod' 8 | 9 | def fetch_data_real(): 10 | print('Doing some very time intensive operations...') 11 | 12 | def fetch_data_fake(): 13 | print('Returning fake data') 14 | return { 15 | 'name': 'Jane Doe', 16 | 'age': 34 17 | } 18 | 19 | fetch_data = fetch_data_real if ENVIRONMENT == 'prod' else fetch_data_fake 20 | 21 | data = fetch_data() -------------------------------------------------------------------------------- /02_03.py: -------------------------------------------------------------------------------- 1 | def add(x, y): 2 | return x + y 3 | 4 | def subtract(x, y): 5 | return x - y 6 | 7 | def combine_2_and_3(func): 8 | return func(2, 3) 9 | 10 | print(combine_2_and_3(min)) 11 | 12 | def combine_names(func): 13 | return func('Shaun', 'Wassell') 14 | 15 | def append_with_space(str1, str2): 16 | return f'{str1} {str2}' 17 | 18 | def get_government_form_notation(first, last): 19 | return f'{last.upper()}, {first.upper()}' 20 | 21 | print(combine_names(get_government_form_notation)) -------------------------------------------------------------------------------- /02_05.py: -------------------------------------------------------------------------------- 1 | def create_printer(): 2 | my_favorite_number = 42 3 | 4 | def printer(): 5 | print(f'My favorite number is {my_favorite_number}') 6 | 7 | return printer 8 | 9 | my_printer = create_printer() 10 | my_printer() 11 | 12 | def create_counter(): 13 | count = 0 14 | 15 | def get_count(): 16 | return count 17 | 18 | def increment(): 19 | nonlocal count 20 | count += 1 21 | 22 | return (get_count, increment) 23 | 24 | get_count, increment = create_counter() 25 | 26 | print(get_count()) 27 | increment() 28 | increment() 29 | print(get_count()) 30 | increment() 31 | increment() 32 | increment() 33 | print(get_count()) -------------------------------------------------------------------------------- /04_02.py: -------------------------------------------------------------------------------- 1 | from functools import partial 2 | 3 | def add(x, y, z): 4 | return x + y + z 5 | 6 | def add_partial(x): 7 | def add_others(y, z): 8 | return x + y + z 9 | 10 | return add_others 11 | 12 | add_5 = add_partial(5) 13 | print(add_5(6, 7)) 14 | 15 | def add_partial_2(x, y): 16 | def add_others(z): 17 | return x + y + z 18 | 19 | return add_others 20 | 21 | add_5_and_6 = add_partial_2(5, 6) 22 | print(add_5_and_6(7)) 23 | 24 | def curry_add(x): 25 | def curry_add_inner(y): 26 | def curry_add_inner_2(z): 27 | return x + y + z 28 | return curry_add_inner_2 29 | return curry_add_inner 30 | 31 | add_5 = curry_add(5) 32 | add_5_and_6 = add_5(6) 33 | print(add_5_and_6(7)) 34 | 35 | print(curry_add(5)(6)(7)) 36 | 37 | add_5 = partial(add, 5) 38 | print(add_5(6, 7)) -------------------------------------------------------------------------------- /03_09.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | employees = [{ 4 | 'name': 'Jane', 5 | 'salary': 90000, 6 | 'job_title': 'developer' 7 | }, { 8 | 'name': 'Bill', 9 | 'salary': 50000, 10 | 'job_title': 'writer' 11 | }, { 12 | 'name': 'Kathy', 13 | 'salary': 120000, 14 | 'job_title': 'executive' 15 | }, { 16 | 'name': 'Anna', 17 | 'salary': 100000, 18 | 'job_title': 'developer' 19 | }, { 20 | 'name': 'Dennis', 21 | 'salary': 95000, 22 | 'job_title': 'developer' 23 | }, { 24 | 'name': 'Albert', 25 | 'salary': 70000, 26 | 'job_title': 'marketing specialist' 27 | }] 28 | 29 | def is_developer(employee): 30 | return employee['job_title'] == 'developer' 31 | 32 | def is_not_developer(employee): 33 | return employee['job_title'] != 'developer' 34 | 35 | def get_salary(employee): 36 | return employee['salary'] 37 | 38 | developer_salaries = [get_salary(x) for x in employees if is_developer(x)] 39 | non_developer_salaries = [get_salary(x) for x in employees if is_not_developer(x)] 40 | 41 | def get_sum(acc, x): 42 | return acc + x 43 | 44 | total_developer_salaries = reduce(get_sum, developer_salaries) 45 | average_developer_salary = total_developer_salaries / len(developer_salaries) 46 | 47 | total_non_developer_salaries = reduce(get_sum, non_developer_salaries) 48 | average_non_developer_salary = total_non_developer_salaries / len(non_developer_salaries) 49 | 50 | print(average_developer_salary) 51 | print(average_non_developer_salary) -------------------------------------------------------------------------------- /03_07.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | employees = [{ 4 | 'name': 'Jane', 5 | 'salary': 90000, 6 | 'job_title': 'developer' 7 | }, { 8 | 'name': 'Bill', 9 | 'salary': 50000, 10 | 'job_title': 'writer' 11 | }, { 12 | 'name': 'Kathy', 13 | 'salary': 120000, 14 | 'job_title': 'executive' 15 | }, { 16 | 'name': 'Anna', 17 | 'salary': 100000, 18 | 'job_title': 'developer' 19 | }, { 20 | 'name': 'Dennis', 21 | 'salary': 95000, 22 | 'job_title': 'developer' 23 | }, { 24 | 'name': 'Albert', 25 | 'salary': 70000, 26 | 'job_title': 'marketing specialist' 27 | }] 28 | 29 | def is_developer(employee): 30 | return employee['job_title'] == 'developer' 31 | 32 | def is_not_developer(employee): 33 | return employee['job_title'] != 'developer' 34 | 35 | developers = list(filter(is_developer, employees)) 36 | non_developers = list(filter(is_not_developer, employees)) 37 | 38 | def get_salary(employee): 39 | return employee['salary'] 40 | 41 | developer_salaries = list(map(get_salary, developers)) 42 | non_developer_salaries = list(map(get_salary, non_developers)) 43 | 44 | def get_sum(acc, x): 45 | return acc + x 46 | 47 | total_developer_salaries = reduce(get_sum, developer_salaries) 48 | average_developer_salary = total_developer_salaries / len(developer_salaries) 49 | 50 | total_non_developer_salaries = reduce(get_sum, non_developer_salaries) 51 | average_non_developer_salary = total_non_developer_salaries / len(non_developer_salaries) 52 | 53 | print(average_developer_salary) 54 | print(average_non_developer_salary) -------------------------------------------------------------------------------- /03_08.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | employees = [{ 4 | 'name': 'Jane', 5 | 'salary': 90000, 6 | 'job_title': 'developer' 7 | }, { 8 | 'name': 'Bill', 9 | 'salary': 50000, 10 | 'job_title': 'writer' 11 | }, { 12 | 'name': 'Kathy', 13 | 'salary': 120000, 14 | 'job_title': 'executive' 15 | }, { 16 | 'name': 'Anna', 17 | 'salary': 100000, 18 | 'job_title': 'developer' 19 | }, { 20 | 'name': 'Dennis', 21 | 'salary': 95000, 22 | 'job_title': 'developer' 23 | }, { 24 | 'name': 'Albert', 25 | 'salary': 70000, 26 | 'job_title': 'marketing specialist' 27 | }] 28 | 29 | def is_developer(employee): 30 | return employee['job_title'] == 'developer' 31 | 32 | def is_not_developer(employee): 33 | return employee['job_title'] != 'developer' 34 | 35 | developers = list(filter(is_developer, employees)) 36 | non_developers = list(filter(is_not_developer, employees)) 37 | 38 | def get_salary(employee): 39 | return employee['salary'] 40 | 41 | developer_salaries = list(map(get_salary, developers)) 42 | non_developer_salaries = list(map(get_salary, non_developers)) 43 | 44 | def get_sum(acc, x): 45 | return acc + x 46 | 47 | total_developer_salaries = reduce(get_sum, developer_salaries) 48 | average_developer_salary = total_developer_salaries / len(developer_salaries) 49 | 50 | total_non_developer_salaries = reduce(get_sum, non_developer_salaries) 51 | average_non_developer_salary = total_non_developer_salaries / len(non_developer_salaries) 52 | 53 | print(average_developer_salary) 54 | print(average_non_developer_salary) -------------------------------------------------------------------------------- /higher-order-functions.py: -------------------------------------------------------------------------------- 1 | def combine(x, y, op): 2 | return op(x, y) 3 | 4 | def add(x, y): 5 | return x + y 6 | 7 | def subtract(x, y): 8 | return x - y 9 | 10 | def polynomial(x, y): 11 | return 2 * x * x + 3 * y 12 | 13 | 14 | def create_printer(): 15 | def printer(): 16 | print('Hello functional!') 17 | 18 | return printer 19 | 20 | # def double(x): 21 | # return x * 2 22 | 23 | # def triple(x): 24 | # return x * 3 25 | 26 | # def quadruple(x): 27 | # return x * 4 28 | 29 | def create_multiplier(y): 30 | def multiplier(x): 31 | return x * y 32 | 33 | return multiplier 34 | 35 | ############################# 36 | 37 | def create_arg_checker(arg_check_func, warning_message): 38 | def arg_checker(func): 39 | def safe_version(*args, **kwargs): 40 | if arg_check_func(*args, **kwargs): 41 | print(f'ARGS: {warning_message}') 42 | return 43 | 44 | return func(*args, **kwargs) 45 | 46 | return safe_version 47 | 48 | return arg_checker 49 | 50 | def second_arg_zero(*args): 51 | return args[1] == 0; 52 | 53 | def first_arg_gt_100(*args): 54 | return args[0] > 100 55 | 56 | @create_arg_checker(second_arg_zero, 'Warning: second arg is zero!') 57 | @create_arg_checker(first_arg_gt_100, 'Warning: first arg is greater than 100') 58 | def divide(x, y): 59 | return x / y 60 | 61 | def name_is_lt_2_chars(*args, **kwargs): 62 | return len(kwargs['name']) < 2 63 | 64 | @create_arg_checker(name_is_lt_2_chars, 'Warning: name arg must be longer than 2 chars') 65 | def create_person(name, age): 66 | return { 67 | 'name': name, 68 | 'age': age, 69 | } 70 | --------------------------------------------------------------------------------