From a4086017c3b875648941a91c77b5e8da599a8f83 Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Fri, 13 Sep 2024 18:37:01 +0200 Subject: [PATCH 1/5] Sample code for the article on closures --- python-closure/README.md | 3 +++ python-closure/app.py | 25 +++++++++++++++++++++++++ python-closure/appender.py | 8 ++++++++ python-closure/closure.py | 16 ++++++++++++++++ python-closure/counter.py | 9 +++++++++ python-closure/cum_average.py | 8 ++++++++ python-closure/decorators.py | 12 ++++++++++++ python-closure/free_variables.py | 11 +++++++++++ python-closure/inner.py | 7 +++++++ python-closure/memoization.py | 27 +++++++++++++++++++++++++++ python-closure/roots.py | 28 ++++++++++++++++++++++++++++ python-closure/stack_class.py | 12 ++++++++++++ python-closure/stack_closure.py | 15 +++++++++++++++ 13 files changed, 181 insertions(+) create mode 100644 python-closure/README.md create mode 100644 python-closure/app.py create mode 100644 python-closure/appender.py create mode 100644 python-closure/closure.py create mode 100644 python-closure/counter.py create mode 100644 python-closure/cum_average.py create mode 100644 python-closure/decorators.py create mode 100644 python-closure/free_variables.py create mode 100644 python-closure/inner.py create mode 100644 python-closure/memoization.py create mode 100644 python-closure/roots.py create mode 100644 python-closure/stack_class.py create mode 100644 python-closure/stack_closure.py diff --git a/python-closure/README.md b/python-closure/README.md new file mode 100644 index 0000000000..ce9c6018e3 --- /dev/null +++ b/python-closure/README.md @@ -0,0 +1,3 @@ +# Python Closures: Common Use Cases and Examples + +This folder provides the code examples for the Real Python tutorial [Python Closures: Common Use Cases and Examples](https://realpython.com/python-closure/). diff --git a/python-closure/app.py b/python-closure/app.py new file mode 100644 index 0000000000..c9368b3824 --- /dev/null +++ b/python-closure/app.py @@ -0,0 +1,25 @@ +import tkinter as tk + +app = tk.Tk() +app.title("GUI App") +app.geometry("200x60") + +label = tk.Label(app, font=("Helvetica", 16, "bold")) +label.pack() + + +def callback(text): + def closure(): + label.config(text=text) + + return closure + + +button = tk.Button( + app, + text="Greet", + command=callback("Hello, World!"), +) +button.pack() + +app.mainloop() diff --git a/python-closure/appender.py b/python-closure/appender.py new file mode 100644 index 0000000000..b179e52668 --- /dev/null +++ b/python-closure/appender.py @@ -0,0 +1,8 @@ +def make_appender(): + items = [] + + def appender(new_item): + items.append(new_item) + return items + + return appender diff --git a/python-closure/closure.py b/python-closure/closure.py new file mode 100644 index 0000000000..ce99e3f69e --- /dev/null +++ b/python-closure/closure.py @@ -0,0 +1,16 @@ +# def outer_func(): +# name = "Pythonista" + +# def inner_func(): +# print(f"Hello, {name}!") + +# return inner_func + + +def outer_func(): + name = "Pythonista" + return lambda name=name: print(f"Hello, {name}!") + + +inner_func = outer_func() +inner_func() diff --git a/python-closure/counter.py b/python-closure/counter.py new file mode 100644 index 0000000000..a2dac3d68e --- /dev/null +++ b/python-closure/counter.py @@ -0,0 +1,9 @@ +def make_counter(): + count = 0 + + def counter(): + nonlocal count + count += 1 + return count + + return counter diff --git a/python-closure/cum_average.py b/python-closure/cum_average.py new file mode 100644 index 0000000000..c1e960fb40 --- /dev/null +++ b/python-closure/cum_average.py @@ -0,0 +1,8 @@ +def cumulative_average(): + data = [] + + def average(value): + data.append(value) + return sum(data) / len(data) + + return average diff --git a/python-closure/decorators.py b/python-closure/decorators.py new file mode 100644 index 0000000000..93ba36b0dc --- /dev/null +++ b/python-closure/decorators.py @@ -0,0 +1,12 @@ +def decorator(function): + def closure(): + print("Doing something before calling the function.") + function() + print("Doing something after calling the function.") + + return closure + + +@decorator +def greet(): + print("Hi, Pythonista!") diff --git a/python-closure/free_variables.py b/python-closure/free_variables.py new file mode 100644 index 0000000000..a24753e361 --- /dev/null +++ b/python-closure/free_variables.py @@ -0,0 +1,11 @@ +def outer_func(outer_arg): + local_var = "Outer local variable" + + def closure(): + print(outer_arg) + print(local_var) + print(another_local_var) + + another_local_var = "Another outer local variable" + + return closure diff --git a/python-closure/inner.py b/python-closure/inner.py new file mode 100644 index 0000000000..4811053b77 --- /dev/null +++ b/python-closure/inner.py @@ -0,0 +1,7 @@ +def outer_func(): + name = "Pythonista" + + def inner_func(): + print(f"Hello, {name}!") + + inner_func() diff --git a/python-closure/memoization.py b/python-closure/memoization.py new file mode 100644 index 0000000000..cd98829679 --- /dev/null +++ b/python-closure/memoization.py @@ -0,0 +1,27 @@ +from time import sleep +from timeit import timeit + + +def memoize(function): + cache = {} + + def closure(number): + if number not in cache: + cache[number] = function(number) + return cache[number] + + return closure + + +@memoize +def slow_operation(number): + sleep(0.5) + + +exec_time = timeit( + "[slow_operation(number) for number in [2, 3, 4, 2, 3, 4]]", + globals=globals(), + number=1, +) + +print(f"Slow operation's time: {exec_time:.2f} seconds.") diff --git a/python-closure/roots.py b/python-closure/roots.py new file mode 100644 index 0000000000..57275bc3da --- /dev/null +++ b/python-closure/roots.py @@ -0,0 +1,28 @@ +def make_root_calculator(root_degree, precision=2): + def root_calculator(number): + return round(pow(number, 1 / root_degree), precision) + + return root_calculator + + +square_root = make_root_calculator(2, 4) +print(square_root(42)) + +cubic_root = make_root_calculator(3, 2) +print(cubic_root(42)) + + +class RootCalculator: + def __init__(self, root_degree, precision=2): + self.root_degree = root_degree + self.precision = precision + + def __call__(self, number): + return round(pow(number, 1 / self.root_degree), self.precision) + + +square_root = RootCalculator(2, 4) +print(square_root(42)) + +cubic_root = RootCalculator(3, 2) +print(cubic_root(42)) diff --git a/python-closure/stack_class.py b/python-closure/stack_class.py new file mode 100644 index 0000000000..51fa654889 --- /dev/null +++ b/python-closure/stack_class.py @@ -0,0 +1,12 @@ +class Stack: + def __init__(self): + self._items = [] + + def push(self, item): + self._items.append(item) + + def pop(self): + return self._items.pop() + + def __str__(self): + return str(self._items) diff --git a/python-closure/stack_closure.py b/python-closure/stack_closure.py new file mode 100644 index 0000000000..36c7bc664e --- /dev/null +++ b/python-closure/stack_closure.py @@ -0,0 +1,15 @@ +def Stack(): + _items = [] + + def push(item): + _items.append(item) + + def pop(): + return _items.pop() + + def closure(): + pass + + closure.push = push + closure.pop = pop + return closure From cead9e46fe5abc9b2972cce19dacc7ca75a929e9 Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Tue, 24 Sep 2024 17:06:03 +0200 Subject: [PATCH 2/5] TR updates, first round --- python-closure/app.py | 2 +- python-closure/{stack_class.py => stack_v1.py} | 0 python-closure/{stack_closure.py => stack_v2.py} | 10 ++++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) rename python-closure/{stack_class.py => stack_v1.py} (100%) rename python-closure/{stack_closure.py => stack_v2.py} (71%) diff --git a/python-closure/app.py b/python-closure/app.py index c9368b3824..bfa197df34 100644 --- a/python-closure/app.py +++ b/python-closure/app.py @@ -2,7 +2,7 @@ app = tk.Tk() app.title("GUI App") -app.geometry("200x60") +app.geometry("320x240") label = tk.Label(app, font=("Helvetica", 16, "bold")) label.pack() diff --git a/python-closure/stack_class.py b/python-closure/stack_v1.py similarity index 100% rename from python-closure/stack_class.py rename to python-closure/stack_v1.py diff --git a/python-closure/stack_closure.py b/python-closure/stack_v2.py similarity index 71% rename from python-closure/stack_closure.py rename to python-closure/stack_v2.py index 36c7bc664e..b0ee1b2c63 100644 --- a/python-closure/stack_closure.py +++ b/python-closure/stack_v2.py @@ -13,3 +13,13 @@ def closure(): closure.push = push closure.pop = pop return closure + + +stack = Stack() +stack.push(1) +stack.push(2) +stack.push(3) + +stack.pop() + +stack._items From 9d11980c6d786f2d4ea81897bf23ab6159bccbe3 Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Tue, 24 Sep 2024 17:07:09 +0200 Subject: [PATCH 3/5] Remove usage code --- python-closure/stack_v2.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/python-closure/stack_v2.py b/python-closure/stack_v2.py index b0ee1b2c63..36c7bc664e 100644 --- a/python-closure/stack_v2.py +++ b/python-closure/stack_v2.py @@ -13,13 +13,3 @@ def closure(): closure.push = push closure.pop = pop return closure - - -stack = Stack() -stack.push(1) -stack.push(2) -stack.push(3) - -stack.pop() - -stack._items From a6c78247314096652f6c35eb7d90b40a2a3ff735 Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Wed, 25 Sep 2024 13:20:08 +0200 Subject: [PATCH 4/5] TR updates, first round --- python-closure/closure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-closure/closure.py b/python-closure/closure.py index ce99e3f69e..65d7ef855a 100644 --- a/python-closure/closure.py +++ b/python-closure/closure.py @@ -9,7 +9,7 @@ def outer_func(): name = "Pythonista" - return lambda name=name: print(f"Hello, {name}!") + return lambda: print(f"Hello, {name}!") inner_func = outer_func() From d716ae61941fea8d7201e291c97a3487ff15e9ae Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Wed, 2 Oct 2024 15:01:53 +0200 Subject: [PATCH 5/5] Sample code for the article on variables --- python-variables/README.md | 3 +++ python-variables/colors.py | 18 ++++++++++++++++++ python-variables/employees.py | 22 ++++++++++++++++++++++ python-variables/matrix.py | 9 +++++++++ python-variables/scopes.py | 24 ++++++++++++++++++++++++ python-variables/timeout.py | 10 ++++++++++ 6 files changed, 86 insertions(+) create mode 100644 python-variables/README.md create mode 100644 python-variables/colors.py create mode 100644 python-variables/employees.py create mode 100644 python-variables/matrix.py create mode 100644 python-variables/scopes.py create mode 100644 python-variables/timeout.py diff --git a/python-variables/README.md b/python-variables/README.md new file mode 100644 index 0000000000..5e15a3aad6 --- /dev/null +++ b/python-variables/README.md @@ -0,0 +1,3 @@ +# Variables in Python: Usage and Best Practices + +This folder provides the code examples for the Real Python tutorial [Variables in Python: Usage and Best Practices](https://realpython.com/python-variables/). diff --git a/python-variables/colors.py b/python-variables/colors.py new file mode 100644 index 0000000000..547f1dddaf --- /dev/null +++ b/python-variables/colors.py @@ -0,0 +1,18 @@ +colors: dict[str, str] = { + "red": "#FF0000", + "green": "#00FF00", + "blue": "#0000FF", + "yellow": "#FFFF00", + "black": "#000000", + "white": "#FFFFFF", +} + + +# colors: dict[str, tuple[int, int, int]] = { +# "Red": (255, 0, 0), +# "Green": (0, 255, 0), +# "Blue": (0, 0, 255), +# "Yellow": (255, 255, 0), +# "Black": (0, 0, 0), +# "White": (255, 255, 255), +# } diff --git a/python-variables/employees.py b/python-variables/employees.py new file mode 100644 index 0000000000..fa77066161 --- /dev/null +++ b/python-variables/employees.py @@ -0,0 +1,22 @@ +class Employee: + count = 0 + + def __init__(self, name, position, salary): + self.name = name + self.position = position + self.salary = salary + type(self).count += 1 + + def display_profile(self): + print(f"Name: {self.name}") + print(f"Position: {self.position}") + print(f"Salary: ${self.salary}") + + +jane = Employee("Jane Doe", "Software Engineer", 90000) +jane.display_profile() + +john = Employee("John Doe", "Product Manager", 120000) +john.display_profile() + +print(f"Total employees: {Employee.count}") diff --git a/python-variables/matrix.py b/python-variables/matrix.py new file mode 100644 index 0000000000..4ead972bd9 --- /dev/null +++ b/python-variables/matrix.py @@ -0,0 +1,9 @@ +matrix = [ + [9, 3, 8], + [4, 5, 2], + [6, 4, 3], +] + +for i in matrix: + for j in i: + print(j) diff --git a/python-variables/scopes.py b/python-variables/scopes.py new file mode 100644 index 0000000000..b72fe20477 --- /dev/null +++ b/python-variables/scopes.py @@ -0,0 +1,24 @@ +def function(): + value = 42 + return value + + +# Global scope +global_variable = "global" + + +def outer_func(): + # Nonlocal scope + nonlocal_variable = "nonlocal" + + def inner_func(): + # Local scope + local_variable = "local" + print(f"Hi from the '{local_variable}' scope!") + + print(f"Hi from the '{global_variable}' scope!") + print(f"Hi from the '{nonlocal_variable}' scope!") + inner_func() + + +outer_func() diff --git a/python-variables/timeout.py b/python-variables/timeout.py new file mode 100644 index 0000000000..4779f865b9 --- /dev/null +++ b/python-variables/timeout.py @@ -0,0 +1,10 @@ +_timeout = 30 # in seconds + + +def get_timeout(): + return _timeout + + +def set_timeout(seconds): + global _timeout + _timeout = seconds