From da5e6c99b575d08746f2ea6eaa940e8073beac32 Mon Sep 17 00:00:00 2001 From: Praise Tompane Date: Sat, 1 Mar 2025 22:29:23 +0200 Subject: [PATCH 1/3] docs: generators and iterators --- README.md | 2 +- application_projects/README.md | 1 - application_projects/run_project.sh | 1 - ...lementation.py => range_implementation.py} | 0 src/applications/math/fibonacci.py | 13 +++++++++ ...ngularNumbers.py => triangular_numbers.py} | 0 src/collections/generators.py | 13 +++++++++ src/collections/iterators.py | 27 +++++++++++++++++++ .../simpleTable.py => io/simple_table.py} | 0 9 files changed, 54 insertions(+), 3 deletions(-) delete mode 100644 application_projects/README.md delete mode 100755 application_projects/run_project.sh rename src/applications/collections/{rangeimplementation.py => range_implementation.py} (100%) create mode 100644 src/applications/math/fibonacci.py rename src/applications/math/{triangularNumbers.py => triangular_numbers.py} (100%) create mode 100644 src/collections/generators.py create mode 100644 src/collections/iterators.py rename src/{_io/simpleTable.py => io/simple_table.py} (100%) diff --git a/README.md b/README.md index 72eb958..7810cd1 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ ## Learning Resources - [roadmap](https://roadmap.sh/python) - [practice problems](https://www.hackerrank.com/domains/python?filters%5Bstatus%5D%5B%5D=unsolved&badge_type=python) - + - [What Does It Take To Be An Expert At Python?](https://www.youtube.com/watch?v=7lmCu8wz8ro) ## Spell Check ```shell pyspelling -c spellcheck.yaml diff --git a/application_projects/README.md b/application_projects/README.md deleted file mode 100644 index 65d936c..0000000 --- a/application_projects/README.md +++ /dev/null @@ -1 +0,0 @@ -# larger implementations to test understanding of the language and its strengths/weaknesses diff --git a/application_projects/run_project.sh b/application_projects/run_project.sh deleted file mode 100755 index dd5c79f..0000000 --- a/application_projects/run_project.sh +++ /dev/null @@ -1 +0,0 @@ -pipenv run python main.py \ No newline at end of file diff --git a/src/applications/collections/rangeimplementation.py b/src/applications/collections/range_implementation.py similarity index 100% rename from src/applications/collections/rangeimplementation.py rename to src/applications/collections/range_implementation.py diff --git a/src/applications/math/fibonacci.py b/src/applications/math/fibonacci.py new file mode 100644 index 0000000..5b7fe00 --- /dev/null +++ b/src/applications/math/fibonacci.py @@ -0,0 +1,13 @@ +def fibonacci(): + a = 0 + b = 1 + while True: + yield a + a = b + b = a + b + + +for n in fibonacci(): + if n > 50: + break + print(n) diff --git a/src/applications/math/triangularNumbers.py b/src/applications/math/triangular_numbers.py similarity index 100% rename from src/applications/math/triangularNumbers.py rename to src/applications/math/triangular_numbers.py diff --git a/src/collections/generators.py b/src/collections/generators.py new file mode 100644 index 0000000..e5bb7e4 --- /dev/null +++ b/src/collections/generators.py @@ -0,0 +1,13 @@ +""" + def yield | (): construct to create generator object +""" + +def generate(): + num = 0 + yield num + num += 1 + + +if __name__ == "__main__": + for v in range(10): + print(next(generate())) diff --git a/src/collections/iterators.py b/src/collections/iterators.py new file mode 100644 index 0000000..a07c958 --- /dev/null +++ b/src/collections/iterators.py @@ -0,0 +1,27 @@ +""" + def iter: construct to traverse an arbitrary data structure + - properties: + - forward and reserve traversal +""" + +collection = [i for i in range(5)] + +print("Forward Iteration") +forward_iterator = iter(collection) +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +# print(f"Print next element {next(forward_iterator)}") + +print("Reverse Iteration") +reverse_iterator = reversed(collection) +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +# print(f"Print next element {next(reverse_iterator)}") + +print(dir(collection)) diff --git a/src/_io/simpleTable.py b/src/io/simple_table.py similarity index 100% rename from src/_io/simpleTable.py rename to src/io/simple_table.py From 0b3bdb4176364991fa3a230b92a0d8cbd91e31bd Mon Sep 17 00:00:00 2001 From: Praise Tompane Date: Sun, 2 Mar 2025 16:28:02 +0200 Subject: [PATCH 2/3] docs: flesh out and position iterators and generators in the standard library. link to types documentation. --- .spellcheck_exceptions_dictionary.txt | 4 + README.md | 9 ++- dictionary.dic | Bin 2992 -> 3312 bytes .../4_iterator_types}/fibonacci.py | 0 .../4_iterator_types/remote_control.py | 23 ++++++ .../5_sequence_types}/__init__.py | 0 .../5_sequence_types}/range_implementation.py | 0 src/collections/generators.py | 13 ---- src/collections/iterators.py | 27 ------- .../4_iterator_types/0_iterators.py | 70 ++++++++++++++++++ .../4_iterator_types/1_generators.py | 39 ++++++++++ 11 files changed, 143 insertions(+), 42 deletions(-) rename src/applications/{math => standard_library/3_built_in_types/4_iterator_types}/fibonacci.py (100%) create mode 100644 src/applications/standard_library/3_built_in_types/4_iterator_types/remote_control.py rename src/applications/{collections => standard_library/3_built_in_types/5_sequence_types}/__init__.py (100%) rename src/applications/{collections => standard_library/3_built_in_types/5_sequence_types}/range_implementation.py (100%) delete mode 100644 src/collections/generators.py delete mode 100644 src/collections/iterators.py create mode 100644 standard_library/3_built_in_types/4_iterator_types/0_iterators.py create mode 100644 standard_library/3_built_in_types/4_iterator_types/1_generators.py diff --git a/.spellcheck_exceptions_dictionary.txt b/.spellcheck_exceptions_dictionary.txt index 45240ac..ac4ccf7 100644 --- a/.spellcheck_exceptions_dictionary.txt +++ b/.spellcheck_exceptions_dictionary.txt @@ -94,6 +94,10 @@ piNY psf tzYhv https +dev +lmCu +ro +wz # pythons implementations: diff --git a/README.md b/README.md index 7810cd1..ed72e94 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ - An in-depth study of Python's: - Interpreter. - This focuses on [CPython](https://github.com/python/cpython). + - [Annotations on the actual interpreter implementation](https://github.com/praisetompane/python_implementation_study_cpython) + - They are prefixed with "Praise:" - Python's design, implementation and ecosystem. ## Language Details @@ -24,14 +26,15 @@ - structuring projects: - [package index](https://pypi.org) - [extending and embedding](https://docs.python.org/3.11/extending/index.html) + - [PEP Index](https://www.python.org/dev/peps/) - [developer contribution guide](https://devguide.python.org/) - memory model: - [computational complexity cost model](https://ocw.mit.edu/courses/6-006-introduction-to-algorithms-fall-2011/pages/readings/python-cost-model/) - history: - [The Story of Python, by Its Creator, Guido van Rossum](https://www.youtube.com/watch?v=J0Aq44Pze-w) -## Testing - - [pytest](https://docs.pytest.org/en/latest/index.html#) +## Community +- [Discord](https://discuss.python.org) ## Use Cases - [Applications of Python](https://www.python.org/about/apps/) @@ -40,11 +43,13 @@ - [roadmap](https://roadmap.sh/python) - [practice problems](https://www.hackerrank.com/domains/python?filters%5Bstatus%5D%5B%5D=unsolved&badge_type=python) - [What Does It Take To Be An Expert At Python?](https://www.youtube.com/watch?v=7lmCu8wz8ro) + ## Spell Check ```shell pyspelling -c spellcheck.yaml ``` + # References: ## Legend: diff --git a/dictionary.dic b/dictionary.dic index 88cad2ffce96c97495cc3ee43b86626a5c17012b..bcba6bcca4401b880853c7282199123b9c4773f5 100644 GIT binary patch delta 1446 zcmZ9MU2Icj9LAru-P%poc9iUccmW%Pi3G_$WYG=gmW_}0oYZrUSt}u-W`{9c*V1*m z8DdS;3pF8VcVoDc5MzuNC`Jf@cmsM#h|wEjVxp3Gvv2`7V4}}+@-_k9^zHBeKL3yR zegEgQ7rXBDoXz!&Z$L2qXabH!fMgr+8kJAJJr!-LWh`JTSC$9#ig}=qw5Ne>BK_M% z8`wc+Is3(N;5ji3>=fyLUSz;7(E)agF0e;r{Xvp4hD62<12s4d*eihnBP5r2N#p@u z7Fl>yWagO2fPEt4_mkcPzz;mePl`Oyl$Zf1!DIdbk$DG2<{c(ysArI%L4lV`}syXp6Ic}p{Oy{smCNaPtWgxQoVZ+|fmvbZkt^uLhm-d|!igY|$8{uNydZG5&4Z@)R9g`K3D zIV$qt)1vLc6`eHR6dAB0dRcrB(80M#O@fE7D0mYNu8VBtt$=CV5z{W##f*bTA`8cw zN%tVS1A6EeJq!B++HlDkzE_JPFLavBTN!*tJ~1xcjJzM}>WD7*D}K>mLVH*bB+?OC zC{8ZdUyXJq5)nRG96?a-}f84WUY@ej+xNN<=HA!fdfnrtV6A`D|)+_DFu#O*(MOF*Ng-^GpYIk{!|2QVd9N!1ojqxRaehs_9 zW#0TYW6!XI?{Z4t#<+9L{hYp&w71i~%tzeFImGof>OUDRYj~uY@6G9_Hu;*)Et~@^ zrUEz2Ci>-S{Ve%A3r;aFX*B5-6DRux>PNZGvCbgpgU5UyGgmRa)K<8Eu=tgWAC2Py z6NYK8o3(;{9wy9~d))Md+4MV8^bX^{H(HYZ`?SxJbId<^ju1^u^7&YID~>w>7+|u-|B_jgsQ>@~ delta 1121 zcmXw&OGs2<6vzLLkD0M3#jFG=%IsE0VY+N3n}G{@1#>Lkg4*<0m5W+b3;Uhh_`%_KzW;fA-#z!peabCTYl}Don6KK$AB(cdzVl(txrJY6!b{VU@2WZ2X zF}67RV~llaK_TR<t?Ei-b!2BV);LqJzfKwpQU-|8xDr2e8Y=IOdI?rOY< zar!iTV1n17sery-8U2Jl2jq!iC*MhBu}#%e4eUf7%3}BpBqjM4d?zw+M?y*%s}ta{@!%Xi)KqJB7SdQTP8D* z$$g7HEhx|3DP5ZV$Yaj33ixc#GVA@=D*PYleb{5(#UOmbt!`oU#4NuJK0>c0|Ai5| zfThS8Bi4#v$IXusw|ranTa*zSC-z^N&CYh_8|H=Cs~kAz8$%@DL7Sk_d2-*=Bt+wb z=+)42M)Nf<(SG93karh5iCO#&yiI+p<>61$;|>0=P*%Ff<}yLSD>P`K=~nnWUtDW( z>=XO>`2(AYPf@c6{kS#FFZ)%^{Q|!eGrtUf3w{s$OpR%q@GI%Dqb4uBh9e|Zz-oeB J@DO`j{{XJl`mq22 diff --git a/src/applications/math/fibonacci.py b/src/applications/standard_library/3_built_in_types/4_iterator_types/fibonacci.py similarity index 100% rename from src/applications/math/fibonacci.py rename to src/applications/standard_library/3_built_in_types/4_iterator_types/fibonacci.py diff --git a/src/applications/standard_library/3_built_in_types/4_iterator_types/remote_control.py b/src/applications/standard_library/3_built_in_types/4_iterator_types/remote_control.py new file mode 100644 index 0000000..700ec58 --- /dev/null +++ b/src/applications/standard_library/3_built_in_types/4_iterator_types/remote_control.py @@ -0,0 +1,23 @@ +class RemoteControlIterator: + def __init__(self): + self.channels = ['HBO', 'SABC2', 'MNET', 'ESPN'] + self.current_channel = -1 + + def __iter__(self): + return self + + def __next__(self): + self.current_channel += 1 + if self.current_channel == len(self.channels): + raise StopIteration + + return self.channels[self.current_channel] + + +if __name__ == "__main__": + r = RemoteControlIterator() + + try: + print(f"Channel {next(r)}") + except StopIteration: + print("All Channel Explored. Goodbye") \ No newline at end of file diff --git a/src/applications/collections/__init__.py b/src/applications/standard_library/3_built_in_types/5_sequence_types/__init__.py similarity index 100% rename from src/applications/collections/__init__.py rename to src/applications/standard_library/3_built_in_types/5_sequence_types/__init__.py diff --git a/src/applications/collections/range_implementation.py b/src/applications/standard_library/3_built_in_types/5_sequence_types/range_implementation.py similarity index 100% rename from src/applications/collections/range_implementation.py rename to src/applications/standard_library/3_built_in_types/5_sequence_types/range_implementation.py diff --git a/src/collections/generators.py b/src/collections/generators.py deleted file mode 100644 index e5bb7e4..0000000 --- a/src/collections/generators.py +++ /dev/null @@ -1,13 +0,0 @@ -""" - def yield | (): construct to create generator object -""" - -def generate(): - num = 0 - yield num - num += 1 - - -if __name__ == "__main__": - for v in range(10): - print(next(generate())) diff --git a/src/collections/iterators.py b/src/collections/iterators.py deleted file mode 100644 index a07c958..0000000 --- a/src/collections/iterators.py +++ /dev/null @@ -1,27 +0,0 @@ -""" - def iter: construct to traverse an arbitrary data structure - - properties: - - forward and reserve traversal -""" - -collection = [i for i in range(5)] - -print("Forward Iteration") -forward_iterator = iter(collection) -print(f"Print next element {next(forward_iterator)}") -print(f"Print next element {next(forward_iterator)}") -print(f"Print next element {next(forward_iterator)}") -print(f"Print next element {next(forward_iterator)}") -print(f"Print next element {next(forward_iterator)}") -# print(f"Print next element {next(forward_iterator)}") - -print("Reverse Iteration") -reverse_iterator = reversed(collection) -print(f"Print next element {next(reverse_iterator)}") -print(f"Print next element {next(reverse_iterator)}") -print(f"Print next element {next(reverse_iterator)}") -print(f"Print next element {next(reverse_iterator)}") -print(f"Print next element {next(reverse_iterator)}") -# print(f"Print next element {next(reverse_iterator)}") - -print(dir(collection)) diff --git a/standard_library/3_built_in_types/4_iterator_types/0_iterators.py b/standard_library/3_built_in_types/4_iterator_types/0_iterators.py new file mode 100644 index 0000000..d65e240 --- /dev/null +++ b/standard_library/3_built_in_types/4_iterator_types/0_iterators.py @@ -0,0 +1,70 @@ +""" + def iterator: + - formal: + - in words: an object that represents a stream of data. + + - properties: + - forward and reserve traversal. + - can only be traversed once. + - plain english: ??? + + - intuition: ??? + + - properties: ??? + + - examples: ??? + + - use cases: ??? + + - proof: None. It is a definition. + + References: + PEP 234 – Iterators. https://peps.python.org/pep-0234/ +""" + +collection = [i for i in range(5)] + +print("Forward Iteration with next(forward_iterator)") +forward_iterator = iter(collection) +print(f"Type: {type(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +print(f"Print next element {next(forward_iterator)}") +# print(f"Print next element {next(forward_iterator)}") +print("\n") + +print("Forward Iteration with __next__") +forward_iterator_2 = iter(collection) +print(f"Print next element {forward_iterator_2.__next__()}") +print(f"Print next element {forward_iterator_2.__next__()}") +print(f"Print next element {forward_iterator_2.__next__()}") +print(f"Print next element {forward_iterator_2.__next__()}") +print(f"Print next element {forward_iterator_2.__next__()}") +# print(f"Print next element {forward_iterator)}") +print("\n") + +print("Reverse Iteration") +reverse_iterator = reversed(collection) +print(f"Type: {type(forward_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +print(f"Print next element {next(reverse_iterator)}") +# print(f"Print next element {next(reverse_iterator)}") +print("\n") + +# Single Travel Example +collection = [i for i in range(5)] +iterator = iter(collection) + +print("First pass of the iterator") +for v in iterator: + print(v) + +# This next pass will fail, because we have exhausted the iterator's single pass +print("Second pass of the iterator") +for v in iterator: + print(v) diff --git a/standard_library/3_built_in_types/4_iterator_types/1_generators.py b/standard_library/3_built_in_types/4_iterator_types/1_generators.py new file mode 100644 index 0000000..156d1da --- /dev/null +++ b/standard_library/3_built_in_types/4_iterator_types/1_generators.py @@ -0,0 +1,39 @@ +""" + def generator | generator function: + - formal: 𝑓: * ↦ Generator Iterator + - in words: a function that creates and returns a Generator Iterator. + + - plain english: ??? + + - intuition: ??? + + - properties: ??? + + - examples: + - useful example: src/applications/math/fibonacci.py + + - use cases: ??? + + - proof: None. It is a definition. + + References: + PEP 255 – Simple Generators. https://www.python.org/dev/peps/pep-0255/#motivation + +""" + + +def generate_infinite_numbers(): + """ + Generate infinite numbers + """ + number = 0 + while True: + yield number + number += 1 + + +if __name__ == "__main__": + last_number = 100 + print(f"Generating a {last_number} numbers") + for number in generate_infinite_numbers(): + print(number) From 91febd88eecafda692c088ca1d52df2e3c3bdfbe Mon Sep 17 00:00:00 2001 From: Praise Tompane Date: Sun, 2 Mar 2025 18:24:18 +0200 Subject: [PATCH 3/3] fix: generator expressions --- .spellcheck_exceptions_dictionary.txt | 3 +++ .../3_built_in_types/4_iterator_types/1_generators.py | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.spellcheck_exceptions_dictionary.txt b/.spellcheck_exceptions_dictionary.txt index ac4ccf7..b034bbf 100644 --- a/.spellcheck_exceptions_dictionary.txt +++ b/.spellcheck_exceptions_dictionary.txt @@ -98,6 +98,9 @@ dev lmCu ro wz +iter +tp +typeobj # pythons implementations: diff --git a/standard_library/3_built_in_types/4_iterator_types/1_generators.py b/standard_library/3_built_in_types/4_iterator_types/1_generators.py index 156d1da..57f98ab 100644 --- a/standard_library/3_built_in_types/4_iterator_types/1_generators.py +++ b/standard_library/3_built_in_types/4_iterator_types/1_generators.py @@ -1,6 +1,6 @@ """ def generator | generator function: - - formal: 𝑓: * ↦ Generator Iterator + - formal: 𝑓: any ↦ Generator Iterator - in words: a function that creates and returns a Generator Iterator. - plain english: ??? @@ -32,8 +32,12 @@ def generate_infinite_numbers(): number += 1 +def generator_expression(): + sum(i * i for i in range(10)) + + if __name__ == "__main__": - last_number = 100 - print(f"Generating a {last_number} numbers") for number in generate_infinite_numbers(): print(number) + + # print(generator_expression())