From 7715a84c4a8fbf73fbf375ac96015b68c1cd0798 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 24 Jul 2023 22:31:54 -0700 Subject: [PATCH 001/178] Update requirements.txt (#72) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 74e4537d..82ac05aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.2.5 +coverage==7.2.7 flake8==6.0.0 isort==5.12.0 From 8934b2202c129ec31bcfc47b166605b425ee004f Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 3 Sep 2023 09:29:55 -0700 Subject: [PATCH 002/178] Update coverage to 7.3.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 82ac05aa..86480366 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.2.7 +coverage==7.3.0 flake8==6.0.0 isort==5.12.0 From 794fa8113303693d3665310d21725d91c2d2d2c2 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 3 Sep 2023 09:31:30 -0700 Subject: [PATCH 003/178] Update flake8 to 6.1.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 86480366..95891ee8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.3.0 -flake8==6.0.0 +flake8==6.1.0 isort==5.12.0 From 8731e3beac518155bbc9512de5fe9431a6a220d0 Mon Sep 17 00:00:00 2001 From: Azeen Hodekar Date: Fri, 6 Oct 2023 21:39:48 +0530 Subject: [PATCH 004/178] Added project-based-learning repo link to README.md (#81) * Update README.md Added link to project-based-learning repository which has over 116k stars * Update README.zh_tw.md * Update README.ko.md * Update README.es.md * Update README.de.md --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + 5 files changed, 5 insertions(+) diff --git a/README.de.md b/README.de.md index eb7dd51c..dfe7e3b9 100644 --- a/README.de.md +++ b/README.de.md @@ -133,6 +133,7 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) ### Interaktive Übungen diff --git a/README.es.md b/README.es.md index 57dad2d1..5db9df48 100644 --- a/README.es.md +++ b/README.es.md @@ -132,6 +132,7 @@ Sigue aprendiendo leyendo otros buenos recursos. - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) ### Práctica interactiva diff --git a/README.ko.md b/README.ko.md index 2afd6ade..4d41f68c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -121,6 +121,7 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) ### 대화 형 연습 diff --git a/README.md b/README.md index a34fb4bb..98c75d84 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,7 @@ Keep learning by reading from other well-regarded resources. - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) ### Interactive practice diff --git a/README.zh_tw.md b/README.zh_tw.md index da0f3901..04b324ab 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -117,6 +117,7 @@ print("Ultimate Python 學習大綱") - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) ### 互動練習 From 121366f9a6243782ecbcde9c274c0625fcb8561f Mon Sep 17 00:00:00 2001 From: Abhinna Manandhar Date: Fri, 6 Oct 2023 22:02:15 +0545 Subject: [PATCH 005/178] Encapsulation (#79) * Added encapsulation. * private function exmple added. * code lint amendments for encapsulation. * random library replaced * Lower bound limit added to withdraw method - Encapsulation. * tests added for newly added exceptions - Encapsulation * coverage fixes and docstring amendments - Encapsulation * Encapsulation added to README. --------- Co-authored-by: Samuel Huang --- README.md | 1 + ultimatepython/classes/encapsulation.py | 130 ++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 ultimatepython/classes/encapsulation.py diff --git a/README.md b/README.md index 98c75d84..b2dff291 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ There are two ways of running the modules: - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) (:pill:) 5. **Advanced** - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) diff --git a/ultimatepython/classes/encapsulation.py b/ultimatepython/classes/encapsulation.py new file mode 100644 index 00000000..818a5b5d --- /dev/null +++ b/ultimatepython/classes/encapsulation.py @@ -0,0 +1,130 @@ +""" +Encapsulation is a feature of OOP that allows you to hide the +implementation details of a class from its users. +Encapsulation allows us to limit the access of certain attributes +within a class. This prevents users from directly accessing and modifying such +attributes from outside the class. Instead, users must use methods to access and +modify attributes. +""" +import secrets + +# Module-level constanct +_INVALID_AMOUNT_MESSAGE = "Invalid amount." +_INSUFFICIENT_BALANCE_MESSAGE = "Insufficient balance." + + +class BankAccount: + def __init__(self, account_holder_name): + """ + In Python, a class attribute can be made private by prefixing it with two underscores. + This makes it inaccessible to users outside the class. + By default, class attributes are public. Therefore, they can be accessed and modified + outside of the class. + + Here, account_number and balance are private while account_holder_name is public. + """ + self.account_holder_name = account_holder_name + """ + The account number is generated automatically using the randbelow function from + the random module when a new instance of the class is created. + The balance is set to 0 by default. + """ + self.__account_number = secrets.randbelow(10**10) # generate a random account number of 10 digits. + self.__balance = 0 + + def deposit(self, balance): + """ + The deposit function is used to add new balance to the account. + The provided balance is added to the existing balance. + """ + self.__balance += int(balance) + + def withdraw(self, balance): + """ + The withraw method is used to deduct the balance from the account. + In case there is insufficient balance, or the input is invalid, + a value error is raised. + """ + if balance <= 0: + raise ValueError(_INVALID_AMOUNT_MESSAGE) + if balance > self.__balance: + raise ValueError(_INSUFFICIENT_BALANCE_MESSAGE) + + self.__balance -= balance + + def get_balance(self): + """ + This function returs the available balance in the account. + """ + return self.__balance + + def get_account_number(self): + """ + The account number is generated randomly when a new instance of the class is created. + Since the attribute is also private, it cannot be accessed directly from outside the class. + The get_account_number method allows you to access the account number outside of the class. + But since we do not define a setter method for this variable, we cannot modify it outside the class. + Therefore, the account number generated while creating an object of the BankAccount class cannot be changed + but can only be read using this function. + """ + return self.__account_number + + def __set_account_number(self, number): + """ + This is a private method. Similar to private variables, + private methods also cannot be accessed outside the class. + """ + self.__account_number = number + + def remove_account_details(self): + """ + This method is used to reset the account details. + Here, the __set_account_number function is private. + This, it cannot be called from outside the class. + However, the remove_account_details calls the function from + inside the class and as it is a public method, it can be called from + outside the class. + """ + self.__balance = 0 + self.__set_account_number(0) + self.account_holder_name = "" + + +def main(): + # Account names constants. + USER1 = "John Doe" + USER2 = "Jane Doe" + + # Account instances. + account1 = BankAccount(USER1) + account2 = BankAccount(USER2) + + assert account1.account_holder_name == USER1 + assert account2.account_holder_name == USER2 + + # Deposit amount and check if the balance is updated. + account1.deposit(100) + assert account1.get_balance() == 100 + + # Withdraw amount and check if the balance is updated. + account1.withdraw(50) + assert account1.get_balance() == 50 + + # validating invalid amounts. + error_inputs = [-10, 0, 150] + for input in error_inputs: + try: + account1.withdraw(input) + except ValueError as e: + assert str(e) in {_INSUFFICIENT_BALANCE_MESSAGE, _INVALID_AMOUNT_MESSAGE} + + # Remove account details and assert values. + account1.remove_account_details() + + assert account1.get_balance() == 0 + assert account1.get_account_number() == 0 + assert account1.account_holder_name == "" + + +if __name__ == "__main__": + main() From 563f71b7590692c98d04aabedb06776225b3cc5c Mon Sep 17 00:00:00 2001 From: Archisman Bera <95976290+ArcXeon@users.noreply.github.com> Date: Sat, 7 Oct 2023 06:50:10 +0530 Subject: [PATCH 006/178] Added Bitwise Operators (#78) * Create bitwise.py Added file explaining bitwise operators * Update README.md * Update README.md * Update README.md * Update README.md * Update README.ko.md * Update bitwise.py * Update README.de.md * Update README.es.md * Update README.zh_tw.md * Update bitwise.py --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + ultimatepython/syntax/bitwise.py | 45 ++++++++++++++++++++++++++++++++ 6 files changed, 50 insertions(+) create mode 100644 ultimatepython/syntax/bitwise.py diff --git a/README.de.md b/README.de.md index dfe7e3b9..fd48f028 100644 --- a/README.de.md +++ b/README.de.md @@ -79,6 +79,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: 2. **Syntax** - Variable: [Built-in literals](ultimatepython/syntax/variable.py) (:cake:) - Expression: [Numeric operations](ultimatepython/syntax/expression.py) (:cake:) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) (:cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - Function: [def | lambda](ultimatepython/syntax/function.py) (:cake:) diff --git a/README.es.md b/README.es.md index 5db9df48..453906da 100644 --- a/README.es.md +++ b/README.es.md @@ -78,6 +78,7 @@ Hay dos maneras de ejecutar los módulos: 2. **Sintaxis** - Variables: [Literales integrados](ultimatepython/syntax/variable.py) (:cake:) - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) (:cake:) + - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) (:cake:), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - Funciones: [def | lambda](ultimatepython/syntax/function.py) (:cake:) diff --git a/README.ko.md b/README.ko.md index 4d41f68c..7b50026e 100644 --- a/README.ko.md +++ b/README.ko.md @@ -67,6 +67,7 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 2. **통사론** - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) (:cake:) - 식 : [숫자 연산](ultimatepython/syntax/expression.py) (:cake:) + - 비트별: [비트 연산자](ultimatepython/syntax/bitwise.py) (:cake:), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - 조건부 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - 루프 : [for 루프 | while-loop](ultimatepython/syntax/loop.py) (:cake:) - 함수 : [def | 람다](ultimatepython/syntax/function.py) (:cake:) diff --git a/README.md b/README.md index b2dff291..ef7d72db 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ There are two ways of running the modules: 2. **Syntax** - Variable: [Built-in literals](ultimatepython/syntax/variable.py) (:cake:) - Expression: [Numeric operations](ultimatepython/syntax/expression.py) (:cake:) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) (:cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - Function: [def | lambda](ultimatepython/syntax/function.py) (:cake:) diff --git a/README.zh_tw.md b/README.zh_tw.md index 04b324ab..934def44 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -63,6 +63,7 @@ print("Ultimate Python 學習大綱") 2. **語法** - 變數:[內置值](ultimatepython/syntax/variable.py) (:cake:) - 運算式:[數值運算](ultimatepython/syntax/expression.py) (:cake:) + - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) (:cake:), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) (:cake:) - 定義函式:[def | lambda](ultimatepython/syntax/function.py) (:cake:) diff --git a/ultimatepython/syntax/bitwise.py b/ultimatepython/syntax/bitwise.py new file mode 100644 index 00000000..008f90b0 --- /dev/null +++ b/ultimatepython/syntax/bitwise.py @@ -0,0 +1,45 @@ +""" +Bitwise operators in Python allow you to manipulate individual bits of integers. +This module demonstrates the use of bitwise operators and their behavior. +""" + + +def main(): + # Define some integer values for demonstration + a = 5 # Binary: 0101 + b = 3 # Binary: 0011 + + # Bitwise AND (&) operator compares each bit of two integers and returns 1 + # if both bits are 1, otherwise returns 0 + result_and = a & b # Binary: 0001 (Decimal: 1) + assert result_and == 1 + + # Bitwise OR (|) operator compares each bit of two integers and returns 1 + # if at least one bit is 1, otherwise returns 0 + result_or = a | b # Binary: 0111 (Decimal: 7) + assert result_or == 7 + + # Bitwise XOR (^) operator compares each bit of two integers and returns 1 + # if the bits are different (one is 1 and the other is 0), otherwise returns 0 + result_xor = a ^ b # Binary: 0110 (Decimal: 6) + assert result_xor == 6 + + # Bitwise NOT (~) operator inverts all bits of an integer + # It return the one's complement of the integer + result_not_a = ~a # Binary: 11111010 (Decimal: -6) + assert result_not_a == -6 + + # Bitwise left shift (<<) operator shifts the bits of an integer to the left by + # a specified number of positions, filling with zeros + result_left_shift = a << 2 # Binary: 010100 (Decimal: 20) + assert result_left_shift == 20 + + # Bitwise right shift (>>) operator shifts the bits of an integer to the right + # by a specified number of positions, filling with zeros for positive numbers + # and with ones for negative numbers + result_right_shift = a >> 1 # Binary: 0010 (Decimal: 2) + assert result_right_shift == 2 + + +if __name__ == "__main__": + main() From 54981d35e7ebd582f1688d15c2085e54b7d62ed5 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 7 Oct 2023 17:39:41 -0700 Subject: [PATCH 007/178] Add encapsulation to all README files --- README.de.md | 1 + README.es.md | 3 ++- README.ko.md | 1 + README.md | 2 +- README.zh_tw.md | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.de.md b/README.de.md index fd48f028..fee43f92 100644 --- a/README.de.md +++ b/README.de.md @@ -97,6 +97,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Fortgeschrittene** - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) diff --git a/README.es.md b/README.es.md index 453906da..6dcf91e8 100644 --- a/README.es.md +++ b/README.es.md @@ -94,8 +94,9 @@ Hay dos maneras de ejecutar los módulos: 4. **Clases** - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) (:cake:) - Clase abstracta: [Definición de abstracta](ultimatepython/classes/abstract_class.py) - - Clase de excepción: [Defición de excepción](ultimatepython/classes/exception_class.py) + - Clase de excepción: [Definición de excepción](ultimatepython/classes/exception_class.py) - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - Encapsulación: [Definición de encapsulación](ultimatepython/classes/encapsulation.py) 5. **Avanzado** - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) (:exploding_head:) diff --git a/README.ko.md b/README.ko.md index 7b50026e..e779e1d3 100644 --- a/README.ko.md +++ b/README.ko.md @@ -85,6 +85,7 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - 추상 클래스 : [추상 정의](ultimatepython/classes/abstract_class.py) - 예외 클래스 : [예외 정의](ultimatepython/classes/exception_class.py) - 반복기 클래스 : [반복기 정의 | 수익률](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - 캡슐화: [캡슐화 정의](ultimatepython/classes/encapsulation.py) 5. **고급** - 데코레이터 : [데코레이터 정의 | 랩](ultimatepython/advanced/decorator.py) (:exploding_head:) - 컨텍스트 관리자 : [컨텍스트 관리자](ultimatepython/advanced/context_manager.py) (:exploding_head:) diff --git a/README.md b/README.md index ef7d72db..63b72272 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ There are two ways of running the modules: - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) - - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) (:pill:) + - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Advanced** - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) diff --git a/README.zh_tw.md b/README.zh_tw.md index 934def44..51f5a690 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -81,6 +81,7 @@ print("Ultimate Python 學習大綱") - 抽象類別:[抽象定義](ultimatepython/classes/abstract_class.py) - 異常類別:[異常定義](ultimatepython/classes/exception_class.py) - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - 封裝: [封裝定義](ultimatepython/classes/encapsulation.py) 5. **進階技巧** - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) From c24d88d939b444998e10a9a9a904479729e6ff29 Mon Sep 17 00:00:00 2001 From: Mayuresh Dharwadkar <98738585+Mayureshd-18@users.noreply.github.com> Date: Sun, 8 Oct 2023 17:11:35 +0530 Subject: [PATCH 008/178] Update README.md (#84) * Update README.md * Update README.de.md * Update README.es.md * Update README.ko.md * Update README.zh_tw.md --------- Co-authored-by: Samuel Huang --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + 5 files changed, 5 insertions(+) diff --git a/README.de.md b/README.de.md index fee43f92..01a9517a 100644 --- a/README.de.md +++ b/README.de.md @@ -148,3 +148,4 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) +- [hackerearth.com](https://www.hackerearth.com/) diff --git a/README.es.md b/README.es.md index 6dcf91e8..c8968b96 100644 --- a/README.es.md +++ b/README.es.md @@ -147,3 +147,4 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) +- [hackerearth.com](https://www.hackerearth.com/) diff --git a/README.ko.md b/README.ko.md index e779e1d3..a95fad8a 100644 --- a/README.ko.md +++ b/README.ko.md @@ -136,3 +136,4 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) +- [hackerearth.com](https://www.hackerearth.com/) diff --git a/README.md b/README.md index 63b72272..1239164a 100644 --- a/README.md +++ b/README.md @@ -149,3 +149,4 @@ Keep practicing so that your coding skills don't get rusty. - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) +- [hackerearth.com](https://www.hackerearth.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index 51f5a690..b4050ed6 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -132,3 +132,4 @@ print("Ultimate Python 學習大綱") - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) +- [hackerearth.com](https://www.hackerearth.com/) From ea46112a94144b5428bfc950de6ecc3097ac4d42 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:53:41 +0530 Subject: [PATCH 009/178] Update README.md (#85) added code chef link in the interactive practice session.. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1239164a..14828615 100644 --- a/README.md +++ b/README.md @@ -150,3 +150,4 @@ Keep practicing so that your coding skills don't get rusty. - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) +- [codechef.com](https://www.codechef.com/) (:necktie:) From b2d56a145e5e7bd6ab25ec15e2c1526d8f396631 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:55:24 +0530 Subject: [PATCH 010/178] Update README.de.md (#86) Co-authored-by: Samuel Huang --- README.de.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.de.md b/README.de.md index 01a9517a..0b8a9e5a 100644 --- a/README.de.md +++ b/README.de.md @@ -149,3 +149,4 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) +- [codechef.com](https://www.codechef.com/) (:necktie:) From f2c15a208921a2f3c4ac881e6034f5a8c80b1564 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:56:25 +0530 Subject: [PATCH 011/178] Update README.es.md (#87) Co-authored-by: Samuel Huang --- README.es.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.es.md b/README.es.md index c8968b96..00017da1 100644 --- a/README.es.md +++ b/README.es.md @@ -148,3 +148,4 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) +- [codechef.com](https://www.codechef.com/) (:necktie:) From 5a7f1a9bb603e7d874625c4195f6778a271be862 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:58:40 +0530 Subject: [PATCH 012/178] Update README.ko.md (#88) Co-authored-by: Samuel Huang --- README.ko.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.ko.md b/README.ko.md index a95fad8a..13ae2960 100644 --- a/README.ko.md +++ b/README.ko.md @@ -137,3 +137,4 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) +- [codechef.com](https://www.codechef.com/) (:necktie:) From 59d212082c24a15a212862965feab76aa42f7307 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:59:28 +0530 Subject: [PATCH 013/178] Update README.zh_tw.md (#89) Co-authored-by: Samuel Huang --- README.zh_tw.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.zh_tw.md b/README.zh_tw.md index b4050ed6..d1c863b9 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -133,3 +133,4 @@ print("Ultimate Python 學習大綱") - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) +- [codechef.com](https://www.codechef.com/) (:necktie:) From d908ef289bdf3c1fe148ec076a66ea223ecf0453 Mon Sep 17 00:00:00 2001 From: Mayuresh Dharwadkar <98738585+Mayureshd-18@users.noreply.github.com> Date: Mon, 9 Oct 2023 22:23:55 +0530 Subject: [PATCH 014/178] Add codeforces link in readme (#91) * Update README.md * Update README.ko.md * Update README.zh_tw.md * Update README.es.md * Update README.de.md --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + 5 files changed, 5 insertions(+) diff --git a/README.de.md b/README.de.md index 0b8a9e5a..e59fec40 100644 --- a/README.de.md +++ b/README.de.md @@ -150,3 +150,4 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [codeforces.com](https://codeforces.com/) diff --git a/README.es.md b/README.es.md index 00017da1..f9250166 100644 --- a/README.es.md +++ b/README.es.md @@ -149,3 +149,4 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [codeforces.com](https://codeforces.com/) diff --git a/README.ko.md b/README.ko.md index 13ae2960..204c2c1c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -138,3 +138,4 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [codeforces.com](https://codeforces.com/) diff --git a/README.md b/README.md index 14828615..95169419 100644 --- a/README.md +++ b/README.md @@ -151,3 +151,4 @@ Keep practicing so that your coding skills don't get rusty. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [codeforces.com](https://codeforces.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index d1c863b9..8ae5b572 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -134,3 +134,4 @@ print("Ultimate Python 學習大綱") - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [codeforces.com](https://codeforces.com/) From 8f3cb0025b09896d8c491fd266a34b44a0a809e6 Mon Sep 17 00:00:00 2001 From: "Ajay Gonepuri (GONAPCORP)" <98868227+HKABIG@users.noreply.github.com> Date: Mon, 9 Oct 2023 22:27:51 +0530 Subject: [PATCH 015/178] Added w3schools link (#92) * Update README.md * Update README.ko.md * Update README.ko.md * Update README.zh_tw.md * Update README.es.md * Update README.de.md --------- Co-authored-by: Samuel Huang --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + 5 files changed, 5 insertions(+) diff --git a/README.de.md b/README.de.md index e59fec40..b36bd614 100644 --- a/README.de.md +++ b/README.de.md @@ -150,4 +150,5 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) diff --git a/README.es.md b/README.es.md index f9250166..66d68557 100644 --- a/README.es.md +++ b/README.es.md @@ -149,4 +149,5 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) diff --git a/README.ko.md b/README.ko.md index 204c2c1c..0c2d54e4 100644 --- a/README.ko.md +++ b/README.ko.md @@ -138,4 +138,5 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) diff --git a/README.md b/README.md index 95169419..eace54fa 100644 --- a/README.md +++ b/README.md @@ -151,4 +151,5 @@ Keep practicing so that your coding skills don't get rusty. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index 8ae5b572..87b12d95 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -134,4 +134,5 @@ print("Ultimate Python 學習大綱") - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) From 9e4cdeb5a0caa9202826cb59c4b171daef72e1f8 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:10:08 +0530 Subject: [PATCH 016/178] Update README.ko.md (#98) --- README.ko.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.ko.md b/README.ko.md index 0c2d54e4..6a0185a5 100644 --- a/README.ko.md +++ b/README.ko.md @@ -124,6 +124,7 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) ### 대화 형 연습 @@ -140,3 +141,5 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [codechef.com](https://www.codechef.com/) (:necktie:) - [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) +- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) From 9f534fb187ad7e6f47d6e54b5f6dfb09043222d0 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:11:29 +0530 Subject: [PATCH 017/178] Update README.zh_tw.md (#99) Co-authored-by: Samuel Huang --- README.zh_tw.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.zh_tw.md b/README.zh_tw.md index 87b12d95..f97a8329 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -120,7 +120,8 @@ print("Ultimate Python 學習大綱") - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) + ### 互動練習 繼續練習才能使您的編碼技能不會生疏。 @@ -136,3 +137,5 @@ print("Ultimate Python 學習大綱") - [codechef.com](https://www.codechef.com/) (:necktie:) - [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) +- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) From 97660252c393dea4768c667f2907366f4ce784d3 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:12:38 +0530 Subject: [PATCH 018/178] Update README.es.md (#97) * Update README.es.md * Update README.es.md --------- Co-authored-by: Samuel Huang --- README.es.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.es.md b/README.es.md index 66d68557..3ddc413d 100644 --- a/README.es.md +++ b/README.es.md @@ -135,7 +135,8 @@ Sigue aprendiendo leyendo otros buenos recursos. - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) + ### Práctica interactiva Continua practicando para que no se oxiden tus habilidades de programación. @@ -151,3 +152,5 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [codechef.com](https://www.codechef.com/) (:necktie:) - [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) +- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) From 1316e19a8daffb5fcc392064abc34003e390a8a7 Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:14:02 +0530 Subject: [PATCH 019/178] Update README.de.md (#96) * Update README.de.md * Update README.de.md Add space --------- Co-authored-by: Samuel Huang --- README.de.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.de.md b/README.de.md index b36bd614..ad43aebb 100644 --- a/README.de.md +++ b/README.de.md @@ -136,6 +136,7 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) ### Interaktive Übungen @@ -152,3 +153,5 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [codechef.com](https://www.codechef.com/) (:necktie:) - [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) +- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) From 79b0ad6dfc3ca88fd1421196d76d4d49f6fcc6da Mon Sep 17 00:00:00 2001 From: PRIYANSHU VARSHNEY <124420199+harshhere905@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:15:26 +0530 Subject: [PATCH 020/178] Update README.md (#90) * Update README.md * Update README.md --------- Co-authored-by: Samuel Huang --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index eace54fa..36c9a7fd 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ Keep learning by reading from other well-regarded resources. - [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) ### Interactive practice @@ -151,5 +152,8 @@ Keep practicing so that your coding skills don't get rusty. - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) (:necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) +- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) - [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) + From 34127922ca8fd575636b9d9188611b793863c15c Mon Sep 17 00:00:00 2001 From: "Ajay Gonepuri (GONAPCORP)" <98868227+HKABIG@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:51:27 +0530 Subject: [PATCH 021/178] Added namedtuples data structure (#95) * Update README.md * Update README.ko.md * Update README.ko.md * Update README.zh_tw.md * Update README.es.md * Update README.de.md * Create namedtuple.py * Update README.md English * Update README.ko.md * Update README.zh_tw.md * Update README.es.md * Update README.de.md * Update namedtuple.py Tried to make to add main function with assert statements as in previous in previous lessons as an example * Update namedtuple.py added asserts and main function and blank lines to pass circle CI test * Update namedtuple.py added blank lines at appropriate positions and added assert and main function into the code * Update namedtuple.py Circle CI testing * Update namedtuple.py testing * Update namedtuple.py passing codecov test * Update namedtuple.py * Update namedtuple.py * Update namedtuple.py * Update namedtuple.py --------- Co-authored-by: Samuel Huang --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + ultimatepython/data_structures/namedtuple.py | 67 ++++++++++++++++++++ 6 files changed, 72 insertions(+) create mode 100644 ultimatepython/data_structures/namedtuple.py diff --git a/README.de.md b/README.de.md index ad43aebb..6c191b04 100644 --- a/README.de.md +++ b/README.de.md @@ -91,6 +91,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - String: [String operations](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Klassen** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.es.md b/README.es.md index 3ddc413d..11824eb4 100644 --- a/README.es.md +++ b/README.es.md @@ -90,6 +90,7 @@ Hay dos maneras de ejecutar los módulos: - Comprensión: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Clases** - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.ko.md b/README.ko.md index 6a0185a5..8e93806e 100644 --- a/README.ko.md +++ b/README.ko.md @@ -79,6 +79,7 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - 이해력 : [목록 | 튜플 | 세트 | dict](ultimatepython/data_structures/comprehension.py) - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - 시간 복잡성 : [cPython 작업](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **클래스** - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.md b/README.md index 36c9a7fd..47f7e17d 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ There are two ways of running the modules: - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - String: [String operations](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Classes** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.zh_tw.md b/README.zh_tw.md index f97a8329..25444c98 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -75,6 +75,7 @@ print("Ultimate Python 學習大綱") - 綜合:[list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - 字串:[字串操作](ultimatepython/data_structures/string.py) (:cake:) - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) (:exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **類別** - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/ultimatepython/data_structures/namedtuple.py b/ultimatepython/data_structures/namedtuple.py new file mode 100644 index 00000000..3e10710b --- /dev/null +++ b/ultimatepython/data_structures/namedtuple.py @@ -0,0 +1,67 @@ +""" +This module demonstrates the use of named tuples, which are a data structure +with named fields, similar to a class but lightweight and immutable. Named +tuples are created using the namedtuple function from the collections module. +""" +from collections import namedtuple + + +def main(): + # Named Tuple Attributes: + # - namedtuple: Callable from collections to define a named tuple + # - Point: A named tuple type with fields "x" and "y" + Point = namedtuple("Point", ["x", "y"]) + + # Named Tuple Fields: + # - x and y: Fields of the named tuple Point representing coordinates + # - point1 and point2: Instances of the Point named tuple + point1 = Point(x=1, y=2) + point2 = Point(x=3, y=4) + assert isinstance(point1, Point) is True + assert isinstance(point2, Point) is True + + # Named Tuple Operations: + # - Accessing fields using dot notation + # - Named tuples are immutable + # - Named tuples support tuple operations + # - Converting named tuples to dictionaries and vice versa + # - Additional methods and attributes + assert point1.x == 1 + assert point1.y == 2 + assert point2.x == 3 + assert point2.y == 4 + + # Attempt to change the "x" field of point1 (raises an error) + access_immutable_error = False + try: + point1.x = 5 + except AttributeError: + access_immutable_error = True + assert access_immutable_error is True + + # One can access Point data by indexes + assert point1[0] + point2[0] == 4 + assert point1[0] + point2[1] == 5 + assert point1[1] + point2[0] == 5 + assert point1[1] + point2[1] == 6 + + point_dict = point1._asdict() + assert point_dict == {"x": 1, "y": 2} + + # It is possible to initialize a Point without explicit parameters + point3 = Point(10, 20) + assert point3.x == 10 + assert point3.y == 20 + assert Point._fields == ("x", "y") + + # It is also possible to create a new point out of an existing one + point4 = point1._replace(x=5) + assert point4.x == 5 + assert point4.y == 2 + + # Note that point4 is not the same as point1 + assert id(point4) != id(point1) + + +if __name__ == "__main__": + main() From bf349e1e47d5379ddf0d554aac99618f580b77f9 Mon Sep 17 00:00:00 2001 From: Jeremias Moreira Gomes Date: Mon, 16 Oct 2023 05:27:57 -0300 Subject: [PATCH 022/178] None special literal type. (#104) * None special literal type. * E721. * Identity check removal. * Update variable.py --------- Co-authored-by: Samuel Huang --- ultimatepython/syntax/variable.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ultimatepython/syntax/variable.py b/ultimatepython/syntax/variable.py index 442d67b9..234314cd 100644 --- a/ultimatepython/syntax/variable.py +++ b/ultimatepython/syntax/variable.py @@ -49,6 +49,13 @@ def main(): assert 0x01_0f_2c == 69_420 assert 3.456_290e-1 == 0.3_456_290 + # There is also a special literal called None. This literal is used to + # point that a particular variable or object is not created + e = None + e_type = type(e) + assert e_type is type(None) + assert isinstance(e, object) and isinstance(e_type, object) + if __name__ == "__main__": main() From e81ab1d898e2a72e8aee527705c454814a4d359e Mon Sep 17 00:00:00 2001 From: Priyanshu Sharma <132160817+iPriyanshu19@users.noreply.github.com> Date: Mon, 16 Oct 2023 19:52:04 +0530 Subject: [PATCH 023/178] Updated Readme (#107) --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + 5 files changed, 5 insertions(+) diff --git a/README.de.md b/README.de.md index 6c191b04..839ffa1a 100644 --- a/README.de.md +++ b/README.de.md @@ -156,3 +156,4 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [codeforces.com](https://codeforces.com/) - [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) - [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [replit.com](https://replit.com/) diff --git a/README.es.md b/README.es.md index 11824eb4..cf2985c8 100644 --- a/README.es.md +++ b/README.es.md @@ -155,3 +155,4 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [codeforces.com](https://codeforces.com/) - [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) - [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [replit.com](https://replit.com/) diff --git a/README.ko.md b/README.ko.md index 8e93806e..00ce1ecb 100644 --- a/README.ko.md +++ b/README.ko.md @@ -144,3 +144,4 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [codeforces.com](https://codeforces.com/) - [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) - [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [replit.com](https://replit.com/) diff --git a/README.md b/README.md index 47f7e17d..2ea081d5 100644 --- a/README.md +++ b/README.md @@ -157,4 +157,5 @@ Keep practicing so that your coding skills don't get rusty. - [coderbyte.com](https://www.coderbyte.com/) (:necktie:) - [w3schools.com](https://www.w3schools.com/python/) (:brain:) - [codeforces.com](https://codeforces.com/) +- [replit.com](https://replit.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index 25444c98..28c81005 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -140,3 +140,4 @@ print("Ultimate Python 學習大綱") - [codeforces.com](https://codeforces.com/) - [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) - [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [replit.com](https://replit.com/) From c5ae8bb05caa3169f587648bf1da6fc3a3787ede Mon Sep 17 00:00:00 2001 From: Jeremias Moreira Gomes Date: Thu, 19 Oct 2023 07:44:34 -0300 Subject: [PATCH 024/178] defaultdict data structure. (#105) * defaultdict data structure. * E201. * Using an EPS value to compare floats. * E302. * READMEs. --------- Co-authored-by: Samuel Huang --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + ultimatepython/data_structures/defaultdict.py | 57 +++++++++++++++++++ 6 files changed, 62 insertions(+) create mode 100644 ultimatepython/data_structures/defaultdict.py diff --git a/README.de.md b/README.de.md index 839ffa1a..9fe47a48 100644 --- a/README.de.md +++ b/README.de.md @@ -92,6 +92,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - String: [String operations](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Klassen** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.es.md b/README.es.md index cf2985c8..a6fa9b03 100644 --- a/README.es.md +++ b/README.es.md @@ -91,6 +91,7 @@ Hay dos maneras de ejecutar los módulos: - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Clases** - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.ko.md b/README.ko.md index 00ce1ecb..05126449 100644 --- a/README.ko.md +++ b/README.ko.md @@ -80,6 +80,7 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - 시간 복잡성 : [cPython 작업](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **클래스** - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.md b/README.md index 2ea081d5..291dbedb 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ There are two ways of running the modules: - String: [String operations](ultimatepython/data_structures/string.py) (:cake:) - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Classes** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/README.zh_tw.md b/README.zh_tw.md index 28c81005..12d7a8a2 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -76,6 +76,7 @@ print("Ultimate Python 學習大綱") - 字串:[字串操作](ultimatepython/data_structures/string.py) (:cake:) - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **類別** - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) (:cake:) diff --git a/ultimatepython/data_structures/defaultdict.py b/ultimatepython/data_structures/defaultdict.py new file mode 100644 index 00000000..331c6104 --- /dev/null +++ b/ultimatepython/data_structures/defaultdict.py @@ -0,0 +1,57 @@ +""" +This module demonstrates the use of defaultdict, which is a dictionary that is +possible to setup a default value in its creation. +""" + +from collections import defaultdict + +# Module-level constants +_GPA_MIN = 0.0 +_GPA_MAX = 4.0 +_EPS = 0.000001 + + +def main(): + # Let's create a defaultdict with student keys and GPA values. The first + # parameter is called default_factory and it is the initialization value for + # first use of a key. It can be a common type or a function + student_gpa = defaultdict(float, [("john", 3.5), ("bob", 2.8), ("mary", 3.2)]) + + # There are three student records in this dictionary + assert len(student_gpa) == 3 + + # Each student has a name key and a GPA value + assert len(student_gpa.keys()) == len(student_gpa.values()) + + # We can get the names in isolation. Note that in Python 3.7 and + # above, dictionary entries are sorted in the order that they were + # defined or inserted + student_names = [] + for student in student_gpa.keys(): + student_names.append(student) + assert student_names == ["john", "bob", "mary"] + + # We can get the GPA for a specific student + assert abs(student_gpa["john"] < 3.5) < _EPS + + # And the defaultdict allow us to get the GPA of a student that is not in + # the data structure yet, returning a default value for float that is 0.0 + assert student_gpa["jane"] == _GPA_MIN + + # And now there are four student records in this dictionary + assert len(student_gpa) == 4 + + # You can set the default value in default_factory attribute + def set_default_to_gpa_max(): + return _GPA_MAX + + student_gpa.default_factory = set_default_to_gpa_max + + assert student_gpa["rika"] == _GPA_MAX + + # And now there are five student records in this dictionary + assert len(student_gpa) == 5 + + +if __name__ == "__main__": + main() From 1906ca5278623f9b712915d16d9c3271284700a9 Mon Sep 17 00:00:00 2001 From: Armaan <104704093+0Armaan025@users.noreply.github.com> Date: Thu, 19 Oct 2023 22:49:39 +0530 Subject: [PATCH 025/178] Updated CONTRIBUTING.md, made it better (#110) --- CONTRIBUTING.md | 159 ++++++++++++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 65 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f043dc95..fa3716b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,95 +1,124 @@ -# Contributing +# 🚀 Welcome to the Ultimate Python Study Guide! 📚 -Thanks for taking the time to understand how you can contribute to the -Ultimate Python Study guide! +🎉 Thank you for considering contributing to this awesome project! 🎉 -Please take a look at the [code of conduct](CODE_OF_CONDUCT.md) before -proceeding further. +But first, before you jump in, let's vibe with our [Code of Conduct](CODE_OF_CONDUCT.md). We want this space to be 🌈 inclusive, respectful, and nothing but fun! ---- +## 🐍 What's This All About? -The repository consists of documentation and Python modules. Before you -contribute to the repository with a pull request, review all of the standards -listed in upcoming sections. That way, you can maintain the craftsmanship of -this project and still make an impact on the developers using this project -for learning purposes. +Our Python Study Guide is your ticket to Python mastery! 🐍 This place is all about energy, excitement, and pure Python magic. 💫 -## README documentation +## 📖 Let's Talk Documentation -The [README](README.md) is important because it is the most frequently viewed -page in this repository. As such, any changes that are made to this page must -follow these guidelines: +Our README is like the opening act at a concert. It's where the party starts, and we want it to be sensational! Here are the keys to this performance: -- Translations are referenced at the top -- Python modules are referenced in the ToC -- External links point to HTTPS resources that return a `2xx` status -- Python documentation is useful for newcomers and professionals -- GitHub repositories have at least 1k stars -- Practice resources have Python exercises +- Translations? 🌍 Yes, they're right at the top for everyone to enjoy! +- Python modules? 🤓 Oh, they've got a VIP seat in our Table of Contents (ToC). +- External links? 🔗 They're all about HTTPS and that sweet `2xx` status. +- Python documentation? For both newbies and wizards, it's all in here! +- GitHub repositories? 🌟 We love stars! If it's got at least 1k stars, bring it on! +- Practice resources? 🏋️‍♂️ We've got Python exercises to keep you in shape. -## Python modules +## 📚 Get into Python Modules -Every Python module is a standalone lesson which helps developers build -their own intuition for core Python. Each module has a name that corresponds -to a topic and explores concepts with `assert` statements. This approach -encourages test-driven development and makes it simple for developers to -discern what the expected output from the code is. +Our Python modules are like mini-python-parties that you can host anywhere! They're packed with energy and make learning a blast! 🎉 -Certain Python concepts are skipped in this study guide because the modules -do not reference each other and make small use of I/O operations. But this -limitation also allows the lessons to be pasted freely to any computing -environment such as an IDE, a browser window or a standalone application. +### 🧩 The Setup -When creating or updating Python modules, please respect the guidelines in -the sub-sections below. - -### Standard structure - -Every standalone Python module consists of the following: +Each Python module follows a rock-solid structure: ```python -# Main function +# The main event 🎉 def main(): - # Assertion comments + # Here's where the magic happens! assert 1 + 1 == 2 assert True is not False - -# Main function conditional +# The show must go on if __name__ == "__main__": main() ``` -If the module involves additional functions and classes, they are placed -above the `main` function. +If there's more Python goodness, it's up front before the main event! -### Style conventions +### ✨ Style and Shine -The project follows conventions from these PEP proposals: +We've got style, oh baby! Check out the PEPs: -- [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) -- [PEP 257 -- Docstring Conventions](https://www.python.org/dev/peps/pep-0257/) +- [PEP 8](https://www.python.org/dev/peps/pep-0008) - Our fashion bible! +- [PEP 257](https://www.python.org/dev/peps/pep-0257) - Docstring Glamour! -The project has additional conventions: +But there's more! We have our own style: -- Module imports are arranged by [isort](https://github.com/timothycrosley/isort) -- Module constants follow an `_UNDER_SCORE_FIRST` convention -- Strings have "double-quotes" unless a `"` exists in the string -- Dynamic strings make use of [f-strings](https://www.python.org/dev/peps/pep-0498/) +- Imports are perfectly sorted with [isort](https://github.com/timothycrosley/isort). +- Constants? They follow the `_UNDER_SCORE_FIRST` party rule. +- Strings love double-quotes, but if there's a `"`, they'll use single quotes! +- For dynamic strings, it's all about those fabulous f-strings! 🎤 -### Code coverage +### 📈 Code Coverage Stars -Each module should have 80-100% code coverage with the [test runner](runner.py). -The reason for this high standard is that the repository code is relatively -simple. All interactive learning tends to revolve around the `main` function -since that is where the assertions are. That way, developers immediately know -when they make a mistake in the module. This is valuable feedback because it -helps them improve quickly. +We like to keep the energy high, and that means every module should have a whopping 80-100% code coverage! Our modules are like dance floors, and we don't want any empty spaces. That's because each module is a standalone lesson, and the `main` function is where the magic happens. -To validate code coverage, run the following commands: +## 🌟 Your Contribution -```bash -$ coverage run -m runner -$ coverage html -$ open htmlcov/index.html -``` +Your contributions are like the encore at a concert - they're a big deal! We appreciate your dedication to making this project even more amazing. Don't hesitate to reach out if you have any questions. Your contributions, no matter how small, are making a big difference in the Python learning world! + +So, get ready to rock and roll, Python style! 🤘🐍💥 + +# 💥 Dive into the Python World + +Python is a versatile language used in web development, data analysis, artificial intelligence, and more. As a contributor, you're joining a vibrant community of learners and mentors. + +# 🧑‍💻 Learning Together + +Our project isn't just a repository; it's a collaborative learning experience. You can learn from the contributions of others and share your Python wisdom with the world. Together, we can unlock the true potential of this fantastic language. + +# 🚀 Opportunities Galore + +When you contribute to this project, you're not just improving it; you're also enhancing your own skills. You might discover new Python tricks, learn more about best practices, and even find inspiration for your own projects. + +# 🌍 Global Impact + +Python is a worldwide phenomenon, and your contributions will impact Python enthusiasts globally. Your work can help someone on the other side of the planet learn Python, kickstart their career, or solve a problem they've been struggling with. + +# 🙋‍♀️ Join a Supportive Community + +Our community is welcoming and supportive. If you have questions or need guidance, don't hesitate to ask. We're all here to help each other and grow together. + +# 📢 Your Voice Matters + +Your unique perspective is valuable. If you have ideas to make this guide even more engaging or fun, share them with us! We're open to creative and innovative suggestions. + +# 🤖 Evolving with Python + +Python is constantly evolving, and so is our guide. You can help keep it up-to-date, ensuring that learners always have access to the latest Python features and best practices. + +# 🎉 Your Contribution Matters + +Your contributions, whether they are big or small, are the building blocks of our project's success. Together, we're creating a resource that makes Python more accessible and exciting. + +# 🌟 Be a Python Star + +By contributing to this project, you're becoming a Python star, and you're helping others shine brightly too. Let's light up the Python world together! + +## How to Contribute + +Ready to dive in? Here's how you can contribute: + +1. **Fork the Repository**: Head to [https://github.com/huangsam/ultimate-python/](https://github.com/huangsam/ultimate-python/) and click the "Fork" button in the top right corner. + +2. **Clone Your Fork**: After forking, you'll have your copy of the repository. Clone it to your local machine. + + + +3. **Make Your Contributions**: Create or update Python modules, documentation, or anything that adds value to the project. + +4. **Push Your Changes**: Once your work is ready, push your changes to your forked repository. + +5. **Create a Pull Request**: Head back to the original repository (https://github.com/huangsam/ultimate-python/) and create a pull request. Describe your changes and let us know why they're awesome. + +We're excited to see what you bring to the table! Your contributions are making the Python world a better place. + +Please don't hesitate to reach out if you have any questions. Your contributions, no matter how small, are making a big difference! 🌟🐍💥 + +## Feel the Pythonic Energy - Contribute Now!🔥 \ No newline at end of file From 579b42003a00e6b883bdffdd0b9ba2c4ebe3248e Mon Sep 17 00:00:00 2001 From: Suin Kim Date: Sun, 22 Oct 2023 06:32:01 +0900 Subject: [PATCH 026/178] docs: refine README.ko.md for Clarity and Accuracy (#112) --- README.ko.md | 101 ++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/README.ko.md b/README.ko.md index 05126449..a1bc7958 100644 --- a/README.ko.md +++ b/README.ko.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) [![r/Python](https://img.shields.io/reddit/subreddit-subscribers/Python)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -초보자와 전문가 모두를위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: +초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: ```python print("Ultimate Python 학습 가이드") @@ -18,38 +18,39 @@ print("Ultimate Python 학습 가이드") [Español](README.es.md) | [Deutsch](README.de.md) -## 이 학습 가이드를 만든 이유 +## 동기 -저는 지난 5 년 동안 대학 졸업생, 대규모 회사의 직원, 셀러리 및 풀 스택 Python과 같은 저장소의 오픈 소스 기고자로 -Python을 사용하면서 핵심 Python에 대해 배운 내용을 공유하기 위해 GitHub 저장소를 만들었습니다. 더 많은 사람들이 -파이썬을 배우고 그것을 통해 그들의 열정을 추구하는 것을 기대합니다. :mortar_board: +이 GitHub 저장소는 대학 졸업 후, 대규모 회사에서 근무하면서 +그리고 [Celery](https://github.com/celery/celery)와 [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) 같은 오픈소스 프로젝트에 기여하면서 +지난 5년 이상 동안 배운 [core Python](https://www.python.org/)에 대한 지식을 공유하기 위해 만들었습니다. +저는 더 많은 사람들이 Python을 배우고 자신의 열정을 추구하길 기대합니다. :mortar_board: ## 목표 -이 가이드를 만드는 기본 목표는 다음과 같습니다. +이 가이드를 만드는 주요 목표는 다음과 같습니다: -:trophy: 실습 학습을 선호하는 Python 초보자를위한 리소스 역할을합니다. 이 저장소에는 PyCharm과 같은 IDE 및 -Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음이 있습니다. 평범한 오래된 터미널조차도 예제와 함께 -작동합니다. 대부분의 줄에는 프로그램이 단계별로 수행하는 작업을 독자에게 안내하는 신중하게 작성된 주석이 있습니다. -기본 루틴이 삭제되지 않고 각 변경 후 성공적으로 실행되는 한 사용자는 어디에서나 소스 코드를 수정하는 것이 좋습니다. +:trophy: 실습 학습을 선호하는 Python 초보자를 위한 **학습 자료를 제공합니다.** +이 저장소에는 [PyCharm](https://www.jetbrains.com/pycharm/)과 같은 IDE 및 [Replit](https://replit.com/languages/python3)와 같은 브라우저에서 실행할 수 있는 독립형 모듈 모음이 있습니다. 기본 터미널에서도 예제를 실행할 수 있습니다. +대부분의 코드 라인에 프로그램이 단계별로 어떤 작업을 하는지 안내하는 신중하게 작성된 주석이 있습니다. +사용자는 `main` 루틴을 삭제하지 않고, 각 변경 후에 [성공적으로 실행](runner.py)되는 한 소스 코드를 얼마든지 수정할 수 있습니다. -:trophy: 핵심 Python 개념을 다시 검토하려는 사용자를위한 순수한 가이드 역할을합니다. 기본 라이브러리 만 활용되므로 -도메인 별 개념의 오버 헤드없이 이러한 개념을 전달할 수 있습니다. 따라서 인기있는 오픈 소스 라이브러리 및 프레임 워크 -(예 : `sqlalchemy`, `requests`, `pandas`)는 설치되지 않습니다. 그러나 목표가 진정한 Pythonista가되는 것이라면 -이러한 프레임 워크의 소스 코드를 읽는 것은 고무적이고 적극 권장됩니다. +:trophy: core Python 개념을 다시 복습하고 싶은 사람들을 위한 **순수 가이드를 제공합니다.** +여기서는 오직 [내장 라이브러리](https://docs.python.org/3/library/)만을 사용하여 이러한 개념을 도메인 특화된 개념의 오버헤드 없이 전달합니다. +따라서 유명한 오픈소스 라이브러리와 프레임워크(`sqlalchemy`, `requests`, `pandas` 등)는 설치되어 있지 않습니다. +그러나, 이러한 프레임워크의 소스 코드를 읽는 것은 당신이 진정한 [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista)가 되는데 매우 도움이 될 것입니다. ## 시작하기 -[![Run on Repl.it](https://repl.it/badge/github/huangsam/ultimate-python)](https://repl.it/github/huangsam/ultimate-python) +[![Run on Replit](https://repl.it/badge/github/huangsam/ultimate-python)](https://repl.it/github/huangsam/ultimate-python) 로컬 컴퓨터에 Git 및 Python을 설치하지 않고도 브라우저에서 작업 환경을 시작하려면 위의 배지를 클릭하세요. 이러한 -요구 사항이 이미 충족 된 경우 저장소를 직접 복제해도됩니다. +요구 사항이 이미 충족된 경우, 저장소를 바로 clone해도 됩니다. -저장소에 액세스 할 수있게되면 독립형 모듈에서 배울 준비가 된 것입니다. 각 모듈을 최대한 활용하려면 모듈 코드를 -읽고 실행하십시오. 모듈을 실행하는 두 가지 방법이 있습니다. +저장소에 접근할 수 있게 되면 독립형 모듈에서 배울 준비가 된 것입니다. 각 모듈을 최대한 활용하려면 모듈 코드를 +읽고 실행하십시오. 모듈을 실행하는 두 가지 방법이 있습니다: 1. 단일 모듈 실행 : `python ultimatepython/syntax/variable.py` -2. 모든 모듈을 실행합니다. `python runner.py` +2. 전체 모듈 실행 : `python runner.py` ## 목차 @@ -58,60 +59,60 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 :exploding_head: = 고급 주제 1. **Python 정보** - - 개요 : [Python이란 무엇입니까](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) + - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) (:books:) - - 스타일 가이드 : [Python 코드 용 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) + - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) (:books:, :exploding_head:) - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) (:books:, :exploding_head:) - - 내장 기능 : [내장 기능](https://docs.python.org/3/library/functions.html) (:books:) + - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) (:books:) 2. **통사론** - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) (:cake:) - - 식 : [숫자 연산](ultimatepython/syntax/expression.py) (:cake:) - - 비트별: [비트 연산자](ultimatepython/syntax/bitwise.py) (:cake:), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - 조건부 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - - 루프 : [for 루프 | while-loop](ultimatepython/syntax/loop.py) (:cake:) - - 함수 : [def | 람다](ultimatepython/syntax/function.py) (:cake:) + - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) (:cake:) + - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) (:cake:), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) + - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) + - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) + - 함수 : [def | lambda](ultimatepython/syntax/function.py) (:cake:) 3. **데이터 구조** - - 목록 : [목록 작업](ultimatepython/data_structures/list.py) (:cake:) + - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) (:cake:) - 튜플 : [튜플 연산](ultimatepython/data_structures/tuple.py) - - 설정 : [설정 작업](ultimatepython/data_structures/set.py) - - Dict : [사전 작업](ultimatepython/data_structures/dict.py) (:cake:) - - 이해력 : [목록 | 튜플 | 세트 | dict](ultimatepython/data_structures/comprehension.py) + - 세트 : [세트 연산](ultimatepython/data_structures/set.py) + - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) (:cake:) + - 컴프리헨션 : [리스트 | 튜플 | 세트 | 딕셔너리](ultimatepython/data_structures/comprehension.py) - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) (:cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) + - 덱: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - - 시간 복잡성 : [cPython 작업](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) + - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **클래스** - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) (:cake:) - 추상 클래스 : [추상 정의](ultimatepython/classes/abstract_class.py) - 예외 클래스 : [예외 정의](ultimatepython/classes/exception_class.py) - - 반복기 클래스 : [반복기 정의 | 수익률](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) - 캡슐화: [캡슐화 정의](ultimatepython/classes/encapsulation.py) 5. **고급** - - 데코레이터 : [데코레이터 정의 | 랩](ultimatepython/advanced/decorator.py) (:exploding_head:) - - 컨텍스트 관리자 : [컨텍스트 관리자](ultimatepython/advanced/context_manager.py) (:exploding_head:) - - 메서드 해결 순서 : [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - - Mixin : [Mixin 정의](ultimatepython/advanced/mixin.py) (:exploding_head:) - - 메타 클래스 : [메타 클래스 정의](ultimatepython/advanced/meta_class.py) (:exploding_head:) - - 글타래 (쓰레드) : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) - - Asyncio : [비동기 | 기다리다](ultimatepython/advanced/async.py) (:exploding_head:) + - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) + - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) (:exploding_head:) + - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) (:exploding_head:) + - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) (:exploding_head:) + - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) (:exploding_head:) + - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) + - Asyncio : [async | await](ultimatepython/advanced/async.py) (:exploding_head:) - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) (:exploding_head:) - - 벤치 마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) - - 조롱 : [MagicMock | PropertyMock | 패치](ultimatepython/advanced/mocking.py) (:exploding_head:) - - 정규식 : [검색 | findall | 일치 | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) - - 데이터 형식 : [json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) - - 날짜 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) + - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) + - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) (:exploding_head:) + - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) + - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) + - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) ## 추가 자료 -:necktie: = 인터뷰 리소스, +:necktie: = 인터뷰 자료, :test_tube: = 코드 샘플, :brain: = 프로젝트 아이디어 ### GitHub 저장소 -다른 잘 알려진 자료를 읽으면서 계속 배우십시오. +잘 알려진 다른 자료를 읽으면서 계속 배우십시오. - [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) - [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) @@ -128,9 +129,9 @@ Repl.it와 같은 브라우저에서 실행할 수있는 독립형 모듈 모음 - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) -### 대화 형 연습 +### 대화형 연습 -코딩 기술이 녹슬지 않도록 계속 연습하십시오. +코딩 기술을 유지하기 위해 계속 연습하십시오. - [leetcode.com](https://leetcode.com/) (:necktie:) - [hackerrank.com](https://www.hackerrank.com/) (:necktie:) From 0a1aaa557a16a9d300c197a72ce43b1b1746e5da Mon Sep 17 00:00:00 2001 From: Archisman Bera <95976290+ArcXeon@users.noreply.github.com> Date: Sun, 22 Oct 2023 03:11:09 +0530 Subject: [PATCH 027/178] Added File Handling (#103) * Create file_handling.py * Update README.md * Update README.de.md * Update README.de.md * Update README.md * Update README.es.md * Update README.zh_tw.md * Update README.ko.md * Update file_handling.py * Update file_handling.py * Update file_handling.py * Update file_handling.py * Update file_handling.py * Update file_handling.py * Update file_handling.py * Update file_handling.py --------- Co-authored-by: Samuel Huang --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + ultimatepython/advanced/file_handling.py | 60 ++++++++++++++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 ultimatepython/advanced/file_handling.py diff --git a/README.de.md b/README.de.md index 9fe47a48..427ecfc3 100644 --- a/README.de.md +++ b/README.de.md @@ -102,6 +102,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Fortgeschrittene** - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) (:exploding_head:) - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) - Method resolution order: [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) (:exploding_head:) diff --git a/README.es.md b/README.es.md index a6fa9b03..7d6e6f3c 100644 --- a/README.es.md +++ b/README.es.md @@ -101,6 +101,7 @@ Hay dos maneras de ejecutar los módulos: - Encapsulación: [Definición de encapsulación](ultimatepython/classes/encapsulation.py) 5. **Avanzado** - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) + - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) (:exploding_head:) - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) (:exploding_head:) - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) (:exploding_head:) diff --git a/README.ko.md b/README.ko.md index a1bc7958..1bcf4c17 100644 --- a/README.ko.md +++ b/README.ko.md @@ -91,6 +91,7 @@ print("Ultimate Python 학습 가이드") - 캡슐화: [캡슐화 정의](ultimatepython/classes/encapsulation.py) 5. **고급** - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) + - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) (:exploding_head:) - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) (:exploding_head:) - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) (:exploding_head:) diff --git a/README.md b/README.md index 291dbedb..b0f7158a 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ There are two ways of running the modules: - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Advanced** - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) (:exploding_head:) - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) - Method resolution order: [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) (:exploding_head:) diff --git a/README.zh_tw.md b/README.zh_tw.md index 12d7a8a2..4f951ca1 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -86,6 +86,7 @@ print("Ultimate Python 學習大綱") - 封裝: [封裝定義](ultimatepython/classes/encapsulation.py) 5. **進階技巧** - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) + - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) (:exploding_head:) - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) - 方法解析順序:[mro](ultimatepython/advanced/mro.py) (:exploding_head:) - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) (:exploding_head:) diff --git a/ultimatepython/advanced/file_handling.py b/ultimatepython/advanced/file_handling.py new file mode 100644 index 00000000..98ab9102 --- /dev/null +++ b/ultimatepython/advanced/file_handling.py @@ -0,0 +1,60 @@ +""" +File handling is a fundamental concept in Python that involves +opening, reading, writing, and appending to files. This module +demonstrates the basics of file handling in Python. + +Python provides various ways to work with files. We can use the +builtin 'open' function to open files in different modes like +reading ('r'), writing ('w'), and appending ('a'). +""" +import os + +_TARGET_FILE = "sample.txt" + + +def read_file(filename): + """Read content from existing file.""" + with open(filename, "r") as file: + content = file.read() + return content + + +def write_file(filename, content): + """Write content to new file.""" + with open(filename, "w") as file: + file.write(content) + return f"Content written to '{filename}'." + + +def append_file(filename, content): + """Append content to existing file.""" + with open(filename, "a") as file: + file.write(content) + return f"Content appended to '{filename}'." + + +def delete_file(filename): + """Delete content of existing file.""" + os.remove(filename) + return f"'{filename}' has been deleted." + + +def main(): + result = write_file(_TARGET_FILE, "This is a test.") + assert result == f"Content written to '{_TARGET_FILE}'." + + content = read_file(_TARGET_FILE) + assert content == "This is a test." + + append_result = append_file(_TARGET_FILE, "\nThis is an appended line.") + assert append_result == f"Content appended to '{_TARGET_FILE}'." + + content = read_file(_TARGET_FILE) + assert content == "This is a test.\nThis is an appended line." + + delete_result = delete_file(_TARGET_FILE) + assert delete_result == f"'{_TARGET_FILE}' has been deleted." + + +if __name__ == "__main__": + main() From 1fbb0dac7d5625e8d998ff0c6da953a05ce65c47 Mon Sep 17 00:00:00 2001 From: mirageoasis <37329424+mirageoasis@users.noreply.github.com> Date: Wed, 25 Oct 2023 02:46:19 +0900 Subject: [PATCH 028/178] Refined korean readme.md (#113) * docs: refine README.ko.md for more korean way of speaking * docs: fixed suffix of korean to make more korean way of speaking --- README.ko.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.ko.md b/README.ko.md index 1bcf4c17..1191f413 100644 --- a/README.ko.md +++ b/README.ko.md @@ -37,7 +37,7 @@ print("Ultimate Python 학습 가이드") :trophy: core Python 개념을 다시 복습하고 싶은 사람들을 위한 **순수 가이드를 제공합니다.** 여기서는 오직 [내장 라이브러리](https://docs.python.org/3/library/)만을 사용하여 이러한 개념을 도메인 특화된 개념의 오버헤드 없이 전달합니다. 따라서 유명한 오픈소스 라이브러리와 프레임워크(`sqlalchemy`, `requests`, `pandas` 등)는 설치되어 있지 않습니다. -그러나, 이러한 프레임워크의 소스 코드를 읽는 것은 당신이 진정한 [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista)가 되는데 매우 도움이 될 것입니다. +그러나, 당신의 목표가 진정한 진정한 [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista)이 되는 것 이라면 이러한 프레임워크의 소스 코드를 읽는 것은 매우 고무적이고 권장이 됩니다. ## 시작하기 @@ -46,7 +46,7 @@ print("Ultimate Python 학습 가이드") 로컬 컴퓨터에 Git 및 Python을 설치하지 않고도 브라우저에서 작업 환경을 시작하려면 위의 배지를 클릭하세요. 이러한 요구 사항이 이미 충족된 경우, 저장소를 바로 clone해도 됩니다. -저장소에 접근할 수 있게 되면 독립형 모듈에서 배울 준비가 된 것입니다. 각 모듈을 최대한 활용하려면 모듈 코드를 +저장소에 접근할 수 있게 되면 단독 모듈에서 배울 준비가 된 것입니다. 각 모듈을 최대한 활용하려면 모듈 코드를 읽고 실행하십시오. 모듈을 실행하는 두 가지 방법이 있습니다: 1. 단일 모듈 실행 : `python ultimatepython/syntax/variable.py` @@ -113,7 +113,7 @@ print("Ultimate Python 학습 가이드") ### GitHub 저장소 -잘 알려진 다른 자료를 읽으면서 계속 배우십시오. +잘 알려진 다른 자료를 읽으면서 계속 배우세요. - [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) - [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) @@ -132,7 +132,7 @@ print("Ultimate Python 학습 가이드") ### 대화형 연습 -코딩 기술을 유지하기 위해 계속 연습하십시오. +코딩 실력이 녹슬지 않기 위해 계속 연습하세요. - [leetcode.com](https://leetcode.com/) (:necktie:) - [hackerrank.com](https://www.hackerrank.com/) (:necktie:) From 54e921df02720b5c1ff340aa2c51c782f7a84ef9 Mon Sep 17 00:00:00 2001 From: Aswin P Kumar <130536278+The-APK@users.noreply.github.com> Date: Wed, 25 Oct 2023 22:33:21 +0530 Subject: [PATCH 029/178] added tutorial for heap (#111) * added tutorial for heap * Delete ultimatepython/data_structures/heap.py * Added tutorial for heap * Update heap.py * Delete ultimatepython/data_structures/heap.py * Added tutorial for heap * Delete ultimatepython/data_structures/heap.py * Added the updated file * Update heap.py * Delete ultimatepython/data_structures/heap.py * Added updated heap file --- ultimatepython/data_structures/heap.py | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 ultimatepython/data_structures/heap.py diff --git a/ultimatepython/data_structures/heap.py b/ultimatepython/data_structures/heap.py new file mode 100644 index 00000000..8a640d8a --- /dev/null +++ b/ultimatepython/data_structures/heap.py @@ -0,0 +1,62 @@ +import heapq + + +def main(): + # Define the list of numbers + nums = [3, 1, 4, 1, 5] + + # Creating a min-heap + min_heap = [] + for num in nums: + heapq.heappush(min_heap, num) + assert min_heap[0] == 1 # The root of the heap is the smallest element + + # Pop the smallest element + smallest = heapq.heappop(min_heap) + assert smallest == 1 + + # Adding a new element + heapq.heappush(min_heap, 5) + assert min_heap[0] == 1 # The root remains the smallest element + + # Creating a max-heap + max_heap = [] + for num in nums: + heapq.heappush(max_heap, -num) # Negate numbers for a max-heap + assert -max_heap[0] == 5 # The root of the heap is the largest element + + # Pop the largest element + largest = -heapq.heappop(max_heap) + assert largest == 5 + + # Converting a list to a heap in-place + data = [3, 1, 4, 1, 5] + heapq.heapify(data) + assert data[0] == 1 # The root is the smallest element + + # Extending a heap + more_data = [2, 6, 5] + for item in more_data: + heapq.heappush(data, item) + assert data[0] == 1 # The root is still the smallest element + + # Using heap for sorting + sorted_data = [heapq.heappop(data) for _ in range(len(data))] + assert sorted_data == [1, 1, 2, 3, 4, 5, 5, 6] + + # Getting the n smallest or largest elements from a list + n_smallest = heapq.nsmallest(3, nums) # Get the 3 smallest elements + assert n_smallest == [1, 1, 3] + + n_largest = heapq.nlargest(3, nums) # Get the 3 largest elements + assert n_largest == [5, 4, 3] + + # Merging multiple sorted lists into a single sorted list using a heap + list1 = [1, 3, 5, 7] + list2 = [2, 4, 6, 8] + merged_list = list(heapq.merge(list1, list2)) + assert merged_list == [1, 2, 3, 4, 5, 6, 7, 8] + + +if __name__ == "__main__": + main() From d46985e47e855f7f082c6a5902984fb1c570eb51 Mon Sep 17 00:00:00 2001 From: Jeremias Moreira Gomes Date: Fri, 27 Oct 2023 16:32:38 -0300 Subject: [PATCH 030/178] Adding a tutorial for inheritance to the classes part. (#119) * Inheritance. * F401. E302. W291. W293. * Assertion for car showing an advantage of inheritance. * Typo. --- README.de.md | 1 + README.es.md | 1 + README.ko.md | 1 + README.md | 1 + ultimatepython/classes/inheritance.py | 140 ++++++++++++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 ultimatepython/classes/inheritance.py diff --git a/README.de.md b/README.de.md index 427ecfc3..ab1b4e0c 100644 --- a/README.de.md +++ b/README.de.md @@ -96,6 +96,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Klassen** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) (:cake:) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) diff --git a/README.es.md b/README.es.md index 7d6e6f3c..aeb4fd4d 100644 --- a/README.es.md +++ b/README.es.md @@ -95,6 +95,7 @@ Hay dos maneras de ejecutar los módulos: - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Clases** - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) (:cake:) + - Herencia: [Herencia](ultimatepython/classes/inheritance.py) (:cake:) - Clase abstracta: [Definición de abstracta](ultimatepython/classes/abstract_class.py) - Clase de excepción: [Definición de excepción](ultimatepython/classes/exception_class.py) - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) diff --git a/README.ko.md b/README.ko.md index 1191f413..7bf8316f 100644 --- a/README.ko.md +++ b/README.ko.md @@ -85,6 +85,7 @@ print("Ultimate Python 학습 가이드") - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **클래스** - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) (:cake:) + - 계승: [계승](ultimatepython/classes/inheritance.py) (:cake:) - 추상 클래스 : [추상 정의](ultimatepython/classes/abstract_class.py) - 예외 클래스 : [예외 정의](ultimatepython/classes/exception_class.py) - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) diff --git a/README.md b/README.md index b0f7158a..7fba6a50 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ There are two ways of running the modules: - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) 4. **Classes** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) (:cake:) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) diff --git a/ultimatepython/classes/inheritance.py b/ultimatepython/classes/inheritance.py new file mode 100644 index 00000000..c9725f7e --- /dev/null +++ b/ultimatepython/classes/inheritance.py @@ -0,0 +1,140 @@ +""" +Inheritance is a way to reuse code and data from a parent class. This +allow us to avoid repeating ourselves and to build upon existing +functionality. This module defines a basic vehicle class, creates a car +class that inherits from vehicle, then creates a truck class that +inherits from car and use it for demonstration purposes. +""" +from inspect import isfunction, ismethod + + +class Vehicle: + """Basic definition of a vehicle. + + We begin with a simple mental model of what a vehicle is. It has + a make, model, year, and miles. That way, we can start exploring + the core concepts that are associated with a class definition. + """ + + def __init__(self, make, model, year, miles): + """Construct a vehicle with make, model, year, and miles.""" + self.make = make + self.model = model + self.year = year + self.miles = miles + + def __repr__(self): + """Return the formal representation of a vehicle.""" + return f"" + + def __str__(self): + """Return the informal representation of a vehicle.""" + return f"{self.make} {self.model} ({self.year})" + + def drive(self, rate_in_mph): + """Drive a vehicle at a certain rate in MPH.""" + return f"{self} is driving at {rate_in_mph} MPH" + + +class Car(Vehicle): + """Definition of a car. + + We inherit from the vehicle class to reuse the code and data that + we have already defined. In addition, we add a new attribute called + `wheels` to the car class. This is an example of extending the + functionality of a parent class. In __init__, we call the parent + constructor with the `super` function. This is a way to invoke the + parent constructor without having to explicitly name the parent + class. We also override the method `__repr__` to have a different + output than the vehicle. + """ + + def __init__(self, make, model, year, miles): + """Construct a car with make, model, year, miles, and wheels.""" + super().__init__(make, model, year, miles) + self.wheels = 4 + + def __repr__(self): + """Return the formal representation of a car.""" + return f"" + + +class Truck(Vehicle): + """Definition of a truck. + + We inherit from vehicle just like we did with the car class. In this case we + will also override the method `drive` to have a different output than the + car and the vehicle. + """ + + def __init__(self, make, model, year, miles): + """Construct a truck with make, model, year, miles, and wheels.""" + super().__init__(make, model, year, miles) + self.wheels = 6 + + def __repr__(self): + """Return the formal representation of a truck.""" + return f"" + + def drive(self, rate_in_mph): + """Drive a truck at a certain rate in MPH.""" + return f"{self} is driving a truck at {rate_in_mph} MPH" + + +def main(): + # Create a vehicle with the provided class constructor + vehicle = Vehicle("Mistery Machine", "Van", 1969, 100000.0) + + # Formal representation + assert repr(vehicle) == "" + + # Informal representation + assert str(vehicle) == "Mistery Machine Van (1969)" + + # Call a method on the class constructor + assert vehicle.drive(50) == "Mistery Machine Van (1969) is driving at 50 MPH" + + # Check the type of the method drive + assert ismethod(vehicle.drive) and not isfunction(vehicle.drive) + + # Now we create a car with the provided class constructor + car = Car("DeLorean", "DMC-12", 1982, 220000.0) + + # The informal representation is similar to the vehicle + assert str(car) == "DeLorean DMC-12 (1982)" + + # But the formal representation is different because we included + # the wheels attribute + assert repr(car) == "" + + # And we can check the type of the method drive like we did with + # the vehicle + assert ismethod(car.drive) and not isfunction(car.drive) + + # If we call the method drive, we can see that we did not + # write any code for the car class, but we can still use it + # because it is inherited from the vehicle class and the + # behavior is the same as the vehicle + assert car.drive(50) == "DeLorean DMC-12 (1982) is driving at 50 MPH" + + # Now we create a truck with the provided class constructor + truck = Truck("Optimus Prime", "Truck", 1984, 1000000.0) + + # Like car and vehicle, the informal representation is similar + assert str(truck) == "Optimus Prime Truck (1984)" + + # And the formal representation is different from the vehicle + # because we included the wheels attribute + assert repr(truck) == "" + + # And we can check the type of the method drive like we did with + # the vehicle + assert ismethod(truck.drive) and not isfunction(truck.drive) + + # For the last part, we can see that the method drive is different + # for the truck + assert truck.drive(50) == "Optimus Prime Truck (1984) is driving a truck at 50 MPH" + + +if __name__ == "__main__": + main() From fc87853861cb861ead6812cc1c352fb1f13ff0ef Mon Sep 17 00:00:00 2001 From: sentious <115402871+Sentious@users.noreply.github.com> Date: Sat, 28 Oct 2023 01:07:26 +0530 Subject: [PATCH 031/178] Update list.py (#120) * Update list.py Added sorting to lists * Update list.py * Update list.py --------- Co-authored-by: Samuel Huang --- ultimatepython/data_structures/list.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ultimatepython/data_structures/list.py b/ultimatepython/data_structures/list.py index 608f1519..18d4376d 100644 --- a/ultimatepython/data_structures/list.py +++ b/ultimatepython/data_structures/list.py @@ -87,6 +87,11 @@ def main(): lengthy.pop() # pop out the 4 from the back assert lengthy == [0, 1, 2, 3] + # Let's sort this list in ascending order + numbers = [5, 4, 3, 2, 1] + numbers.sort() + assert numbers == [1, 2, 3, 4, 5] + if __name__ == "__main__": main() From de99b73ce24c6a68ad91890aae3b455ec444ca92 Mon Sep 17 00:00:00 2001 From: Jeremias Moreira Gomes Date: Mon, 30 Oct 2023 14:08:52 -0300 Subject: [PATCH 032/178] Chained comparisons in conditional.py. (#124) * Chained comparisons in conditional.py. * Change in the range. * Adjust to fit the code coverage. * W291. * Does comments make any difference to codecov? --- ultimatepython/syntax/conditional.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ultimatepython/syntax/conditional.py b/ultimatepython/syntax/conditional.py index aafa2ba2..3cdc27bd 100644 --- a/ultimatepython/syntax/conditional.py +++ b/ultimatepython/syntax/conditional.py @@ -50,6 +50,17 @@ def main(): ran_5 = True if x_add_two == 3 else False assert ran_5 is True + # Python is one of the few programming languages that allows chained + # comparisons. This is useful for checking if a variable is within + # a range of values. You can see that in this example, the expression + # `0 < x_add_two < 2` is equivalent to `x_add_two > 0 and x_add_two < 2` + ran_6 = False + if 0 < x_add_two < 2: + ran_6 = False # skip: if + else: + ran_6 = True # run + assert ran_6 is True + if __name__ == "__main__": main() From 7be181e78dad317829ee38f1189108d1c27671f0 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 19 Dec 2023 09:37:13 -0800 Subject: [PATCH 033/178] Update dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 95891ee8..510a8671 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.3.0 +coverage==7.3.3 flake8==6.1.0 -isort==5.12.0 +isort==5.13.2 From 6a80158dd4210455ed9bbbfcd4a7b8413a84917b Mon Sep 17 00:00:00 2001 From: Animish Yadav <66960835+AnimishY@users.noreply.github.com> Date: Wed, 3 Jan 2024 22:54:45 +0530 Subject: [PATCH 034/178] Fixed Emoji Visibility (#126) * Fixed Emoji Visibility * fixing emoji visibility other languages readmes updates. --- README.de.md | 102 ++++++++++++++++++++++++------------------------ README.es.md | 100 +++++++++++++++++++++++------------------------ README.ko.md | 102 ++++++++++++++++++++++++------------------------ README.md | 102 ++++++++++++++++++++++++------------------------ README.zh_tw.md | 100 +++++++++++++++++++++++------------------------ 5 files changed, 253 insertions(+), 253 deletions(-) diff --git a/README.de.md b/README.de.md index ab1b4e0c..0bdbf3a6 100644 --- a/README.de.md +++ b/README.de.md @@ -70,52 +70,52 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: :exploding_head: = Fortgeschrittenes Thema 1. **Über Python** - - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) - - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) (:books:) - - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) - - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) (:books:, :exploding_head:) - - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) (:books:, :exploding_head:) - - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) (:books:) + - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) + - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) + - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) + - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) + - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head:) + - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books:) 2. **Syntax** - - Variable: [Built-in literals](ultimatepython/syntax/variable.py) (:cake:) - - Expression: [Numeric operations](ultimatepython/syntax/expression.py) (:cake:) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) (:cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - - Function: [def | lambda](ultimatepython/syntax/function.py) (:cake:) + - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake:) + - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake:) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) + - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) + - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) + - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake:) 3. **Daten-Strukturen** - - List: [List operations](ultimatepython/data_structures/list.py) (:cake:) + - List: [List operations](ultimatepython/data_structures/list.py) ( :cake:) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) (:cake:) + - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake:) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - String: [String operations](ultimatepython/data_structures/string.py) (:cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) + - String: [String operations](ultimatepython/data_structures/string.py) ( :cake:) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) + - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) 4. **Klassen** - - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) - - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) (:cake:) + - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake:) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake:) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Fortgeschrittene** - - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) (:exploding_head:) - - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) - - Method resolution order: [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) (:exploding_head:) - - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) (:exploding_head:) - - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) - - Asyncio: [async | await](ultimatepython/advanced/async.py) (:exploding_head:) - - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) (:exploding_head:) - - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) (:exploding_head:) - - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) - - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) - - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) + - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head:) + - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head:) + - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) + - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head:) + - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head:) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) + - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) + - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) + - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) ## Zusätzliche Ressourcen @@ -127,36 +127,36 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: Lernen Sie weiter, indem Sie von anderen Quellen lesen. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) (:test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) (:test_tube:) -- [karan/Projects](https://github.com/karan/Projects) (:brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) (:brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) +- [karan/Projects](https://github.com/karan/Projects) ( :brain:) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) ### Interaktive Übungen Üben Sie weiter, damit Ihre Programmierkenntnisse nicht einrosten. -- [leetcode.com](https://leetcode.com/) (:necktie:) -- [hackerrank.com](https://www.hackerrank.com/) (:necktie:) -- [kaggle.com](https://www.kaggle.com/) (:brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie:) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) +- [kaggle.com](https://www.kaggle.com/) ( :brain:) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) (:necktie:) -- [w3schools.com](https://www.w3schools.com/python/) (:brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie:) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) -- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) - [replit.com](https://replit.com/) diff --git a/README.es.md b/README.es.md index aeb4fd4d..c0b08963 100644 --- a/README.es.md +++ b/README.es.md @@ -69,52 +69,52 @@ Hay dos maneras de ejecutar los módulos: :exploding_head: = Tema avanzado 1. **Sobre Python** - - Resumen: [¿Qué es Python?](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) - - Filosofía de diseño: [El Zen de Python](https://www.python.org/dev/peps/pep-0020/) (:books:) - - Guía de estilos: [Guía de estilos para código de Python](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) - - Modelo de datos: [Modelo de datos](https://docs.python.org/3/reference/datamodel.html) (:books:, :exploding_head:) - - Librería estándar: [La librería estándar de Python](https://docs.python.org/3/library/) (:books:, :exploding_head:) - - Funciones integradas: [Funciones integradas](https://docs.python.org/3/library/functions.html) (:books:) + - Resumen: [¿Qué es Python?](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) + - Filosofía de diseño: [El Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) + - Guía de estilos: [Guía de estilos para código de Python](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) + - Modelo de datos: [Modelo de datos](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) + - Librería estándar: [La librería estándar de Python](https://docs.python.org/3/library/) ( :books:, :exploding_head:) + - Funciones integradas: [Funciones integradas](https://docs.python.org/3/library/functions.html) ( :books:) 2. **Sintaxis** - - Variables: [Literales integrados](ultimatepython/syntax/variable.py) (:cake:) - - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) (:cake:) - - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) (:cake:), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - - Funciones: [def | lambda](ultimatepython/syntax/function.py) (:cake:) + - Variables: [Literales integrados](ultimatepython/syntax/variable.py) ( :cake:) + - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) ( :cake:) + - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) ( :cake:), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) + - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) + - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) + - Funciones: [def | lambda](ultimatepython/syntax/function.py) ( :cake:) 3. **Estructura de datos** - - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) (:cake:) + - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) ( :cake:) - Tupla: [Operaciones con tuplas](ultimatepython/data_structures/tuple.py) - Set: [Operaciones con sets](ultimatepython/data_structures/set.py) - - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) (:cake:) + - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) ( :cake:) - Comprensión: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) (:cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) + - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) ( :cake:) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) + - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) 4. **Clases** - - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) (:cake:) - - Herencia: [Herencia](ultimatepython/classes/inheritance.py) (:cake:) + - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) ( :cake:) + - Herencia: [Herencia](ultimatepython/classes/inheritance.py) ( :cake:) - Clase abstracta: [Definición de abstracta](ultimatepython/classes/abstract_class.py) - Clase de excepción: [Definición de excepción](ultimatepython/classes/exception_class.py) - - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) - Encapsulación: [Definición de encapsulación](ultimatepython/classes/encapsulation.py) 5. **Avanzado** - - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) (:exploding_head:) - - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) (:exploding_head:) - - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) (:exploding_head:) - - Metaclase: [Definición de metaclase](ultimatepython/advanced/meta_class.py) (:exploding_head:) - - Hilos: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) - - Asyncio: [async | await](ultimatepython/advanced/async.py) (:exploding_head:) - - Referencias débiles: [weakref](ultimatepython/advanced/weak_ref.py) (:exploding_head:) - - Referencia: [cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) (:exploding_head:) - - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) - - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) - - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) + - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) + - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) ( :exploding_head:) + - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) ( :exploding_head:) + - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) + - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) ( :exploding_head:) + - Metaclase: [Definición de metaclase](ultimatepython/advanced/meta_class.py) ( :exploding_head:) + - Hilos: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) + - Referencias débiles: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) + - Referencia: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) + - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) + - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) + - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) ## Recursos adicionales @@ -126,36 +126,36 @@ Hay dos maneras de ejecutar los módulos: Sigue aprendiendo leyendo otros buenos recursos. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) (:test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) (:test_tube:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) - [karan/Projects](https://github.com/karan/Projects) (:brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) (:brain:) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) ### Práctica interactiva Continua practicando para que no se oxiden tus habilidades de programación. -- [leetcode.com](https://leetcode.com/) (:necktie:) -- [hackerrank.com](https://www.hackerrank.com/) (:necktie:) -- [kaggle.com](https://www.kaggle.com/) (:brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie:) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) +- [kaggle.com](https://www.kaggle.com/) ( :brain:) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) (:necktie:) -- [w3schools.com](https://www.w3schools.com/python/) (:brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie:) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) -- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) - [replit.com](https://replit.com/) diff --git a/README.ko.md b/README.ko.md index 7bf8316f..efc94f94 100644 --- a/README.ko.md +++ b/README.ko.md @@ -59,52 +59,52 @@ print("Ultimate Python 학습 가이드") :exploding_head: = 고급 주제 1. **Python 정보** - - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) - - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) (:books:) - - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) - - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) (:books:, :exploding_head:) - - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) (:books:, :exploding_head:) - - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) (:books:) + - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) + - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) + - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) + - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) + - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) ( :books:, :exploding_head:) + - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) ( :books:) 2. **통사론** - - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) (:cake:) - - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) (:cake:) - - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) (:cake:), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - - 함수 : [def | lambda](ultimatepython/syntax/function.py) (:cake:) + - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) ( :cake:) + - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) ( :cake:) + - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) ( :cake:), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) + - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) + - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) + - 함수 : [def | lambda](ultimatepython/syntax/function.py) ( :cake:) 3. **데이터 구조** - - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) (:cake:) + - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) ( :cake:) - 튜플 : [튜플 연산](ultimatepython/data_structures/tuple.py) - 세트 : [세트 연산](ultimatepython/data_structures/set.py) - - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) (:cake:) + - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) ( :cake:) - 컴프리헨션 : [리스트 | 튜플 | 세트 | 딕셔너리](ultimatepython/data_structures/comprehension.py) - - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) (:cake:) - - 덱: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) + - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) ( :cake:) + - 덱: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) + - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) 4. **클래스** - - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) (:cake:) - - 계승: [계승](ultimatepython/classes/inheritance.py) (:cake:) + - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) ( :cake:) + - 계승: [계승](ultimatepython/classes/inheritance.py) ( :cake:) - 추상 클래스 : [추상 정의](ultimatepython/classes/abstract_class.py) - 예외 클래스 : [예외 정의](ultimatepython/classes/exception_class.py) - - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) - 캡슐화: [캡슐화 정의](ultimatepython/classes/encapsulation.py) 5. **고급** - - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) (:exploding_head:) - - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) (:exploding_head:) - - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) (:exploding_head:) - - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) (:exploding_head:) - - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) - - Asyncio : [async | await](ultimatepython/advanced/async.py) (:exploding_head:) - - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) (:exploding_head:) - - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) - - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) (:exploding_head:) - - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) - - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) - - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) + - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) + - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) ( :exploding_head:) + - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) ( :exploding_head:) + - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) + - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) ( :exploding_head:) + - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) ( :exploding_head:) + - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) + - Asyncio : [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) + - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) + - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) + - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) + - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) + - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) + - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) ## 추가 자료 @@ -116,36 +116,36 @@ print("Ultimate Python 학습 가이드") 잘 알려진 다른 자료를 읽으면서 계속 배우세요. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) (:test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) (:test_tube:) -- [karan/Projects](https://github.com/karan/Projects) (:brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) (:brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) +- [karan/Projects](https://github.com/karan/Projects) ( :brain:) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) ### 대화형 연습 코딩 실력이 녹슬지 않기 위해 계속 연습하세요. -- [leetcode.com](https://leetcode.com/) (:necktie:) -- [hackerrank.com](https://www.hackerrank.com/) (:necktie:) -- [kaggle.com](https://www.kaggle.com/) (:brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie:) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) +- [kaggle.com](https://www.kaggle.com/) ( :brain:) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) (:necktie:) -- [w3schools.com](https://www.w3schools.com/python/) (:brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie:) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) -- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) - [replit.com](https://replit.com/) diff --git a/README.md b/README.md index 7fba6a50..d1977810 100644 --- a/README.md +++ b/README.md @@ -71,52 +71,52 @@ There are two ways of running the modules: :exploding_head: = Advanced topic 1. **About Python** - - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) - - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) (:books:) - - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) - - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) (:books:, :exploding_head:) - - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) (:books:, :exploding_head:) - - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) (:books:) + - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) + - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) + - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) + - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) + - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head:) + - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books:) 2. **Syntax** - - Variable: [Built-in literals](ultimatepython/syntax/variable.py) (:cake:) - - Expression: [Numeric operations](ultimatepython/syntax/expression.py) (:cake:) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) (:cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) (:cake:) - - Function: [def | lambda](ultimatepython/syntax/function.py) (:cake:) + - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake:) + - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake:) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) + - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) + - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) + - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake:) 3. **Data Structures** - - List: [List operations](ultimatepython/data_structures/list.py) (:cake:) + - List: [List operations](ultimatepython/data_structures/list.py) ( :cake:) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) (:cake:) + - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake:) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - String: [String operations](ultimatepython/data_structures/string.py) (:cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) + - String: [String operations](ultimatepython/data_structures/string.py) ( :cake:) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) + - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) 4. **Classes** - - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) (:cake:) - - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) (:cake:) + - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake:) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake:) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Advanced** - - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) (:exploding_head:) - - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) - - Method resolution order: [mro](ultimatepython/advanced/mro.py) (:exploding_head:) - - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) (:exploding_head:) - - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) (:exploding_head:) - - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) - - Asyncio: [async | await](ultimatepython/advanced/async.py) (:exploding_head:) - - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) (:exploding_head:) - - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) (:exploding_head:) - - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) - - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) - - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) + - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head:) + - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head:) + - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) + - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head:) + - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head:) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) + - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) + - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) + - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) ## Additional resources @@ -128,37 +128,37 @@ There are two ways of running the modules: Keep learning by reading from other well-regarded resources. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) (:test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) (:test_tube:) -- [karan/Projects](https://github.com/karan/Projects) (:brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) (:brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie: , :test_tube:) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie: , :test_tube:) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) +- [karan/Projects](https://github.com/karan/Projects) ( :brain:) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) ### Interactive practice Keep practicing so that your coding skills don't get rusty. -- [leetcode.com](https://leetcode.com/) (:necktie:) -- [hackerrank.com](https://www.hackerrank.com/) (:necktie:) -- [kaggle.com](https://www.kaggle.com/) (:brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie:) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) +- [kaggle.com](https://www.kaggle.com/) ( :brain:) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) (:necktie:) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) -- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) -- [w3schools.com](https://www.w3schools.com/python/) (:brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) - [codeforces.com](https://codeforces.com/) - [replit.com](https://replit.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index 4f951ca1..ab3f68d2 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -54,51 +54,51 @@ print("Ultimate Python 學習大綱") :exploding_head: = 進階題目 1. **關於 Python** - - 概述:[什麼是 Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) (:books:, :cake:) - - 設計理念:[Python之格言](https://www.python.org/dev/peps/pep-0020/) (:books:) - - 樣式指南:[Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/) (:books:, :exploding_head:) - - 數據模型:[數據模型](https://docs.python.org/3/reference/datamodel.html) (:books:, :exploding_head:) - - 標準庫:[Python標準庫](https://docs.python.org/3/library/) (:books:, :exploding_head:) - - 內置函式:[內置函式](https://docs.python.org/3/library/functions.html) (:books:) + - 概述:[什麼是 Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) + - 設計理念:[Python之格言](https://www.python.org/dev/peps/pep-0020/) ( :books:) + - 樣式指南:[Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) + - 數據模型:[數據模型](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) + - 標準庫:[Python標準庫](https://docs.python.org/3/library/) ( :books:, :exploding_head:) + - 內置函式:[內置函式](https://docs.python.org/3/library/functions.html) ( :books:) 2. **語法** - - 變數:[內置值](ultimatepython/syntax/variable.py) (:cake:) - - 運算式:[數值運算](ultimatepython/syntax/expression.py) (:cake:) - - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) (:cake:), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) (:cake:) - - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) (:cake:) - - 定義函式:[def | lambda](ultimatepython/syntax/function.py) (:cake:) + - 變數:[內置值](ultimatepython/syntax/variable.py) ( :cake:) + - 運算式:[數值運算](ultimatepython/syntax/expression.py) ( :cake:) + - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) ( :cake:), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) + - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) + - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) ( :cake:) + - 定義函式:[def | lambda](ultimatepython/syntax/function.py) ( :cake:) 3. **資料結構** - - 列表:[列表操作](ultimatepython/data_structures/list.py) (:cake:) + - 列表:[列表操作](ultimatepython/data_structures/list.py) ( :cake:) - 元組:[元組操作](ultimatepython/data_structures/tuple.py) - 集合:[集合操作](ultimatepython/data_structures/set.py) - - 字典:[字典操作](ultimatepython/data_structures/dict.py) (:cake:) + - 字典:[字典操作](ultimatepython/data_structures/dict.py) ( :cake:) - 綜合:[list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - 字串:[字串操作](ultimatepython/data_structures/string.py) (:cake:) - - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) (:exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) (:exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) (:exploding_head:) - - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) (:books:, :exploding_head:) + - 字串:[字串操作](ultimatepython/data_structures/string.py) ( :cake:) + - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) + - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) 4. **類別** - - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) (:cake:) + - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) ( :cake:) - 抽象類別:[抽象定義](ultimatepython/classes/abstract_class.py) - 異常類別:[異常定義](ultimatepython/classes/exception_class.py) - - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) (:exploding_head:) + - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) ( :exploding_head:) - 封裝: [封裝定義](ultimatepython/classes/encapsulation.py) 5. **進階技巧** - - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) (:exploding_head:) - - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) (:exploding_head:) - - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) (:exploding_head:) - - 方法解析順序:[mro](ultimatepython/advanced/mro.py) (:exploding_head:) - - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) (:exploding_head:) - - 元類:[Metaclass定義](ultimatepython/advanced/meta_class.py) (:exploding_head:) - - 執行緒:[ThreadPoolExecutor](ultimatepython/advanced/thread.py) (:exploding_head:) - - 異步:[async | await](ultimatepython/advanced/async.py) (:exploding_head:) - - 弱引用:[weakref](ultimatepython/advanced/weak_ref.py) (:exploding_head:) - - 基準:[cProfile | pstats](ultimatepython/advanced/benchmark.py) (:exploding_head:) - - 模擬:[MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) (:exploding_head:) - - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) (:exploding_head:) - - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) (:exploding_head:) - - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) (:exploding_head:) + - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) + - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head:) + - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head:) + - 方法解析順序:[mro](ultimatepython/advanced/mro.py) ( :exploding_head:) + - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) ( :exploding_head:) + - 元類:[Metaclass定義](ultimatepython/advanced/meta_class.py) ( :exploding_head:) + - 執行緒:[ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) + - 異步:[async | await](ultimatepython/advanced/async.py) ( :exploding_head:) + - 弱引用:[weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) + - 基準:[cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) + - 模擬:[MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) + - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) + - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) + - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) ## 額外資源 @@ -110,36 +110,36 @@ print("Ultimate Python 學習大綱") 通過閱讀其他備受尊重的資源來繼續學習。 -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) (:necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) (:necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) (:test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) (:test_tube:) -- [karan/Projects](https://github.com/karan/Projects) (:brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) (:brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) +- [karan/Projects](https://github.com/karan/Projects) ( :brain:) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) (:test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) (:necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) ### 互動練習 繼續練習才能使您的編碼技能不會生疏。 -- [leetcode.com](https://leetcode.com/) (:necktie:) -- [hackerrank.com](https://www.hackerrank.com/) (:necktie:) -- [kaggle.com](https://www.kaggle.com/) (:brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie:) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) +- [kaggle.com](https://www.kaggle.com/) ( :brain:) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) (:necktie:) -- [w3schools.com](https://www.w3schools.com/python/) (:brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie:) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) (:necktie:) -- [coderbyte.com](https://www.coderbyte.com/) (:necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) - [replit.com](https://replit.com/) From 905ad8a3aa40dd2aa78eaa8472b177a12fc49215 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 6 Jan 2024 22:29:46 -0800 Subject: [PATCH 035/178] Update formatting of emojis --- README.de.md | 102 ++++++++++++++++++++++++------------------------ README.es.md | 102 ++++++++++++++++++++++++------------------------ README.ko.md | 102 ++++++++++++++++++++++++------------------------ README.md | 102 ++++++++++++++++++++++++------------------------ README.zh_tw.md | 100 +++++++++++++++++++++++------------------------ 5 files changed, 254 insertions(+), 254 deletions(-) diff --git a/README.de.md b/README.de.md index 0bdbf3a6..3fe51a82 100644 --- a/README.de.md +++ b/README.de.md @@ -70,52 +70,52 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: :exploding_head: = Fortgeschrittenes Thema 1. **Über Python** - - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) - - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) - - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) - - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) - - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head:) - - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books:) + - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) + - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) + - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) + - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) + - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) + - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books: ) 2. **Syntax** - - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake:) - - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake:) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) - - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) - - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) - - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake:) + - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake: ) + - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake: ) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake: ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) + - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) + - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) + - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) 3. **Daten-Strukturen** - - List: [List operations](ultimatepython/data_structures/list.py) ( :cake:) + - List: [List operations](ultimatepython/data_structures/list.py) ( :cake: ) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake:) + - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake: ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - String: [String operations](ultimatepython/data_structures/string.py) ( :cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) - - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) + - String: [String operations](ultimatepython/data_structures/string.py) ( :cake: ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) + - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) 4. **Klassen** - - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake:) - - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake:) + - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake: ) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake: ) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) + - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Fortgeschrittene** - - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) - - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head:) - - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head:) - - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) - - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head:) - - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head:) - - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) - - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) - - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) - - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) - - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) - - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) - - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) + - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) + - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) + - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) + - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head: ) + - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) + - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) + - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) + - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) ## Zusätzliche Ressourcen @@ -127,36 +127,36 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: Lernen Sie weiter, indem Sie von anderen Quellen lesen. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) -- [karan/Projects](https://github.com/karan/Projects) ( :brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) +- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) ### Interaktive Übungen Üben Sie weiter, damit Ihre Programmierkenntnisse nicht einrosten. -- [leetcode.com](https://leetcode.com/) ( :necktie:) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) -- [kaggle.com](https://www.kaggle.com/) ( :brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) ( :necktie:) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [replit.com](https://replit.com/) diff --git a/README.es.md b/README.es.md index c0b08963..9cb1ea6f 100644 --- a/README.es.md +++ b/README.es.md @@ -69,52 +69,52 @@ Hay dos maneras de ejecutar los módulos: :exploding_head: = Tema avanzado 1. **Sobre Python** - - Resumen: [¿Qué es Python?](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) - - Filosofía de diseño: [El Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) - - Guía de estilos: [Guía de estilos para código de Python](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) - - Modelo de datos: [Modelo de datos](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) - - Librería estándar: [La librería estándar de Python](https://docs.python.org/3/library/) ( :books:, :exploding_head:) - - Funciones integradas: [Funciones integradas](https://docs.python.org/3/library/functions.html) ( :books:) + - Resumen: [¿Qué es Python?](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) + - Filosofía de diseño: [El Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) + - Guía de estilos: [Guía de estilos para código de Python](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) + - Modelo de datos: [Modelo de datos](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) + - Librería estándar: [La librería estándar de Python](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) + - Funciones integradas: [Funciones integradas](https://docs.python.org/3/library/functions.html) ( :books: ) 2. **Sintaxis** - - Variables: [Literales integrados](ultimatepython/syntax/variable.py) ( :cake:) - - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) ( :cake:) - - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) ( :cake:), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) - - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) - - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) - - Funciones: [def | lambda](ultimatepython/syntax/function.py) ( :cake:) + - Variables: [Literales integrados](ultimatepython/syntax/variable.py) ( :cake: ) + - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) ( :cake: ) + - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) ( :cake: ), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) + - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) + - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) + - Funciones: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) 3. **Estructura de datos** - - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) ( :cake:) + - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) ( :cake: ) - Tupla: [Operaciones con tuplas](ultimatepython/data_structures/tuple.py) - Set: [Operaciones con sets](ultimatepython/data_structures/set.py) - - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) ( :cake:) + - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) ( :cake: ) - Comprensión: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) ( :cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) - - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) + - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) ( :cake: ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) + - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) 4. **Clases** - - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) ( :cake:) - - Herencia: [Herencia](ultimatepython/classes/inheritance.py) ( :cake:) + - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) ( :cake: ) + - Herencia: [Herencia](ultimatepython/classes/inheritance.py) ( :cake: ) - Clase abstracta: [Definición de abstracta](ultimatepython/classes/abstract_class.py) - Clase de excepción: [Definición de excepción](ultimatepython/classes/exception_class.py) - - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) + - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) - Encapsulación: [Definición de encapsulación](ultimatepython/classes/encapsulation.py) 5. **Avanzado** - - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) - - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) ( :exploding_head:) - - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) ( :exploding_head:) - - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) - - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) ( :exploding_head:) - - Metaclase: [Definición de metaclase](ultimatepython/advanced/meta_class.py) ( :exploding_head:) - - Hilos: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) - - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) - - Referencias débiles: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) - - Referencia: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) - - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) - - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) - - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) + - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) + - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) + - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) + - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) + - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) ( :exploding_head: ) + - Metaclase: [Definición de metaclase](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) + - Hilos: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) + - Referencias débiles: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) + - Referencia: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) + - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) + - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) + - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) ## Recursos adicionales @@ -126,36 +126,36 @@ Hay dos maneras de ejecutar los módulos: Sigue aprendiendo leyendo otros buenos recursos. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) -- [karan/Projects](https://github.com/karan/Projects) (:brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) +- [karan/Projects](https://github.com/karan/Projects) (:brain: ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) ### Práctica interactiva Continua practicando para que no se oxiden tus habilidades de programación. -- [leetcode.com](https://leetcode.com/) ( :necktie:) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) -- [kaggle.com](https://www.kaggle.com/) ( :brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) ( :necktie:) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [replit.com](https://replit.com/) diff --git a/README.ko.md b/README.ko.md index efc94f94..e6c6f3d0 100644 --- a/README.ko.md +++ b/README.ko.md @@ -59,52 +59,52 @@ print("Ultimate Python 학습 가이드") :exploding_head: = 고급 주제 1. **Python 정보** - - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) - - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) - - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) - - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) - - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) ( :books:, :exploding_head:) - - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) ( :books:) + - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) + - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) + - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) + - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) + - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) + - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) ( :books: ) 2. **통사론** - - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) ( :cake:) - - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) ( :cake:) - - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) ( :cake:), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) - - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) - - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) - - 함수 : [def | lambda](ultimatepython/syntax/function.py) ( :cake:) + - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) ( :cake: ) + - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) ( :cake: ) + - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) ( :cake: ), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) + - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) + - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) + - 함수 : [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) 3. **데이터 구조** - - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) ( :cake:) + - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) ( :cake: ) - 튜플 : [튜플 연산](ultimatepython/data_structures/tuple.py) - 세트 : [세트 연산](ultimatepython/data_structures/set.py) - - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) ( :cake:) + - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) ( :cake: ) - 컴프리헨션 : [리스트 | 튜플 | 세트 | 딕셔너리](ultimatepython/data_structures/comprehension.py) - - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) ( :cake:) - - 덱: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) - - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) + - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) ( :cake: ) + - 덱: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) + - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) 4. **클래스** - - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) ( :cake:) - - 계승: [계승](ultimatepython/classes/inheritance.py) ( :cake:) + - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) ( :cake: ) + - 계승: [계승](ultimatepython/classes/inheritance.py) ( :cake: ) - 추상 클래스 : [추상 정의](ultimatepython/classes/abstract_class.py) - 예외 클래스 : [예외 정의](ultimatepython/classes/exception_class.py) - - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) + - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) - 캡슐화: [캡슐화 정의](ultimatepython/classes/encapsulation.py) 5. **고급** - - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) - - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) ( :exploding_head:) - - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) ( :exploding_head:) - - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) - - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) ( :exploding_head:) - - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) ( :exploding_head:) - - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) - - Asyncio : [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) - - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) - - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) - - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) - - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) - - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) - - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) + - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) + - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) + - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) + - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) + - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) ( :exploding_head: ) + - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) + - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) + - Asyncio : [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) + - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) + - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) + - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) + - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) + - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) + - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) ## 추가 자료 @@ -116,36 +116,36 @@ print("Ultimate Python 학습 가이드") 잘 알려진 다른 자료를 읽으면서 계속 배우세요. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) -- [karan/Projects](https://github.com/karan/Projects) ( :brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) +- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) ### 대화형 연습 코딩 실력이 녹슬지 않기 위해 계속 연습하세요. -- [leetcode.com](https://leetcode.com/) ( :necktie:) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) -- [kaggle.com](https://www.kaggle.com/) ( :brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) ( :necktie:) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [replit.com](https://replit.com/) diff --git a/README.md b/README.md index d1977810..01abb4d9 100644 --- a/README.md +++ b/README.md @@ -71,52 +71,52 @@ There are two ways of running the modules: :exploding_head: = Advanced topic 1. **About Python** - - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) - - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books:) - - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) - - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) - - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head:) - - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books:) + - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) + - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) + - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) + - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) + - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) + - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books: ) 2. **Syntax** - - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake:) - - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake:) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake:), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books:) - - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) - - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake:) - - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake:) + - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake: ) + - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake: ) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake: ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books: ) + - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) + - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) + - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) 3. **Data Structures** - - List: [List operations](ultimatepython/data_structures/list.py) ( :cake:) + - List: [List operations](ultimatepython/data_structures/list.py) ( :cake: ) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake:) + - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake: ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - String: [String operations](ultimatepython/data_structures/string.py) ( :cake:) - - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) - - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) + - String: [String operations](ultimatepython/data_structures/string.py) ( :cake: ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) + - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) 4. **Classes** - - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake:) - - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake:) + - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake: ) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake: ) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head:) + - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Advanced** - - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) - - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head:) - - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head:) - - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head:) - - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head:) - - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head:) - - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) - - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head:) - - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) - - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) - - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) - - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) - - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) + - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) + - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) + - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) + - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head: ) + - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) + - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) + - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) + - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) ## Additional resources @@ -128,37 +128,37 @@ There are two ways of running the modules: Keep learning by reading from other well-regarded resources. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie: , :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie: , :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) -- [karan/Projects](https://github.com/karan/Projects) ( :brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie: , :test_tube: ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie: , :test_tube: ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) +- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) ### Interactive practice Keep practicing so that your coding skills don't get rusty. -- [leetcode.com](https://leetcode.com/) ( :necktie:) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) -- [kaggle.com](https://www.kaggle.com/) ( :brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) ( :necktie:) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) - [replit.com](https://replit.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index ab3f68d2..19f68c21 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -54,51 +54,51 @@ print("Ultimate Python 學習大綱") :exploding_head: = 進階題目 1. **關於 Python** - - 概述:[什麼是 Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake:) - - 設計理念:[Python之格言](https://www.python.org/dev/peps/pep-0020/) ( :books:) - - 樣式指南:[Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head:) - - 數據模型:[數據模型](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head:) - - 標準庫:[Python標準庫](https://docs.python.org/3/library/) ( :books:, :exploding_head:) - - 內置函式:[內置函式](https://docs.python.org/3/library/functions.html) ( :books:) + - 概述:[什麼是 Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) + - 設計理念:[Python之格言](https://www.python.org/dev/peps/pep-0020/) ( :books: ) + - 樣式指南:[Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) + - 數據模型:[數據模型](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) + - 標準庫:[Python標準庫](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) + - 內置函式:[內置函式](https://docs.python.org/3/library/functions.html) ( :books: ) 2. **語法** - - 變數:[內置值](ultimatepython/syntax/variable.py) ( :cake:) - - 運算式:[數值運算](ultimatepython/syntax/expression.py) ( :cake:) - - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) ( :cake:), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books:) - - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake:) - - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) ( :cake:) - - 定義函式:[def | lambda](ultimatepython/syntax/function.py) ( :cake:) + - 變數:[內置值](ultimatepython/syntax/variable.py) ( :cake: ) + - 運算式:[數值運算](ultimatepython/syntax/expression.py) ( :cake: ) + - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) ( :cake: ), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) + - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) + - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) ( :cake: ) + - 定義函式:[def | lambda](ultimatepython/syntax/function.py) ( :cake: ) 3. **資料結構** - - 列表:[列表操作](ultimatepython/data_structures/list.py) ( :cake:) + - 列表:[列表操作](ultimatepython/data_structures/list.py) ( :cake: ) - 元組:[元組操作](ultimatepython/data_structures/tuple.py) - 集合:[集合操作](ultimatepython/data_structures/set.py) - - 字典:[字典操作](ultimatepython/data_structures/dict.py) ( :cake:) + - 字典:[字典操作](ultimatepython/data_structures/dict.py) ( :cake: ) - 綜合:[list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - 字串:[字串操作](ultimatepython/data_structures/string.py) ( :cake:) - - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( :exploding_head:) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head:) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head:) - - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head:) + - 字串:[字串操作](ultimatepython/data_structures/string.py) ( :cake: ) + - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) + - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) 4. **類別** - - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) ( :cake:) + - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) ( :cake: ) - 抽象類別:[抽象定義](ultimatepython/classes/abstract_class.py) - 異常類別:[異常定義](ultimatepython/classes/exception_class.py) - - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) ( :exploding_head:) + - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) - 封裝: [封裝定義](ultimatepython/classes/encapsulation.py) 5. **進階技巧** - - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head:) - - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head:) - - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head:) - - 方法解析順序:[mro](ultimatepython/advanced/mro.py) ( :exploding_head:) - - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) ( :exploding_head:) - - 元類:[Metaclass定義](ultimatepython/advanced/meta_class.py) ( :exploding_head:) - - 執行緒:[ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head:) - - 異步:[async | await](ultimatepython/advanced/async.py) ( :exploding_head:) - - 弱引用:[weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head:) - - 基準:[cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head:) - - 模擬:[MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head:) - - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head:) - - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head:) - - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head:) + - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) + - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) + - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) + - 方法解析順序:[mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) + - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) ( :exploding_head: ) + - 元類:[Metaclass定義](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) + - 執行緒:[ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) + - 異步:[async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) + - 弱引用:[weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) + - 基準:[cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) + - 模擬:[MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) + - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) + - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) + - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) ## 額外資源 @@ -110,36 +110,36 @@ print("Ultimate Python 學習大綱") 通過閱讀其他備受尊重的資源來繼續學習。 -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube:) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube:) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube:) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube:) -- [karan/Projects](https://github.com/karan/Projects) ( :brain:) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain:) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) +- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube:) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie:) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) ### 互動練習 繼續練習才能使您的編碼技能不會生疏。 -- [leetcode.com](https://leetcode.com/) ( :necktie:) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie:) -- [kaggle.com](https://www.kaggle.com/) ( :brain:) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) - [exercism.io](https://exercism.io/) - [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) - [codewars.com](https://www.codewars.com/) - [hackerearth.com](https://www.hackerearth.com/) -- [codechef.com](https://www.codechef.com/) ( :necktie:) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain:) +- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie:) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie:) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [replit.com](https://replit.com/) From 0d84adf6f92f47f9ed046efaee8400f8f1876ef1 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 15 Feb 2024 10:01:11 -0800 Subject: [PATCH 036/178] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01abb4d9..b317aba3 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ There are two ways of running the modules: 2. **Syntax** - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake: ) - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake: ) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake: ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) (:books: ) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake: ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) From ec425fd70c592733c06f8fe09c6ae4907466404b Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 4 Apr 2024 03:53:31 -0700 Subject: [PATCH 037/178] Update coverage and flake --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 510a8671..ff75fbd5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.3.3 -flake8==6.1.0 +coverage==7.4.4 +flake8==7.0.0 isort==5.13.2 From d1b60f093d7ea4b213941b938cd27e32c40c496a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 4 Apr 2024 04:48:25 -0700 Subject: [PATCH 038/178] Add 3.12 to setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 4a1adffe..a9cc0ef1 100644 --- a/setup.py +++ b/setup.py @@ -12,5 +12,6 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ], ) From cdf3710a1dcbe990a0e15b6a4e55dccad41a1f79 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 4 Apr 2024 04:48:38 -0700 Subject: [PATCH 039/178] Add build/ to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 18804740..2da90cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ venv/ __pycache__/ *.egg-info/ htmlcov/ +build/ *.pyc .DS_Store .coverage From cf7c45e5e189b5daa3edd6b7be731ef0c193f624 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 14 Apr 2024 23:28:00 -0700 Subject: [PATCH 040/178] Add changes to comments in PRs --- ultimatepython/advanced/decorator.py | 2 +- ultimatepython/advanced/meta_class.py | 2 +- ultimatepython/advanced/mixin.py | 2 +- ultimatepython/advanced/mro.py | 4 ++-- ultimatepython/advanced/weak_ref.py | 6 ++--- ultimatepython/classes/encapsulation.py | 22 +++++++++---------- ultimatepython/classes/inheritance.py | 2 +- ultimatepython/classes/iterator_class.py | 2 +- .../data_structures/comprehension.py | 2 +- ultimatepython/data_structures/defaultdict.py | 4 ++-- ultimatepython/data_structures/deque.py | 2 +- ultimatepython/data_structures/list.py | 2 +- ultimatepython/syntax/bitwise.py | 2 +- ultimatepython/syntax/conditional.py | 2 +- ultimatepython/syntax/loop.py | 4 ++-- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ultimatepython/advanced/decorator.py b/ultimatepython/advanced/decorator.py index c7e173d3..a4bd00bc 100644 --- a/ultimatepython/advanced/decorator.py +++ b/ultimatepython/advanced/decorator.py @@ -43,7 +43,7 @@ def wrapper(obj): """Apply wrapped function to a string or a collection. This looks like a policy-based engine which runs a `return` statement - if a particular set of rules is true. Otherwise it aborts. This is + if a particular set of rules is true. Otherwise, it aborts. This is an example of the Strategy design pattern. https://en.wikipedia.org/wiki/Strategy_pattern diff --git a/ultimatepython/advanced/meta_class.py b/ultimatepython/advanced/meta_class.py index eea77ae1..de087b6f 100644 --- a/ultimatepython/advanced/meta_class.py +++ b/ultimatepython/advanced/meta_class.py @@ -76,7 +76,7 @@ def __new__(mcs, name, bases, attrs): # the metaclass `table` registry. After all the tables are # registered, the registry can be sent to a database adapter # which uses each table to create a properly defined schema - # for the database of choice (i.e. PostgreSQL, MySQL) + # for the database of choice (i.e. PostgresSQL, MySQL) if kls.model_name: kls.model_table = ModelTable(kls.model_name, kls.model_fields) ModelMeta.tables[kls.model_name] = kls.model_table diff --git a/ultimatepython/advanced/mixin.py b/ultimatepython/advanced/mixin.py index 9063fa03..7d417a07 100644 --- a/ultimatepython/advanced/mixin.py +++ b/ultimatepython/advanced/mixin.py @@ -26,7 +26,7 @@ class RequestHandler(ABC): In the real world, a URL is expected to handle different kinds of HTTP methods. To support this, we would define a `View` class with a method that dispatches the request payload to the appropriate HTTP handler. - Afterwards, we would register the class to a URL router. Check out + Afterward, we would register the class to a URL router. Check out the source code in Django and Flask to see how that works: https://github.com/django/django diff --git a/ultimatepython/advanced/mro.py b/ultimatepython/advanced/mro.py index 0d140d2e..36f3a11e 100644 --- a/ultimatepython/advanced/mro.py +++ b/ultimatepython/advanced/mro.py @@ -1,5 +1,5 @@ """ -MRO stands for method resolution order and it's used by class definitions +MRO stands for method resolution order, and it's used by class definitions to determine which method will be run by a class instance. This module shows how the MRO is useful for the classic diamond problem where classes B and C depend on class A, and class D depends on classes B and C. @@ -102,7 +102,7 @@ def main(): # Creating a new class `ConfusedPlayer` and `IndecisivePlayer` # results in a `TypeError` because both classes do not have # matching MRO outputs. This means that they cannot be reconciled - # as one class. Hence `MissingPlayer` will not be created + # as one class. Hence, `MissingPlayer` will not be created type("MissingPlayer", (ConfusedPlayer, IndecisivePlayer), {}) except TypeError: class_creation_failed = True diff --git a/ultimatepython/advanced/weak_ref.py b/ultimatepython/advanced/weak_ref.py index b5bffedb..40bcafa0 100644 --- a/ultimatepython/advanced/weak_ref.py +++ b/ultimatepython/advanced/weak_ref.py @@ -52,7 +52,7 @@ def setup_and_teardown_servers(registry): """Explicitly setup and implicitly teardown servers.""" app_servers = {} - # Let's create all of the servers and store them properly + # Let's create all the servers and store them properly for app in _CLOUD_APPS: app_servers[app] = set() for component in _CLOUD_APP_COMPONENTS: @@ -72,13 +72,13 @@ def setup_and_teardown_servers(registry): for server in servers]) ) - # What's really interesting is that servers go away when we leave the + # What's fascinating is that servers go away when we leave the # scope of this function. In this function, each server is created and # strongly referenced by the `app_servers` variable. When we leave this # function, the `app_servers` variable no longer exists which brings # the reference count for each server from 1 to 0. A reference count of # 0 for each server triggers the garbage collector to run the cleanup - # process for all of the servers in this function scope + # process for all the servers in this function scope def main(): diff --git a/ultimatepython/classes/encapsulation.py b/ultimatepython/classes/encapsulation.py index 818a5b5d..2794add1 100644 --- a/ultimatepython/classes/encapsulation.py +++ b/ultimatepython/classes/encapsulation.py @@ -8,7 +8,7 @@ """ import secrets -# Module-level constanct +# Module-level constant _INVALID_AMOUNT_MESSAGE = "Invalid amount." _INSUFFICIENT_BALANCE_MESSAGE = "Insufficient balance." @@ -19,7 +19,7 @@ def __init__(self, account_holder_name): In Python, a class attribute can be made private by prefixing it with two underscores. This makes it inaccessible to users outside the class. By default, class attributes are public. Therefore, they can be accessed and modified - outside of the class. + outside the class. Here, account_number and balance are private while account_holder_name is public. """ @@ -41,7 +41,7 @@ def deposit(self, balance): def withdraw(self, balance): """ - The withraw method is used to deduct the balance from the account. + The withdrawal method is used to deduct the balance from the account. In case there is insufficient balance, or the input is invalid, a value error is raised. """ @@ -54,7 +54,7 @@ def withdraw(self, balance): def get_balance(self): """ - This function returs the available balance in the account. + This function returns the available balance in the account. """ return self.__balance @@ -62,7 +62,7 @@ def get_account_number(self): """ The account number is generated randomly when a new instance of the class is created. Since the attribute is also private, it cannot be accessed directly from outside the class. - The get_account_number method allows you to access the account number outside of the class. + The get_account_number method allows you to access the account number outside the class. But since we do not define a setter method for this variable, we cannot modify it outside the class. Therefore, the account number generated while creating an object of the BankAccount class cannot be changed but can only be read using this function. @@ -92,15 +92,15 @@ def remove_account_details(self): def main(): # Account names constants. - USER1 = "John Doe" - USER2 = "Jane Doe" + user1 = "John Doe" + user2 = "Jane Doe" # Account instances. - account1 = BankAccount(USER1) - account2 = BankAccount(USER2) + account1 = BankAccount(user1) + account2 = BankAccount(user2) - assert account1.account_holder_name == USER1 - assert account2.account_holder_name == USER2 + assert account1.account_holder_name == user1 + assert account2.account_holder_name == user2 # Deposit amount and check if the balance is updated. account1.deposit(100) diff --git a/ultimatepython/classes/inheritance.py b/ultimatepython/classes/inheritance.py index c9725f7e..b922ef70 100644 --- a/ultimatepython/classes/inheritance.py +++ b/ultimatepython/classes/inheritance.py @@ -1,6 +1,6 @@ """ Inheritance is a way to reuse code and data from a parent class. This -allow us to avoid repeating ourselves and to build upon existing +allows us to avoid repeating ourselves and to build upon existing functionality. This module defines a basic vehicle class, creates a car class that inherits from vehicle, then creates a truck class that inherits from car and use it for demonstration purposes. diff --git a/ultimatepython/classes/iterator_class.py b/ultimatepython/classes/iterator_class.py index 64c84101..2035b73e 100644 --- a/ultimatepython/classes/iterator_class.py +++ b/ultimatepython/classes/iterator_class.py @@ -79,7 +79,7 @@ def __next__(self): The logic may seem complex, but it's actually a common algorithm used in traversing a relationship graph. It is called depth-first - search and it can be found on Wikipedia: + search, and it can be found on Wikipedia: https://en.wikipedia.org/wiki/Depth-first_search """ diff --git a/ultimatepython/data_structures/comprehension.py b/ultimatepython/data_structures/comprehension.py index d533c838..76afc783 100644 --- a/ultimatepython/data_structures/comprehension.py +++ b/ultimatepython/data_structures/comprehension.py @@ -10,7 +10,7 @@ def main(): # we just want to create zeros so our expression is set to `0` # since no computing is required; because `0` is a constant value, # we can set the item that we compute with to `_`; and we want to - # create five zeros so we set the iterator as `range(5)` + # create five zeros, so we set the iterator as `range(5)` assert [0 for _ in range(5)] == [0] * 5 == [0, 0, 0, 0, 0] # For the next comprehension operations, let's see what we can do diff --git a/ultimatepython/data_structures/defaultdict.py b/ultimatepython/data_structures/defaultdict.py index 331c6104..096bf567 100644 --- a/ultimatepython/data_structures/defaultdict.py +++ b/ultimatepython/data_structures/defaultdict.py @@ -1,6 +1,6 @@ """ This module demonstrates the use of defaultdict, which is a dictionary that is -possible to setup a default value in its creation. +possible to set up a default value in its creation. """ from collections import defaultdict @@ -13,7 +13,7 @@ def main(): # Let's create a defaultdict with student keys and GPA values. The first - # parameter is called default_factory and it is the initialization value for + # parameter is called default_factory, and it is the initialization value for # first use of a key. It can be a common type or a function student_gpa = defaultdict(float, [("john", 3.5), ("bob", 2.8), ("mary", 3.2)]) diff --git a/ultimatepython/data_structures/deque.py b/ultimatepython/data_structures/deque.py index a5016654..451b05ed 100644 --- a/ultimatepython/data_structures/deque.py +++ b/ultimatepython/data_structures/deque.py @@ -1,5 +1,5 @@ """ -A deque is similar to all of the other sequential data structures but +A deque is similar to all the other sequential data structures but has some implementation details that are different from other sequences like a list. This module highlights those differences and shows how a deque can be used as a LIFO stack and a FIFO queue. diff --git a/ultimatepython/data_structures/list.py b/ultimatepython/data_structures/list.py index 18d4376d..bf8341a2 100644 --- a/ultimatepython/data_structures/list.py +++ b/ultimatepython/data_structures/list.py @@ -79,7 +79,7 @@ def main(): assert len(matrix) == len(row) # Notice that lists have variable length and can be modified to have - # more elements. Lists can also be modified to have less elements + # more elements. Lists can also be modified to have fewer elements lengthy = [] for i in range(5): lengthy.append(i) # add 0..4 to the back diff --git a/ultimatepython/syntax/bitwise.py b/ultimatepython/syntax/bitwise.py index 008f90b0..9ba36779 100644 --- a/ultimatepython/syntax/bitwise.py +++ b/ultimatepython/syntax/bitwise.py @@ -25,7 +25,7 @@ def main(): assert result_xor == 6 # Bitwise NOT (~) operator inverts all bits of an integer - # It return the one's complement of the integer + # It returns the one's complement of the integer result_not_a = ~a # Binary: 11111010 (Decimal: -6) assert result_not_a == -6 diff --git a/ultimatepython/syntax/conditional.py b/ultimatepython/syntax/conditional.py index 3cdc27bd..f18e462b 100644 --- a/ultimatepython/syntax/conditional.py +++ b/ultimatepython/syntax/conditional.py @@ -30,7 +30,7 @@ def main(): assert ran_3 is True # The `else` statement also runs once all other `if` and `elif` conditions - # fail. Notice that multiple lines get skipped, and that all of the + # fail. Notice that multiple lines get skipped, and that all the # conditions could have been compressed to `x_add_two != 3` for # simplicity. In this case, less logic results in more clarity if x_add_two == 1: diff --git a/ultimatepython/syntax/loop.py b/ultimatepython/syntax/loop.py index 844135da..00aa8622 100644 --- a/ultimatepython/syntax/loop.py +++ b/ultimatepython/syntax/loop.py @@ -35,8 +35,8 @@ def main(): assert fact == 120 # This is a simple `while` loop, similar to a `for` loop except that the - # counter is declared outside of the loop and its state is explicitly - # managed inside of the loop. The loop will continue until the counter + # counter is declared outside the loop and its state is explicitly + # managed inside the loop. The loop will continue until the counter # exceeds 8 i = 0 while i < 8: From 232a0782d18663a950b83290600535c0208b5ad3 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 9 May 2024 19:21:32 -0700 Subject: [PATCH 041/178] Update coverage to 7.5.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ff75fbd5..034ad0b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.4.4 +coverage==7.5.1 flake8==7.0.0 isort==5.13.2 From 21f2280ad4aba0508c50ce671ac8b8101ccc1918 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 21 Jun 2024 22:59:39 -0700 Subject: [PATCH 042/178] Update coverage and flake8 versions --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 034ad0b1..46a1616b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.5.1 -flake8==7.0.0 +coverage==7.5.3 +flake8==7.1.0 isort==5.13.2 From 2472be97a4c9851260464b954a6268fb2fb7bf1f Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 21 Jun 2024 23:15:54 -0700 Subject: [PATCH 043/178] Remove trailing space from README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index b317aba3..5fda6e39 100644 --- a/README.md +++ b/README.md @@ -161,4 +161,3 @@ Keep practicing so that your coding skills don't get rusty. - [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) - [replit.com](https://replit.com/) - From a427691ac7954df8d51694d1a65db153c32873af Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 22 Jun 2024 21:53:46 -0700 Subject: [PATCH 044/178] Update CircleCI config to use Python 3.12 (#127) --- .circleci/config.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3f5de212..67172c2e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,7 +6,11 @@ orbs: jobs: build-and-test: - executor: python/default + docker: + - image: cimg/python:3.12 + auth: + username: $DOCKERHUB_USERNAME + password: $DOCKERHUB_PASSWORD steps: - checkout - python/install-packages: From 17dcea528c18368143e215fef15db6a3fdf83269 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 18 Jul 2024 01:42:46 -0700 Subject: [PATCH 045/178] Update coverage to 7.6.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 46a1616b..7827d6d1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.5.3 +coverage==7.6.0 flake8==7.1.0 isort==5.13.2 From 0d810e3bec39c9dbb200ef72f6224d2959eee065 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 7 Aug 2024 23:39:26 -0700 Subject: [PATCH 046/178] Update coverage to 7.6.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7827d6d1..3f524f58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.0 +coverage==7.6.1 flake8==7.1.0 isort==5.13.2 From 3f2d904255425543c31d196c931dc66b867c24c9 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 7 Aug 2024 23:40:03 -0700 Subject: [PATCH 047/178] Update flake8 to 7.1.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3f524f58..3255dec2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.1 -flake8==7.1.0 +flake8==7.1.1 isort==5.13.2 From 125c67a979a6959646e483398811023c9ae55b2b Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 29 Sep 2024 17:23:16 -0700 Subject: [PATCH 048/178] Add line break to contrib docs --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fa3716b4..9a9d5055 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,4 +121,4 @@ We're excited to see what you bring to the table! Your contributions are making Please don't hesitate to reach out if you have any questions. Your contributions, no matter how small, are making a big difference! 🌟🐍💥 -## Feel the Pythonic Energy - Contribute Now!🔥 \ No newline at end of file +## Feel the Pythonic Energy - Contribute Now!🔥 From acad2ef5df1f9ff8ca3d1c5af906eddaebfead62 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 29 Sep 2024 17:39:09 -0700 Subject: [PATCH 049/178] Migrate to Ruff as linter (#129) --- .circleci/config.yml | 2 +- .gitignore | 20 +++++++++++++------- pyproject.toml | 28 ++++++++++++++++++++++++++++ requirements.txt | 2 +- setup.cfg | 20 -------------------- 5 files changed, 43 insertions(+), 29 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.cfg diff --git a/.circleci/config.yml b/.circleci/config.yml index 67172c2e..a759546f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: - python/install-packages: pkg-manager: pip - run: - command: flake8 + command: ruff check ultimatepython name: Lint - run: command: coverage run -m runner diff --git a/.gitignore b/.gitignore index 2da90cc1..e10d6853 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,17 @@ +# System +.DS_Store + +# IDE .idea/ -venv/ -__pycache__/ -*.egg-info/ -htmlcov/ -build/ +.vscode/ + +# Python *.pyc -.DS_Store .coverage -coverage.xml coverage.json +coverage.xml +*.egg-info/ +__pycache__/ +build/ +htmlcov/ +venv/ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..914e24f8 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[tool.ruff] +line-length = 160 + +[tool.isort] +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +ensure_newline_before_comments = true +line_length = 160 + +[tool.coverage.run] +branch = true + +[tool.coverage.report] +exclude_lines = [ + "skip: (if|else)", + "def __repr__", + "raise NotImplementedError", + "if __name__ == .__main__.:", + "any\\(" +] +fail_under = 80 +omit = [ + "venv/**", + "runner.py", + "**/__init__.py" +] diff --git a/requirements.txt b/requirements.txt index 3255dec2..35941d57 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.1 -flake8==7.1.1 isort==5.13.2 +ruff==0.6.8 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index db4d247a..00000000 --- a/setup.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[coverage:run] -branch = True - -[coverage:report] -exclude_lines = - skip: (if|else) - def __repr__ - raise NotImplementedError - if __name__ == .__main__.: - any\( -fail_under = 80 -omit = - venv/** - runner.py - **/__init__.py - -[flake8] -max-line-length = 160 -exclude = - venv From 6ca0e6d371bf76072cf7ca26fefdd8e4693a4d45 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 29 Sep 2024 17:42:18 -0700 Subject: [PATCH 050/178] Enforce 4-space TOML --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index bdbda7b8..0c2bca81 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true -[*.py] +[*.{py,toml}] indent_size = 4 indent_style = space From 19b95d80b31cd5ccc9b459f1188a31ab52d13b40 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 29 Sep 2024 17:43:31 -0700 Subject: [PATCH 051/178] Ignore cache for ruff tooling --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e10d6853..b7a777fd 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ coverage.json coverage.xml *.egg-info/ +.ruff_cache/ __pycache__/ build/ htmlcov/ From 246d341de1719ce2525893477d4263fab233f7ab Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 30 Sep 2024 08:38:35 -0700 Subject: [PATCH 052/178] Change Reddit badge on README files (#130) --- README.de.md | 4 ++-- README.es.md | 10 +++++----- README.ko.md | 2 +- README.md | 2 +- README.zh_tw.md | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.de.md b/README.de.md index 3fe51a82..21bad3a8 100644 --- a/README.de.md +++ b/README.de.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/reddit/subreddit-subscribers/Python)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Der ultimative Python-Lernführer für Einsteiger und Profis gleichermaßen. :snake: :snake: :snake: @@ -34,7 +34,7 @@ Dies sind die Hauptziele bei der Erstellung dieses Leitfadens: :trophy: **Als Ressource fungieren** für Python-Neulinge, die es vorziehen, praktisch zu lernen. Dieses Repository enthält eine Sammlung von eigenständigen Modulen, die in einer IDE wie [PyCharm](https://www.jetbrains.com/pycharm/) und im Browser wie -[Replit](https://replit.com/languages/python3). Wleches wie ein einfaches Terminal +[Replit](https://replit.com/languages/python3). Wleches wie ein einfaches Terminal mit den Beispielen funktioniert. Die meisten Zeilen haben sorgfältig ausgearbeitete Kommentare, die den Leser Schritt für Schritt durch das Programm führen. Die Benutzer werden ermutigt, den Quellcode überall zu ändern, solange die "Haupt"-Routinen nicht gelöscht werden und diff --git a/README.es.md b/README.es.md index 9cb1ea6f..f177522c 100644 --- a/README.es.md +++ b/README.es.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/reddit/subreddit-subscribers/Python)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Guía de estudio "Python Definitivo" para principiantes y profesionales. :snake: :snake: :snake: @@ -21,8 +21,8 @@ print("Guía de estudio 'Python Definitivo'") ## Motivación Creé este repositorio de GitHub para compartir lo que he aprendido sobre [Python](https://www.python.org/) -durante más de 5 años usándolo como graduado de universidad, empleado en grandes empresas y como contribuidor -de código abierto en repositorios como [Celery](https://github.com/celery/celery) y +durante más de 5 años usándolo como graduado de universidad, empleado en grandes empresas y como contribuidor +de código abierto en repositorios como [Celery](https://github.com/celery/celery) y [Full Stack Python](https://github.com/mattmakai/fullstackpython.com). Espero ver a más personas aprendiendo Python y persiguiendo su pasión a través de él. :mortar_board: @@ -42,7 +42,7 @@ se eliminen y se [ejecuten con éxito](runner.py) tras cada cambio. :trophy: **Servir como una guía pura** para aquellos que quieren reforzar los conceptos base de Python. Se utilizan sólo las [librerías integradas](https://docs.python.org/3/library/) para que estos conceptos puedan adquirirse sin el esfuerzo de aprender conocimientos de dominios específicos. -Por ello no se han instalado librerías y entornos de código abierto populares (como `sqlalchemy`, +Por ello no se han instalado librerías y entornos de código abierto populares (como `sqlalchemy`, `requests`, `pandas`). No obstante, leer el código fuente de estos frameworks es inspirador y altamente recomendado si tu objetivo es convertirte en un verdadero [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista). @@ -140,7 +140,7 @@ Sigue aprendiendo leyendo otros buenos recursos. - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) - + ### Práctica interactiva Continua practicando para que no se oxiden tus habilidades de programación. diff --git a/README.ko.md b/README.ko.md index e6c6f3d0..14903641 100644 --- a/README.ko.md +++ b/README.ko.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/reddit/subreddit-subscribers/Python)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) 초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: diff --git a/README.md b/README.md index 5fda6e39..1c1525c6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/reddit/subreddit-subscribers/Python)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python study guide for newcomers and professionals alike. :snake: :snake: :snake: diff --git a/README.zh_tw.md b/README.zh_tw.md index 19f68c21..ef5972d7 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/reddit/subreddit-subscribers/Python)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python 學習大綱 - 適用於新手和專業人士。:snake: :snake: :snake: @@ -124,7 +124,7 @@ print("Ultimate Python 學習大綱") - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) - + ### 互動練習 繼續練習才能使您的編碼技能不會生疏。 From 477658a0e58b08ed9cb3f1ddc802280d158b227a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 30 Sep 2024 08:40:55 -0700 Subject: [PATCH 053/178] Change badge color from red to white --- README.de.md | 2 +- README.es.md | 2 +- README.ko.md | 2 +- README.md | 2 +- README.zh_tw.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.de.md b/README.de.md index 21bad3a8..de3964db 100644 --- a/README.de.md +++ b/README.de.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Der ultimative Python-Lernführer für Einsteiger und Profis gleichermaßen. :snake: :snake: :snake: diff --git a/README.es.md b/README.es.md index f177522c..987a3b8f 100644 --- a/README.es.md +++ b/README.es.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Guía de estudio "Python Definitivo" para principiantes y profesionales. :snake: :snake: :snake: diff --git a/README.ko.md b/README.ko.md index 14903641..35ddd943 100644 --- a/README.ko.md +++ b/README.ko.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) 초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: diff --git a/README.md b/README.md index 1c1525c6..df7cec40 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python study guide for newcomers and professionals alike. :snake: :snake: :snake: diff --git a/README.zh_tw.md b/README.zh_tw.md index ef5972d7..d8533e82 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python 學習大綱 - 適用於新手和專業人士。:snake: :snake: :snake: From d8433aa3cd30fc5d187f8c2c053bb55374237fbe Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 30 Sep 2024 08:42:00 -0700 Subject: [PATCH 054/178] Revert "Change badge color from red to white" This reverts commit 477658a0e58b08ed9cb3f1ddc802280d158b227a. --- README.de.md | 2 +- README.es.md | 2 +- README.ko.md | 2 +- README.md | 2 +- README.zh_tw.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.de.md b/README.de.md index de3964db..21bad3a8 100644 --- a/README.de.md +++ b/README.de.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Der ultimative Python-Lernführer für Einsteiger und Profis gleichermaßen. :snake: :snake: :snake: diff --git a/README.es.md b/README.es.md index 987a3b8f..f177522c 100644 --- a/README.es.md +++ b/README.es.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Guía de estudio "Python Definitivo" para principiantes y profesionales. :snake: :snake: :snake: diff --git a/README.ko.md b/README.ko.md index 35ddd943..14903641 100644 --- a/README.ko.md +++ b/README.ko.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) 초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: diff --git a/README.md b/README.md index df7cec40..1c1525c6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python study guide for newcomers and professionals alike. :snake: :snake: :snake: diff --git a/README.zh_tw.md b/README.zh_tw.md index d8533e82..ef5972d7 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -4,7 +4,7 @@ [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-white)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python 學習大綱 - 適用於新手和專業人士。:snake: :snake: :snake: From de5f9be25fc0821c3302d012b51439cecd829049 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 30 Sep 2024 17:18:44 -0700 Subject: [PATCH 055/178] Switch repo links from master to main --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- README.de.md | 2 +- README.es.md | 2 +- README.ko.md | 2 +- README.md | 2 +- README.zh_tw.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 000a8182..38ab8116 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,4 +1,4 @@ -*Please read the [contributing guidelines](https://github.com/huangsam/ultimate-python/blob/master/CONTRIBUTING.md) before submitting a pull request.* +*Please read the [contributing guidelines](https://github.com/huangsam/ultimate-python/blob/main/CONTRIBUTING.md) before submitting a pull request.* --- diff --git a/README.de.md b/README.de.md index 21bad3a8..38eeaad5 100644 --- a/README.de.md +++ b/README.de.md @@ -3,7 +3,7 @@ [![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) -[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Der ultimative Python-Lernführer für Einsteiger und Profis gleichermaßen. :snake: :snake: :snake: diff --git a/README.es.md b/README.es.md index f177522c..32f917db 100644 --- a/README.es.md +++ b/README.es.md @@ -3,7 +3,7 @@ [![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) -[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Guía de estudio "Python Definitivo" para principiantes y profesionales. :snake: :snake: :snake: diff --git a/README.ko.md b/README.ko.md index 14903641..bf80a573 100644 --- a/README.ko.md +++ b/README.ko.md @@ -3,7 +3,7 @@ [![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) -[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) 초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: diff --git a/README.md b/README.md index 1c1525c6..47f99730 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) -[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python study guide for newcomers and professionals alike. :snake: :snake: :snake: diff --git a/README.zh_tw.md b/README.zh_tw.md index ef5972d7..88573ff6 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -3,7 +3,7 @@ [![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) -[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/master/LICENSE) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) Ultimate Python 學習大綱 - 適用於新手和專業人士。:snake: :snake: :snake: From 025a3f984f52dfad91c3d14b6c17230e4d8d3fd5 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 30 Sep 2024 17:56:07 -0700 Subject: [PATCH 056/178] Sort resource links in README --- README.de.md | 18 +++++++++--------- README.es.md | 18 +++++++++--------- README.ko.md | 18 +++++++++--------- README.md | 20 ++++++++++---------- README.zh_tw.md | 18 +++++++++--------- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/README.de.md b/README.de.md index 38eeaad5..cbf4e5b7 100644 --- a/README.de.md +++ b/README.de.md @@ -146,17 +146,17 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. Üben Sie weiter, damit Ihre Programmierkenntnisse nicht einrosten. -- [leetcode.com](https://leetcode.com/) ( :necktie: ) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [exercism.io](https://exercism.io/) -- [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) -- [codewars.com](https://www.codewars.com/) -- [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) ( :necktie: ) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) diff --git a/README.es.md b/README.es.md index 32f917db..cdca4c54 100644 --- a/README.es.md +++ b/README.es.md @@ -145,17 +145,17 @@ Sigue aprendiendo leyendo otros buenos recursos. Continua practicando para que no se oxiden tus habilidades de programación. -- [leetcode.com](https://leetcode.com/) ( :necktie: ) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [exercism.io](https://exercism.io/) -- [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) -- [codewars.com](https://www.codewars.com/) -- [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) ( :necktie: ) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) diff --git a/README.ko.md b/README.ko.md index bf80a573..eaccb1b1 100644 --- a/README.ko.md +++ b/README.ko.md @@ -135,17 +135,17 @@ print("Ultimate Python 학습 가이드") 코딩 실력이 녹슬지 않기 위해 계속 연습하세요. -- [leetcode.com](https://leetcode.com/) ( :necktie: ) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [exercism.io](https://exercism.io/) -- [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) -- [codewars.com](https://www.codewars.com/) -- [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) ( :necktie: ) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) diff --git a/README.md b/README.md index 47f99730..67c8168f 100644 --- a/README.md +++ b/README.md @@ -147,17 +147,17 @@ Keep learning by reading from other well-regarded resources. Keep practicing so that your coding skills don't get rusty. -- [leetcode.com](https://leetcode.com/) ( :necktie: ) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [exercism.io](https://exercism.io/) -- [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) -- [codewars.com](https://www.codewars.com/) -- [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) ( :necktie: ) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) diff --git a/README.zh_tw.md b/README.zh_tw.md index 88573ff6..5f8fc05d 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -129,17 +129,17 @@ print("Ultimate Python 學習大綱") 繼續練習才能使您的編碼技能不會生疏。 -- [leetcode.com](https://leetcode.com/) ( :necktie: ) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [exercism.io](https://exercism.io/) -- [projecteuler.net](https://projecteuler.net/) - [DevProjects](https://www.codementor.io/projects/python) -- [codewars.com](https://www.codewars.com/) -- [hackerearth.com](https://www.hackerearth.com/) - [codechef.com](https://www.codechef.com/) ( :necktie: ) -- [w3schools.com](https://www.w3schools.com/python/) ( :brain: ) - [codeforces.com](https://codeforces.com/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) From 8eaceb91e9c0752303d6c0a480ad4a4273b001e3 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 02:58:39 -0700 Subject: [PATCH 057/178] Update codementor link in README --- README.de.md | 2 +- README.es.md | 2 +- README.ko.md | 2 +- README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.de.md b/README.de.md index cbf4e5b7..539a83e8 100644 --- a/README.de.md +++ b/README.de.md @@ -146,9 +146,9 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. Üben Sie weiter, damit Ihre Programmierkenntnisse nicht einrosten. -- [DevProjects](https://www.codementor.io/projects/python) - [codechef.com](https://www.codechef.com/) ( :necktie: ) - [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( :brain: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) diff --git a/README.es.md b/README.es.md index cdca4c54..ebc9f2e8 100644 --- a/README.es.md +++ b/README.es.md @@ -145,9 +145,9 @@ Sigue aprendiendo leyendo otros buenos recursos. Continua practicando para que no se oxiden tus habilidades de programación. -- [DevProjects](https://www.codementor.io/projects/python) - [codechef.com](https://www.codechef.com/) ( :necktie: ) - [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( :brain: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) diff --git a/README.ko.md b/README.ko.md index eaccb1b1..388b02c0 100644 --- a/README.ko.md +++ b/README.ko.md @@ -135,9 +135,9 @@ print("Ultimate Python 학습 가이드") 코딩 실력이 녹슬지 않기 위해 계속 연습하세요. -- [DevProjects](https://www.codementor.io/projects/python) - [codechef.com](https://www.codechef.com/) ( :necktie: ) - [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( :brain: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) diff --git a/README.md b/README.md index 67c8168f..946b99bb 100644 --- a/README.md +++ b/README.md @@ -147,9 +147,9 @@ Keep learning by reading from other well-regarded resources. Keep practicing so that your coding skills don't get rusty. -- [DevProjects](https://www.codementor.io/projects/python) - [codechef.com](https://www.codechef.com/) ( :necktie: ) - [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( :brain: ) - [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) From 53f3e3d1f9ee6a0ac6796930d10e902376f80c66 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:12:03 -0700 Subject: [PATCH 058/178] Onboard to GitHub actions --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..2a174c7e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + python-build: + name: Python 3.12 + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Python 3.12 + uses: actions/setup-python@v3 + with: + python-version: '3.12' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Lint with ruff + run: | + ruff check + - name: Run tests and report with coverage + run: | + coverage run runner.py + coverage report From 9f9bf81cf879447b1eff964a118ca6c2a90f3849 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:14:20 -0700 Subject: [PATCH 059/178] Remove setup.py --- setup.py | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 setup.py diff --git a/setup.py b/setup.py deleted file mode 100644 index a9cc0ef1..00000000 --- a/setup.py +++ /dev/null @@ -1,17 +0,0 @@ -from setuptools import find_packages, setup - -setup( - name="ultimate-python", - version="1.0.0", - packages=find_packages(), - description="Ultimate Python study guide", - classifiers=[ - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - ], -) From d9e0827238bdfa9a65ce1a43c1b34df445fc90dd Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:17:28 -0700 Subject: [PATCH 060/178] Update setup-python to v5 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a174c7e..01fa7f34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.12 - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install dependencies From c8ac951282095843cec284979e655146b68b85e5 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:38:35 -0700 Subject: [PATCH 061/178] Upload coverage data to Codecov (#131) --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01fa7f34..9709c362 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,3 +32,11 @@ jobs: run: | coverage run runner.py coverage report + - name: Generate coverage.xml artifact + run: | + coverage xml -o ./coverage.xml + - name: Upload coverage data to Codecov + uses: codecov/codecov-action@v4 + with: + files: ./coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} From 6c93ca837a73c3c035cd8708d5a7ffdd2a7d5f99 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:43:05 -0700 Subject: [PATCH 062/178] Update badge for GitHub actions --- README.de.md | 2 +- README.es.md | 2 +- README.ko.md | 2 +- README.md | 2 +- README.zh_tw.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.de.md b/README.de.md index 539a83e8..c12a4660 100644 --- a/README.de.md +++ b/README.de.md @@ -1,6 +1,6 @@ # Ultimativer Python-Lernführer -[![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.es.md b/README.es.md index ebc9f2e8..76d0c0ba 100644 --- a/README.es.md +++ b/README.es.md @@ -1,6 +1,6 @@ # Guía de estudio "Python Definitivo" -[![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.ko.md b/README.ko.md index 388b02c0..5472867f 100644 --- a/README.ko.md +++ b/README.ko.md @@ -1,6 +1,6 @@ # Ultimate Python 학습 가이드 -[![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.md b/README.md index 946b99bb..0ba12723 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ultimate Python study guide -[![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.zh_tw.md b/README.zh_tw.md index 5f8fc05d..ac339356 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -1,6 +1,6 @@ # Ultimate Python 學習大綱 -[![CircleCI](https://img.shields.io/circleci/build/github/huangsam/ultimate-python)](https://circleci.com/gh/huangsam/ultimate-python) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) From a328aab2e84cb759dfda8be6171ebb03d004365a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:43:24 -0700 Subject: [PATCH 063/178] Remove CircleCI config --- .circleci/config.yml | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index a759546f..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,35 +0,0 @@ -version: 2.1 - -orbs: - python: circleci/python@2.1.1 - codecov: codecov/codecov@3.2.3 - -jobs: - build-and-test: - docker: - - image: cimg/python:3.12 - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - steps: - - checkout - - python/install-packages: - pkg-manager: pip - - run: - command: ruff check ultimatepython - name: Lint - - run: - command: coverage run -m runner - name: Test - - run: - command: coverage xml -o /tmp/coverage.xml - name: Prepare coverage results - - store_artifacts: - path: /tmp/coverage.xml - - codecov/upload: - file: /tmp/coverage.xml - -workflows: - main: - jobs: - - build-and-test From b815e3405d1221c2a55593e49370598fb701f978 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 1 Oct 2024 03:46:21 -0700 Subject: [PATCH 064/178] Fix repo references in badge --- README.de.md | 2 +- README.es.md | 2 +- README.ko.md | 2 +- README.md | 2 +- README.zh_tw.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.de.md b/README.de.md index c12a4660..00263c45 100644 --- a/README.de.md +++ b/README.de.md @@ -1,6 +1,6 @@ # Ultimativer Python-Lernführer -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.es.md b/README.es.md index 76d0c0ba..87f306fd 100644 --- a/README.es.md +++ b/README.es.md @@ -1,6 +1,6 @@ # Guía de estudio "Python Definitivo" -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.ko.md b/README.ko.md index 5472867f..a29e5b87 100644 --- a/README.ko.md +++ b/README.ko.md @@ -1,6 +1,6 @@ # Ultimate Python 학습 가이드 -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.md b/README.md index 0ba12723..2f216d96 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ultimate Python study guide -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) diff --git a/README.zh_tw.md b/README.zh_tw.md index ac339356..f357b3e4 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -1,6 +1,6 @@ # Ultimate Python 學習大綱 -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/huangsam.github.io/ci.yml)](https://github.com/huangsam/huangsam.github.io/actions) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) [![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) [![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) From c29dfefa4cf23ef3ba2958f92b94c78f27c25a2e Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 6 Oct 2024 23:29:37 -0700 Subject: [PATCH 065/178] Update ruff to 0.6.9 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 35941d57..2c47a953 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.1 isort==5.13.2 -ruff==0.6.8 +ruff==0.6.9 From 022cba5886a42024edf983a5b3c16f65f9e1995d Mon Sep 17 00:00:00 2001 From: Naman Verma <82778097+NamanVer02@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:35:44 +0530 Subject: [PATCH 066/178] Add Hindi README and Update Main README Reference (#132) * Added reference to the hindi readme * Added hindi readme * Update README.md * Update README.hi.md * Added reference to the hindi readme --------- Co-authored-by: Samuel Huang --- README.de.md | 3 +- README.es.md | 3 +- README.hi.md | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ README.ko.md | 3 +- README.md | 3 +- README.zh_tw.md | 3 +- 6 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 README.hi.md diff --git a/README.de.md b/README.de.md index 00263c45..77d379d1 100644 --- a/README.de.md +++ b/README.de.md @@ -16,7 +16,8 @@ print("Ultimativer Python-Lernführer") [한국어](README.ko.md) | [繁体中文](README.zh_tw.md) | [Español](README.es.md) | -[Deutsch](README.de.md) +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) ## Motivation diff --git a/README.es.md b/README.es.md index 87f306fd..b6118a68 100644 --- a/README.es.md +++ b/README.es.md @@ -16,7 +16,8 @@ print("Guía de estudio 'Python Definitivo'") [한국어](README.ko.md) | [繁体中文](README.zh_tw.md) | [Español](README.es.md) | -[Deutsch](README.de.md) +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) ## Motivación diff --git a/README.hi.md b/README.hi.md new file mode 100644 index 00000000..f117d650 --- /dev/null +++ b/README.hi.md @@ -0,0 +1,146 @@ +# अल्टीमेट Python अध्ययन गाइड + +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) +[![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) +[![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) + +नए और पेशेवर लोगों के लिए अल्टीमेट पायथन अध्ययन गाइड। :snake: :snake: :snake: + +```python +print("Ultimate Python study guide") +``` + +[English](README.md) | +[한국어](README.ko.md) | +[繁体中文](README.zh_tw.md) | +[Español](README.es.md) | +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) + +## प्रेरणा + +मैंने यह गिटहब रिपोजिटरी [core Python](https://www.python.org/) के बारे में जो कुछ मैंने पिछले 5+ वर्षों में सीखा है, उसे साझा करने के लिए बनाई है। मैंने इसे एक कॉलेज ग्रेजुएट, बड़ी कंपनियों के कर्मचारी, और [Celery](https://github.com/celery/celery) और [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) जैसी रिपोजिटरी के ओपन-सोर्स कंट्रीब्यूटर के रूप में उपयोग किया है। मैं यह देखने के लिए उत्सुक हूँ कि और लोग पायथन सीखें और इसके माध्यम से अपने जुनून को आगे बढ़ाएं। :mortar_board: + + +## लक्ष्य + +इस गाइड को बनाने के मुख्य लक्ष्य निम्नलिखित हैं: + +:trophy: **संसाधन के रूप में सेवा देना** उन नए पायथन उपयोगकर्ताओं के लिए जो प्रैक्टिकल तरीके से सीखना पसंद करते हैं। इस रिपोजिटरी में स्वतंत्र मॉड्यूलों का एक संग्रह है, जिन्हें IDE जैसे [PyCharm](https://www.jetbrains.com/pycharm/) में या [Replit](https://replit.com/languages/python3) जैसे ब्राउज़र में चलाया जा सकता है। पुराने साधारण टर्मिनल में भी इन उदाहरणों को चलाया जा सकता है। अधिकतर लाइनों में बहुत ही अच्छे से लिखे गए comments होते हैं, जो पाठक को प्रोग्राम्स के प्रत्येक चरण के माध्यम से मार्गदर्शन करते हैं। उपयोगकर्ताओं को कोड में बदलाव करने के लिए प्रोत्साहित किया जाता है, बशर्ते कि `main` रूटीन को हटाया न जाए और हर परिवर्तन के बाद [सफलतापूर्वक चलाया जाए](runner.py)। + +:trophy: **शुद्ध गाइड के रूप में सेवा देना** उन लोगों के लिए जो मुख्य पायथन अवधारणाओं को फिर से समझना चाहते हैं। केवल [बिल्ट-इन लाइब्रेरीज़](https://docs.python.org/3/library/) का उपयोग किया गया है ताकि इन अवधारणाओं को बिना किसी विशेष डोमेन की अवधारणाओं के सरलता से समझाया जा सके। इसी कारण से लोकप्रिय ओपन-सोर्स लाइब्रेरीज़ और फ्रेमवर्क (जैसे `sqlalchemy`, `requests`, `pandas`) को इंस्टॉल नहीं किया गया है। हालांकि, इन फ्रेमवर्क्स के स्रोत कोड को पढ़ना प्रेरणादायक है और यदि आपका लक्ष्य एक सच्चे [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista) बनने का है तो इसे ज़रूर पढ़ना चाहिए। + + +## शुरूआत + +[![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) + +ऊपर दिए गए बैज पर क्लिक करें ताकि आप ब्राउज़र में एक कार्यशील वातावरण शुरू कर सकें, इसके लिए आपके स्थानीय मशीन पर Git और पायथन की आवश्यकता नहीं होगी। यदि ये आवश्यकताएँ पहले से ही पूरी हो चुकी हैं, तो आप सीधे रिपोजिटरी को क्लोन कर सकते हैं। + +एक बार जब रिपोजिटरी उपलब्ध हो जाती है, तो आप स्वतंत्र मॉड्यूल से सीखने के लिए तैयार हैं। प्रत्येक मॉड्यूल का अधिकतम लाभ उठाने के लिए, मॉड्यूल का कोड पढ़ें और इसे चलाएं। मॉड्यूल चलाने के दो तरीके हैं: + +1. एकल मॉड्यूल चलाएं: `python ultimatepython/syntax/variable.py` +2. सभी मॉड्यूल चलाएं: `python runner.py` + +## विषय सूची + +:books: = बाहरी स्रोत, +:cake: = शुरुआती विषय, +:exploding_head: = उन्नत विषय + + +1. **पायथन के बारे में** + - अवलोकन: [पायथन क्या है](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) + - डिज़ाइन दर्शन: [पायथन का ज़ेन](https://www.python.org/dev/peps/pep-0020/) ( :books: ) + - शैली मार्गदर्शिका: [पायथन कोड के लिए शैली मार्गदर्शिका](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) + - डेटा मॉडल: [डेटा मॉडल](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) + - मानक पुस्तकालय: [पायथन मानक पुस्तकालय](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) + - अंतर्निहित कार्य: [अंतर्निहित कार्य](https://docs.python.org/3/library/functions.html) ( :books: ) +2. **सिंटेक्स** + - वेरिएबल: [अंतर्निहित लिटरल](ultimatepython/syntax/variable.py) ( :cake: ) + - अभिव्यक्ति: [संख्यात्मक ऑपरेशन्स](ultimatepython/syntax/expression.py) ( :cake: ) + - बाइनरी: [बाइनरी ऑपरेटर](ultimatepython/syntax/bitwise.py) ( :cake: ), [एक्स/टू का पूरक](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) + - कंडीशनल: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) + - लूप: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) + - फ़ंक्शन: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) +3. **डेटा संरचनाएँ** + - लिसट: [लिसट ऑपरेशन्स](ultimatepython/data_structures/list.py) ( :cake: ) + - ट्यूपल: [ट्यूपल ऑपरेशन्स](ultimatepython/data_structures/tuple.py) + - सेट: [सेट ऑपरेशन्स](ultimatepython/data_structures/set.py) + - डिक्ट: [डिक्शनरी ऑपरेशन्स](ultimatepython/data_structures/dict.py) ( :cake: ) + - संकलन: [लिसट | ट्यूपल | सेट | डिक्ट](ultimatepython/data_structures/comprehension.py) + - स्ट्रिंग: [स्ट्रिंग ऑपरेशन्स](ultimatepython/data_structures/string.py) ( :cake: ) + - डेक: [डेक](ultimatepython/data_structures/deque.py) ( :exploding_head: ) + - नामित ट्यूपल: [नामित ट्यूपल](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) + - डिफ़ॉल्ट डिक्ट: [डिफ़ॉल्ट डिक्ट](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) + - समय कोम्पलेक्सिटी: [cPython ऑपरेशन्स](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) +4. **क्लासेज़** + - बेसिक क्लास: [बेसिक परिभाषा](ultimatepython/classes/basic_class.py) ( :cake: ) + - इन्हरिटैंस: [इन्हरिटैंस](ultimatepython/classes/inheritance.py) ( :cake: ) + - एैबस्टराक्ट क्लास: [एैबस्टराक्ट परिभाषा](ultimatepython/classes/abstract_class.py) + - एक्सेपशन क्लास: [एक्सेपशन परिभाषा](ultimatepython/classes/exception_class.py) + - इटरेटर क्लास: [इटरेटर परिभाषा | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - ऐनकैपसुलेषन: [ऐनकैपसुलेषन परिभाषा](ultimatepython/classes/encapsulation.py) +5. **उन्नत** + - डेकोरेटर: [डेकोरेटर परिभाषा | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) + - फ़ाइल प्रबंधन: [फ़ाइल प्रबंधन](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) + - संदर्भ प्रबंधक: [संदर्भ प्रबंधक](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) + - मेथड रिज़ॉल्यूशन क्रम: [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) + - मिक्सिन: [मिक्सिन परिभाषा](ultimatepython/advanced/mixin.py) ( :exploding_head: ) + - मेटाक्लास: [मेटाक्लास परिभाषा](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) + - थ्रेड: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) + - एसिंको: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) + - वीक रेफरेंस: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) + - बेंचमार्क: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) + - मॉकिंग: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) + - नियमित अभिव्यक्ति: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) + - डेटा फ़ॉर्मेट: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) + - दिनांक और समय: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + + +## अतिरिक्त संसाधन + +:necktie: = इंटरव्यू संसाधन, +:test_tube: = कोड नमूने, +:brain: = प्रोजेक्ट विचार + + +### गिटहब रिपॉजिटरी + +अन्य उच्च मानक संसाधनों से पढ़कर सीखना जारी रखें। + +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie: , :test_tube: ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie: , :test_tube: ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) +- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [vinta/awesome-python](https://github.com/vinta/awesome-python) +- [academic/awesome-datascience](https://github.com/academic/awesome-datascience) +- [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) +- [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) + +### इंटरैक्टिव प्रैक्टिस + +अभ्यास करते रहें ताकि आपकी कोडिंग कौशल खराब न हों। + +- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( :brain: ) +- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) +- [kaggle.com](https://www.kaggle.com/) ( :brain: ) +- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [projecteuler.net](https://projecteuler.net/) +- [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) diff --git a/README.ko.md b/README.ko.md index a29e5b87..30b72034 100644 --- a/README.ko.md +++ b/README.ko.md @@ -16,7 +16,8 @@ print("Ultimate Python 학습 가이드") [한국어](README.ko.md) | [繁体中文](README.zh_tw.md) | [Español](README.es.md) | -[Deutsch](README.de.md) +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) ## 동기 diff --git a/README.md b/README.md index 2f216d96..ebd83db6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ print("Ultimate Python study guide") [한국어](README.ko.md) | [繁体中文](README.zh_tw.md) | [Español](README.es.md) | -[Deutsch](README.de.md) +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) ## Motivation diff --git a/README.zh_tw.md b/README.zh_tw.md index f357b3e4..2f41378e 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -16,7 +16,8 @@ print("Ultimate Python 學習大綱") [한국어](README.ko.md) | [繁体中文](README.zh_tw.md) | [Español](README.es.md) | -[Deutsch](README.de.md) +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) ## 動力 From 25bd4655439f7699bd911de9d0ca5819b6a2646c Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 17 Oct 2024 19:25:11 -0700 Subject: [PATCH 067/178] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2c47a953..7731d1aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.1 isort==5.13.2 -ruff==0.6.9 +ruff==0.7.0 From 5b51ff08dcdbc4cb61a4fcb5ef4be344cf154f4a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 25 Oct 2024 05:16:13 -0700 Subject: [PATCH 068/178] Update coverage to 7.6.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7731d1aa..c02bfd6f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.1 +coverage==7.6.4 isort==5.13.2 ruff==0.7.0 From 868738ce75cf1eb9d3208d349cedf3cb2f11d650 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 25 Oct 2024 05:16:30 -0700 Subject: [PATCH 069/178] Update ruff to 0.7.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c02bfd6f..d0e526bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.4 isort==5.13.2 -ruff==0.7.0 +ruff==0.7.1 From 40a9703462dccc02924e0c18a060553b1eaffff8 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 25 Oct 2024 05:27:44 -0700 Subject: [PATCH 070/178] Fix indenting of a few comments --- ultimatepython/syntax/conditional.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ultimatepython/syntax/conditional.py b/ultimatepython/syntax/conditional.py index f18e462b..67537b32 100644 --- a/ultimatepython/syntax/conditional.py +++ b/ultimatepython/syntax/conditional.py @@ -56,9 +56,9 @@ def main(): # `0 < x_add_two < 2` is equivalent to `x_add_two > 0 and x_add_two < 2` ran_6 = False if 0 < x_add_two < 2: - ran_6 = False # skip: if + ran_6 = False # skip: if else: - ran_6 = True # run + ran_6 = True # run assert ran_6 is True From 2f55a23bcb0445f143d977a43e30a6c3038f461a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 25 Oct 2024 05:28:27 -0700 Subject: [PATCH 071/178] Fix formatting of decimals --- ultimatepython/advanced/async.py | 2 +- ultimatepython/advanced/benchmark.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ultimatepython/advanced/async.py b/ultimatepython/advanced/async.py index d7efbc59..e52b739a 100644 --- a/ultimatepython/advanced/async.py +++ b/ultimatepython/advanced/async.py @@ -12,7 +12,7 @@ from uuid import uuid4 # Module-level constants -_DELAY_SMALL = .001 +_DELAY_SMALL = 0.001 _DELAY_LARGE = 3600 diff --git a/ultimatepython/advanced/benchmark.py b/ultimatepython/advanced/benchmark.py index 386f95bd..d33195fd 100644 --- a/ultimatepython/advanced/benchmark.py +++ b/ultimatepython/advanced/benchmark.py @@ -11,7 +11,7 @@ import time # Module-level constants -_SLEEP_DURATION = .001 +_SLEEP_DURATION = 0.001 def finish_slower(): From c2a6ca1c09fd7c2154f8a2506f0fd9c902877fb4 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 25 Oct 2024 05:29:26 -0700 Subject: [PATCH 072/178] Fixup variable naming --- ultimatepython/syntax/variable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultimatepython/syntax/variable.py b/ultimatepython/syntax/variable.py index 234314cd..64cc80df 100644 --- a/ultimatepython/syntax/variable.py +++ b/ultimatepython/syntax/variable.py @@ -46,7 +46,7 @@ def main(): # We can use underscores (literal `_`) to separate digit groups in # integer literals assert 10_000 == 10000 - assert 0x01_0f_2c == 69_420 + assert 0x01_0F_2C == 69_420 assert 3.456_290e-1 == 0.3_456_290 # There is also a special literal called None. This literal is used to From bad665e6772337611e00134bb6bf80a1a6c94b2a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 5 Nov 2024 09:12:15 -0800 Subject: [PATCH 073/178] Update ruff to 0.7.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d0e526bf..1e543df2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.4 isort==5.13.2 -ruff==0.7.1 +ruff==0.7.2 From a03495f39afab91e45ffb5209fb8f5a3b4ea1c9f Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 9 Nov 2024 22:09:51 -0800 Subject: [PATCH 074/178] Update ruff to 0.7.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1e543df2..a0d5bfef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.4 isort==5.13.2 -ruff==0.7.2 +ruff==0.7.3 From 137563966905878b8fcca14dc22ce439be1ae566 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 16 Nov 2024 12:03:35 -0800 Subject: [PATCH 075/178] Update ruff to 0.7.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a0d5bfef..504f70db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.4 isort==5.13.2 -ruff==0.7.3 +ruff==0.7.4 From e54f2e7fda925c969c14d32aea9922c1e9425fa6 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 16 Nov 2024 12:04:28 -0800 Subject: [PATCH 076/178] Update coverage to 7.6.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 504f70db..f77db98c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.4 +coverage==7.6.7 isort==5.13.2 ruff==0.7.4 From 4979caa63dd8e94579a5eca7d40a592b0634fc12 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 22 Nov 2024 18:51:30 -0800 Subject: [PATCH 077/178] Update ruff to 0.8.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f77db98c..b5c1523f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.7 isort==5.13.2 -ruff==0.7.4 +ruff==0.8.0 From b7ecbd1156628ebc602417f8ebb936e06171259f Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 6 Dec 2024 11:47:24 -0800 Subject: [PATCH 078/178] Update ruff to 0.8.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b5c1523f..86ddeee3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.7 isort==5.13.2 -ruff==0.8.0 +ruff==0.8.2 From d890cdf29edf7f1f1b38f1b56504f4c658b615be Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 16 Dec 2024 22:12:49 -0800 Subject: [PATCH 079/178] Update pypi dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 86ddeee3..262dd732 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.7 +coverage==7.6.9 isort==5.13.2 -ruff==0.8.2 +ruff==0.8.3 From 51442473b8f4b929dfe6db49145a5d97c727389a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 17 Dec 2024 04:22:22 -0800 Subject: [PATCH 080/178] Add codecov config to root --- codecov.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..e62f4b99 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,7 @@ +# https://docs.codecov.com/docs/common-recipe-list +# https://docs.codecov.com/docs/commit-status +coverage: + status: + patch: + default: + target: 100% From ab383eb2d5ac247b2698b686cd3a90f737c89a24 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 21 Dec 2024 06:57:46 -0800 Subject: [PATCH 081/178] Update ruff to 0.8.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 262dd732..f60d074c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.9 isort==5.13.2 -ruff==0.8.3 +ruff==0.8.4 From edffcd01f8f522fc9aedae491fae3db4399e67f2 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 1 Jan 2025 08:57:22 -0800 Subject: [PATCH 082/178] Update coverage to 7.6.10 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f60d074c..6d83e381 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.9 +coverage==7.6.10 isort==5.13.2 ruff==0.8.4 From a7e09fb65237331d5e8a200870cec65f49fc4d10 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 5 Jan 2025 18:59:05 -0800 Subject: [PATCH 083/178] Update ruff to 0.8.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6d83e381..0684529d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.8.4 +ruff==0.8.6 From 2fb7114a37262042f1cfc93dac883c97bb9b8ceb Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 5 Jan 2025 22:47:24 -0800 Subject: [PATCH 084/178] Hardcode emojis into READMEs (#134) --- README.de.md | 118 ++++++++++++++++++++++++------------------------ README.es.md | 118 ++++++++++++++++++++++++------------------------ README.hi.md | 118 ++++++++++++++++++++++++------------------------ README.ko.md | 118 ++++++++++++++++++++++++------------------------ README.md | 118 ++++++++++++++++++++++++------------------------ README.zh_tw.md | 114 +++++++++++++++++++++++----------------------- 6 files changed, 352 insertions(+), 352 deletions(-) diff --git a/README.de.md b/README.de.md index 77d379d1..ef577047 100644 --- a/README.de.md +++ b/README.de.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -Der ultimative Python-Lernführer für Einsteiger und Profis gleichermaßen. :snake: :snake: :snake: +Der ultimative Python-Lernführer für Einsteiger und Profis gleichermaßen. 🐍 🐍 🐍 ```python print("Ultimativer Python-Lernführer") @@ -66,98 +66,98 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: ## Inhaltsübersicht -:books: = Externe Ressource, -:cake: = Thema für Anfänger, -:exploding_head: = Fortgeschrittenes Thema +📚 = Externe Ressource, +🍰 = Thema für Anfänger, +🤯 = Fortgeschrittenes Thema 1. **Über Python** - - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) - - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) - - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) - - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) - - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) - - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books: ) + - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( 📚 ) 2. **Syntax** - - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake: ) - - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake: ) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake: ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) - - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) + - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( 🍰 ) + - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( 🍰 ) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( 🍰 ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) + - Function: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) 3. **Daten-Strukturen** - - List: [List operations](ultimatepython/data_structures/list.py) ( :cake: ) + - List: [List operations](ultimatepython/data_structures/list.py) ( 🍰 ) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake: ) + - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( 🍰 ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - String: [String operations](ultimatepython/data_structures/string.py) ( :cake: ) - - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) - - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) + - String: [String operations](ultimatepython/data_structures/string.py) ( 🍰 ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Klassen** - - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake: ) - - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake: ) + - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( 🍰 ) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( 🍰 ) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Fortgeschrittene** - - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) - - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) - - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) - - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) - - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head: ) - - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) - - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) - - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) - - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) - - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) - - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) - - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) - - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( 🤯 ) + - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) ## Zusätzliche Ressourcen -:necktie: = Interview-Ressource, -:test_tube: = Code-Beispiele, -:brain: = Projektideen +👔 = Interview-Ressource, +🧪 = Code-Beispiele, +🧠 = Projektideen ### GitHub repositories Lernen Sie weiter, indem Sie von anderen Quellen lesen. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) -- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) ### Interaktive Übungen Üben Sie weiter, damit Ihre Programmierkenntnisse nicht einrosten. -- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) -- [codementor.io](https://www.codementor.io) ( :brain: ) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) - [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) diff --git a/README.es.md b/README.es.md index b6118a68..815f7c31 100644 --- a/README.es.md +++ b/README.es.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -Guía de estudio "Python Definitivo" para principiantes y profesionales. :snake: :snake: :snake: +Guía de estudio "Python Definitivo" para principiantes y profesionales. 🐍 🐍 🐍 ```python print("Guía de estudio 'Python Definitivo'") @@ -65,98 +65,98 @@ Hay dos maneras de ejecutar los módulos: ## Contenido -:books: = Recurso externo, -:cake: = Tema principiante, -:exploding_head: = Tema avanzado +📚 = Recurso externo, +🍰 = Tema principiante, +🤯 = Tema avanzado 1. **Sobre Python** - - Resumen: [¿Qué es Python?](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) - - Filosofía de diseño: [El Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) - - Guía de estilos: [Guía de estilos para código de Python](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) - - Modelo de datos: [Modelo de datos](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) - - Librería estándar: [La librería estándar de Python](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) - - Funciones integradas: [Funciones integradas](https://docs.python.org/3/library/functions.html) ( :books: ) + - Resumen: [¿Qué es Python?](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - Filosofía de diseño: [El Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - Guía de estilos: [Guía de estilos para código de Python](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - Modelo de datos: [Modelo de datos](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - Librería estándar: [La librería estándar de Python](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - Funciones integradas: [Funciones integradas](https://docs.python.org/3/library/functions.html) ( 📚 ) 2. **Sintaxis** - - Variables: [Literales integrados](ultimatepython/syntax/variable.py) ( :cake: ) - - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) ( :cake: ) - - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) ( :cake: ), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) - - Funciones: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) + - Variables: [Literales integrados](ultimatepython/syntax/variable.py) ( 🍰 ) + - Expresiones: [Operaciones numéricas](ultimatepython/syntax/expression.py) ( 🍰 ) + - Bit a bit: [Operadores bit a bit](ultimatepython/syntax/bitwise.py) ( 🍰 ), [Complemento a uno/dos](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) + - Funciones: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) 3. **Estructura de datos** - - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) ( :cake: ) + - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) ( 🍰 ) - Tupla: [Operaciones con tuplas](ultimatepython/data_structures/tuple.py) - Set: [Operaciones con sets](ultimatepython/data_structures/set.py) - - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) ( :cake: ) + - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) ( 🍰 ) - Comprensión: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) ( :cake: ) - - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) - - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) + - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) ( 🍰 ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Clases** - - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) ( :cake: ) - - Herencia: [Herencia](ultimatepython/classes/inheritance.py) ( :cake: ) + - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) ( 🍰 ) + - Herencia: [Herencia](ultimatepython/classes/inheritance.py) ( 🍰 ) - Clase abstracta: [Definición de abstracta](ultimatepython/classes/abstract_class.py) - Clase de excepción: [Definición de excepción](ultimatepython/classes/exception_class.py) - - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - Clase iteradora: [Definición de iteradora | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) - Encapsulación: [Definición de encapsulación](ultimatepython/classes/encapsulation.py) 5. **Avanzado** - - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) - - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) - - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) - - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) - - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) ( :exploding_head: ) - - Metaclase: [Definición de metaclase](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) - - Hilos: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) - - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) - - Referencias débiles: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) - - Referencia: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) - - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) - - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) - - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + - Decorador: [Definición de decorador | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - Manejo de archivos: [Manejo de archivos](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - Gestor de contexto: [Gestores de contexto](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - Orden de resolución de método (MRO por sus siglas en inglés): [mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - Mixin: [Definición de Mixin](ultimatepython/advanced/mixin.py) ( 🤯 ) + - Metaclase: [Definición de metaclase](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - Hilos: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - Referencias débiles: [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - Referencia: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) ## Recursos adicionales -:necktie: = Recurso de entrevista, -:test_tube: = Ejemplos de código, -:brain: = Ideas para proyecto +👔 = Recurso de entrevista, +🧪 = Ejemplos de código, +🧠 = Ideas para proyecto ### Repositorios de GitHub Sigue aprendiendo leyendo otros buenos recursos. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) -- [karan/Projects](https://github.com/karan/Projects) (:brain: ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) (🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) ### Práctica interactiva Continua practicando para que no se oxiden tus habilidades de programación. -- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) -- [codementor.io](https://www.codementor.io) ( :brain: ) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) - [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) diff --git a/README.hi.md b/README.hi.md index f117d650..c62b548f 100644 --- a/README.hi.md +++ b/README.hi.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -नए और पेशेवर लोगों के लिए अल्टीमेट पायथन अध्ययन गाइड। :snake: :snake: :snake: +नए और पेशेवर लोगों के लिए अल्टीमेट पायथन अध्ययन गाइड। 🐍 🐍 🐍 ```python print("Ultimate Python study guide") @@ -46,101 +46,101 @@ print("Ultimate Python study guide") ## विषय सूची -:books: = बाहरी स्रोत, -:cake: = शुरुआती विषय, -:exploding_head: = उन्नत विषय +📚 = बाहरी स्रोत, +🍰 = शुरुआती विषय, +🤯 = उन्नत विषय 1. **पायथन के बारे में** - - अवलोकन: [पायथन क्या है](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) - - डिज़ाइन दर्शन: [पायथन का ज़ेन](https://www.python.org/dev/peps/pep-0020/) ( :books: ) - - शैली मार्गदर्शिका: [पायथन कोड के लिए शैली मार्गदर्शिका](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) - - डेटा मॉडल: [डेटा मॉडल](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) - - मानक पुस्तकालय: [पायथन मानक पुस्तकालय](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) - - अंतर्निहित कार्य: [अंतर्निहित कार्य](https://docs.python.org/3/library/functions.html) ( :books: ) + - अवलोकन: [पायथन क्या है](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - डिज़ाइन दर्शन: [पायथन का ज़ेन](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - शैली मार्गदर्शिका: [पायथन कोड के लिए शैली मार्गदर्शिका](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - डेटा मॉडल: [डेटा मॉडल](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - मानक पुस्तकालय: [पायथन मानक पुस्तकालय](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - अंतर्निहित कार्य: [अंतर्निहित कार्य](https://docs.python.org/3/library/functions.html) ( 📚 ) 2. **सिंटेक्स** - - वेरिएबल: [अंतर्निहित लिटरल](ultimatepython/syntax/variable.py) ( :cake: ) - - अभिव्यक्ति: [संख्यात्मक ऑपरेशन्स](ultimatepython/syntax/expression.py) ( :cake: ) - - बाइनरी: [बाइनरी ऑपरेटर](ultimatepython/syntax/bitwise.py) ( :cake: ), [एक्स/टू का पूरक](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - - कंडीशनल: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - - लूप: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) - - फ़ंक्शन: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) + - वेरिएबल: [अंतर्निहित लिटरल](ultimatepython/syntax/variable.py) ( 🍰 ) + - अभिव्यक्ति: [संख्यात्मक ऑपरेशन्स](ultimatepython/syntax/expression.py) ( 🍰 ) + - बाइनरी: [बाइनरी ऑपरेटर](ultimatepython/syntax/bitwise.py) ( 🍰 ), [एक्स/टू का पूरक](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - कंडीशनल: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - लूप: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) + - फ़ंक्शन: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) 3. **डेटा संरचनाएँ** - - लिसट: [लिसट ऑपरेशन्स](ultimatepython/data_structures/list.py) ( :cake: ) + - लिसट: [लिसट ऑपरेशन्स](ultimatepython/data_structures/list.py) ( 🍰 ) - ट्यूपल: [ट्यूपल ऑपरेशन्स](ultimatepython/data_structures/tuple.py) - सेट: [सेट ऑपरेशन्स](ultimatepython/data_structures/set.py) - - डिक्ट: [डिक्शनरी ऑपरेशन्स](ultimatepython/data_structures/dict.py) ( :cake: ) + - डिक्ट: [डिक्शनरी ऑपरेशन्स](ultimatepython/data_structures/dict.py) ( 🍰 ) - संकलन: [लिसट | ट्यूपल | सेट | डिक्ट](ultimatepython/data_structures/comprehension.py) - - स्ट्रिंग: [स्ट्रिंग ऑपरेशन्स](ultimatepython/data_structures/string.py) ( :cake: ) - - डेक: [डेक](ultimatepython/data_structures/deque.py) ( :exploding_head: ) - - नामित ट्यूपल: [नामित ट्यूपल](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) - - डिफ़ॉल्ट डिक्ट: [डिफ़ॉल्ट डिक्ट](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) - - समय कोम्पलेक्सिटी: [cPython ऑपरेशन्स](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) + - स्ट्रिंग: [स्ट्रिंग ऑपरेशन्स](ultimatepython/data_structures/string.py) ( 🍰 ) + - डेक: [डेक](ultimatepython/data_structures/deque.py) ( 🤯 ) + - नामित ट्यूपल: [नामित ट्यूपल](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - डिफ़ॉल्ट डिक्ट: [डिफ़ॉल्ट डिक्ट](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - समय कोम्पलेक्सिटी: [cPython ऑपरेशन्स](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **क्लासेज़** - - बेसिक क्लास: [बेसिक परिभाषा](ultimatepython/classes/basic_class.py) ( :cake: ) - - इन्हरिटैंस: [इन्हरिटैंस](ultimatepython/classes/inheritance.py) ( :cake: ) + - बेसिक क्लास: [बेसिक परिभाषा](ultimatepython/classes/basic_class.py) ( 🍰 ) + - इन्हरिटैंस: [इन्हरिटैंस](ultimatepython/classes/inheritance.py) ( 🍰 ) - एैबस्टराक्ट क्लास: [एैबस्टराक्ट परिभाषा](ultimatepython/classes/abstract_class.py) - एक्सेपशन क्लास: [एक्सेपशन परिभाषा](ultimatepython/classes/exception_class.py) - - इटरेटर क्लास: [इटरेटर परिभाषा | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - इटरेटर क्लास: [इटरेटर परिभाषा | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) - ऐनकैपसुलेषन: [ऐनकैपसुलेषन परिभाषा](ultimatepython/classes/encapsulation.py) 5. **उन्नत** - - डेकोरेटर: [डेकोरेटर परिभाषा | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) - - फ़ाइल प्रबंधन: [फ़ाइल प्रबंधन](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) - - संदर्भ प्रबंधक: [संदर्भ प्रबंधक](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) - - मेथड रिज़ॉल्यूशन क्रम: [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) - - मिक्सिन: [मिक्सिन परिभाषा](ultimatepython/advanced/mixin.py) ( :exploding_head: ) - - मेटाक्लास: [मेटाक्लास परिभाषा](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) - - थ्रेड: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) - - एसिंको: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) - - वीक रेफरेंस: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) - - बेंचमार्क: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) - - मॉकिंग: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) - - नियमित अभिव्यक्ति: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) - - डेटा फ़ॉर्मेट: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) - - दिनांक और समय: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + - डेकोरेटर: [डेकोरेटर परिभाषा | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - फ़ाइल प्रबंधन: [फ़ाइल प्रबंधन](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - संदर्भ प्रबंधक: [संदर्भ प्रबंधक](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - मेथड रिज़ॉल्यूशन क्रम: [mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - मिक्सिन: [मिक्सिन परिभाषा](ultimatepython/advanced/mixin.py) ( 🤯 ) + - मेटाक्लास: [मेटाक्लास परिभाषा](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - थ्रेड: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - एसिंको: [async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - वीक रेफरेंस: [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - बेंचमार्क: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - मॉकिंग: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - नियमित अभिव्यक्ति: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - डेटा फ़ॉर्मेट: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - दिनांक और समय: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) ## अतिरिक्त संसाधन -:necktie: = इंटरव्यू संसाधन, -:test_tube: = कोड नमूने, -:brain: = प्रोजेक्ट विचार +👔 = इंटरव्यू संसाधन, +🧪 = कोड नमूने, +🧠 = प्रोजेक्ट विचार ### गिटहब रिपॉजिटरी अन्य उच्च मानक संसाधनों से पढ़कर सीखना जारी रखें। -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie: , :test_tube: ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie: , :test_tube: ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) -- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) ### इंटरैक्टिव प्रैक्टिस अभ्यास करते रहें ताकि आपकी कोडिंग कौशल खराब न हों। -- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) -- [codementor.io](https://www.codementor.io) ( :brain: ) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) - [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) diff --git a/README.ko.md b/README.ko.md index 30b72034..d30b4ca6 100644 --- a/README.ko.md +++ b/README.ko.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. :snake: :snake: :snake: +초보자와 전문가 모두를 위한 최고의 Python 학습 가이드입니다. 🐍 🐍 🐍 ```python print("Ultimate Python 학습 가이드") @@ -55,98 +55,98 @@ print("Ultimate Python 학습 가이드") ## 목차 -:books: = 외부 리소스, -:cake: = 초급 주제, -:exploding_head: = 고급 주제 +📚 = 외부 리소스, +🍰 = 초급 주제, +🤯 = 고급 주제 1. **Python 정보** - - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) - - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) - - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) - - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) - - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) - - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) ( :books: ) + - 개요 : [Python이란 무엇인가](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - 디자인 철학 : [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - 스타일 가이드 : [Python 코드 스타일 가이드](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - 데이터 모델 : [데이터 모델](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - 표준 라이브러리 : [Python 표준 라이브러리](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - 내장 함수 : [내장 함수](https://docs.python.org/3/library/functions.html) ( 📚 ) 2. **통사론** - - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) ( :cake: ) - - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) ( :cake: ) - - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) ( :cake: ), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) - - 함수 : [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) + - 변수 : [내장 리터럴](ultimatepython/syntax/variable.py) ( 🍰 ) + - 표현식 : [숫자 연산](ultimatepython/syntax/expression.py) ( 🍰 ) + - 비트 연산 : [비트 연산자](ultimatepython/syntax/bitwise.py) ( 🍰 ), [1의 보수/2의 보수](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) + - 함수 : [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) 3. **데이터 구조** - - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) ( :cake: ) + - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) ( 🍰 ) - 튜플 : [튜플 연산](ultimatepython/data_structures/tuple.py) - 세트 : [세트 연산](ultimatepython/data_structures/set.py) - - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) ( :cake: ) + - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) ( 🍰 ) - 컴프리헨션 : [리스트 | 튜플 | 세트 | 딕셔너리](ultimatepython/data_structures/comprehension.py) - - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) ( :cake: ) - - 덱: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) - - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) + - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) ( 🍰 ) + - 덱: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **클래스** - - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) ( :cake: ) - - 계승: [계승](ultimatepython/classes/inheritance.py) ( :cake: ) + - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) ( 🍰 ) + - 계승: [계승](ultimatepython/classes/inheritance.py) ( 🍰 ) - 추상 클래스 : [추상 정의](ultimatepython/classes/abstract_class.py) - 예외 클래스 : [예외 정의](ultimatepython/classes/exception_class.py) - - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - 이터레이터 클래스 : [이터레이터 정의 | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) - 캡슐화: [캡슐화 정의](ultimatepython/classes/encapsulation.py) 5. **고급** - - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) - - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) - - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) - - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) - - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) ( :exploding_head: ) - - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) - - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) - - Asyncio : [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) - - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) - - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) - - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) - - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) - - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) - - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + - 데코레이터 : [데코레이터 정의 | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - 파일 처리: [파일 처리](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - 컨텍스트 매니저 : [컨텍스트 매니저](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - 메서드 결정 순서 : [mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - 믹스인 : [믹스인 정의](ultimatepython/advanced/mixin.py) ( 🤯 ) + - 메타클래스 : [메타클래스 정의](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - 스레드 : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - Asyncio : [async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - 약한 참조 : [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - 벤치마크 : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - 모킹 : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) ## 추가 자료 -:necktie: = 인터뷰 자료, -:test_tube: = 코드 샘플, -:brain: = 프로젝트 아이디어 +👔 = 인터뷰 자료, +🧪 = 코드 샘플, +🧠 = 프로젝트 아이디어 ### GitHub 저장소 잘 알려진 다른 자료를 읽으면서 계속 배우세요. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) -- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) ### 대화형 연습 코딩 실력이 녹슬지 않기 위해 계속 연습하세요. -- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) -- [codementor.io](https://www.codementor.io) ( :brain: ) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) - [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) diff --git a/README.md b/README.md index ebd83db6..191a1115 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -Ultimate Python study guide for newcomers and professionals alike. :snake: :snake: :snake: +Ultimate Python study guide for newcomers and professionals alike. 🐍 🐍 🐍 ```python print("Ultimate Python study guide") @@ -67,98 +67,98 @@ There are two ways of running the modules: ## Table of contents -:books: = External resource, -:cake: = Beginner topic, -:exploding_head: = Advanced topic +📚 = External resource, +🍰 = Beginner topic, +🤯 = Advanced topic 1. **About Python** - - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) - - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( :books: ) - - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) - - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) - - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) - - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( :books: ) + - Overview: [What is Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - Design philosophy: [The Zen of Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - Style guide: [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - Data model: [Data model](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - Standard library: [The Python Standard Library](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - Built-in functions: [Built-in Functions](https://docs.python.org/3/library/functions.html) ( 📚 ) 2. **Syntax** - - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( :cake: ) - - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( :cake: ) - - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( :cake: ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( :cake: ) - - Function: [def | lambda](ultimatepython/syntax/function.py) ( :cake: ) + - Variable: [Built-in literals](ultimatepython/syntax/variable.py) ( 🍰 ) + - Expression: [Numeric operations](ultimatepython/syntax/expression.py) ( 🍰 ) + - Bitwise: [Bitwise operators](ultimatepython/syntax/bitwise.py) ( 🍰 ), [One's/Two's Complement](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) + - Function: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) 3. **Data Structures** - - List: [List operations](ultimatepython/data_structures/list.py) ( :cake: ) + - List: [List operations](ultimatepython/data_structures/list.py) ( 🍰 ) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( :cake: ) + - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( 🍰 ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - String: [String operations](ultimatepython/data_structures/string.py) ( :cake: ) - - Deque: [deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) - - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) + - String: [String operations](ultimatepython/data_structures/string.py) ( 🍰 ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Classes** - - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( :cake: ) - - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( :cake: ) + - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( 🍰 ) + - Inheritance: [Inheritance](ultimatepython/classes/inheritance.py) ( 🍰 ) - Abstract class: [Abstract definition](ultimatepython/classes/abstract_class.py) - Exception class: [Exception definition](ultimatepython/classes/exception_class.py) - - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - Iterator class: [Iterator definition | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) - Encapsulation: [Encapsulation definition](ultimatepython/classes/encapsulation.py) 5. **Advanced** - - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) - - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) - - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) - - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) - - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( :exploding_head: ) - - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) - - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) - - Asyncio: [async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) - - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) - - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) - - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) - - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) - - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) - - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + - Decorator: [Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - File Handling: [File Handling](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - Context manager: [Context managers](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - Method resolution order: [mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - Mixin: [Mixin definition](ultimatepython/advanced/mixin.py) ( 🤯 ) + - Metaclass: [Metaclass definition](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - Weak reference: [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) ## Additional resources -:necktie: = Interview resource, -:test_tube: = Code samples, -:brain: = Project ideas +👔 = Interview resource, +🧪 = Code samples, +🧠 = Project ideas ### GitHub repositories Keep learning by reading from other well-regarded resources. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie: , :test_tube: ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie: , :test_tube: ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) -- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) ### Interactive practice Keep practicing so that your coding skills don't get rusty. -- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) -- [codementor.io](https://www.codementor.io) ( :brain: ) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) - [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) diff --git a/README.zh_tw.md b/README.zh_tw.md index 2f41378e..b67916a9 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) [![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) -Ultimate Python 學習大綱 - 適用於新手和專業人士。:snake: :snake: :snake: +Ultimate Python 學習大綱 - 適用於新手和專業人士。🐍 🐍 🐍 ```python print("Ultimate Python 學習大綱") @@ -50,97 +50,97 @@ print("Ultimate Python 學習大綱") ## 目錄 -:books: = 外部資源, -:cake: = 入門題目, -:exploding_head: = 進階題目 +📚 = 外部資源, +🍰 = 入門題目, +🤯 = 進階題目 1. **關於 Python** - - 概述:[什麼是 Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( :books:, :cake: ) - - 設計理念:[Python之格言](https://www.python.org/dev/peps/pep-0020/) ( :books: ) - - 樣式指南:[Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/) ( :books:, :exploding_head: ) - - 數據模型:[數據模型](https://docs.python.org/3/reference/datamodel.html) ( :books:, :exploding_head: ) - - 標準庫:[Python標準庫](https://docs.python.org/3/library/) ( :books:, :exploding_head: ) - - 內置函式:[內置函式](https://docs.python.org/3/library/functions.html) ( :books: ) + - 概述:[什麼是 Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - 設計理念:[Python之格言](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - 樣式指南:[Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - 數據模型:[數據模型](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - 標準庫:[Python標準庫](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - 內置函式:[內置函式](https://docs.python.org/3/library/functions.html) ( 📚 ) 2. **語法** - - 變數:[內置值](ultimatepython/syntax/variable.py) ( :cake: ) - - 運算式:[數值運算](ultimatepython/syntax/expression.py) ( :cake: ) - - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) ( :cake: ), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( :books: ) - - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( :cake: ) - - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) ( :cake: ) - - 定義函式:[def | lambda](ultimatepython/syntax/function.py) ( :cake: ) + - 變數:[內置值](ultimatepython/syntax/variable.py) ( 🍰 ) + - 運算式:[數值運算](ultimatepython/syntax/expression.py) ( 🍰 ) + - 按位: [中的位元運算符](ultimatepython/syntax/bitwise.py) ( 🍰 ), [一個的補語/補碼](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) ( 🍰 ) + - 定義函式:[def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) 3. **資料結構** - - 列表:[列表操作](ultimatepython/data_structures/list.py) ( :cake: ) + - 列表:[列表操作](ultimatepython/data_structures/list.py) ( 🍰 ) - 元組:[元組操作](ultimatepython/data_structures/tuple.py) - 集合:[集合操作](ultimatepython/data_structures/set.py) - - 字典:[字典操作](ultimatepython/data_structures/dict.py) ( :cake: ) + - 字典:[字典操作](ultimatepython/data_structures/dict.py) ( 🍰 ) - 綜合:[list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - - 字串:[字串操作](ultimatepython/data_structures/string.py) ( :cake: ) - - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( :exploding_head: ) - - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( :exploding_head: ) - - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( :exploding_head: ) - - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) ( :books:, :exploding_head: ) + - 字串:[字串操作](ultimatepython/data_structures/string.py) ( 🍰 ) + - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( 🤯 ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **類別** - - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) ( :cake: ) + - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) ( 🍰 ) - 抽象類別:[抽象定義](ultimatepython/classes/abstract_class.py) - 異常類別:[異常定義](ultimatepython/classes/exception_class.py) - - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) ( :exploding_head: ) + - 迭代類別:[迭代器定義](ultimatepython/classes/iterator_class.py) ( 🤯 ) - 封裝: [封裝定義](ultimatepython/classes/encapsulation.py) 5. **進階技巧** - - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( :exploding_head: ) - - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) ( :exploding_head: ) - - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) ( :exploding_head: ) - - 方法解析順序:[mro](ultimatepython/advanced/mro.py) ( :exploding_head: ) - - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) ( :exploding_head: ) - - 元類:[Metaclass定義](ultimatepython/advanced/meta_class.py) ( :exploding_head: ) - - 執行緒:[ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( :exploding_head: ) - - 異步:[async | await](ultimatepython/advanced/async.py) ( :exploding_head: ) - - 弱引用:[weakref](ultimatepython/advanced/weak_ref.py) ( :exploding_head: ) - - 基準:[cProfile | pstats](ultimatepython/advanced/benchmark.py) ( :exploding_head: ) - - 模擬:[MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( :exploding_head: ) - - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( :exploding_head: ) - - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) ( :exploding_head: ) - - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) ( :exploding_head: ) + - 裝飾器:[Decorator definition | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - 文件處理: [File Handling](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - 資源管理器:[Context managers](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - 方法解析順序:[mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - Mixin:[Mixin定義](ultimatepython/advanced/mixin.py) ( 🤯 ) + - 元類:[Metaclass定義](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - 執行緒:[ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - 異步:[async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - 弱引用:[weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - 基準:[cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - 模擬:[MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) ## 額外資源 -:necktie: = 面試資源, -:test_tube: = 代碼範例, -:brain: = 項目構想 +👔 = 面試資源, +🧪 = 代碼範例, +🧠 = 項目構想 ### GitHub儲存庫 通過閱讀其他備受尊重的資源來繼續學習。 -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( :necktie:, :test_tube: ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( :necktie:, :test_tube: ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( :test_tube: ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( :test_tube: ) -- [karan/Projects](https://github.com/karan/Projects) ( :brain: ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( :brain: ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) - [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) - [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( :test_tube: ) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( :necktie: ) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) ### 互動練習 繼續練習才能使您的編碼技能不會生疏。 - [DevProjects](https://www.codementor.io/projects/python) -- [codechef.com](https://www.codechef.com/) ( :necktie: ) +- [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) -- [coderbyte.com](https://www.coderbyte.com/) ( :necktie: ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( :necktie: ) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) - [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( :necktie: ) -- [kaggle.com](https://www.kaggle.com/) ( :brain: ) -- [leetcode.com](https://leetcode.com/) ( :necktie: ) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( :test_tube: ) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) From 49bd6e7203a608e7ea08213253600ee41867a382 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 5 Jan 2025 22:49:12 -0800 Subject: [PATCH 085/178] Hardcode a few more emojis --- README.de.md | 6 +++--- README.es.md | 6 +++--- README.hi.md | 6 +++--- README.ko.md | 6 +++--- README.md | 6 +++--- README.zh_tw.md | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.de.md b/README.de.md index ef577047..3e91833b 100644 --- a/README.de.md +++ b/README.de.md @@ -26,13 +26,13 @@ in den letzten 5 Jahren als Hochschulabsolvent, Angestellter in großen Unternehmen und als Open-Source-Mitarbeiter von Repositories wie [Celery](https://github.com/celery/celery) und [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) weiterzugeben. -Ich freue mich darauf, dass noch mehr Menschen Python lernen und damit ihren Leidenschaften nachgehen. :mortar_board: +Ich freue mich darauf, dass noch mehr Menschen Python lernen und damit ihren Leidenschaften nachgehen. 🎓 ## Ziele Dies sind die Hauptziele bei der Erstellung dieses Leitfadens: -:trophy: **Als Ressource fungieren** für Python-Neulinge, die es vorziehen, praktisch zu lernen. +🏆 **Als Ressource fungieren** für Python-Neulinge, die es vorziehen, praktisch zu lernen. Dieses Repository enthält eine Sammlung von eigenständigen Modulen, die in einer IDE wie [PyCharm](https://www.jetbrains.com/pycharm/) und im Browser wie [Replit](https://replit.com/languages/python3). Wleches wie ein einfaches Terminal @@ -41,7 +41,7 @@ Schritt für Schritt durch das Programm führen. Die Benutzer werden ermutigt, d Quellcode überall zu ändern, solange die "Haupt"-Routinen nicht gelöscht werden und [run successfully](runner.py) nach jeder Änderung. -:trophy: **Als reiner Leitfaden dienen** für diejenigen, die die wichtigsten Python-Konzepte wiederholen möchten. +🏆 **Als reiner Leitfaden dienen** für diejenigen, die die wichtigsten Python-Konzepte wiederholen möchten. Wo nur [builtin libraries](https://docs.python.org/3/library/) genutzt werden, so dass diese Konzepte ohne den Overhead der bereichsspezifischen Konzepte vermittelt werden können. Als beliebte Open-Source-Bibliotheken und -Frameworks (d.h. `sqlalchemy`, `requests`, diff --git a/README.es.md b/README.es.md index 815f7c31..6fd60c9f 100644 --- a/README.es.md +++ b/README.es.md @@ -25,13 +25,13 @@ Creé este repositorio de GitHub para compartir lo que he aprendido sobre [Pytho durante más de 5 años usándolo como graduado de universidad, empleado en grandes empresas y como contribuidor de código abierto en repositorios como [Celery](https://github.com/celery/celery) y [Full Stack Python](https://github.com/mattmakai/fullstackpython.com). -Espero ver a más personas aprendiendo Python y persiguiendo su pasión a través de él. :mortar_board: +Espero ver a más personas aprendiendo Python y persiguiendo su pasión a través de él. 🎓 ## Objetivos Estos son los objetivos principales de esta guía: -:trophy: **Servir como un recurso** para principiantes de Python que prefieren aprender por su cuenta. +🏆 **Servir como un recurso** para principiantes de Python que prefieren aprender por su cuenta. Este repositorio enumera una colección de módulos independientes que pueden ser ejecutados en un IDE como [PyCharm](https://www.jetbrains.com/pycharm/) e incluso en el navegador, como [Repl.it](https://repl.it/languages/python3). Incluso una terminal antigua funcionará igual de bien @@ -40,7 +40,7 @@ al lector para entender paso a paso el proceso que el programa está ejecutando. a que modifiquen el código fuente en cualquier parte siempre y cuando las rutinas principales (`main`) se eliminen y se [ejecuten con éxito](runner.py) tras cada cambio. -:trophy: **Servir como una guía pura** para aquellos que quieren reforzar los conceptos base de +🏆 **Servir como una guía pura** para aquellos que quieren reforzar los conceptos base de Python. Se utilizan sólo las [librerías integradas](https://docs.python.org/3/library/) para que estos conceptos puedan adquirirse sin el esfuerzo de aprender conocimientos de dominios específicos. Por ello no se han instalado librerías y entornos de código abierto populares (como `sqlalchemy`, diff --git a/README.hi.md b/README.hi.md index c62b548f..030a4a50 100644 --- a/README.hi.md +++ b/README.hi.md @@ -21,16 +21,16 @@ print("Ultimate Python study guide") ## प्रेरणा -मैंने यह गिटहब रिपोजिटरी [core Python](https://www.python.org/) के बारे में जो कुछ मैंने पिछले 5+ वर्षों में सीखा है, उसे साझा करने के लिए बनाई है। मैंने इसे एक कॉलेज ग्रेजुएट, बड़ी कंपनियों के कर्मचारी, और [Celery](https://github.com/celery/celery) और [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) जैसी रिपोजिटरी के ओपन-सोर्स कंट्रीब्यूटर के रूप में उपयोग किया है। मैं यह देखने के लिए उत्सुक हूँ कि और लोग पायथन सीखें और इसके माध्यम से अपने जुनून को आगे बढ़ाएं। :mortar_board: +मैंने यह गिटहब रिपोजिटरी [core Python](https://www.python.org/) के बारे में जो कुछ मैंने पिछले 5+ वर्षों में सीखा है, उसे साझा करने के लिए बनाई है। मैंने इसे एक कॉलेज ग्रेजुएट, बड़ी कंपनियों के कर्मचारी, और [Celery](https://github.com/celery/celery) और [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) जैसी रिपोजिटरी के ओपन-सोर्स कंट्रीब्यूटर के रूप में उपयोग किया है। मैं यह देखने के लिए उत्सुक हूँ कि और लोग पायथन सीखें और इसके माध्यम से अपने जुनून को आगे बढ़ाएं। 🎓 ## लक्ष्य इस गाइड को बनाने के मुख्य लक्ष्य निम्नलिखित हैं: -:trophy: **संसाधन के रूप में सेवा देना** उन नए पायथन उपयोगकर्ताओं के लिए जो प्रैक्टिकल तरीके से सीखना पसंद करते हैं। इस रिपोजिटरी में स्वतंत्र मॉड्यूलों का एक संग्रह है, जिन्हें IDE जैसे [PyCharm](https://www.jetbrains.com/pycharm/) में या [Replit](https://replit.com/languages/python3) जैसे ब्राउज़र में चलाया जा सकता है। पुराने साधारण टर्मिनल में भी इन उदाहरणों को चलाया जा सकता है। अधिकतर लाइनों में बहुत ही अच्छे से लिखे गए comments होते हैं, जो पाठक को प्रोग्राम्स के प्रत्येक चरण के माध्यम से मार्गदर्शन करते हैं। उपयोगकर्ताओं को कोड में बदलाव करने के लिए प्रोत्साहित किया जाता है, बशर्ते कि `main` रूटीन को हटाया न जाए और हर परिवर्तन के बाद [सफलतापूर्वक चलाया जाए](runner.py)। +🏆 **संसाधन के रूप में सेवा देना** उन नए पायथन उपयोगकर्ताओं के लिए जो प्रैक्टिकल तरीके से सीखना पसंद करते हैं। इस रिपोजिटरी में स्वतंत्र मॉड्यूलों का एक संग्रह है, जिन्हें IDE जैसे [PyCharm](https://www.jetbrains.com/pycharm/) में या [Replit](https://replit.com/languages/python3) जैसे ब्राउज़र में चलाया जा सकता है। पुराने साधारण टर्मिनल में भी इन उदाहरणों को चलाया जा सकता है। अधिकतर लाइनों में बहुत ही अच्छे से लिखे गए comments होते हैं, जो पाठक को प्रोग्राम्स के प्रत्येक चरण के माध्यम से मार्गदर्शन करते हैं। उपयोगकर्ताओं को कोड में बदलाव करने के लिए प्रोत्साहित किया जाता है, बशर्ते कि `main` रूटीन को हटाया न जाए और हर परिवर्तन के बाद [सफलतापूर्वक चलाया जाए](runner.py)। -:trophy: **शुद्ध गाइड के रूप में सेवा देना** उन लोगों के लिए जो मुख्य पायथन अवधारणाओं को फिर से समझना चाहते हैं। केवल [बिल्ट-इन लाइब्रेरीज़](https://docs.python.org/3/library/) का उपयोग किया गया है ताकि इन अवधारणाओं को बिना किसी विशेष डोमेन की अवधारणाओं के सरलता से समझाया जा सके। इसी कारण से लोकप्रिय ओपन-सोर्स लाइब्रेरीज़ और फ्रेमवर्क (जैसे `sqlalchemy`, `requests`, `pandas`) को इंस्टॉल नहीं किया गया है। हालांकि, इन फ्रेमवर्क्स के स्रोत कोड को पढ़ना प्रेरणादायक है और यदि आपका लक्ष्य एक सच्चे [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista) बनने का है तो इसे ज़रूर पढ़ना चाहिए। +🏆 **शुद्ध गाइड के रूप में सेवा देना** उन लोगों के लिए जो मुख्य पायथन अवधारणाओं को फिर से समझना चाहते हैं। केवल [बिल्ट-इन लाइब्रेरीज़](https://docs.python.org/3/library/) का उपयोग किया गया है ताकि इन अवधारणाओं को बिना किसी विशेष डोमेन की अवधारणाओं के सरलता से समझाया जा सके। इसी कारण से लोकप्रिय ओपन-सोर्स लाइब्रेरीज़ और फ्रेमवर्क (जैसे `sqlalchemy`, `requests`, `pandas`) को इंस्टॉल नहीं किया गया है। हालांकि, इन फ्रेमवर्क्स के स्रोत कोड को पढ़ना प्रेरणादायक है और यदि आपका लक्ष्य एक सच्चे [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista) बनने का है तो इसे ज़रूर पढ़ना चाहिए। ## शुरूआत diff --git a/README.ko.md b/README.ko.md index d30b4ca6..928518ac 100644 --- a/README.ko.md +++ b/README.ko.md @@ -24,18 +24,18 @@ print("Ultimate Python 학습 가이드") 이 GitHub 저장소는 대학 졸업 후, 대규모 회사에서 근무하면서 그리고 [Celery](https://github.com/celery/celery)와 [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) 같은 오픈소스 프로젝트에 기여하면서 지난 5년 이상 동안 배운 [core Python](https://www.python.org/)에 대한 지식을 공유하기 위해 만들었습니다. -저는 더 많은 사람들이 Python을 배우고 자신의 열정을 추구하길 기대합니다. :mortar_board: +저는 더 많은 사람들이 Python을 배우고 자신의 열정을 추구하길 기대합니다. 🎓 ## 목표 이 가이드를 만드는 주요 목표는 다음과 같습니다: -:trophy: 실습 학습을 선호하는 Python 초보자를 위한 **학습 자료를 제공합니다.** +🏆 실습 학습을 선호하는 Python 초보자를 위한 **학습 자료를 제공합니다.** 이 저장소에는 [PyCharm](https://www.jetbrains.com/pycharm/)과 같은 IDE 및 [Replit](https://replit.com/languages/python3)와 같은 브라우저에서 실행할 수 있는 독립형 모듈 모음이 있습니다. 기본 터미널에서도 예제를 실행할 수 있습니다. 대부분의 코드 라인에 프로그램이 단계별로 어떤 작업을 하는지 안내하는 신중하게 작성된 주석이 있습니다. 사용자는 `main` 루틴을 삭제하지 않고, 각 변경 후에 [성공적으로 실행](runner.py)되는 한 소스 코드를 얼마든지 수정할 수 있습니다. -:trophy: core Python 개념을 다시 복습하고 싶은 사람들을 위한 **순수 가이드를 제공합니다.** +🏆 core Python 개념을 다시 복습하고 싶은 사람들을 위한 **순수 가이드를 제공합니다.** 여기서는 오직 [내장 라이브러리](https://docs.python.org/3/library/)만을 사용하여 이러한 개념을 도메인 특화된 개념의 오버헤드 없이 전달합니다. 따라서 유명한 오픈소스 라이브러리와 프레임워크(`sqlalchemy`, `requests`, `pandas` 등)는 설치되어 있지 않습니다. 그러나, 당신의 목표가 진정한 진정한 [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista)이 되는 것 이라면 이러한 프레임워크의 소스 코드를 읽는 것은 매우 고무적이고 권장이 됩니다. diff --git a/README.md b/README.md index 191a1115..4934389e 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,13 @@ large-scale companies and an open-source contributor of repositories like [Celery](https://github.com/celery/celery) and [Full Stack Python](https://github.com/mattmakai/fullstackpython.com). I look forward to seeing more people learn Python and pursue their passions -through it. :mortar_board: +through it. 🎓 ## Goals Here are the primary goals of creating this guide: -:trophy: **Serve as a resource** for Python newcomers who prefer to learn hands-on. +🏆 **Serve as a resource** for Python newcomers who prefer to learn hands-on. This repository has a collection of standalone modules which can be run in an IDE like [PyCharm](https://www.jetbrains.com/pycharm/) and in the browser like [Replit](https://replit.com/languages/python3). Even a plain old terminal will work @@ -42,7 +42,7 @@ through what the programs are doing step-by-step. Users are encouraged to modify source code anywhere as long as the `main` routines are not deleted and [run successfully](runner.py) after each change. -:trophy: **Serve as a pure guide** for those who want to revisit core Python concepts. +🏆 **Serve as a pure guide** for those who want to revisit core Python concepts. Only [builtin libraries](https://docs.python.org/3/library/) are leveraged so that these concepts can be conveyed without the overhead of domain-specific concepts. As such, popular open-source libraries and frameworks (i.e. `sqlalchemy`, `requests`, diff --git a/README.zh_tw.md b/README.zh_tw.md index b67916a9..38bc018b 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -22,17 +22,17 @@ print("Ultimate Python 學習大綱") ## 動力 我為了分享過去五年作為一個學生,大公司員工,以及開源(例如 Celery 和 Full Stack Python)貢獻者所習得的知識而創 -建了這個代碼倉庫。我期待更多人能抱持熱忱並開始一段與Python的美好旅程。:mortar_board: +建了這個代碼倉庫。我期待更多人能抱持熱忱並開始一段與Python的美好旅程。🎓 ## 目標 這是創建本指南的主要目標: -:trophy: **為喜歡動手學習的Python新手提供資源。** 本存儲庫集合了不同題目的獨立模組範例,而每個模組可以獨立在普通 +🏆 **為喜歡動手學習的Python新手提供資源。** 本存儲庫集合了不同題目的獨立模組範例,而每個模組可以獨立在普通 終端機(Terminal),IDE(如PyCharm)或者瀏覽器(如Repl.it)中運行。範例中的註解都經過精心編寫,引導讀者逐步了解程 式流程。在不刪除主例程(main)並在修改後成功運行大前題下,我鼓勵讀者修改源代碼作練習。 -:trophy: **為想重溫Python核心概念的程式員提供指南。** 本存儲庫主要借助內置庫(builtin libraries)作重溫工具, +🏆 **為想重溫Python核心概念的程式員提供指南。** 本存儲庫主要借助內置庫(builtin libraries)作重溫工具, 故不需額外安裝開源庫(如`sqlalchemy`,`requests`,`pandas`)。但是,如果您的目標是成為一個真正的Python 達人(Pythonista),那麼我會鼓勵您閱讀這些源代碼,而激發靈感。 From a1f248cef21ddb0f4c986e51b74140e664c4564f Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 5 Jan 2025 22:53:47 -0800 Subject: [PATCH 086/178] Fix unnecessary whitespace --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a9d5055..0e5b09ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -109,8 +109,6 @@ Ready to dive in? Here's how you can contribute: 2. **Clone Your Fork**: After forking, you'll have your copy of the repository. Clone it to your local machine. - - 3. **Make Your Contributions**: Create or update Python modules, documentation, or anything that adds value to the project. 4. **Push Your Changes**: Once your work is ready, push your changes to your forked repository. From 2b936a5167689ebed676c412c6ee15d149678e35 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Jan 2025 08:45:15 -0800 Subject: [PATCH 087/178] Update ruff to 0.9.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0684529d..8b5f969e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.8.6 +ruff==0.9.1 From f0515355c519b61e3463ea3c7090753fca570d2a Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 22 Jan 2025 22:42:04 -0800 Subject: [PATCH 088/178] Add branding to READMEs --- README.de.md | 2 ++ README.es.md | 2 ++ README.hi.md | 2 ++ README.ko.md | 2 ++ README.md | 2 ++ images/ultimatepython.webp | Bin 0 -> 224372 bytes 6 files changed, 10 insertions(+) create mode 100644 images/ultimatepython.webp diff --git a/README.de.md b/README.de.md index 3e91833b..359163bf 100644 --- a/README.de.md +++ b/README.de.md @@ -19,6 +19,8 @@ print("Ultimativer Python-Lernführer") [Deutsch](README.de.md) | [हिन्दी](README.hi.md) +Ultimate Python + ## Motivation Ich habe dieses GitHub-Repository erstellt, um meine Erkenntnisse über [core Python](https://www.python.org/) diff --git a/README.es.md b/README.es.md index 6fd60c9f..fed028e3 100644 --- a/README.es.md +++ b/README.es.md @@ -19,6 +19,8 @@ print("Guía de estudio 'Python Definitivo'") [Deutsch](README.de.md) | [हिन्दी](README.hi.md) +Ultimate Python + ## Motivación Creé este repositorio de GitHub para compartir lo que he aprendido sobre [Python](https://www.python.org/) diff --git a/README.hi.md b/README.hi.md index 030a4a50..e128dbed 100644 --- a/README.hi.md +++ b/README.hi.md @@ -19,6 +19,8 @@ print("Ultimate Python study guide") [Deutsch](README.de.md) | [हिन्दी](README.hi.md) +Ultimate Python + ## प्रेरणा मैंने यह गिटहब रिपोजिटरी [core Python](https://www.python.org/) के बारे में जो कुछ मैंने पिछले 5+ वर्षों में सीखा है, उसे साझा करने के लिए बनाई है। मैंने इसे एक कॉलेज ग्रेजुएट, बड़ी कंपनियों के कर्मचारी, और [Celery](https://github.com/celery/celery) और [Full Stack Python](https://github.com/mattmakai/fullstackpython.com) जैसी रिपोजिटरी के ओपन-सोर्स कंट्रीब्यूटर के रूप में उपयोग किया है। मैं यह देखने के लिए उत्सुक हूँ कि और लोग पायथन सीखें और इसके माध्यम से अपने जुनून को आगे बढ़ाएं। 🎓 diff --git a/README.ko.md b/README.ko.md index 928518ac..9c416281 100644 --- a/README.ko.md +++ b/README.ko.md @@ -19,6 +19,8 @@ print("Ultimate Python 학습 가이드") [Deutsch](README.de.md) | [हिन्दी](README.hi.md) +Ultimate Python + ## 동기 이 GitHub 저장소는 대학 졸업 후, 대규모 회사에서 근무하면서 diff --git a/README.md b/README.md index 4934389e..324d6d5b 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ print("Ultimate Python study guide") [Deutsch](README.de.md) | [हिन्दी](README.hi.md) +Ultimate Python + ## Motivation I created this GitHub repo to share what I've learned about [core Python](https://www.python.org/) diff --git a/images/ultimatepython.webp b/images/ultimatepython.webp new file mode 100644 index 0000000000000000000000000000000000000000..c055f065b2c51364c2dd302135239b70f850d0ad GIT binary patch literal 224372 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

o|W+-ytJRThySFW6g zgPpR?KF7Jm2%lUE-gQm3t@!%)*HkU3`yBj8l7blb+VXmT*6>px54D}oT%vtGch0aO zW^m0iN(c3wBG|5!IQ?68o1`B}pO&E~sk#hmKyD_7x_K((!9jyjGIPp+mV{ny%;^@-_zOG`fMS+q#5(9#2Mn2P-A%HzYUuMBN*5;F67%JPWcpMA@`$Xd)SVoUU>>V zjh>EdChsRtY1_vV1{lN;qATia5um=Z_-0GiLB`}$)_fMxV^DTl2*w`b0weHH)68ym zHKi4p@x22LYwd(Mw=8wY6Cf@YivtG&2~+Oy18-kP{gY~^P`m>UV+G26WM{tY90+g(&#lR)cWbJT@ zHwCB-8VR~_D;Xlko>Nnr)EM0v4ut;{iz50$ud3#Gh+(_WfH?Tj7VgQF=c%=z12cr= zBW=QOKf}@E(B%gl^`-os*m^9p6odrfb3RT1@NK`sI&Q!pmE$lB6*Mb8F3?2&_s*p_%!BdC!tlI@+QC8nMLp0l^yteGc(6lA z@N2k=VE14;Q?f&2#|Enh5%A)fd_A!vwaG+iiti@fH&H%Zy6zTt&3MOI#zr?!dR+Z& zgcF-6^MRGxX(_9#_(e628+(X%!!JtKZAE!@Y(m@ZUs^MoVRHrK>7n^D{RAbA00x?c zLWH^KR|C(`ZfFiIF@IYj`^(@bxt-tjF6>0)WSkWczG=H_-{jS9zTk!Hs;q9CJrC}Y zFe)F!{KS~z-m*1Yr)4ESfY~`o;+N>@ItqSS_BWa6G3L;rHpT}%5_VD3X{laBiH?;pohzL2Y(wfJ z{vR`J*&WThOI?=p7j0rp&R?{!5?}eCIAmZXfWR7sNzFicau|*z6%?vZDKoM5b1t>Y zZvBD4iDJ?CknfUh_2{8$T2NDF=mIS@DZcCr7?&?5(y6KCXGB+lR0Xgw^L4YJyT10H zOpvUwCT#K`dh%5aP=}H7a2L%AzN`duzHr5uhv~W`$U>O6kk6a(tma(_F#I7!Xu>|c z$t#QLrqaN*{9w+u?p)%G5-*+#?iW1MhL=yMiFL9SRHzE5TohElu6N00E-O`0T=R@u)LwcDGSi<@8De~?e50~;e9CTE4m5xS zV0}pLGZ#D$>&(j4`2Hsu3UX8iw&UrF_dK|vJFz$+Se&q@sjkqI_Y};*H+|r5krp zK~=(N9hQ5jabYsqU$YnHAXvrf3o1C4T*tBtcB=~yO{i=koCUOq9E+z0w_42CbmQz1 zBu6CQ;FjmziRuQ4Og<#K3l|+Z6+O`m#q+Oez`YU9w~4jn4?RVKXWm}46Zy$cqE*Cv zhUzKvGgwy*uP6n!&RK(VoKkt0`0`sz#nb(~>Va19J0=%ckOQ}g=-bBQj~MU9rvvY* z@1qM>cr%#lD3Ggxvii|VXMq2BpN%NVO~6p@VPD}5Gy+Rb0(#(ps$!azX0bWKY(q&- zhJPX7*E!~FR_=3IUG%aMK{6xkC;`TGWl#zzwhO944WvtQ-Lplrq2^v;bzMKjRZKhA zBcNc06-?(;)M~$tQ1o3PeOioGQD@s*;Hw0I7nmX$KKzEH@IUr)e8)RM=8AGwMtJZz zh|V^J0>o4GG3Q~KPN%Vprr9WvtHcAff~+;RnVBUsencrnjf*1E=n^j1n^7UQO;X$#HVx|5 z(Za-(^~7LYWBaLJBB9XeYD$2x6w#?lfUlF{lbbtdWRA3*Wv)kI^r=_|M#MnnxCIJM z+%L9xbmw2gcv{;Wv>VS&*(k_fdMy%~`7`X?;}JgP=WD3ch}11}(eZy>uWML~3XPno z=7Bwe1Dq;Ojb)BY2Zc&2zX44papdDw8e7?jHb zvqV;d6QI|H8H6aH6~uP<_=q8Nps5`eqoBK`1mBdM$K-@jN6H47X+zXeKm+d;{6*7u-k<#5-niEYY32<- zX@y~t`>?wPQS&dY2Ynac-`FbO1#_ zy1ycV3qwUp8U))^XjBHv>i_JVYN|+!9xZuG06LG3D$&L6QY-IC+D|UF%-LgVU{h@H zw`Bj<#nwG;u5FNjG(QCq+X?)Ycs7TiPk{lhtt)@f3ejc1RpF@^IpReby;lujv0>fm zg<&o>0|X;wc9gl7dv;YRtW{6=GV%*5FQQgtw4u)5RrvF7hB0QY27oaifXwx|0<4>h zDLJk`S-;$nz~E3jh?R0`56Du8?%G-9@BriW4pJ2uJ`WnE>txEV+h zpG3$UFIZq}%W32q_t^s-tiFVKZO1k!bm8eJO%c^)2BQ7iHoe{obz@)YAb`gRL#2c2wJR*a!s8+B)VrW~=(7kc;2PnCf*>GgGgqMYgouqh^!Y>EA z!Fk(PNTKH!>ZqhX)awGHSn>YfY_3`UDm7CURO2-UjooA0NoHkBf2@K&WabtRwTK84 z7N$6z=*@K?AAUGeIJ(2S4LQ)A$zk;0F6Km3XMH{BW<@6%kYN;URD>QqVuk+N1P#Hq zw`*6B;6ac{jIA{Pd*X^@rRjQ2J7k?0Tc`U)mE-445*~OzdBei;yOd6Klz>FkdA}G5 zTP8O%m=&HwiIEd2u~JPF4r_RWRB(H5D&_^+!>mDxF zc&bpkfS(lGP)FjGH#AT_A*T*ORVYaJr0q~qw~#@$dLR3#mvL&gCF4%u`DR6*!%;Pu zo9&o_&r4Ke<)mIi2=R|o%3^6{%}VbY0e7Y@V2i?D$rM&AO~oUQt^8>wIXwd5&%4;K z!e!pmkNaEBl7cP>)fFqjocC-u~j^NS-pk&&4fhV^Ulv( zN=<15tB7KuP90Tk56y;@|BXO;3!L^Q`_exQ%1^N1t6}1|b+fT_x7aR|OAolLbUzHn zCqSP4VjF;3L_fQyBiS(-#`-azE_rRhr{UaoVOTC2B>Pz8VZzj#wa>zqTz%rA^&f*n zOsUTAWW=l3E=~O_!b~{@5?4FD6RUP zfhz-61S`Pdht?VR)Z3J2U8v_9GwT&t3Rk%qKwx(S)fp~lFaB-xd3LN|jN!mXQKi1t zLQm})gm}S3b4j5s=C+~A6o^rz-zzp-rUbAr*k*;>!n%1@F$sFKzE2X<0?CIV#&J+_ zD*3$MN#bOa2pXKBAV3xPjL&A~N3A3v=%iEKS&_ksfowi&!2pNv_oRChjOpn%@-5A; zlDO-Cz0PDdajPCT=PlbR-RI3PE_0W79$EK^NilNKpYxa%PC#=m)!=e-OvCI~fJU}s z&+dq51afgk!cGJWhEFGrO8pD)>aP1;Iy^|d4ok6vug-+I$If8Kxj{?-P9aeW914g1KM`T4hp5m?PyAH)ZlIIDDqc6wb$xJ zf@oMM)WuiZaa_yq6j^+#G1ccX&iw^qL;GfqebE!eLAVQ&htM&?X`x=7t&%rV&(dK8 zh+-&O4E#^cfY>~hiON7TTOg8_i|1oe?Itv+0RY2npv-KgUfU>8nMOf^Lxe(F~c zFjBU6{5Nm=A%$Q7+dgYr9^xFP&kOA00=$(zcm_tvIiog_c}COq3V?L=^IY#M))$~R zBfKf+T^#Dy1JrjmT&+1k!vCb-wvvJ7kOE*;|1tP;HJ8h)@`;Cu#k%@$3E;q1?Q`Kr zFTc^6pVGc`L*o^crAQ-$SFw5Dc~p6P|L;uqE}}5=B*&ZNsv;$>HG{`xC?UvKW`{dA z?C9}RNiJ3fNww3w+IpcM(Ryx^7YF7Ox$J2aT=LSyA;ksaO|O~IFHg(@`;|Glc0=b_ST@$l;yR8aaCSbR_;%SkSS zFINRdtfiU7=Sbk!3okT_IK73-T5B-z&&feuPet(vURh5L791aD)n)Q}x+~@{@RM8P zvgS8%xsksxBGkgmnmOX^hKBOolDzhP@3BX4cae3b^wpove1Sj;cO&kE$N#TYA|_pB(FQ8xSFy`Mu^Q3M7gyF~G5WsK=zekw)uK-|!;*FDuqg_OK=qOxk!`?MRtxdG# zs9?J;4L|BKCTSJIORKx9ZPPbvje#6oKtP6(Y8w6OcV>%~#+0Nyj{$Z*B|y;fV#h;d zg&nSn)@$Q=bZT|&TaV{k_A@z-`6QlGYmF(%dK{8#cwRM4Z2*Vo!fXBpm6;D|OkBv< z%rszd+1W&+yLr*C1@OuJC!b){>8~uuG-+ZHL21v`7}QvyO(>!AbuDmjw`d`oq{`C8 zW1v3%-#xskATHnUWtY4F%}gAzqWmX^n1@?fGpRjggge%?&q`kI3XT~;zZ5RT^9L13 z49az1TyqDk;Y-67ZSl{|h~TQ(taa*`rke~YFftg#p}oJvsj7U7lc|WFMr)X@(c6S& z7`lqNtPEE|C{1RI*R?RXZx|^UL~tI>yJV9~!GV2PGY0l`8_yWW1DdJBElAU-5k%t2 zqBv{Vqx_)OB`9dTf2B93`k=8uP+rQwMUDEiAVn!+7N;k&mg4Pv{|i}Z-Pt?fZw=xR zxOh4kR*q}Cu0*lHjk`>>?^8kXpvK}G%Mf$^p;xD=Svsv8?p|NkJ-uHo`}{|-wn|Ib zho-w=q*2jN%#csaQ0TphR3~T?DhPjr!QbUMOz+Jx5ays{I?N3B30VS;2VMp=cM1!WV(-5L6%xgNZnq34(u(Y--ckw<2kBuS+`D%$2-kfSM$-wvy(rD2pYO2# zy~QjFYTA26CTRUo&8%ak4z}(%r%O?Av@DRa8~yRA!p{rBK~I87%|2YGZF*CWoMb4` zq4t=sTI|?SFqTR|Jk9P;`_wFo|(C}IQZW5ef`*=qAn1R*Y>$B3_i z9=HOKU=5Jzp<$bMaduO{!PeNTA@6oc{hjIV=`_$L?6A3*qw>$MJG+y+B zkw7kc8d;<@ds~cD3z7F}R#ka%U#TaMEa2efK57(=WoN@xsdW<=Ll zEVpu8&8@NL&DeOaQd;gZH6#hg?i4zDFAZ7lBTF~*V5yc__WvwDFsGkMWx`#~BwozU zkdVMO%=bl`wm40xDdK9q&)(D!9`wNwgw?@>O2$hc2DNf&STh?PsL{xGKG3PqyyHhP zqqcN!&68V5$RW`e>h!3-^l~%ZET?)% zPNmwhQ-fr+x%rz14rtb6wx`oXL@vmqNi&^YmpB7`%aJFcC5ZWLXx!t7QIN3>r;I_k z9D85$HyO^3MS-_EcY6NKF9HJ)x~}xilW+(YZ9Eb8v=y-Zaz)C%uA5$ce19JgxCI*x z62#50wF|AAw+DCu31LZvFd2cFl)`-uAQS zRTowTN^=~z!D4N`r!y3*B(BsV@MKi3l8r)*2j!Lyz;OP9-~PYfPX6q;f5E^fiwu%{ zuXdg_;JO21j_f@1hu{AxufS*&bG;!sK24)u)bcY!mYS?X z+5hr~3f~2%Fdf41VlYg0)hAO9*lkgxx~$ZN;~m6-Eu_Yd)b3~>|0HTB#pkoxk>g7 z?DV?Q=ORu0C8F+cl?@}or~<5DD!sfg4RGr+y<2(532#hT-qHPN>L~Zgs(N^@HsM%O zNQdkB3-Wu`Z?pJJcjzzG2;t%xS!G18%4scYc5R_JLm#kH=lHPSo zFUXh1#I!;2HNEWdMo?g#{(i(O8+EfEFsFoh*)Ghw$F%vpAJOJpf2&>ZZPoYa>y&JB5P9GIQMNl9+$J%*l$7`QDqYbjaVvQgAM-Qx$b z-L>%o{UJ@)%x#~EyR29}y_^B)cV_7W=$TFcKk2+)bGrND@qLOla@wlEk2Q~!V_#ft z<|!=*v(vrRz%hdu4hU@_O%aBXceF1#ywtC#xAq*Xuu!U)kJKjY(i zVJ~>R<;DgtuO+SHKIp{K5gDQ)ury9RW$7wj0vCUx5ryJTfUZu!)0r%8D07V=LL|bH zfpcNNo0Pl~rmJf%@wRoz+qf~-Okq=C1N8!V7;eez>+Z+zwCnyoFpxzEX(zc$I{=MG zU&BB_aBjxlNm2f1JYY=Hp96O=>BZQH+TB*vw!E*MukFgtwUW3}o1U|x{knr4Ce%E> zdF9;Je_IW_b%rZ^taG2IwzSKg>kq&;R^K(Gvf}(0`rL2gEW(}%|IiSx9Ey1xi+Y?F z8n%FhIk1=TFOQ)BoVth zKsW%IL7Fk!MZgTc@(Vg7{fWnSNs66fD7J8y!;N`eDDs^%YL|P=nc;q57N0_dO(j-% z;()-$?)BOCHxelFj0mCmgC)PmH{g)OpEXH3Risu!(Rd>1UVR~A`L8F&_33A4NkSB1s*AgdyzvYp10vZL zju3gR&f?jC0`#NVN-9wh1HKf$t4Ow5Q>sO1qhBVu4RdAo$r3UkL+yuUPA$M|dDeS1 zUBva)QCk#QZOR1wP0E_5fD)>eTi^C@oeFNdV`vLrj#~vP+|>i$h?jm_8vviqto{$8 zr$Dxa)byi-z`k=8zUEJ?nU&R`G)JqgdW|~zwsq+k&61V_Q^Q%ZsE&=!o9A~WLqWGZ z??9=@_LU$OL?oQK4~e#IXPJO5Ji+?4rskWCni9@J(0o3S9Y6~YGtzUp1Xv}5yt;56 z6gsX-C7d_S8u{vCFsg4LXJ#S6){bKoi(fj-|d zY*!X!LAyliH)Nj&4T!PuVqK7(x!~C9h*0-SjPF_4+Yge`a0u zr)wJ4TN&1G$np~=L@%UfunKU$wS|T|E9KBG71k10Sp26L>wp5T^DT(fe%Z-R*gs0o zs77$p7<)YSfYMytTN@-952tiqNTF>-hg30|*uZ~1;xtVZm?vEJ*SP2muL(((7p7Id zOO-hpYK9wKcCYc;%bpT~T~N3sBM3+X)!808m|7?HWwPx~fqtj#*T6mBlmF5u5E(j7 z-S*|F?1R30E>SGl6FuDULk8Yd=Gm-1?Sz#yeED(L;M~!0+^5!aC-^9bt}2>7Fz|Qq_GD7d;?TI`H;4K@6y(qt!j)@FA3mK@5S}s|P+VGXPM+ zFBJ388^x)u-u4(P8@K|XT8ld^#>;<2Q?a}8?T%xiaS<*CF{LA_w@3$vc=EyQXpK*J z(K8$6;Xz>(o`}xr_Woq?Kz#*{!U=kB1i*yblfB4j+lZo{Vy*IgL*z&LoG|Kf7l3lI zPF2{9f}D_-n^$pSR7@Z)<%^jq_LV7OXNCZ+vfmRYMci7#IJnpc_kcN==ohU?DfZ99HE0n6z z@Nc**hZpb90!qUc3{SUYShUGAb}J34WwTZErT+VxDEQHyQq}Vc{)gudqyCJ;20R{A z@f_|^od0PK^DCh7l|0W~JRev&N=}b1GpC%7sc=H7t40MB7euMa*)pt+vDi#$yQ_z6 zAG+rytEM0)&#;J7#ZVBse;U5v(TdY(2}JWgq=+f1R-XqfSt|URrqr)V1LdQm1TGC1K_92EW>Ii0T?~x6Ww%j?s$7t zT-KN+Q!33_umWU@b3H2>D+uzqphE1L&R%0BK%>b?Wj6BidaQtB{d`3TCG4D>6uI&6 zRaZs;2h15imr%A)In_zVjB7rk-YGhR~uUH&okFZ96DG5PxsV3O0mc&Di7?xA4; z8QBTYd>e8IX#@r5UuE3QBqNl61Hvo>NL2GpkAdagYZ~!l*uu(s`g)j3PCe%Hwn6OK zL7=#Fu9K}N&pBla#dg3@YUDOeg zS9%?Kg$twnob}?JAN)zN)u{l1B}EXg`h(e1i2c=4)28+-KSW-H)eX%V7hlT%Dbqp7 z=;nip$4-N%)JdH^p3*4`4kSjk!Bf6!PHX`lh#(T+)$W`-!CR#!&iStFbhfJP!4@PT z%rwl%vg7zCjk+86?dPVb>L{u+J4BAsdK})Z$ApB|E8|Qt*1~IT(a|bheeY ziLlc%ieYt15>Ynp>D0y|m+{|&>ZXa?vHN`4%S91|u@LzmE2>}?df=Q!7c^>fbXuDZ zn3Q@FpGR_kUwPJ`vIm)kQo5n7iv-sP9A27JALg*UpxGGg+4_+|pEM_1N55{<(?Aay}d3QiK6p*WF2C&iXb1 zw;;k818(g#MCwy9^*si6UDU|G2D$-kNUO0@?7R#D&8FfS`8c+D%teLTXS+oxT7(O( zcFfu1rfSG04VP5CjjV=f9D$5p!k8i|3hCyzuylre(b-T8h`~BL8}NIWm7eOz+pdEn zvpHsCaGye9#%RYZ)*?DRV$D)k0^7aNmd#-hYPJTaleq&@V{oH`o9zjIYEDjp5rP#C zv%1#N>?p?beVDE%zws}8CNE1l%y)W3gy-3XJ5u!i`R*9{*L>!*pA+2a&hH*fw z&r`Vu&kjDDUEtUBvj|>|h8Sd?12kC7ixZiu->hfhj*)gdcjUX|qx^V!lA43}egbU} zaP8EAncsg_V~&~gaI2_L_kE{DTFeP^L+}L&p?ZhpA585G_EX?*20R(lV?S(_ACkJ~ zIFjHJ!sq$w6Gw$xXl|47dd@2E^%~Kw!rf(-X~P0tO)OUFLc^sfhWzqFHon<+=!OR^ zJ{|;m@aLAM-0?w$|nnxNe3I954I;w)D6=0>~t#rh7TF*m3t-)-* z!-3DCYb{ezA;QS{F56c>&c@HUsOd2A|4xK3^yqXqw>K})8v7^rJp!D)i#}{i4iSVh zyx!T~_wlj422uz#3ZiC(cjxlp?f#^uxi$Pj4urSR<%4mY4>#}}&b{z7k-K4=cpmy4 z5*oV9#h7q^Y1@a>0YGI~JQ3nv_CJ1Cz6M4-Q^cy6yGdN1N~Z{B89!@8^8#h4N5f|= zwWa?n+nUyjHdtAc$gi)Bgz3rJ`%4KUCuju1f6^TrQ(G?~Zzc~RZV6rKef7DF=^SJq zb)1XqwV`v1{WW=WxX;Bvg??v0HtnIfP8e@kG{Wxsd4$^aKZKbtno;9#E1JIh#?kt0 zp6?FF-kJi;2X}$ZftW>&PDn_W@jvexhqx%=l2@jD^hY|OBOj!hX!(h?-hw4}TYpxZd|o>F^qbfMC5X$m9!KmYsAvspy`6CAYFrp^Yij z9P*qQ)n6(m`Rn^56yirb=lX)mkT~{*pyqA~)QObIqgvW!ayi_IFeex3reKs@hoT-A zL&A%Ky2GFd2#r74NNCcedT7*#u4C9vd)CXJNa}Jt*2-6SIZ7oN1!e=59&uH}SkQ36)t`>D#VdMshOKe+;C#5_0+oWOcpPZ@k5z7$0^lIWI|n zcPYU8V>;^DLI9YgLYOw#M6!Wt=h9Y$&r4`JRGA1p2J9O3`kMA_LL$tn?sVZ(Yo+EU zeK$L6bfnbuxSelEu%>J|h@VFQ9~J)Qi2V(DG4;;*@7gLN#PDw50q>5JX;8IHK`4I1Ik^2?oBieT+ef@p@n)F8?uH_x^tX z@w4(wCg6e6hA(MY-ImuKiL3Rjk{a>1rI^SgLckw+D)nl6C0`~d1FA#GXSY;?`M>}G z_GE>1&`5+*s+4o!W&>%id)vh_&vr}L`=xdQyEjEbefomI)eY z{-dC&*XlrF)$g*o{1UOz1X_-yB%W}Za>ExaV*xga|2Mcfe9%cRdy?_!Iyl*m(jkld z95MO)N9$XnQ8RkT^YI;g;d#s7n`)6ANIE8PLV~`G{ACpSHda2Bfs(TwzBES5-jZw` zpX-KehJh$V`dV2wz9k?F70jtsCq8QOJ%4FQU`TTP&e{{o@5o|OiNvhFP7D+f8AX?S-;deQ<;bfN z1!YiEF;)wxT>ikq?@;FdtVaQ-x5!rg=T!O$WKtgSoH^x#>=meIOCGUn9b56)h$c_Q zI-R-Bu;+kdC=dtpUVH`Gtwu~Zkn@LefJ78)t;?CZ;+|IO-5}St^ z*2JN33D?!8p`}Jo=X^zO1~sb5iNB5dP`8-Yl(V8=uFw zO;ae;ufXOqILkH<^5yW{k1q#xc;VP*wNU3HKM9dnhpFSrsX32QeK#L?T_fZhlD;;S zPDe@qIx8s@)DUGDU3G`fJFg8~SNcT@Sgq>Cm~9Nq3KT6!j4?6Y+>W|JXVM>k)!ta$ zto#}GJN;f;Yj4Y6Kv3o`;=YCjkD?*5AsKRQuO9u#X4%{yDiPQMf4IvA0t(Nf~Je1h){I|wtqJm^7S(J^4MI{mP+DS*U&QU z;kX_*Ik)wV1dzlqG4R>=NVBklILY7tNZYHb*EcsO?_h(+*;U)(D#7@uxg`eH)YHJ) z<*LF()v`o&3qbZoRqq%XO+42PU^}6zte`+@Hg@cLjb#C5bw{YKnJhG!6xR=(4Llkw zP1fxNG`0uMi6#95^$p#;k@RCGkHo7&lW1+dl!vyPn*Zt60for9u-b7LSk(jR=3S#? zn&8%Ut>;MK>(k<#A2A!C*dq{ckMO>93zFSMq^IKbah(9t|Ix~-bf#aVfKi)AIF)cwrp8(-XLmWn-1|fq~rG{2&0Mhvphbz32P=@lJH4uE9*~M-sUagc&eC zmPIp3OdUa%tr)wmq=VKvZtW6dNDq>uC_t#IgSFyTgC7Gqlc0cT&n#az*U7IxS7FyG z(0Q+{U+Qx|1#G&^L*9{-4a77Fz(N}+Vrc*XKJMYsU#@LMHkrtgM)N`mLrj?v`0ve1 z6cq;+PTHl4kUID-uawl_r4Zej2!vB&{=R;;Am{(;Y!l4YUI=i2tusdT-IW0wjCzG$ ziUlatN0ckku%YE5dLKmVl03t$J~K8o{Fw0AjZod+Nn*DhPbiem^UV&LW+TdTaXa~o zsA(zltvVbdN6~o90r=)u`1puTu!U+5?fYT35V`zu1(VGYW|S#_fT1WMP?}=)iriAYEHx&png; zb@*j`GPdQ>ilGZKKoLwx>ft79un)nUoTEALUEpyZT<+a!ZzgzvkdX|aPs#`Ut>!^5 z3;;$}k5|?Hp*e?jg=rhj5T=P@te}cRKN;Ct3PqEg`I?VKbNbLjR$3VlguP-yj@{+; zqL;){`|mAf2kHO91m!yJuZbv$nz-5?^*!(4%m5p-OdW2-o=%OtAh5Hvo@0j`q;CW< z7q~k}n=Mg$tC!1|BjhybI*K_DD4x&&P8F*1?Mo!|M_MYDB~iD%#D1i>VkC@B*+f~0Du+(q{G@S}6SQBKZkO$QO&KEr>IG+rD6g~Io zhGSM^KW|sMRSNg0vQ#77{ScqK-yzHXupO*lH;$2*=j$X0XC0)t_35hO{UL1NHFvhW z{x5lu9zyV|fzrS4cL@)!*0HY8dFX=aDL({ZkDq#@M>m?pB{eT*ZbkXmBbGo#ss0*! zJE$S+^NY}D2=1cpsFA_c%$x`4K3pT%X6}t;B1VWY0v6ns3vz~|`bY9B7{X+UiT6QS zbE&=K#4EbBen{{QK ziL@q{4N*k5F?E-4A)(NBWoyf=$B)NC83iBV?{l+QIOd1 z&jXj9OtV6-ijPp+Gw6im?mcr;`~nVF#t{{)lp6R0VL=db1z3F+WDLy| zO%cZZ=%<~40C{$Q-%H)3HO|OJdICva3f_5{L+;P=!lxi*65BcMhrVRjr$s@$79Esj zvqbeEdc@?Jo&hKkK~hxVln`1uXH=t~{XghJM9_>GPC`rXAYN$W!(bsy zdPxQ=aD21x|LE~r$JFwpGzCRtDg~em#nh1cZtsJ8_Wp$42%2Vpin~{_+i05VO zWo)EoXxFe$CzOCA?VU$z4?Gy9I_l1j72YgZcJ!ht*A= z8U&dPda4Q-DDf)4kW|oJF4!A$nu(%L711)s2w<<6!yBh>TT5h=qp?Y{y+froQkzgX zXN${`Z+#+NdK}MIr{~H50kB=+M&<9zp&23S2{g(i^qU-t#<%Gm8Y?b;KsBl8bFZ3E z8MLL1!}_o@=5DDcDey^TQva@Aa`gpJ_yF@UnkWe2g%H!%o6R!%S3F0=e!|27EkWmGB8$xH4j~ z?V~i+5#5sUh{XWxU)7r)M*y-XPySM|*RSr^i!TE{=8!kcB&zytRxME3xEbIY325sH zxZ&vB_CNB5vI8WW?jU25?!F7T0x#OfXMu=9!GP{0`Hj8P8XT1MLc2~E`cQwV%!qPH z)io!*Km^pIe)|DC(p(Qf6G*}~m*XygMNM^cz5_5`4{Ul|2oRlrXIf=aBbSu;KhQf; zJC^3F5IMWY8W#521|&!wcI40$6W(aCx_>Q&Radiq&h)lV;Fh*+db-8HTqVeV1_{H`qhEdlRX&5qvi*J6!$avAQ3ElS%7j%SCe zxgCt?v`K%nYgWw-Ko}FZkz3kmATZog?V2gufvyf!zwZg4{SXO-Ij18up|OdQDbtkT zVRND?wr&*v!iQ<6=@p$nC-EjT@21iKOksx5{sWQ;l=t**%Mx}dhJaUc7ihSGZpq%o zzX_~Qp;UzHezj<)l<6$f{kx69D+L2yv8?f(8Qf)@?f^fOwS%EG<3smvnAurfoO`gZ zJB6hL`Ewz$0K&9IDGvqPsptrSF2iH)lh7X|QyduiIyNL7b0diJBR|3mFu#Z%rKr0x zF$xT}C3F?HjBMvuTLl0!y+TjkutZr)h+)PCvbENcJ^JeY;3~%jXyCw9XM_x*Abant zM8|y?Fq(~J=`o6w11|W*j78;pn(-1Q=ib6w@R1wCZhf`^6dkzU)i)@d&gns6Z_sc2 zhFFC;WRq&IzF#E1F}XAvVjr_bnkE!d+JorsVwA(+jjdP320paJCEI@BCqlL!fZ{y= z0@G;%l&_}L#aOYIX{@5mO%COug4yimZO|$tS2iQaw;#CQ9wQTbA*sXZAzd4t+55|& z#(7w2LXQSUGbv)DHbTr|w{dldcJR-sNnJ z2El8UG!^#y6TEBIHdu(}?)fPa&H~~^&nL}VkssXP#a8IJ#$VrIGxwvNP%ic6CV@w$ z`lp#Gf4k`X7GB9`uC5b;07Ej+-Rqxu(fAG^11HS5od`*cR$c#u-FkLl9CDB z-jtNHi>d){CY$f?aHO>`11^#6uNsdiJ1#O;ApH!Ek8Y3`LpX<8!fkH`GKG&5ZI>Rw zRcKppAIhV~R&CJ>kHVybI51QcMe|Zn{ziT?;CnG01HOL60*!-qpeY8#*@78;un5?Y zFN{W3R|BynL+N~8+ivZxJQ-gkzLk*uJ05CX3ONvVhnc?w#wK&ADjq1%$VaiNkGqix zi>HcZRfOaqi;d?aT*~GJ(%u#IWiTA#(n1f`1B^v z_llD^QtbO)%%2g_G{nQmhPc2AYF;v9XGp`heY@MQi zAq)G2+MqbwAgLKF{OgF8(I5UkM>)MAr7Q=5O*7c`yIwwaXmqeNO=oc*ioY=1i1a$g z_A&&oJKOzsPK0sbz9#VMpu`y4Tc*5fj#0+G+Uq6Z75F1)KV8;L=~lw{6`<)sOpiIk zWZt}rA^7w?;EH(wHN>-!wKpPu%Ln$3H%Ncb2_OEbiOTe#;LvsLZnLpWSTGH$7i55i zYiO)oV~>Ak$+`R15LznfN41i6PJJzNV`Zhi9@& zD3j>p(2G|^kqzJJ=ezfTS1AsQ)BULb`&h6mN!h|i)2;^*K27{^v6%z!-Obi47lG7# z^KQFzatW34<~>EpK8(9PdB4I-A%bfMe9?q$WO&&Cslrnq7??zqndA*r9lryB0L#f0 zMIa*Lk{a>K-M}C|*Mg!bZ}kDM6@@J;XCG3)6z1u;)mGyd(4HbxBEz7?>GBqNj6Y5F z<2dk4awpP3LG$&bRX3|R!7nE8NK-1{Uv{Y>pr|D?%`Gnq$Wdgkg%&OBX|n;Fs$x_M zPo(j$Xr0t$9&nxK+JVbQZ}Yi)gmS46NBV_h|CNASRBq0{e39k!+s|W#wU)_${%z^^ z;d_$x7x|x~kmynGjx!!Ea7|R%5*DrKU$Hozl)f6s!jMaDWPl5H&~jN@xjaIh&-kg0 z@EJmN#Rk7R?c{yW?V9PANg%P%nq+sDjztZnL4DuiU?5I=37M_WQz=+lTq%}Mf1J`@ z+#TzQ{|f#Em^+!lT_$U3cHrhdCYm(r*(v5;eKQ$K08Gut@U*H*$_HW8_GQQ~lDhV$ z5dGSYQST!X8bLYD)b@MB8Kst2_TCZO*rY>?MXUtIhL9$3F*N^NT>f4g?PtO%=v?*c z`cJ(}J?0T#;iS5ul!Z}W>Q9o!$QcZQIl;`4aw zT?Aon=qEPA6iH#jbp8HLlUeeX7_Ol3lO?6k_ui-J5 zaKkF(5eDHLHjKmj4(z$#LB|a3Ma#i$6fg`Yei)~z#@qw9ZxfY9R6C!U%y{kS;~o6V zz}OtftesWCptA{jP!i!>I{UT|r_~p$6<|#}2!iVCv@_JFhmcC)q5{!`Cu2EAS zr$8M#|Mk83Lsl{Zj81e)MSRV5L>f3#&xeU+FSt~ONwkeNlao<&(Rd-$=OrGA_fz-8 z$^KoP?x$v)1A7VeQaA1L8j6@1gF%HZkr)Aj=MlDP?#Keh_#}rhM5_gg3nx>C>1ADd zlmYQ5cD6LGUb^AqE|{+D*>%v4Oe%iLFI!ThMzpokHjr#iXUah13na%gTB7kxVuw`w ztjq509I-kvhOvAy?;D(GCQji7O?L-3W^-byLuS#D+u-;vOpo_o%D1OXDB3c4$wk)L zuzdsyuw}yer2mg-B*cywI?7P4arYQvIqhmlnZkKTvT9_JrNJl>qR!33n~?9f6NcMR zi)lh?%j=XwZs}kd6Zwq9cm)m`Ez+eZC7$WY)S?|C(+4t#!#&28fIap-!H9RjIG?5! zfTzNk8#&U{Kf!~{%k_!t6l@AG5v{cQDiM>Nm*u)5x|_x;fC*NX{GBV`^R#LyJIm}y zEUcH$)EFhfFKVi7@_1QbpN6-Fsijw?4@0SuO5hpuGkujW7eR|Qk*NV(rj9{@NxtZw z;25pK=5kbR|Be!`m8Bhr(!N|G6O|2#4xMc_>n4z7;DGC=<8Zw`%su?L=u7|0Olnfvy7g$?bd zJV9-sIUnexuPJPq4d{qD}RVQdADeq!&J4LYrR@|wzqhPZrwxJuW(DCL){xb%7-vnC#z85;w(Xyif^P`;nAIB#N5lGH z;>!xKtWDFFg0_ zgsdcvC)QyLGWdkaLSwB5)K+3;3(OKYfi{Z#EjuiX213tJ-6dp1Z_n`?<~3||4JNdL z^`bocg}r=oPI~S(+%(wQ_lvdTdwfC|Y_ndfgfsDwI(fFd9f@mukt;j7)f^MkXfo=T zt^>Tg&T<%IUGMywC{Z`Izh%u(s`)fptg3}_&rGrqygT|{_?S6)+YlCF4w0+_UHOMO zsMZ?^7;(MHnOSB!2;jZvw}1 z4|Z+Q%?y1~X~gNF1&a~ie_dvShl$W%c1{9bUUA*qgUrVFvv@dH`H~nJQZVx#P{_3( zlBfAegbn>fu}G&~zB>d+_IZ?ca%W1+AK@h%)L)---MPj|gdjiD!S!71PmOTNxHU$% z>HAUSg9Wgq2m2yaoqh0cqBBDc}S3mflLc-iv<%f@Ib0c=UsA zRZAiujCjfQb?6=*Qu0n~G#5lI$pPJQLUSxJGr}u4?n5)pSH&_7lWfmPvO8B}`s#-` zB3pad(*M6Knm0yM~iZiX@ojb3%UYzHv1fPc$4|%(U(32+{f9X9o3XL0nx!KXHz9g zZ&E)dJ$-g?QrF^D+|-1BQNo7Wgod0L$V4zGg*1X+uSu{LhWim_VRJ*;Lcv|h*x(-d zaI%auMICAN)_~E=tmS+*9%>EZ(t2YoCO7|52O#FbU{z^#j;_6&C&XD}icvLeE<=WX z%0y2GNkEDDYuPi`Ygnbv@f``Vw~*r+@v3LpWy6s%6Bs&p^~90I5R6v5h~X!nZ*DEPV+zi@ox{M#fezg%VM&FX)k-ADvz}V%AYxJ z5Wnsox*?ai6eX3SB>L; zf9BW|MOejQ&XSD5Iv_E74y%E@8EB|*ZZa#9B^|lQ89Y(q;b3MxcMbBg#slXb3=Y2k zhsSe>VKEDnKfg_)Y&es8`TwE|%^)YOY09HeUS@!>x_Tuh*w39%Nh4wT)wcoyCFc!@ z52aIWlYR+uv6NbiZW(9WPf|r_jSYt37^kXJkXaZU3Hmk?3@^crJNaXev*kVTp`2tRPRK8sAuPaCoV6=J zGsr|xM~=OB9kzr4J%&O?O^CAe7F;hRgJRM(KOS zWRnx_ONX{6B{xv8D$Y4mbI2*T^VKu7RG`9J$p*6p=F{QMVZU#I6j%NCM?=Od42(ht zYQrN{VF-r9^Ivi{YbPhY3{YEaUkd-Bvg8UH2blwU3cn7hIj%{plJs(qm|G`G;4oh0 zi(GlvFd6INnc;pg-*R=w)d>>YnL;2^Wd*ns9KlD;bu5KnFp;kEZkNXp^lz99x7DJr zVF#N#T{RhR7EbrfgpYc`VrG>O8iHDVjERLwg2LP>cM9u-i@k?pS_6u%ijssCbc@09 zjXxeL%&YQFwS|ke;sg2RnkzypReC0_`?9wBqOsBlx`7bcr~*FELt`x4P2pk&uvcyA zy%i7SRv7L~gQ_|ux)qmkh6Dj{TuRrVAu;=w!34V2+9A#4X=(XC@VS|Ci5;X}hXZ?= z_ipVuIn@(V$6^daPTqLa+9D2R!i@w1Pe}qNB(G1wNx=U2#FcAjL=x*t#Xjz7Fj!}& zux5#m6mnP(^QeT**b59g0}5KTRLle|Cyg9z%sq(YBjm4x)ZU9e4t+P7`q$ zMY*=RK(z*KNx7&{!4VT8Fp-+%mND%Zjp;TYUcB8#833Bys+@_}{Fm?d*lGDpc;l54 z4RfKm1lm`gOcu{NC2HJau=ZaIU_^+1T!$NA&w5acZIAsStXfDvA;QL+W;9`A2Y5V) zgvczvcgk6?&$J|nP4VA=>(UFY?4EHD4WU9ADA2)VK5BM4)II0|BoO<3%}kxIEsq(R z>eN~(osTRANfpvdY(c+pL-4UH+S6*faB{((>JvkR$pMUB(S1DT;C?dZ{!qp|^Y7=h zQ|7DwEBB0e!-&lWU8uszEE9!&RziFn>PP~4lADEzS~yhb!#geIXfVdLO>#(Vn7qb0 zN+tZ`mr#O#^79BT7ZPV3*TW!LR^WM}P(1`dA*4T^BHtVM4K-xN4?em{qsF0db96>I zQ*#(yZgj?EJQXkU&Kp4KRwy5Aqv(4P#cQKk0_J#zqe(Ap)~TmNByvmhVYe#K-hSF%RF@8D>v!y_#aYI`J#Q zWoT*h+HZ@ROx!qS!1<4p3KJvOCTk-AH9*S01VUb!{9~4)^XinPVhazhAYB7VWV{^< zQ?(MV)^;E%95gM0MI;wzIbw?{%#YVG>g6xuPi3d+_d4<9Q|klzadg1IZ{jmd{-xkk zj&5r(Z@F*{iTYZ-%k`Tim5CUKANE@%8x`SuEMi#yeUpZab0ZWEv@yO&%p$KlQft zr>@PF8)zCqSluxw*Y_iuoHIly7pK$3yuHIVm(VoY5724OELLA<#cO%s_Umcaw@Zst z!SWB5(Uzs0L6k4mM_?DxX9?8-yGrub!_rkEb>?_60SR@YhW%*W4^DqP@M6U?l0e(JUwl;dfJMP=l$|ftOS5qsyjA}QRU}Ze?NZITI?IUzT~OmutdFPCGR4DwI>fw zv(8KCKyvr+n23S^sRK%79tbAT&tOnw6IHOx2#XzADa*R(XG^UHpKr3P$V&x*Rw~z* zD^LH6m&g(SJl9d-M=JL0h*mq?<#k4ZB?!A+T%?83PYVNpryB$0IiWT_DX> zEt9=_O=Ue759RTc=Qb=WK&e)}MHMwnuINx|BboPfL_F_|o z*{u@Q1cG?D*>Wk3*!!<1Kcl4XV<`rV;%;Er6ri=|vx~jc54!}mK+p>U4x1zy&j5OL zTp*#+Ll)$xIs~%lUWT_CF{tkac{ar5MQSuI%yTIK=>V}bD}9qeCQs}+7aAF z7cNGS-@xq5ExQSdRP(@$Nph9_DfW)k8h^U6R8t*;cyqKXwa2M%$*KK1u=b`7#~}no z?7BC7xW*d8z6v37#yX+-P#qQq91r)7$Hpjr_M@aRiN~q8{Ftm5l!QtJI~&!=C5n?e z|3u1&?Rnc@%oc2ixKQsaKg_nF63JD466>+tO_w)D3Qbcu;}oWpuR;$AeBBvcHGrwS zGstWiE_>$=z#V1`84b+BX^UwvN0*F~>v^_(Lh?hzD%QA_89uK$t_7%Bu6*s|9zN&Y9*@%&} z9tALx<+Lo)+=_RPSdePw7KgSRoEP+)YobK&% zL&jI|wI(?rF0Kq=Fwvj%GeJrk-&9<0rcBoI+Lsx;$+UIdG%hN?wWU*D^Fbd^U}0X@ zqvk;gDUsf+2{T%MxH_4}?vReamSw`8tKo-m2Lq8uj%4ZXuEO{5n&UEPlfYxLrJ)x9kqcB?tH%+f1LDah<24PgKb-_4dv$;H8hKzty!FCYu zB?ELZxJg?U;Q2lH^CMwv=A8`nP4;0s6>r|){EWeVllVBc+D%VuTgG5!bg_Cfj#0r9 zn^^${LGF3OX?xLapS2GOC;E{qgz7ob#L;-_o> zM#yN4@HWX-l`zTJ5M22v?G3g7DEw>Kis_gz_1QL<(uuxv%c{9ft?dJ5zp|x0(;k!_8)@u6TPY10()ZsCkWb5b{3dSZ{^cd_ahVB7u>v9_( zp&`fw6aW*uvEUje_%Fj=Nt*kqL~y^4o^V-GBkD-U=<6szCNQK4ah?0v!iEc7J!>1G z=-95>%*#8wN5WUgUK*TLlUvL)Jft5}KLMP+jVmsvpQWmIUgf!xcSQk^{RVlqK#yy* zwVu9oYe`c}(k0tJVjCkDg^4{$5HD9=w^ku<9f=sYt)2zZXi^2!ou=TJuEfR0OYb6s zR$RvIb>~RXSy|kaCgf8O+QBw>iM*+f4k(k~xD2M*?1;8h#-5&UF&FGQg)NAQ!$qzv za28Axs9#;O@ZQt|pMi(4CoQ&^m<+s`9btvDTY1FV5@4s9Rb-Y~s;7vYoWdCf7xDla zOMn0<&us+~2EagbaWw&1hH5WpNzO_Cu=!A0JMl99CKyid+mW}<2f+_4cKWx%um3`v z6e>Q~>A`@berZZB#+xCMlvCKQsph_Oaq$`7!SbYY?bCmR<>kg@K9ZzvBX-=IM(HoZvjoMaYNGrRr zev7_2@Ukf$MOpd0Yl8TB+r-&@mpJmEzoi;z6s<7I_qinHPC8J>U8D?@eFy0|G`H5V zkR8MG>a~4&TXTn7Up|YnIRCxD5|1xQ#N}Gf>qJc~-86~D;WFye%8ycCNl~NSrF@gm z$w%4Ly6_91>~p53KXBf$VEX3XdQrfx)hXJ`w5^esI~d?sxtUeC0fFPnE72e{GSmbO8cDtd1G zt|pa7)c|bdD-uk6Vv^oXO|StM|Ltm*D}&(Mj8fpp%_4ltne(Fr7o1;^d5EXseg;!2 zk1UARxR(p6)R&kh4OdgHz&k2M$!jE22QHbeYeGii6$dbKH*B(Q%OSM*G=r@0f8FjG z)rwZ10u&?cJPHX{fFY)*GDsTZBD@;Z*;j~6A<~|aC6eGft zSoK7U-j%b~ck~DTOuXLfrTkgkUdOdBTmw0m!to3H2~az-L};Gr$?t@&mKhil&%ZZ` z%t8>@jD}q(C9sVl^ zrBMi~0^(S!-6b{V{_ZJXFk*NSDf zbU)CN4xYu(BiSH8TsL-zP%}NI*hS@f_xf|fyI#o+$ZK!DgwE!I(UnWrJp+Z_jDD|B z3fmK2qiW#Uosc<6<595i;Swrwc5Z$CWfhllGG4 zMYNma>lKN&CBuGIW6^TqBb>lfH?w%F2Mtlxj7VGP7=e=d@s2vl0bh((^Mz{W2n9Kb zv{j}-geDh5Cy}*`X(ehv!S+ax<3}={5g%ROTx*U$EJj5M>7v<*@vH?aHghp~x<;pH zwCKvaeOyU734J|%1NE_-h_iMy+HCckE$=@&AHvDO{*FUtVyG=PaVIwyEwob^GGF?< zqWfmCUV$U`?E*iBC>5quP2M;_nEB;!Ts{Bh6B3dH7(KF(C)X)im4~Q?Yp0vnJI=QX z>IZf0OC(A^krJ!e=`R+OwLKfNsH&5*H{|<>#Ui2}Z;3#-e1%u;W&dog*f_B_>!^#z5=_6oJ@w6Up#_rZbF&hTChG7RQJ0!0^0BPK0!#uzHuFOVu@xoGx?R7@ zM%c3h)?O#vN){|ut5YOdVQ2xG`+@x<2|{2FY&`}t1Wo52+v^PtDtl~F#B9BzUg@X% z^R`0mn}5O-Cpzplth2DVLr}-@QkH5uI(I!z1Z(YR1a9rGHF|a9&J|cxc?5VeO7Gzx zwcx-IKdPfA44X|ynY+U*i7|;xkrfYPWXb=`#bY}zd2UBhPiQ9qwk9suR)P@FFKm}* zvB2vtnax+iQgsn?2Pq#zk&GHwBushCx?WKEgyPS~-xkoZ5+#Ct9B=P>V!ATWv?Kf!waffeuk1U+rX*EwEZp&?+&+=ri22JY?#$X|bpk zQIk}HLhY*oD_~oMAXw$vBSf1}>8#3rQ|9qfxLuhfUxYT0Tr`zzv6s`-VA=vlr3i1# z>#{TAK~!h4lyQ=g$d}XMeELIUq2?$toi`r@AC02!C!4UZ6Sm=3hS|bVzd99MYxirz zFjd#|Rgs6GUnQ*$T?bf7ZMjPCI%%~7JSv5DqqD0Fw-AAzPSILsFKh%kq}WmaBDtI+ zz zrYKQT+)?cIEhHlIGzIJec(Z;dK(H=D15Mj0%b0`FT7Oj)X6@&Pvq~)I zt;g{F4<6rE5W?-$)gh|9(!SGM&jSXA@3x_3vE z(phtPE;f4##_vZcI9CB`0-ANTFq*rF1&aR7NqMlQmPp+Ocv^&jeO&0)a5wGL5gwdz zNIaZ*PR$eA^~-4fx_Mi#BxvnIORA5QrJ>_!Qt`ysj+HtEjprD_w{h^!a?spXoMtj- z_Q>hnV{1mdtDFY)Gb)~&N)?fZ32xsuxFCoOtH=~xf2L6}0;H$Z-Jsu~ z>$y~FVUsc{cm_eUf&2w&P?Ge=2n->#8O8YfI}y1DvpADhuC7+_i>@LHE0;F{*o?y; zRgNg7uJR5;&Th7vE})Z>t_`@MswFR8Q*`$_UvuY@`iF>JH7?|~5-UU_{5rOj7_ukD zmjW!uc_sXr^Pxo8mXQmPK`W^1_wEl>bHNgLz{K|YSrKU1wU?4^xkKU(REXeXmP$}t zh0y?Fc!MWuziQboK(}VtNX4`ZFY=mVL{R)b)jFxFB66b^>^C`(hH$WS=^3t*C%YxB={je?1zK)MVo%8hd#32A06Fl}Vi6L=GyEyYO&Y)7rmCsx z^jqXs?!wfgwSbE{8kwM+xz0!+f~l^2aj7f6gz4hx++iwwZGAJTNtq13hr!4UA)=Z# zQQ`lc9TK+gPGWVKvh?v@@Rx&0N9k>+yjNNz;Wb64?(yF>8uGNYP9 zYj__>{QJGZ@bUo>g^gQD^{8Vz7egQy4uBfZKDZ!!@(`F@G-v>BDuhxN>FJyK#8OBd zM_-&3T?#$*z5)Dt1UwwD-)N1ti^E4CoW8KH5<=@Z4VFrV_Us^2GWw#$I1=)gLbr3u zrDwG9vZjF~c@{I5t$RXa3haBng!*vaUPL@WjQN-A-tmG;N+$qG@LwX<+VsCV9DVh%R|KOq zQvHqgApO3B`E2aQ&O=IJe_AROSh}tZJj^}3vSBvA2Zx)@qLRhvsw0RIB^V@>9B?^! z)?M{RE=>N*Q&)K@;IgR-ZdmF@^<5!ck zLFR4H3Wqzjwpd+k;Lx8SBu4RU;e^2`=J~a$`4VJ;4bX6gRuICIabF57_I9?`|3dB; zR*x4?0w$H%fiLkOT5Lsjp(pe48eB2aCL}6SR%XyvXcfbgP40ASA!7HE-)sEzYc{0c z=O|gE;GSu_97532lx~SnUljAxB-x^vz`Ey?XUf$Ytw1pvZ7xg#f;_F6=}syH{8x&i zOz$b3+AwTj*z+f`hcf-D%aj#jKkFYxqYJ@CN~%;!AG@> z9z3GTCs4$;!5sC zkKM3PnnBar;c}HapkUU)zxKrPa1WeywYlqgT0*(T-oK|t_Z?m}QxM<%Im_;|XQ@u2 zz39dyL2Do$qcZH{W47!i}4Ru_iU+ca;b0^!rS@Z!Zk zH{R6|j2n=9Jt?$UMKdN;M2JwMZC>APBR{MiFo5pl_kpIxu9tg+91U)1Bz-J~^`MCM zF&hMn(zk~GL_w-@SP3ap;&Ue2Xu zTal93N3r4VODgQ|=Xm@)|HLZVG(jBj_jtsSIVv*QeUOejGuU1Y-I$uws%@x^C1z>q zwBp^TSa;BLZHG5t5Q^~tf!G@c!%#qDo#dpSQ!dk#IC+AQ=i)g5*lKu^`%1pD8l~Mj zeB=&ShOC5M_21kZetc{5_C02BO|04d^*J`$W|!ALrU`wOI@p@y8(XU^-l4kp)rX_c zV++{tO1B#X%;i&3{}Ps0u7rXmNu<|}RU~8$OPeTP340#>@v!Bm1|=f@iC6nV!kfX_ zH!CGD^~TV4bbCD;DJ_f;QJ(PDS`wC%$~-U`_ff@J5&_&hAWIj6m{bP+yx^ zRp`kyd{Zx2j-lr!^5`mx2^u?$OzANFq4Ge6J0UH`f=u)m&v?FcL{9Vk-7Q7yP&#?& z+bSnXj;s0OFBeg;<&#~6mnK4DE%Vq~R``ig;G=7aczpZAWIU5rfzA>6T%z}MR5#*u zC&!1iW=*k=m~>?=T1Xz8eLuFfg6PBED#!Ko8pgm0%Sz*mG1dW3i_H4$l>lvp%4lGG zw;i4*+$AuwSTgS=tGKe=Xmlz2N#)Z={dbTr7Pa=qr6L$J(7B)nz;(WY_JpPeT%^9( zM;_z_E&VHHrc-4Q6qpmV?e#NVdYL&w#~{bICEjj3#|%9tY?D&a+Tv@8TEw8nAA+3F zFD#Br+>~AZ$$!i(@i4OTB2%E0wYI2LD@gRSs6i1ncVIfO7)eVcEG)-&bnXJVVx%T~ zuf7_6TytjpNtkhavJN6+L!vtg??h&-U^N}Q$JEWCjch$~0JV{2+PTKsdo>z~-=>Tn zvdvxzPK=YOnQ?A-q;rO$oDM4FQne7KN{~L04$GqLlEk-BmN9U>4Q!9`G*TAGn*zQG zG5!@!(rExPkR&H?;Gh&{!>_WN%g}7SvD=1dZscKjoJZV0re_+dlDKc(2!tXX_`4KEgBN$=-+JPH1A(g zD~gG=elTS&yVfj&IpmB1?;Il7 z!6KPfXHVM1lkhkcZx#r8!xZuHctEBz;OwVU$)~Ef{caT(d^kK0+aN~8pCGalvQIAL zc4+lnm`kPBHae>c3C@|wtZSIi6=s*mzWNe*$T&EwU$^A2TFVAp$fO`gvSr&`ONJsc zoRyQgP85}a*`f!xt=YS9DHt*l6v1{w4xvj1g5hvD7{R*|?3ti1Kc_fs(l0Bhik(_> zCFx7H+YV7#R5fCZq02A8IrYA9&@5H`!paZhI~5lM?Cuy&L|Dw-ZSCK zfT}R$f+aH9s>{6lc5P+r4Yedz8L99;1e(}xlf4#;P_T9>_0`m^rZAD>PIWadh4V6F znuBeFh1&Uu>fK$7X%zz?*ILED+d67*c#btcYfW&0h2G><*OP62kaa;54_nnyowgYb z)x=BFikGNrjJzQiO5RY@CrX2*|1YlmxgHMKfBp*uIHUSx#Kq=~!BjvIO{L7recJXe zMD>VL2*$vm2Iv(Oi{zvKhO3?XBE?)*;5!`@gYL2zyo_<2_7rd0f{`TPr~(ahiPaL= z=>R=c2AtOo+QXyxMkK>De?c}%c2u$H%3Nrqvv1UgfFk%BB@KF&C+g&(=keo7If|O` zyb9kQI4i8ls|zGAX%uM%TJWa6FZhVzIJ*FFJQuALnLOwED3`muR6O(bKzb#N*=)_> zCOJ7A;iXvzsPlg^XK~EcEpNf;3QnycGQ2C;BSXc!^`COg5?<0`+5S@?G}R!mh&Y3} zPNpw%2>t-|J*{~}D@L8oP(XusBq;it|Dl5CjLs2-y&3YXBnxe^?f!%4ymft=rxBV$ zKNl+sNS}^rmtw>B7%B-HCYvsyAqb{E3_R=wN7KBtDGe40*!^~Z*ck-#-Y)O7 zUegQ?xdpNdIo1Pk)0jf&92~gUDHpp8-P~vcEhAx$m!?1m!NoJBWR@=+`efEm5NP5iGrTTkF zJ0sen!JQQRWj~bh>Du0aQz>9uZfKI;O`G|d zr*ajNwuo+pjzV$tn9V05;n^eUj}6F%HUa5Yiti1T`4|CHKFW8?nMwcliNf&m{oKxO z?RYD#i=<*B*&ECHs=INP&9wjm&^<-2m_08uJvi{egb{-6 z&|fboRGJ3AA0liH#y*w(&_c5(Pztc0q=SnkoAo>=NY`WG0(meQT|2LXshQ;!g*fU5 zGuhvrD$2;TFI?n)Q8gE^!c&>mJ@o_#5Yy(nUK~J)^3D5!`4aAE4pg)rq=INK!yX+= zG>Nw@S7?yXou0V(8%8wZY$gBX03S# z-goZt=oE_o!_6yVlUVZeW^Z-jYg5V|=|v*V%h<-aXuuff{hW>&TlM2bl>F5h%{F8| z7XF%?6Jxso7rBG6fAK>8-X!H$I^}!?`CQ~ix1+DGY)gY{=GBDtERKb#;(f6IMiqb` z&#i>=v>(+}5-jYtMAN8ZKvie~pR_}Mp#`x0O%DVd+L4d4Xpn5DNWVeSV<=@(^f zD*vbNesk~X5}?aOmIxW%&HZ|T;A-d=mtAJuJY?aG=XbBXK^ca_7tM?N2ni$s){XY1 zof~6xSJp(h>5&X}Xg&nlvhU8`5fFR@nX z3UPyJ^DmA=%rZ-tOWlAkwM$@aet{~~s_ggd?Kvry&2VIZR(XF9psAHj2M z#-s%Y$)O*GOA6@K;c%zu=@(9q?W&MUBYt3}NI{8fViwhoH&=ycYfp{;C~}|L7Ebj2 zg)&Bp5}}Agr^_O{GNq^dX=x=F7}Zy{EUboHnaIdgD5K(xoHcsLXm+(kBlNgxh`A$K z=q$7|9Tj2$oW+>!Jr=jBK8S%+)$pXRhk&unB9$@&E{RY~E8x6}*{N0z zTD&FUDBx|~CtkbgnapT^wTAi97t&t6@N1j$HnvOv(TFJfYq+q{y4ymU@!5 zYg)@bVvQ7dzYNEL7CVmj*IhX++LIQUWt2^Hr2=Hj$bztC6L8|Nz~)oy?boB%e_@jn zi2Qy=9^Gdk-8@1JFBhR|1wYRjy2Xtm_KVAAiy&&u*<3`X{JyKgyPpglcSp(lX&ihz zw1{*-kvbJt`F}h!kh0Z}Orz$XodFu6c|%^Q=#(MOqrr8#-Eaw9U;0SE*A3l%v3;6; zR51__@4f~4$+p`D|K&R3`D)=>GDWY0)DHt7b`QeAR3beKwLNmFHIfSUCZ4PnNL%Ra zoCs=F{-;`OB%+uJ?p-z{7VFM&oq{IP2dvo>!f%hQvi3h9+QGGQ0UNtaEfAplye-O$v!6|@9ihrox7jGRveyNotibM;I#~T3$F3vJiE4$x?hbCh2LhX zvWB(QteJk}C#(t~Ne;19AqINt`y{Tquu4~5uRH#u#Ac&lq6vOolXS!vk_T-f6Nc!0 z@ffZ5BZ}1K*_Mw7!1V^v_P%IWysPSeWklc@Wy3AaJ$ns+cWD$346|`Xz*D(mCW*)e zHyT|Y5BKOUTxo|=o9vSYQLMIMy+D}$=&VmzxN38EXlWP$L?(cu!b_c;UuEA+6!Tt~rWd~Q^ZSY~{f*CzN*9yyudPw4aU z8G!InLO_m5@qtS!{`}TwdHjoG@i5pq+s9wz2B-p7&gehpa1`_dv@MNh$$*i!Na(*K zkUCiDMXE_pAJ4tq2$gLEA_M!f(p^6#`y)l_9(uA+8P!MXE$^e5iFL~_(ChgiH!|R> zgxykWBmo+dY{BOTjAfSjVfSAR#(V|M3`n687I}t9R6yRa&`dv9%Ouqeg$_NzeCxHR zzmpB5q4_^Ng46I)A(T5aj(#W<@fg9NNonoftQRH6twlg>j|`w1KE*8CPWbIqHGQYpb*i z2th^vVv3v?Ur-U0*55O$ZFgUnYYOZL+gKhd%K2B2!pq;HyT38Pp6h>5kgpTZAkfw9vq~Ah@bepLp>oj_7qq{dUYnMoYl(HKPzX85`{J{C#dY9=9Bch6#Zi8vXq< zX9n8SxuFwFI0Qdw$QWL~5%_R0>=NEbc=C)x%zl*RA|Cp{$xKUdnt5n0%Opsvv8x%d6S3^(Tn2?AxI}$LD!AurnBdbRU{G?{e?m6ON7f;ge{w z4#G0dIQ>zH!|O(vO<^sm$%cjAm)%Is^blC(u@02{m+b$KS}d1U9HK}Y_OI}Qi0Ua$BrjSGTtbKFj><4)6e=nT&_tSFfKJfl&Byk!KWkLawL#2a)bgwWk$1EY6DkO zH>MTA*BKi=!Nmx@!urbjCkN!k{3gfuW1pWk)6#Sj=m>}-Ylb2Y^G7YQBlhLcJHt@>`g>8PY7&*WYIKb zOZ%<&y*;Z#X(D<#M3mroLwlwA&vhC*<*v4D8xN9i%qQ506}?APaf?HYo0U@jsf+H+V)L! zFmXHb6=AijX0`)seWOCxFPR2T@S+erK?{Dl;ipr<;guqaEOM|BelN0gj8?B9WR7r+MjZmy8E*{^CiTQ;7d^R3{6*lcKP4o(By z1=H<6Sbtxc-|L1TM`O5IS*$-KgHk*p>bnzCptu^s)VS@QY-9nfWfysf32XD2Qc)JE zKYhtf-c2=6Xi?BUii7_7qIYoHoV{k>K=uFBv12)Fz)m`Xfdm)xF)Adf2t<{1c^TQ# zwaK1=4BU(}%}+qbr{~(eKW>KUO4nLWz36S3~7*_5g=LN-A7XyH%{qQ7didn6_#7XaD8(?Pm)E{ zr^`5R2Wm~_9yH;AVY=LVm9W7ud!0dT&W(&scDiF|2=jEE!i$-tr>%VP`t%~j`Mm_V zE;8pAJS39>e!QqdLDw8xUm)C=rr(upmqPp(iH z6)oacke^p8z~nFqS6*=FF-I<$?tQG-1G-6EcIvM&HL7C4fJ}XNxBt$iS(812YFO`l zR}_;8#zmQ2-N%p-%qjv$AME?FQeC>2j0{^zFvTnVDX1Z_0!jMRWChwp{K!ccTeh>P zXn=>SefFPvpKdAy(#|o> zhZzAX{Zgn8?H!34BOa;)zeTK5Ru%SJTzm-Z-sCB*ipRJ>b=DVC(*WQBD-p?Io*rLk zAn~HkRX^jB(5?*E6gJ2}=pftpcP4q;9A?%5hTmDu|~ z;L%rYYZ8g5xP#f1lOxr3mCoSfR!W98cWV_U*$qA2lr}tzK2HJ@L7~r!_|F;&)0;7& znxv!menCx%XJd2ZUE-LgVld)7{%A8UbUa4Bgfe{xoE3A#tnyH}fR5J=( zm6KQGmCkgI=lH4^4t0|cyY&ZoY#8%Dd0gZS*xAWR_0*grn(4sW1#6-Um_kp zdkS?-<0$ubN)&C=3>#91BMzTN(yv=O227>2EC7O42@5JU2$%$)*^(sy#T!V!*VHMZx_SB|88A7-`1}P6zxrRCN8ib;T%G+4qg-57ClY?^+ zgjWuxii%k~FetEXX6!a{Ja(AVH)ew;KVwmj1zj6gDwh~@j|7PM1imIgszt*-ojx!m zaG@TW665bhaI?^NAQD_XI6+4h%S?LN)`f(+98YgUZhNZwvEql*PEqyv%JMnv&%KAE zPptXkmQOt}IUMLm=469Cd2boW(bXmO9U(NZNaE$#G4Pm`~USGdsMw-TBvXyf{$a9Mx0s6S!4k{}T_Q(Tb6IJ4<7n=aPltSS<>yWb!Ts zp!G_la>4aLrF;%^h)ub~&=%^9=ONpdxu=gin$X$rL(!^F)$xxKR(?mQkI zEL;p1$j5*yp@mQ-6c!#5YR1Y(R8mbVU9<6G^ZIA+SanmeJYW{WmZj+o_LLvUiCjRb zTJ|tMPGbh!1H+^%kEOZRH6k$5gw1{HW@w66pZ!M;kf^O7nBH&*v%G;@YZ1`Gq()B% z0Z;G3nrUS+`e(4Una~Xex=i2V2ziN~e67Z3_G%cF3L)cV9l^T2Lo{NNIL(bR2l_3*$&(Ee;wNe?R zy=j>m_%&gJc@TMgC4K-!hT|gsZ=tB3I>tuu>#xsp>Nbw|=3s|qKzWz!fkbV7s2K1` z@{DahCN6mztJTfH9LQ&9To=@#jN>wswe0SqzKmV&nz%aC;42C&svS`zI;{pC;?0!2)yMo5zRmt^+r^t3yBN^oR3kj zx|;Zq(OUes`uT5nvk4O-1jdk2vATK@hF9~pipj9rw4K|9UVWysSL5}ae(6-77LtOy zS(N#y!YUT5Hjj8f9F2L0J`Wf(?7NP91LICeBBaE&qk~=E#QRY>lj7SPn!{6JM!YN) zS_1&*K0JAL_JdGhFj`WNR<}Z+w7nE(dSXfeWRr-KZJ-7s5hK<<(AOhpNns{^@g+Y}nISFi+!!?Yv1sw#0r*6k7726l;z-cZhfKsIw3F-UW)3 z1a&UNjxVPNcvx+@4oQ7Y?H;cb^K7p&5YW<0Ds8o;waTo$;Kj~pU@@_G31cz~00j+l zmu6zhjOu8i>kLlThmnPHRtL*g>FZ0pUz_I7Lrpb4nl%Nq%6hW3EKWbr-xpu@QK-%R zKDet*d}pZT1QxWTlumQja8u4QQ-17wRN8Q)DlgR6ux>X8<;=v4_k$h&t-a$sfv|VK z-TPa^9F0+wCoIgvt3QiRmx_;qvlM_*g4{|j-P!Kd@9cxe{?aLA$i|iW? zg~#&(fq^I1i^|Ht=WR+b(Nkt-b0cD&n8WOQ#%On6AX%4aRJ@1jxDO%Yv%vBx&-^1sx$x4fh@*|t08S+FlSicA@OAMpDH5XyBmEPw^R@dznC#dqDSc1{p z6V>7Ghh=8rz${M_L1IqP_{F4z7CH<&D>sJ{UJCupfMa#0Z+4n;7d`PpyJ}@hi^KNj zYHaKa4`G~E%TY&PNoNQi5$8T`AY;`Q7jh{VP zw3Q{=`EJzE2Oks|NhsI^6fVVf-g5f&K&gNM_DMAHua+I9^JBxt;|Vd_%8=VksEwm7 z{K zCG9djvxiteDW9m8;9hwJ^8+IU#ze0pL^Er)*eVzYNCHd+a06w2G;HH$aCobb5^?%u z7L)ws5PVInHE1~lqr)P(&eyUkr^Od|dIqGsv=4D|56Y;-Ac(n5M-PTecEHPv*HTrx z5PV_Euj-d+XVhHq{xP8_$^)A%6e!+ySG%*NE7+^?5HdUn!P8$(2Q^jFutV19)+}bG z&W1*f+B)BRizv{_WzT$WXa_ka$G{8zELYd11^Y+QqNo$*y>kF%8DrJ~VMfH}*5=h$ z5EcMC0a1R@_+C&IbUSCb772)XS*%Y#`49B32P{1G(BB2yVa{42)6^mFE@vqxdu_jS zw9G71N-r0SFk-_7Y#aG8YkJecXF06ajVCWyKb)qA20*qiVeE$_Y3#o6=`XkCfB3YY zPqy?0E+N~pse6SS@1HUwHdvzWUY2>nGJqZ_#D9m2N3Qms1#bA=at^OTsjpjFxN%>- zmO+My3Gv|M+*V^-%lCJ6J>B}7PQN3l+SH1O72=n;gX%Y&@eBz|s1 zd|VU^{Ovj~L3im;r|0HQ_F79wP4x0biXXFd|6i*&x#L3NJO|Z&{bcuT%q3%asg1i9Pk=+E8&%p9ks?QfAdEd&4MRHbYdN=Dqf&`;+IEi9yfT8EJu)V^;5F6-v$_19>Yk$NZB_VUDql1 zA<#b4cp8Y91Sv(qj4=4RyV|K-H`x8S^1`B`8ZTxkQX&p0`7MDO3Qe*B?xk!X^ZBGZ zYs4g=YRIYQ^reMnfX-5^2dqgqw#0|qIrJs%HWjKgyawmlDZ#GYCDSZ+$tE4C5N#fp zVa;*VNklx0vkl5&iBuJYZRq=LvaMdsR5-AI0Jm8my0x`d9h1;0e8QL)%BB)nZ|vY_wGE z*X(L7;cj4w7-v1%9*UxoCz#;3eAXk5!NWhl<_R-1*np1E5pR9Rv7nx{PA8&7{@2))Wf+u_(HDF)|8}om1 z+#%9QH1nZA{e*aiuZGuNp%Le+SvfRcYs4~gza%MetXDz~cFeto@F^zx;QtUa9xWE9 zq)K2UKZJCM@Ptlr040U2W|L-G)gjlshQTExw&&ft4XN(cefDWp`x6xgP4-zR7zw}S zhZRIVL1>Jp5PMDw&Y6u%+s=>`+0af@vKlct%e0`f&1Bc~X-;C5P=_$o)S4OM0Kb@j z;Xn@Lq8Fmq-2UZY9cWd@%09|^;0E1^98`R1%YTu%Acc+Xzyt+5@`L=W+R(@PyV}z_ z=%=vHQYQvCdvy>FJmu>1LwE~$|6LZ!5&bQyc=(M{R97JipAMEt~-9L!%kV}861TXOk}$#{elj+jv+eqm?n42SeQCIGOHFSCZ3%a<_RJdBcdGY_K@ zx~A4uo)6*XGWI}tv7ht_uZG4dq@d<;v_aQaQo(DxdH_g3x4#tGGPzmwP3Mi&{4|?# zknKMZab%NlE*~}>tA9eGD%P1g+8^5@E-;b6^Drp+g;nAJ`&cr#<5b=S*fd%8AR%RN z@VM{L&RxPMvF&P_pp8e`0}R)i=ASNO+OUSjw-*M71f8uw3?B}a7XmkN8ur4uqNK6r zc_E}f;5~D1_OER$koHb&T~D2bR@JYw7+vnE zx-e+&J8iYD(p_YV@NGOEm3p730Vyty`fHCN62}l0V$D#i3lt=M%X!{b&2Jy`<9s}r z5}%iLiwdw)ygv22^*>gsEoaz1oRH+yLj9QD{8m}YVd|dJ0@MaTQE9jpv6y)u5|kg> zbVq=Dtyd6S-C-?oSPV>jE5$(4(ob2xJ+HOSbqD^EIBRX6b`lUinpImg^+ozeHaP^16C79=zDSpveA>1f=tE70|003)onDm9cG4CCHmSoDg4$b`ft5rteYpIyz z3)@~bd3n^MO{_Y-HaW1wIW*u+GfYaY1CxvW>&6qo~(lL2hMAv+|N>#`mC*3)c3(9E#YvM}FqNN|31J|qW)sznZ{O%J87Qb2K%$zNx1sr02>ri)Hpz+qh zH&6d|UMUz##iaEDBr9hoY*M2_>03d8_H)vtPu}cp^*JsU?)Pa<-DIK3su-#ylM2C>S{>&_i;bc6gy;aC_6a_Js~6#J7LGA>?PrD=i9%dc+-Ec15a~trXC`++ zA89@zz%Wm&MAw2DOj`N3zlOTfAf<{mm3Un6;+{lt}i_+818I$VY53V-|p zZ<+!C6iILZs5ejgl%>u*Z0~s-nYL>eWo*DHqv1*?WES;-J4N31tr+XCLu21_u-s`g z3mZuAvpJ>s#(EBPBDl}*Iiy4|QYuCs!syL8I)_*-1Zkx`g3tAmF=wHcvekD*7`C1> zYgz7d8FY^X_s(L9#`Xc0cxclG;-Zd8P~g^?e_3AoaqU%Xv$h>6=dfKRW))Y!DcCx} z#EXm(4Wz+_Pv!&OL(YT_2Z6W9Bttx}Oge_mkMTdP4D%E|2wG)h5R=4htntynSLS3o z+}>_7nD!}`4GjD41@9=rigmTR^sT+B;M%D3aH*B#`+hl;ByyMP5{CC#2|gX?`$L9<<}`scUw zfbD2nTSYhh;vzF`j6)eAFax3)5ws*b1Qv89^qorA>aQXjsrl;8xHuX1IG&cY)7^Hb z@}aqIC9%9g`FKYqXlT*-itGL!Q^e8%Q}_-885CB+L9p(BoG6bb|L&$?C+2F1Iy6z_ znr4kyH1`aZ=*BY04iJK^SiLo}mxC_zhZ~Vu1`S_Z>5dj?@!;x(wD>Y7u0fcnN|^

)qmF80Nr**Mb)gdFQ|BQM*S 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 Date: Wed, 22 Jan 2025 22:42:23 -0800 Subject: [PATCH 089/178] Update ruff to 0.9.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8b5f969e..9e919a06 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.9.1 +ruff==0.9.2 From 34531980642ee67f8f04143f52e163269ce78c23 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 22 Jan 2025 22:52:34 -0800 Subject: [PATCH 090/178] Add missing logo to Taiwanese README --- README.zh_tw.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.zh_tw.md b/README.zh_tw.md index 38bc018b..4261be8b 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -19,6 +19,8 @@ print("Ultimate Python 學習大綱") [Deutsch](README.de.md) | [हिन्दी](README.hi.md) +Ultimate Python + ## 動力 我為了分享過去五年作為一個學生,大公司員工,以及開源(例如 Celery 和 Full Stack Python)貢獻者所習得的知識而創 From 5376b4b48400e710e663c56bf4ee21c8b335ed95 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 27 Jan 2025 08:14:07 -0800 Subject: [PATCH 091/178] Update ruff to 0.9.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9e919a06..f25c5f0b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.9.2 +ruff==0.9.3 From 0e6f0f0e6a5afbbae1e90d388e9e97fff952c6aa Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 5 Feb 2025 04:43:37 -0800 Subject: [PATCH 092/178] Update ruff to 0.9.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f25c5f0b..0b223b0e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.9.3 +ruff==0.9.4 From 932a76059ea3de7161724ad1e241b259759ad8cc Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 13 Feb 2025 02:06:15 -0800 Subject: [PATCH 093/178] Update ruff to 0.9.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0b223b0e..aef619f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.9.4 +ruff==0.9.6 From 802d667ba6e0a34f1a94a4ae873700dd8a741992 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 13 Feb 2025 05:06:55 -0800 Subject: [PATCH 094/178] Use math.isclose to compare floats --- ultimatepython/data_structures/dict.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ultimatepython/data_structures/dict.py b/ultimatepython/data_structures/dict.py index 34855400..eea04b42 100644 --- a/ultimatepython/data_structures/dict.py +++ b/ultimatepython/data_structures/dict.py @@ -3,6 +3,7 @@ access, modify, remove and extend key-value pairs with this data structure. """ +import math # Module-level constants _GPA_MIN = 0.0 @@ -42,7 +43,7 @@ def main(): assert gpa_values == [3.5, _GPA_MAX, 2.8, 3.2] # We can get the GPA for a specific student - assert student_gpa["john"] == 3.5 + assert math.isclose(student_gpa["john"], 3.5) # If the key does not always exist inside a dictionary, we # can check for its existence by using `in` From 0c7bc1baef348d3bb752cbbd823cf456b7431340 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 13 Feb 2025 05:11:47 -0800 Subject: [PATCH 095/178] Use math.isclose in other modules --- ultimatepython/syntax/expression.py | 3 ++- ultimatepython/syntax/variable.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ultimatepython/syntax/expression.py b/ultimatepython/syntax/expression.py index b0fd0d13..0ad19eb2 100644 --- a/ultimatepython/syntax/expression.py +++ b/ultimatepython/syntax/expression.py @@ -2,6 +2,7 @@ This module shows how to create new integers by applying math expressions on existing integers. """ +import math def main(): @@ -19,7 +20,7 @@ def main(): # Division is tricky because Python 3.x returns 0.5 of type `float` # whereas Python 2.x returns 0 of type `int`. If this line fails, it # is a sign that the wrong version of Python was used - assert x / 2 == 0.5 + assert math.isclose(x / 2, 0.5) # If an integer division is desired, then an extra slash must be # added to the expression. In Python 2.x and Python 3.x, the behavior diff --git a/ultimatepython/syntax/variable.py b/ultimatepython/syntax/variable.py index 64cc80df..ddd3ce8d 100644 --- a/ultimatepython/syntax/variable.py +++ b/ultimatepython/syntax/variable.py @@ -3,6 +3,7 @@ a program. This module shows how to define variables and make assertions about the state of each defined variable. """ +import math def main(): @@ -47,7 +48,7 @@ def main(): # integer literals assert 10_000 == 10000 assert 0x01_0F_2C == 69_420 - assert 3.456_290e-1 == 0.3_456_290 + assert math.isclose(3.456_290e-1, 0.3_456_290) # There is also a special literal called None. This literal is used to # point that a particular variable or object is not created From bb6d6137c10e36e6ed6d190e832b316c03d92543 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 24 Feb 2025 00:02:27 -0800 Subject: [PATCH 096/178] Update ruff to 0.9.7 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aef619f3..d3be3e4e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.10 isort==5.13.2 -ruff==0.9.6 +ruff==0.9.7 From dbb91a431203706a7a5ea68b7fe0cae155fd5fee Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 1 Mar 2025 04:32:27 -0800 Subject: [PATCH 097/178] Update ci.yml --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9709c362..a822f646 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,16 +11,16 @@ permissions: jobs: python-build: - name: Python 3.12 + name: Python 3.13 runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install dependencies run: | python -m pip install --upgrade pip From 28bc49865a2c37e67f080dd27e35b1dc997fc9fc Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 8 Mar 2025 17:32:23 -0800 Subject: [PATCH 098/178] Update coverage to 7.6.12 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d3be3e4e..e87b29e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.10 +coverage==7.6.12 isort==5.13.2 ruff==0.9.7 From 5d175c8be3a30d5f818832751701d21577b9f157 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 8 Mar 2025 17:32:50 -0800 Subject: [PATCH 099/178] Update isort to 6.0.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e87b29e4..fbe1a4b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.12 -isort==5.13.2 +isort==6.0.1 ruff==0.9.7 From f7244553fece3d3d347e4e71754df82797253424 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 8 Mar 2025 17:33:10 -0800 Subject: [PATCH 100/178] Update ruff to 0.9.10 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fbe1a4b1..9837822b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.12 isort==6.0.1 -ruff==0.9.7 +ruff==0.9.10 From 655dfe5e717c3a76558df9a94df4978a85dc2a96 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 15 Mar 2025 12:40:03 -0700 Subject: [PATCH 101/178] Update ruff to 0.11.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9837822b..0314dc2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.6.12 isort==6.0.1 -ruff==0.9.10 +ruff==0.11.0 From dabd484de16245a4a21797a55f4dc82744962737 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 22 Mar 2025 06:56:25 -0700 Subject: [PATCH 102/178] Update coverage to 7.7.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0314dc2b..33eb545f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.6.12 +coverage==7.7.1 isort==6.0.1 ruff==0.11.0 From 1c0e5a558731cfe2dc666da2b3d8c67ac6a3addc Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 22 Mar 2025 06:56:36 -0700 Subject: [PATCH 103/178] Update ruff to 0.11.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 33eb545f..dee6b8f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.7.1 isort==6.0.1 -ruff==0.11.0 +ruff==0.11.2 From c258dbdb6be35507008ec348d19b6eb90a79aa14 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 3 Apr 2025 00:21:39 -0700 Subject: [PATCH 104/178] Update coverage to 7.8.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dee6b8f0..2aed80ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.7.1 +coverage==7.8.0 isort==6.0.1 ruff==0.11.2 From d7611804ac09fe6d8fbb8d95ea3500a4fcbdb63d Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 11 Apr 2025 21:03:28 -0700 Subject: [PATCH 105/178] Update ruff to 0.11.5 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2aed80ca..7513e8a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.8.0 isort==6.0.1 -ruff==0.11.2 +ruff==0.11.5 From bb3f5642c489c21ea95569372f8e40950a28f1a1 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 19 Apr 2025 01:35:00 -0700 Subject: [PATCH 106/178] Update ruff to 0.11.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7513e8a2..e5fa7074 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.8.0 isort==6.0.1 -ruff==0.11.5 +ruff==0.11.6 From 6374d5740494c8f5a577ec8f2505339aab75533b Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 26 Apr 2025 17:46:41 -0700 Subject: [PATCH 107/178] Update ruff to 0.11.7 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e5fa7074..fc7f0474 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.8.0 isort==6.0.1 -ruff==0.11.6 +ruff==0.11.7 From 9fd8084ce98c330a7f5f1647810254cfe49ff120 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 11 May 2025 00:26:55 -0700 Subject: [PATCH 108/178] Update ruff to 0.11.9 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fc7f0474..d8bdbd6b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.8.0 isort==6.0.1 -ruff==0.11.7 +ruff==0.11.9 From 445e985f8292830a342f34cecc389e985dfec8c1 Mon Sep 17 00:00:00 2001 From: "Robert Fodor, Ing." <138567045+IngRobertFodor@users.noreply.github.com> Date: Mon, 12 May 2025 18:11:24 +0200 Subject: [PATCH 109/178] Add "empty list" validation(check) to list.py (#135) * Add "empty list" validation(check) to list.py * Update list.py --------- Co-authored-by: Samuel Huang --- ultimatepython/data_structures/list.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ultimatepython/data_structures/list.py b/ultimatepython/data_structures/list.py index bf8341a2..44cc9f23 100644 --- a/ultimatepython/data_structures/list.py +++ b/ultimatepython/data_structures/list.py @@ -92,6 +92,13 @@ def main(): numbers.sort() assert numbers == [1, 2, 3, 4, 5] + # Let's check if these lists are empty + assert len(numbers) == 5 + empty_list = [] + assert len(empty_list) == 0 + assert not empty_list + assert len([None]) == 1 + if __name__ == "__main__": main() From 45c2249b7fe38d3367c04f1cdc3de75bbe557946 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 23 May 2025 23:23:13 -0700 Subject: [PATCH 110/178] Update ruff to 0.11.11 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d8bdbd6b..ca6c72ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.8.0 isort==6.0.1 -ruff==0.11.9 +ruff==0.11.11 From 26887e626b9509aa56f99da604399ed800405aaa Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 23 May 2025 23:23:24 -0700 Subject: [PATCH 111/178] Update coverage to 7.8.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ca6c72ed..f37f1706 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.8.0 +coverage==7.8.2 isort==6.0.1 ruff==0.11.11 From 1501df750c7283716d7ca852393a58bf5aae51fd Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 6 Jun 2025 12:06:37 -0700 Subject: [PATCH 112/178] Update ruff to 0.11.13 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f37f1706..0825f3c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.8.2 isort==6.0.1 -ruff==0.11.11 +ruff==0.11.13 From 6b87d519f1ec4be02136b98b3bf278de34bc1337 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 19 Jun 2025 01:22:32 -0700 Subject: [PATCH 113/178] Update coverage and ruff --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0825f3c9..a2c713dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.8.2 +coverage==7.9.1 isort==6.0.1 -ruff==0.11.13 +ruff==0.12.0 From 9846e3cba099a882c3167b37a2b4e256c721b7b9 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 25 Jun 2025 23:28:44 -0700 Subject: [PATCH 114/178] Add another bitwise example --- ultimatepython/syntax/bitwise.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ultimatepython/syntax/bitwise.py b/ultimatepython/syntax/bitwise.py index 9ba36779..ddd4559b 100644 --- a/ultimatepython/syntax/bitwise.py +++ b/ultimatepython/syntax/bitwise.py @@ -40,6 +40,11 @@ def main(): result_right_shift = a >> 1 # Binary: 0010 (Decimal: 2) assert result_right_shift == 2 + # Note that bitwise shifts have lower precedence than arithmetic operations + # https://docs.python.org/3/reference/expressions.html + result_right_shift_with_addition = a >> 1 + 1 # Equivalent to a >> (1 + 1) + assert result_right_shift_with_addition == 1 # Binary: 0001 (Decimal: 1) + if __name__ == "__main__": main() From be16512e7f6e7a770d91ed797b981d84ea1bb623 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 27 Jun 2025 11:03:26 -0700 Subject: [PATCH 115/178] Update ruff to 0.12.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a2c713dd..69b23551 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.9.1 isort==6.0.1 -ruff==0.12.0 +ruff==0.12.1 From 0bbe3082f3f9054a5be47d0afcbd49d47bc6e243 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 6 Jul 2025 01:13:27 -0700 Subject: [PATCH 116/178] Update ruff to 0.12.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 69b23551..1684588e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.9.1 isort==6.0.1 -ruff==0.12.1 +ruff==0.12.2 From 1b9d721deaca0f7750f4f25fd2be39b2e8577800 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 6 Jul 2025 01:13:52 -0700 Subject: [PATCH 117/178] Update coverage to 7.9.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1684588e..adc59096 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.9.1 +coverage==7.9.2 isort==6.0.1 ruff==0.12.2 From f22997ed2f6cd55dc92a687dfc6df861ac16b23d Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 21 Jul 2025 01:45:28 -0700 Subject: [PATCH 118/178] Update ruff to 0.12.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index adc59096..ce9a835d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.9.2 isort==6.0.1 -ruff==0.12.2 +ruff==0.12.4 From d156d4c2b41b5d337b54bfa370a157d251de442e Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 26 Jul 2025 09:42:58 -0700 Subject: [PATCH 119/178] Bump ruff to 0.12.5 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ce9a835d..6352a7d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.9.2 isort==6.0.1 -ruff==0.12.4 +ruff==0.12.5 From 4bcff9c0b0c6a97b0fa62808f7d6b841ab918716 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 26 Jul 2025 09:43:24 -0700 Subject: [PATCH 120/178] Update coverage to 7.10.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6352a7d8..48bf2ac5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.9.2 +coverage==7.10.0 isort==6.0.1 ruff==0.12.5 From b336c0a0ad8aa797f9ce9f511e0eef0e5fc23b85 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 1 Aug 2025 21:39:55 -0700 Subject: [PATCH 121/178] Update coverage to 7.10.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 48bf2ac5..1e9c1847 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.10.0 +coverage==7.10.1 isort==6.0.1 ruff==0.12.5 From 67ca60260c5ec3a3d5a3d12f4ed2d44a5ca47be3 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 1 Aug 2025 21:40:22 -0700 Subject: [PATCH 122/178] Update ruff to 0.12.7 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1e9c1847..bdbafed3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.10.1 isort==6.0.1 -ruff==0.12.5 +ruff==0.12.7 From 055118d9c5b4a12f280384f14df01e2f4ce3878d Mon Sep 17 00:00:00 2001 From: JackieL Date: Sat, 9 Aug 2025 15:55:26 +0800 Subject: [PATCH 123/178] Add new resource to Interactive Practice section (#136) * Update README.md * Update all README files --------- Co-authored-by: Lei --- README.de.md | 1 + README.es.md | 1 + README.hi.md | 1 + README.ko.md | 1 + README.md | 1 + README.zh_tw.md | 1 + 6 files changed, 6 insertions(+) diff --git a/README.de.md b/README.de.md index 359163bf..80d96e61 100644 --- a/README.de.md +++ b/README.de.md @@ -159,6 +159,7 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [hackerearth.com](https://www.hackerearth.com/) - [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) - [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) - [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) diff --git a/README.es.md b/README.es.md index fed028e3..54a03f9c 100644 --- a/README.es.md +++ b/README.es.md @@ -158,6 +158,7 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [hackerearth.com](https://www.hackerearth.com/) - [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) - [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) - [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) diff --git a/README.hi.md b/README.hi.md index e128dbed..1b7b1cc7 100644 --- a/README.hi.md +++ b/README.hi.md @@ -142,6 +142,7 @@ print("Ultimate Python study guide") - [hackerearth.com](https://www.hackerearth.com/) - [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) - [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) - [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) diff --git a/README.ko.md b/README.ko.md index 9c416281..cc5f28b9 100644 --- a/README.ko.md +++ b/README.ko.md @@ -148,6 +148,7 @@ print("Ultimate Python 학습 가이드") - [hackerearth.com](https://www.hackerearth.com/) - [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) - [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) - [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) diff --git a/README.md b/README.md index 324d6d5b..dde8ccf0 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ Keep practicing so that your coding skills don't get rusty. - [hackerearth.com](https://www.hackerearth.com/) - [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) - [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) - [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) diff --git a/README.zh_tw.md b/README.zh_tw.md index 4261be8b..c6475077 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -142,6 +142,7 @@ print("Ultimate Python 學習大綱") - [hackerearth.com](https://www.hackerearth.com/) - [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) - [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) - [leetcode.com](https://leetcode.com/) ( 👔 ) - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) From ab5caaa8664dbbd3ec9367e2d0eba5d4c70ab3ac Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 28 Aug 2025 02:40:16 -0700 Subject: [PATCH 124/178] Update coverage to 7.10.5 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bdbafed3..d620751b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.10.1 +coverage==7.10.5 isort==6.0.1 ruff==0.12.7 From db7483d4c937c075ee3a8ba0fe58913b1d5e7f5c Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 28 Aug 2025 02:40:31 -0700 Subject: [PATCH 125/178] Update ruff to 0.12.10 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d620751b..754ea9a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.10.5 isort==6.0.1 -ruff==0.12.7 +ruff==0.12.10 From d6ff8ae18b5cdff58bbd6a478059d2a1294bbc79 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 13 Sep 2025 10:43:38 -0700 Subject: [PATCH 126/178] Update python dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 754ea9a6..adfed964 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.10.5 +coverage==7.10.6 isort==6.0.1 -ruff==0.12.10 +ruff==0.13.0 From 7d3d1afa7987371e3e3fe8890bbc01b08ad6b585 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 20 Sep 2025 21:54:25 -0700 Subject: [PATCH 127/178] Update ruff to 0.13.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index adfed964..f09ac989 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.10.6 isort==6.0.1 -ruff==0.13.0 +ruff==0.13.1 From 336cfe23a3f06880d864dbfed7a94bf86fc1dfdc Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 26 Sep 2025 02:56:10 -0700 Subject: [PATCH 128/178] Update coverage to 7.10.7 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f09ac989..a49d6ef9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -coverage==7.10.6 +coverage==7.10.7 isort==6.0.1 ruff==0.13.1 From 6c50ff5c149303ef14f720dbfdcc53a8a2ec600c Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 26 Sep 2025 02:56:51 -0700 Subject: [PATCH 129/178] Update ruff to 0.13.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a49d6ef9..bbc1c0d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.10.7 isort==6.0.1 -ruff==0.13.1 +ruff==0.13.2 From 49c79aa3e3b986ca68e257a74fbfb50383cb6e2e Mon Sep 17 00:00:00 2001 From: Gurpreet Kaur <140369686+Gurpreet0022@users.noreply.github.com> Date: Sun, 12 Oct 2025 08:16:42 +0530 Subject: [PATCH 130/178] Added resources for ML, Data Science, Interactive Practice, and Full Stack Python (#138) * Added github repositories to learn ML and Data Science , Added a section named Full Stack with Python in which mentioned a website to learn fullstack with python , Also added a practice website in interactive practice section * Update README.md * Update README.md --------- Co-authored-by: Samuel Huang --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index dde8ccf0..f9b21f64 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,9 @@ Keep learning by reading from other well-regarded resources. - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) ### Interactive practice @@ -165,3 +168,5 @@ Keep practicing so that your coding skills don't get rusty. - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) From fd75a5119e217d93cd859d4dde92146667ecc220 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 19:50:00 -0700 Subject: [PATCH 131/178] Add links back into other translations --- README.de.md | 9 +++++++-- README.es.md | 11 ++++++++--- README.hi.md | 5 +++++ README.ko.md | 9 +++++++-- README.zh_tw.md | 4 +++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/README.de.md b/README.de.md index 80d96e61..a73dbd04 100644 --- a/README.de.md +++ b/README.de.md @@ -130,8 +130,8 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: Lernen Sie weiter, indem Sie von anderen Quellen lesen. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) - [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) - [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) - [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) @@ -144,6 +144,9 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) ### Interaktive Übungen @@ -164,3 +167,5 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) diff --git a/README.es.md b/README.es.md index 54a03f9c..a7755674 100644 --- a/README.es.md +++ b/README.es.md @@ -129,11 +129,11 @@ Hay dos maneras de ejecutar los módulos: Sigue aprendiendo leyendo otros buenos recursos. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) - [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) - [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) -- [karan/Projects](https://github.com/karan/Projects) (🧠 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) - [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) - [vinta/awesome-python](https://github.com/vinta/awesome-python) - [academic/awesome-datascience](https://github.com/academic/awesome-datascience) @@ -143,6 +143,9 @@ Sigue aprendiendo leyendo otros buenos recursos. - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) ### Práctica interactiva @@ -163,3 +166,5 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) diff --git a/README.hi.md b/README.hi.md index 1b7b1cc7..d12c351b 100644 --- a/README.hi.md +++ b/README.hi.md @@ -127,6 +127,9 @@ print("Ultimate Python study guide") - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) ### इंटरैक्टिव प्रैक्टिस @@ -147,3 +150,5 @@ print("Ultimate Python study guide") - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) diff --git a/README.ko.md b/README.ko.md index cc5f28b9..f7be4e6c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -119,8 +119,8 @@ print("Ultimate Python 학습 가이드") 잘 알려진 다른 자료를 읽으면서 계속 배우세요. -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔, 🧪 ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔, 🧪 ) +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) - [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) - [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) - [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) @@ -133,6 +133,9 @@ print("Ultimate Python 학습 가이드") - [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) ### 대화형 연습 @@ -153,3 +156,5 @@ print("Ultimate Python 학습 가이드") - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) diff --git a/README.zh_tw.md b/README.zh_tw.md index c6475077..a0f12180 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -132,9 +132,9 @@ print("Ultimate Python 學習大綱") 繼續練習才能使您的編碼技能不會生疏。 -- [DevProjects](https://www.codementor.io/projects/python) - [codechef.com](https://www.codechef.com/) ( 👔 ) - [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( 🧠 ) - [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) - [codewars.com](https://www.codewars.com/) - [exercism.io](https://exercism.io/) @@ -147,3 +147,5 @@ print("Ultimate Python 學習大綱") - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) From 77f4613b3436b8d7237a3589dcd32a1045943bbb Mon Sep 17 00:00:00 2001 From: lmr lumiere <126115024+Lumiere-MULAGWA@users.noreply.github.com> Date: Sun, 12 Oct 2025 03:58:26 +0100 Subject: [PATCH 132/178] add a french documentation (#139) * add a french documentation * modify a function * Update function.py * Update function.py * Update function.py --------- Co-authored-by: Samuel Huang --- README.fr.md | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 README.fr.md diff --git a/README.fr.md b/README.fr.md new file mode 100644 index 00000000..60851d95 --- /dev/null +++ b/README.fr.md @@ -0,0 +1,176 @@ +# Guide d’étude Python ultime + +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) +[![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) +[![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) + +Guide d’étude Python ultime pour les débutants comme pour les professionnels. 🐍 🐍 🐍 + +```python +print("Guide d’étude Python ultime") +``` + +[English](README.md) | +[한국어](README.ko.md) | +[繁体中文](README.zh_tw.md) | +[Español](README.es.md) | +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) + +Ultimate Python + +## Motivation + +J’ai créé ce dépôt GitHub pour partager ce que j’ai appris sur le [cœur de Python](https://www.python.org/) +au cours de plus de 5 années d’utilisation — en tant que diplômé universitaire, employé +dans de grandes entreprises et contributeur open-source à des dépôts tels que +[Celery](https://github.com/celery/celery) et +[Full Stack Python](https://github.com/mattmakai/fullstackpython.com). +J’espère voir de plus en plus de personnes apprendre Python et poursuivre leurs passions +grâce à ce langage. 🎓 + +## Objectifs + +Voici les principaux objectifs de ce guide : + +🏆 **Servir de ressource** pour les débutants en Python qui préfèrent apprendre de manière pratique.  +Ce dépôt contient une collection de modules indépendants pouvant être exécutés dans un IDE +comme [PyCharm](https://www.jetbrains.com/pycharm/) ou dans le navigateur via +[Replit](https://replit.com/languages/python3). Même un simple terminal suffit +pour exécuter les exemples. La plupart des lignes contiennent des commentaires détaillés +qui guident le lecteur pas à pas.  +Les utilisateurs sont encouragés à modifier le code source à leur guise tant que les +routines `main` ne sont pas supprimées et que les programmes +[s’exécutent correctement](runner.py) après chaque modification. + +🏆 **Servir de guide pur** pour ceux qui souhaitent revoir les concepts fondamentaux de Python.  +Seules les [bibliothèques intégrées](https://docs.python.org/3/library/) sont utilisées afin de +présenter les concepts sans dépendre de notions spécifiques à un domaine. Ainsi, les +bibliothèques open-source populaires comme `sqlalchemy`, `requests` ou `pandas` +ne sont pas installées.  +Cependant, lire le code source de ces frameworks est fortement recommandé +si ton objectif est de devenir un véritable +[Pythonista](https://www.urbandictionary.com/define.php?term=pythonista). + +## Pour commencer + +[![Exécuter sur Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) + +Clique sur le badge ci-dessus pour lancer un environnement fonctionnel dans ton navigateur +sans avoir besoin d’installer Git ou Python localement.  +Si ces outils sont déjà installés, tu peux cloner directement le dépôt. + +Une fois le dépôt accessible, tu es prêt à apprendre à partir des modules indépendants.  +Pour tirer le meilleur parti de chaque module, lis le code et exécute-le. + +Deux méthodes sont possibles : + +1. Exécuter un seul module :  +  `python ultimatepython/syntax/variable.py` +2. Exécuter tous les modules :  +  `python runner.py` + +## Table des matières + +📚 = Ressource externe  +🍰 = Sujet débutant  +🤯 = Sujet avancé  + +1. **À propos de Python** +    - Vue d’ensemble : [Qu’est-ce que Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) +    - Philosophie : [Le Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) +    - Guide de style : [Guide de style du code Python](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) +    - Modèle de données : [Modèle de données](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) +    - Bibliothèque standard : [Bibliothèque standard Python](https://docs.python.org/3/library/) ( 📚, 🤯 ) +    - Fonctions intégrées : [Fonctions intégrées](https://docs.python.org/3/library/functions.html) ( 📚 ) + +2. **Syntaxe** +    - Variable : [Littéraux intégrés](ultimatepython/syntax/variable.py) ( 🍰 ) +    - Expression : [Opérations numériques](ultimatepython/syntax/expression.py) ( 🍰 ) +    - Opérateurs binaires : [Opérateurs binaires](ultimatepython/syntax/bitwise.py) ( 🍰 ), [Complément à un et à deux](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) +    - Conditionnelle : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) +    - Boucle : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) +    - Fonction : [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + +3. **Structures de données** +    - Liste : [Opérations sur les listes](ultimatepython/data_structures/list.py) ( 🍰 ) +    - Tuple : [Opérations sur les tuples](ultimatepython/data_structures/tuple.py) +    - Ensemble : [Opérations sur les ensembles](ultimatepython/data_structures/set.py) +    - Dictionnaire : [Opérations sur les dictionnaires](ultimatepython/data_structures/dict.py) ( 🍰 ) +    - Compréhension : [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) +    - Chaîne : [Opérations sur les chaînes](ultimatepython/data_structures/string.py) ( 🍰 ) +    - Deque : [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) +    - Namedtuple : [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) +    - Defaultdict : [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) +    - Complexité temporelle : [Opérations CPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) + +4. **Classes** +    - Classe basique : [Définition basique](ultimatepython/classes/basic_class.py) ( 🍰 ) +    - Héritage : [Héritage](ultimatepython/classes/inheritance.py) ( 🍰 ) +    - Classe abstraite : [Définition abstraite](ultimatepython/classes/abstract_class.py) +    - Classe d’exception : [Définition d’exception](ultimatepython/classes/exception_class.py) +    - Itérateur : [Définition d’itérateur | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) +    - Encapsulation : [Définition de l’encapsulation](ultimatepython/classes/encapsulation.py) + +5. **Avancé** +    - Décorateur : [Définition de décorateur | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) +    - Gestion de fichiers : [File Handling](ultimatepython/advanced/file_handling.py) ( 🤯 ) +    - Gestionnaire de contexte : [Context managers](ultimatepython/advanced/context_manager.py) ( 🤯 ) +    - Ordre de résolution des méthodes : [mro](ultimatepython/advanced/mro.py) ( 🤯 ) +    - Mixin : [Définition de Mixin](ultimatepython/advanced/mixin.py) ( 🤯 ) +    - Métaclasse : [Définition de métaclasse](ultimatepython/advanced/meta_class.py) ( 🤯 ) +    - Thread : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) +    - Asyncio : [async | await](ultimatepython/advanced/async.py) ( 🤯 ) +    - Référence faible : [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) +    - Benchmark : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) +    - Mocking : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) +    - Expressions régulières : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) +    - Format de données : [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) +    - Date et heure : [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + +## Ressources supplémentaires + +👔 = Ressource d’entretien  +🧪 = Exemples de code  +🧠 = Idées de projets  + +### Dépôts GitHub + +Continue d’apprendre grâce à ces ressources bien établies : + +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) +- [vinta/awesome-python](https://github.com/vinta/awesome-python) +- [academic/awesome-datascience](https://github.com/academic/awesome-datascience) +- [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) +- [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) +- [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) + +### Pratique interactive + +Continue à t’exercer pour ne pas perdre la main : + +- [codechef.com](https://www.codechef.com/) ( 👔 ) +- [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python) ( 🧪 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) +- [projecteuler.net](https://projecteuler.net/) +- [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) \ No newline at end of file From 3457d9d872ac33fc3e6546932276900c24d60262 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 20:01:17 -0700 Subject: [PATCH 133/178] Add new links back into French translation --- README.fr.md | 357 ++++++++++++++++++++++++++------------------------- 1 file changed, 181 insertions(+), 176 deletions(-) diff --git a/README.fr.md b/README.fr.md index 60851d95..9f1136c5 100644 --- a/README.fr.md +++ b/README.fr.md @@ -1,176 +1,181 @@ -# Guide d’étude Python ultime - -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) -[![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) -[![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) -[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) -[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) - -Guide d’étude Python ultime pour les débutants comme pour les professionnels. 🐍 🐍 🐍 - -```python -print("Guide d’étude Python ultime") -``` - -[English](README.md) | -[한국어](README.ko.md) | -[繁体中文](README.zh_tw.md) | -[Español](README.es.md) | -[Deutsch](README.de.md) | -[हिन्दी](README.hi.md) - -Ultimate Python - -## Motivation - -J’ai créé ce dépôt GitHub pour partager ce que j’ai appris sur le [cœur de Python](https://www.python.org/) -au cours de plus de 5 années d’utilisation — en tant que diplômé universitaire, employé -dans de grandes entreprises et contributeur open-source à des dépôts tels que -[Celery](https://github.com/celery/celery) et -[Full Stack Python](https://github.com/mattmakai/fullstackpython.com). -J’espère voir de plus en plus de personnes apprendre Python et poursuivre leurs passions -grâce à ce langage. 🎓 - -## Objectifs - -Voici les principaux objectifs de ce guide : - -🏆 **Servir de ressource** pour les débutants en Python qui préfèrent apprendre de manière pratique.  -Ce dépôt contient une collection de modules indépendants pouvant être exécutés dans un IDE -comme [PyCharm](https://www.jetbrains.com/pycharm/) ou dans le navigateur via -[Replit](https://replit.com/languages/python3). Même un simple terminal suffit -pour exécuter les exemples. La plupart des lignes contiennent des commentaires détaillés -qui guident le lecteur pas à pas.  -Les utilisateurs sont encouragés à modifier le code source à leur guise tant que les -routines `main` ne sont pas supprimées et que les programmes -[s’exécutent correctement](runner.py) après chaque modification. - -🏆 **Servir de guide pur** pour ceux qui souhaitent revoir les concepts fondamentaux de Python.  -Seules les [bibliothèques intégrées](https://docs.python.org/3/library/) sont utilisées afin de -présenter les concepts sans dépendre de notions spécifiques à un domaine. Ainsi, les -bibliothèques open-source populaires comme `sqlalchemy`, `requests` ou `pandas` -ne sont pas installées.  -Cependant, lire le code source de ces frameworks est fortement recommandé -si ton objectif est de devenir un véritable -[Pythonista](https://www.urbandictionary.com/define.php?term=pythonista). - -## Pour commencer - -[![Exécuter sur Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) - -Clique sur le badge ci-dessus pour lancer un environnement fonctionnel dans ton navigateur -sans avoir besoin d’installer Git ou Python localement.  -Si ces outils sont déjà installés, tu peux cloner directement le dépôt. - -Une fois le dépôt accessible, tu es prêt à apprendre à partir des modules indépendants.  -Pour tirer le meilleur parti de chaque module, lis le code et exécute-le. - -Deux méthodes sont possibles : - -1. Exécuter un seul module :  -  `python ultimatepython/syntax/variable.py` -2. Exécuter tous les modules :  -  `python runner.py` - -## Table des matières - -📚 = Ressource externe  -🍰 = Sujet débutant  -🤯 = Sujet avancé  - -1. **À propos de Python** -    - Vue d’ensemble : [Qu’est-ce que Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) -    - Philosophie : [Le Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) -    - Guide de style : [Guide de style du code Python](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) -    - Modèle de données : [Modèle de données](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) -    - Bibliothèque standard : [Bibliothèque standard Python](https://docs.python.org/3/library/) ( 📚, 🤯 ) -    - Fonctions intégrées : [Fonctions intégrées](https://docs.python.org/3/library/functions.html) ( 📚 ) - -2. **Syntaxe** -    - Variable : [Littéraux intégrés](ultimatepython/syntax/variable.py) ( 🍰 ) -    - Expression : [Opérations numériques](ultimatepython/syntax/expression.py) ( 🍰 ) -    - Opérateurs binaires : [Opérateurs binaires](ultimatepython/syntax/bitwise.py) ( 🍰 ), [Complément à un et à deux](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) -    - Conditionnelle : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) -    - Boucle : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) -    - Fonction : [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) - -3. **Structures de données** -    - Liste : [Opérations sur les listes](ultimatepython/data_structures/list.py) ( 🍰 ) -    - Tuple : [Opérations sur les tuples](ultimatepython/data_structures/tuple.py) -    - Ensemble : [Opérations sur les ensembles](ultimatepython/data_structures/set.py) -    - Dictionnaire : [Opérations sur les dictionnaires](ultimatepython/data_structures/dict.py) ( 🍰 ) -    - Compréhension : [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) -    - Chaîne : [Opérations sur les chaînes](ultimatepython/data_structures/string.py) ( 🍰 ) -    - Deque : [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) -    - Namedtuple : [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) -    - Defaultdict : [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) -    - Complexité temporelle : [Opérations CPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) - -4. **Classes** -    - Classe basique : [Définition basique](ultimatepython/classes/basic_class.py) ( 🍰 ) -    - Héritage : [Héritage](ultimatepython/classes/inheritance.py) ( 🍰 ) -    - Classe abstraite : [Définition abstraite](ultimatepython/classes/abstract_class.py) -    - Classe d’exception : [Définition d’exception](ultimatepython/classes/exception_class.py) -    - Itérateur : [Définition d’itérateur | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) -    - Encapsulation : [Définition de l’encapsulation](ultimatepython/classes/encapsulation.py) - -5. **Avancé** -    - Décorateur : [Définition de décorateur | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) -    - Gestion de fichiers : [File Handling](ultimatepython/advanced/file_handling.py) ( 🤯 ) -    - Gestionnaire de contexte : [Context managers](ultimatepython/advanced/context_manager.py) ( 🤯 ) -    - Ordre de résolution des méthodes : [mro](ultimatepython/advanced/mro.py) ( 🤯 ) -    - Mixin : [Définition de Mixin](ultimatepython/advanced/mixin.py) ( 🤯 ) -    - Métaclasse : [Définition de métaclasse](ultimatepython/advanced/meta_class.py) ( 🤯 ) -    - Thread : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) -    - Asyncio : [async | await](ultimatepython/advanced/async.py) ( 🤯 ) -    - Référence faible : [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) -    - Benchmark : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) -    - Mocking : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) -    - Expressions régulières : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) -    - Format de données : [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) -    - Date et heure : [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) - -## Ressources supplémentaires - -👔 = Ressource d’entretien  -🧪 = Exemples de code  -🧠 = Idées de projets  - -### Dépôts GitHub - -Continue d’apprendre grâce à ces ressources bien établies : - -- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) -- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) -- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) -- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) -- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) -- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) -- [vinta/awesome-python](https://github.com/vinta/awesome-python) -- [academic/awesome-datascience](https://github.com/academic/awesome-datascience) -- [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) -- [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) -- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) -- [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) -- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) -- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) - -### Pratique interactive - -Continue à t’exercer pour ne pas perdre la main : - -- [codechef.com](https://www.codechef.com/) ( 👔 ) -- [codeforces.com](https://codeforces.com/) -- [codementor.io](https://www.codementor.io) ( 🧠 ) -- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) -- [codewars.com](https://www.codewars.com/) -- [exercism.io](https://exercism.io/) -- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) -- [hackerearth.com](https://www.hackerearth.com/) -- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) -- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) -- [labex.io](https://labex.io/exercises/python) ( 🧪 ) -- [leetcode.com](https://leetcode.com/) ( 👔 ) -- [projecteuler.net](https://projecteuler.net/) -- [replit.com](https://replit.com/) -- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) \ No newline at end of file +# Guide d’étude Python ultime + +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) +[![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) +[![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) + +Guide d’étude Python ultime pour les débutants comme pour les professionnels. 🐍 🐍 🐍 + +```python +print("Guide d’étude Python ultime") +``` + +[English](README.md) | +[한국어](README.ko.md) | +[繁体中文](README.zh_tw.md) | +[Español](README.es.md) | +[Deutsch](README.de.md) | +[हिन्दी](README.hi.md) + +Ultimate Python + +## Motivation + +J’ai créé ce dépôt GitHub pour partager ce que j’ai appris sur le [cœur de Python](https://www.python.org/) +au cours de plus de 5 années d’utilisation — en tant que diplômé universitaire, employé +dans de grandes entreprises et contributeur open-source à des dépôts tels que +[Celery](https://github.com/celery/celery) et +[Full Stack Python](https://github.com/mattmakai/fullstackpython.com). +J’espère voir de plus en plus de personnes apprendre Python et poursuivre leurs passions +grâce à ce langage. 🎓 + +## Objectifs + +Voici les principaux objectifs de ce guide : + +🏆 **Servir de ressource** pour les débutants en Python qui préfèrent apprendre de manière pratique.  +Ce dépôt contient une collection de modules indépendants pouvant être exécutés dans un IDE +comme [PyCharm](https://www.jetbrains.com/pycharm/) ou dans le navigateur via +[Replit](https://replit.com/languages/python3). Même un simple terminal suffit +pour exécuter les exemples. La plupart des lignes contiennent des commentaires détaillés +qui guident le lecteur pas à pas.  +Les utilisateurs sont encouragés à modifier le code source à leur guise tant que les +routines `main` ne sont pas supprimées et que les programmes +[s’exécutent correctement](runner.py) après chaque modification. + +🏆 **Servir de guide pur** pour ceux qui souhaitent revoir les concepts fondamentaux de Python.  +Seules les [bibliothèques intégrées](https://docs.python.org/3/library/) sont utilisées afin de +présenter les concepts sans dépendre de notions spécifiques à un domaine. Ainsi, les +bibliothèques open-source populaires comme `sqlalchemy`, `requests` ou `pandas` +ne sont pas installées.  +Cependant, lire le code source de ces frameworks est fortement recommandé +si ton objectif est de devenir un véritable +[Pythonista](https://www.urbandictionary.com/define.php?term=pythonista). + +## Pour commencer + +[![Exécuter sur Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) + +Clique sur le badge ci-dessus pour lancer un environnement fonctionnel dans ton navigateur +sans avoir besoin d’installer Git ou Python localement.  +Si ces outils sont déjà installés, tu peux cloner directement le dépôt. + +Une fois le dépôt accessible, tu es prêt à apprendre à partir des modules indépendants.  +Pour tirer le meilleur parti de chaque module, lis le code et exécute-le. + +Deux méthodes sont possibles : + +1. Exécuter un seul module :  +  `python ultimatepython/syntax/variable.py` +2. Exécuter tous les modules :  +  `python runner.py` + +## Table des matières + +📚 = Ressource externe  +🍰 = Sujet débutant  +🤯 = Sujet avancé  + +1. **À propos de Python** +    - Vue d’ensemble : [Qu’est-ce que Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) +    - Philosophie : [Le Zen de Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) +    - Guide de style : [Guide de style du code Python](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) +    - Modèle de données : [Modèle de données](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) +    - Bibliothèque standard : [Bibliothèque standard Python](https://docs.python.org/3/library/) ( 📚, 🤯 ) +    - Fonctions intégrées : [Fonctions intégrées](https://docs.python.org/3/library/functions.html) ( 📚 ) + +2. **Syntaxe** +    - Variable : [Littéraux intégrés](ultimatepython/syntax/variable.py) ( 🍰 ) +    - Expression : [Opérations numériques](ultimatepython/syntax/expression.py) ( 🍰 ) +    - Opérateurs binaires : [Opérateurs binaires](ultimatepython/syntax/bitwise.py) ( 🍰 ), [Complément à un et à deux](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) +    - Conditionnelle : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) +    - Boucle : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) +    - Fonction : [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + +3. **Structures de données** +    - Liste : [Opérations sur les listes](ultimatepython/data_structures/list.py) ( 🍰 ) +    - Tuple : [Opérations sur les tuples](ultimatepython/data_structures/tuple.py) +    - Ensemble : [Opérations sur les ensembles](ultimatepython/data_structures/set.py) +    - Dictionnaire : [Opérations sur les dictionnaires](ultimatepython/data_structures/dict.py) ( 🍰 ) +    - Compréhension : [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) +    - Chaîne : [Opérations sur les chaînes](ultimatepython/data_structures/string.py) ( 🍰 ) +    - Deque : [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) +    - Namedtuple : [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) +    - Defaultdict : [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) +    - Complexité temporelle : [Opérations CPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) + +4. **Classes** +    - Classe basique : [Définition basique](ultimatepython/classes/basic_class.py) ( 🍰 ) +    - Héritage : [Héritage](ultimatepython/classes/inheritance.py) ( 🍰 ) +    - Classe abstraite : [Définition abstraite](ultimatepython/classes/abstract_class.py) +    - Classe d’exception : [Définition d’exception](ultimatepython/classes/exception_class.py) +    - Itérateur : [Définition d’itérateur | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) +    - Encapsulation : [Définition de l’encapsulation](ultimatepython/classes/encapsulation.py) + +5. **Avancé** +    - Décorateur : [Définition de décorateur | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) +    - Gestion de fichiers : [File Handling](ultimatepython/advanced/file_handling.py) ( 🤯 ) +    - Gestionnaire de contexte : [Context managers](ultimatepython/advanced/context_manager.py) ( 🤯 ) +    - Ordre de résolution des méthodes : [mro](ultimatepython/advanced/mro.py) ( 🤯 ) +    - Mixin : [Définition de Mixin](ultimatepython/advanced/mixin.py) ( 🤯 ) +    - Métaclasse : [Définition de métaclasse](ultimatepython/advanced/meta_class.py) ( 🤯 ) +    - Thread : [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) +    - Asyncio : [async | await](ultimatepython/advanced/async.py) ( 🤯 ) +    - Référence faible : [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) +    - Benchmark : [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) +    - Mocking : [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) +    - Expressions régulières : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) +    - Format de données : [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) +    - Date et heure : [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + +## Ressources supplémentaires + +👔 = Ressource d’entretien  +🧪 = Exemples de code  +🧠 = Idées de projets  + +### Dépôts GitHub + +Continue d’apprendre grâce à ces ressources bien établies : + +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) +- [vinta/awesome-python](https://github.com/vinta/awesome-python) +- [academic/awesome-datascience](https://github.com/academic/awesome-datascience) +- [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) +- [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) +- [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) + +### Pratique interactive + +Continue à t’exercer pour ne pas perdre la main : + +- [codechef.com](https://www.codechef.com/) ( 👔 ) +- [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) +- [projecteuler.net](https://projecteuler.net/) +- [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) From 96fb844b6c5ad667c2528a5d35d5e9bb9aaae42b Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 20:03:08 -0700 Subject: [PATCH 134/178] Add backref to French in all README files --- README.de.md | 1 + README.es.md | 1 + README.fr.md | 1 + README.hi.md | 1 + README.ko.md | 1 + README.md | 3 ++- README.zh_tw.md | 1 + 7 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.de.md b/README.de.md index a73dbd04..d03f2eff 100644 --- a/README.de.md +++ b/README.de.md @@ -17,6 +17,7 @@ print("Ultimativer Python-Lernführer") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python diff --git a/README.es.md b/README.es.md index a7755674..e0025fd7 100644 --- a/README.es.md +++ b/README.es.md @@ -17,6 +17,7 @@ print("Guía de estudio 'Python Definitivo'") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python diff --git a/README.fr.md b/README.fr.md index 9f1136c5..a940b449 100644 --- a/README.fr.md +++ b/README.fr.md @@ -17,6 +17,7 @@ print("Guide d’étude Python ultime") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python diff --git a/README.hi.md b/README.hi.md index d12c351b..73058e8b 100644 --- a/README.hi.md +++ b/README.hi.md @@ -17,6 +17,7 @@ print("Ultimate Python study guide") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python diff --git a/README.ko.md b/README.ko.md index f7be4e6c..37f923bf 100644 --- a/README.ko.md +++ b/README.ko.md @@ -17,6 +17,7 @@ print("Ultimate Python 학습 가이드") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python diff --git a/README.md b/README.md index f9b21f64..b1c9d7ef 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ print("Ultimate Python study guide") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python @@ -168,5 +169,5 @@ Keep practicing so that your coding skills don't get rusty. - [projecteuler.net](https://projecteuler.net/) - [replit.com](https://replit.com/) - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) -- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) diff --git a/README.zh_tw.md b/README.zh_tw.md index a0f12180..c69391dd 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -17,6 +17,7 @@ print("Ultimate Python 學習大綱") [繁体中文](README.zh_tw.md) | [Español](README.es.md) | [Deutsch](README.de.md) | +[Français](README.fr.md) | [हिन्दी](README.hi.md) Ultimate Python From fce21184752e4d1140c69fdcd6a601b0c687de07 Mon Sep 17 00:00:00 2001 From: lmr lumiere <126115024+Lumiere-MULAGWA@users.noreply.github.com> Date: Sun, 12 Oct 2025 04:10:17 +0100 Subject: [PATCH 135/178] function (#140) * add a french documentation * modify a function * Delete README.fr.md * Update function.py * Update function.py * Update function.py --------- Co-authored-by: Samuel Huang --- ultimatepython/syntax/function.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ultimatepython/syntax/function.py b/ultimatepython/syntax/function.py index 141c9b46..ef47b01a 100644 --- a/ultimatepython/syntax/function.py +++ b/ultimatepython/syntax/function.py @@ -33,6 +33,16 @@ def sum_until(fn, n): return total +def without_parameters(): + """A function that does not accept parameters and does not return a value.""" + pass + + +def sum(x: int, y: int) -> int: + """A function that accepts parameters and has type hints.""" + return x + y + + def main(): # The `add` function can be used for numbers as expected add_result_int = add(1, 2) @@ -54,6 +64,10 @@ def main(): # attribute! Remember this - everything in Python is an object assert "includes this docstring!" in sum_until.__doc__ + # Call a few more functions to show that they are valid + assert without_parameters() is None + assert sum(1, 2) == 3 + if __name__ == "__main__": main() From 782d566e3aee11acff90a563f6b3a0f9959c4fdd Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 20:23:44 -0700 Subject: [PATCH 136/178] Add AGENTS.md to empower LLMs --- AGENTS.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..b497c7a9 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,51 @@ +## Quick orientation for AI coding agents + +This repository is a hands-on, runnable "Ultimate Python" study guide composed of many small, standalone example modules under `ultimatepython/` grouped by topic (syntax, data_structures, classes, advanced). The goal for any change is to keep examples readable and runnable by humans and by the provided runner. + +Key facts an agent must know (short): + +- The runner: `runner.py` dynamically imports every module under `ultimatepython` and runs any callable named `main` with zero parameters. Keep `main()` functions parameterless, idempotent, and side-effect safe for CI. +- Single-file runs are supported: modules are runnable with `python ultimatepython//.py`. Most modules already include `if __name__ == "__main__": main()`. +- Examples use plain Python stdlib only. Avoid adding new third-party dependencies without updating `requirements.txt` and `pyproject.toml`. +- Assertions are used as the primary verification mechanism inside examples (not pytest tests). Preserve their intent and messages when editing. + +Patterns and conventions to follow + +- main() contract: must be a function, accept zero parameters, and not raise exceptions when run. The runner asserts the function is callable and has zero parameters. Example: `ultimatepython/syntax/function.py` and `ultimatepython/classes/basic_class.py`. +- Module structure: brief module docstring, helper functions/classes, then `main()` demonstrating usage via asserts, and final `if __name__ == "__main__": main()`. +- Avoid long-running or destructive operations in examples. If a module interacts with the filesystem (e.g., `advanced/file_handling.py`), keep operations local to ephemeral files (module uses `_TARGET_FILE = "sample.txt"`), and clean up after running. +- Typing: some modules include simple type hints; prefer to keep existing style and minimal typing additions only. +- Formatting & linting: the repo uses `ruff` and `isort` settings in `pyproject.toml`. Try to keep line-length <= 160 and maintain import ordering consistent with isort defaults. + +Developer workflows and useful commands + +- Run all examples locally (fast smoke): + + python runner.py + +- Run a single example (recommended when editing): + + python ultimatepython/syntax/function.py + +- Check formatting/linting (ruff/isort configured in `pyproject.toml`): run your local ruff/isort commands or CI. +- Coverage config exists in `pyproject.toml` (coverage fail_under=80). The examples use assertions; running `runner.py` is a good quick coverage smoke. + +Integration points & CI notes + +- CI expects that running `runner.py` and executing each `main()` will succeed. Avoid adding code that requires network access, long sleeps, or interactive input. +- Do not introduce external services or config files; this repo intentionally uses only the Python standard library. + +When creating or modifying modules + +- Preserve the didactic nature: keep explanatory comments and short, clear examples. +- If you add new modules, include them under the appropriate folder and follow the same pattern (module docstring, helpers, `main()`, `if __name__...`). The runner will pick them up automatically. +- If a change requires a new dependency, add it to `requirements.txt` and update `pyproject.toml` before proposing a PR. + +Files and locations of interest (examples to inspect) + +- `runner.py` — how modules are discovered and executed (pkgutil.walk_packages + `main` lookups). +- `ultimatepython/syntax/*.py` — simple, illustrative examples of the `main()` pattern. +- `ultimatepython/advanced/*` — more involved examples; watch for filesystem or concurrency code (e.g., `advanced/file_handling.py`, `advanced/async.py`). +- `pyproject.toml` — linting/format settings and coverage rules. + +If anything in these instructions is unclear or you want additional examples (CI commands, recommended local dev Docker container, or a tiny unit-test harness), tell me which areas to expand and I'll iterate. From ac471aaad3cb2d5a6d077045569867947f047bc8 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 20:31:25 -0700 Subject: [PATCH 137/178] Update AGENTS.md with context about docs --- AGENTS.md | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b497c7a9..e4efa791 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,15 +1,13 @@ -## Quick orientation for AI coding agents +# Quick orientation for AI coding agents -This repository is a hands-on, runnable "Ultimate Python" study guide composed of many small, standalone example modules under `ultimatepython/` grouped by topic (syntax, data_structures, classes, advanced). The goal for any change is to keep examples readable and runnable by humans and by the provided runner. - -Key facts an agent must know (short): +## Key facts an agent must know (short): - The runner: `runner.py` dynamically imports every module under `ultimatepython` and runs any callable named `main` with zero parameters. Keep `main()` functions parameterless, idempotent, and side-effect safe for CI. - Single-file runs are supported: modules are runnable with `python ultimatepython//.py`. Most modules already include `if __name__ == "__main__": main()`. - Examples use plain Python stdlib only. Avoid adding new third-party dependencies without updating `requirements.txt` and `pyproject.toml`. - Assertions are used as the primary verification mechanism inside examples (not pytest tests). Preserve their intent and messages when editing. -Patterns and conventions to follow +## Patterns and conventions to follow - main() contract: must be a function, accept zero parameters, and not raise exceptions when run. The runner asserts the function is callable and has zero parameters. Example: `ultimatepython/syntax/function.py` and `ultimatepython/classes/basic_class.py`. - Module structure: brief module docstring, helper functions/classes, then `main()` demonstrating usage via asserts, and final `if __name__ == "__main__": main()`. @@ -17,31 +15,40 @@ Patterns and conventions to follow - Typing: some modules include simple type hints; prefer to keep existing style and minimal typing additions only. - Formatting & linting: the repo uses `ruff` and `isort` settings in `pyproject.toml`. Try to keep line-length <= 160 and maintain import ordering consistent with isort defaults. -Developer workflows and useful commands +## When creating or modifying modules + +- Preserve the didactic nature: keep explanatory comments and short, clear examples. +- If you add new modules, include them under the appropriate folder and follow the same pattern (module docstring, helpers, `main()`, `if __name__...`). The runner will pick them up automatically. +- If a change requires a new dependency, add it to `requirements.txt` and update `pyproject.toml` before proposing a PR. + +## Top-level README files + +- The top-level `README.md` is the primary project landing page: it explains the repo goals, running instructions, and links to example modules (it also shows badges for CI and coverage). When changing top-level documentation, keep the runner guidance intact (it points to `runner.py`) and preserve any badges and links. +- Translated files like `README.ko.md`, `README.zh_tw.md`, `README.es.md`, `README.de.md`, `README.fr.md`, and `README.hi.md` are language variants of the same content. If you update the English `README.md`, consider updating translations or add a brief note in the PR explaining why translations were not updated. + +## Developer workflows and useful commands - Run all examples locally (fast smoke): - python runner.py +```bash +python runner.py +``` - Run a single example (recommended when editing): - python ultimatepython/syntax/function.py +```bash +python ultimatepython/syntax/function.py +``` - Check formatting/linting (ruff/isort configured in `pyproject.toml`): run your local ruff/isort commands or CI. - Coverage config exists in `pyproject.toml` (coverage fail_under=80). The examples use assertions; running `runner.py` is a good quick coverage smoke. -Integration points & CI notes +## Integration points & CI notes - CI expects that running `runner.py` and executing each `main()` will succeed. Avoid adding code that requires network access, long sleeps, or interactive input. - Do not introduce external services or config files; this repo intentionally uses only the Python standard library. -When creating or modifying modules - -- Preserve the didactic nature: keep explanatory comments and short, clear examples. -- If you add new modules, include them under the appropriate folder and follow the same pattern (module docstring, helpers, `main()`, `if __name__...`). The runner will pick them up automatically. -- If a change requires a new dependency, add it to `requirements.txt` and update `pyproject.toml` before proposing a PR. - -Files and locations of interest (examples to inspect) +## Files and locations of interest (examples to inspect) - `runner.py` — how modules are discovered and executed (pkgutil.walk_packages + `main` lookups). - `ultimatepython/syntax/*.py` — simple, illustrative examples of the `main()` pattern. From df415fecb382253d7dcb1797b77f82acc2eb2771 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 20:34:35 -0700 Subject: [PATCH 138/178] Apply formatting to all Python modules --- ultimatepython/advanced/async.py | 1 + ultimatepython/advanced/benchmark.py | 4 ++-- ultimatepython/advanced/context_manager.py | 1 + ultimatepython/advanced/data_format.py | 9 +++------ ultimatepython/advanced/date_time.py | 1 + ultimatepython/advanced/decorator.py | 1 + ultimatepython/advanced/file_handling.py | 1 + ultimatepython/advanced/meta_class.py | 13 ++++++------- ultimatepython/advanced/mixin.py | 12 ++++++------ ultimatepython/advanced/mocking.py | 1 + ultimatepython/advanced/mro.py | 15 ++++----------- ultimatepython/advanced/regex.py | 1 + ultimatepython/advanced/thread.py | 1 + ultimatepython/advanced/weak_ref.py | 5 ++--- ultimatepython/classes/abstract_class.py | 1 + ultimatepython/classes/basic_class.py | 1 + ultimatepython/classes/encapsulation.py | 1 + ultimatepython/classes/inheritance.py | 1 + ultimatepython/classes/iterator_class.py | 5 +---- ultimatepython/data_structures/comprehension.py | 5 +---- ultimatepython/data_structures/deque.py | 1 + ultimatepython/data_structures/dict.py | 6 ++---- ultimatepython/data_structures/namedtuple.py | 1 + ultimatepython/syntax/bitwise.py | 4 ++-- ultimatepython/syntax/conditional.py | 2 +- ultimatepython/syntax/expression.py | 3 ++- ultimatepython/syntax/variable.py | 1 + 27 files changed, 47 insertions(+), 51 deletions(-) diff --git a/ultimatepython/advanced/async.py b/ultimatepython/advanced/async.py index e52b739a..ea324a83 100644 --- a/ultimatepython/advanced/async.py +++ b/ultimatepython/advanced/async.py @@ -6,6 +6,7 @@ hit an API endpoint, ask the operating system for resources) so we assume that starting a job has some intrinsic delay. """ + import asyncio from dataclasses import dataclass from datetime import datetime diff --git a/ultimatepython/advanced/benchmark.py b/ultimatepython/advanced/benchmark.py index d33195fd..0c8a8e58 100644 --- a/ultimatepython/advanced/benchmark.py +++ b/ultimatepython/advanced/benchmark.py @@ -5,6 +5,7 @@ and their code intuition to optimize programs further. This module uses cProfile to compare the performance of two functions with each other. """ + import cProfile import io import pstats @@ -54,8 +55,7 @@ def main(): # large projects. Consider profiling in isolation when analyzing complex # classes and functions ps.print_stats() - time_sleep_called = any("60" in line and "time.sleep" in line - for line in buffer.getvalue().split("\n")) + time_sleep_called = any("60" in line and "time.sleep" in line for line in buffer.getvalue().split("\n")) assert time_sleep_called is True diff --git a/ultimatepython/advanced/context_manager.py b/ultimatepython/advanced/context_manager.py index 4467fb35..5abcef6d 100644 --- a/ultimatepython/advanced/context_manager.py +++ b/ultimatepython/advanced/context_manager.py @@ -5,6 +5,7 @@ we simulate how a context manager can handle open and close operations of a file-like object called StringIO. """ + from contextlib import contextmanager from io import StringIO diff --git a/ultimatepython/advanced/data_format.py b/ultimatepython/advanced/data_format.py index bfd0800c..33133062 100644 --- a/ultimatepython/advanced/data_format.py +++ b/ultimatepython/advanced/data_format.py @@ -3,6 +3,7 @@ converting data to serialized objects for further analysis. This module shows how to parse and process these data formats: JSON, XML and CSV. """ + import json from csv import DictReader from dataclasses import dataclass, fields @@ -59,6 +60,7 @@ class Note: associated with them. To streamline the creation and comparison of these records, we define an in-memory model of what it is. """ + author: str title: str body: str @@ -84,12 +86,7 @@ def main(): # Let's use `ElementTree.parse` to parse note data from a XML file # https://docs.python.org/3/library/xml.html tree = ETree.parse(StringIO(_XML_DATA)) - xml_notes = [ - Note.from_data({ - field: note_el.findtext(field) - for field in Note.fields() - }) for note_el in tree.getroot() - ] + xml_notes = [Note.from_data({field: note_el.findtext(field) for field in Note.fields()}) for note_el in tree.getroot()] assert all(isinstance(note, Note) for note in xml_notes) # Let's use `csv.DictReader` to parse note data from a CSV file diff --git a/ultimatepython/advanced/date_time.py b/ultimatepython/advanced/date_time.py index dd65e11b..c70453ce 100644 --- a/ultimatepython/advanced/date_time.py +++ b/ultimatepython/advanced/date_time.py @@ -22,6 +22,7 @@ UTC timezone and show how it can be used to make the default `datetime` object more powerful. """ + from datetime import datetime, timezone diff --git a/ultimatepython/advanced/decorator.py b/ultimatepython/advanced/decorator.py index a4bd00bc..5527140b 100644 --- a/ultimatepython/advanced/decorator.py +++ b/ultimatepython/advanced/decorator.py @@ -4,6 +4,7 @@ be decorated to work with a collection of strings. Note that the decorator handles nested collections with the use of recursion. """ + from functools import wraps # Module-level constants diff --git a/ultimatepython/advanced/file_handling.py b/ultimatepython/advanced/file_handling.py index 98ab9102..c3a0cd39 100644 --- a/ultimatepython/advanced/file_handling.py +++ b/ultimatepython/advanced/file_handling.py @@ -7,6 +7,7 @@ builtin 'open' function to open files in different modes like reading ('r'), writing ('w'), and appending ('a'). """ + import os _TARGET_FILE = "sample.txt" diff --git a/ultimatepython/advanced/meta_class.py b/ultimatepython/advanced/meta_class.py index de087b6f..da49f6c6 100644 --- a/ultimatepython/advanced/meta_class.py +++ b/ultimatepython/advanced/meta_class.py @@ -3,6 +3,7 @@ This module shows how a metaclass can add database attributes and tables to "logic-free" model classes for the developer. """ + from abc import ABC @@ -66,11 +67,7 @@ def __new__(mcs, name, bases, attrs): kls.model_fields.update(base.model_fields) # Fill model fields from itself - kls.model_fields.update({ - field_name: field_obj - for field_name, field_obj in attrs.items() - if isinstance(field_obj, BaseField) - }) + kls.model_fields.update({field_name: field_obj for field_name, field_obj in attrs.items() if isinstance(field_obj, BaseField)}) # Register a real table (a table with valid `model_name`) to # the metaclass `table` registry. After all the tables are @@ -121,12 +118,14 @@ class BaseModel(metaclass=ModelMeta): In short, think of a metaclass as the creator of classes. This is very similar to how classes are the creator of instances. """ + __abstract__ = True # This is NOT a real table row_id = IntegerField() class UserModel(BaseModel): """User model.""" + __table_name__ = "user_rocks" # This is a custom table name username = CharField() password = CharField() @@ -136,6 +135,7 @@ class UserModel(BaseModel): class AddressModel(BaseModel): """Address model.""" + user_id = IntegerField() address = CharField() state = CharField() @@ -168,8 +168,7 @@ def main(): # Every model is created by `ModelMeta` assert isinstance(BaseModel, ModelMeta) - assert all(isinstance(model, ModelMeta) - for model in BaseModel.__subclasses__()) + assert all(isinstance(model, ModelMeta) for model in BaseModel.__subclasses__()) # And `ModelMeta` is created by `type` assert isinstance(ModelMeta, type) diff --git a/ultimatepython/advanced/mixin.py b/ultimatepython/advanced/mixin.py index 7d417a07..0f7b1174 100644 --- a/ultimatepython/advanced/mixin.py +++ b/ultimatepython/advanced/mixin.py @@ -5,6 +5,7 @@ mixins to illustrate how mixins can make our lives easier when defining concrete classes. """ + from abc import ABC, abstractmethod from dataclasses import dataclass @@ -16,6 +17,7 @@ class Request: Assumes only GET requests for simplicity so there is no method attribute associated with this class. """ + url: str user: str @@ -48,6 +50,7 @@ class TemplateHandlerMixin(RequestHandler): class helps if downstream developers typically implement request handlers that retrieve template content. """ + template_suffix = ".template" def handle(self, request): @@ -118,8 +121,7 @@ def get_template_name(self, request_url): return request_url[1:] def is_valid_template(self, template_name): - return (super().is_valid_template(template_name) - and template_name in self.template_dir) + return super().is_valid_template(template_name) and template_name in self.template_dir def render_template(self, template_name): return self.template_dir[template_name] @@ -143,8 +145,7 @@ def is_valid_user(self, request_user): def main(): # Handle requests with simple template handler - simple_dir = {"welcome.template": "

Hello world

", - "about.template": "

About me

"} + simple_dir = {"welcome.template": "

Hello world

", "about.template": "

About me

"} simple_handler = TemplateFolderHandler(simple_dir) welcome_from_nobody = Request("/welcome.template", "nobody") about_from_nobody = Request("/about.template", "nobody") @@ -155,8 +156,7 @@ def main(): # Handle requests with admin template handler admin_users = {"john", "jane"} - admin_dir = {"fqdn.template": "

server.example.com

", - "salary.template": "

123456789.00

"} + admin_dir = {"fqdn.template": "

server.example.com

", "salary.template": "

123456789.00

"} admin_handler = AdminTemplateHandler(admin_users, admin_dir) fqdn_from_john = Request("/fqdn.template", "john") salary_from_jane = Request("/salary.template", "jane") diff --git a/ultimatepython/advanced/mocking.py b/ultimatepython/advanced/mocking.py index 46fd2f71..8cef4e41 100644 --- a/ultimatepython/advanced/mocking.py +++ b/ultimatepython/advanced/mocking.py @@ -4,6 +4,7 @@ properly. This module shows how to use mocking to modify an application server so that it is easier to test. """ + from collections import Counter from unittest.mock import MagicMock, PropertyMock, patch diff --git a/ultimatepython/advanced/mro.py b/ultimatepython/advanced/mro.py index 36f3a11e..46f85c5b 100644 --- a/ultimatepython/advanced/mro.py +++ b/ultimatepython/advanced/mro.py @@ -49,12 +49,7 @@ def ping(self): def ping_pong(self): """Run `ping` and `pong` in different ways.""" - return [ - self.ping(), - super().ping(), - self.pong(), - super().pong() - ] + return [self.ping(), super().ping(), self.pong(), super().pong()] class IndecisivePlayer(NeutralPlayer, PongPlayer): @@ -78,18 +73,16 @@ def ping_pong(self): self.ping(), super().ping(), self.pong(), - super(PongPlayer, self).pong() # bypass MRO to `BasePlayer` + super(PongPlayer, self).pong(), # bypass MRO to `BasePlayer` ] def main(): # `ConfusedPlayer` methods are resolved from child to parent like this - assert ConfusedPlayer.mro() == [ - ConfusedPlayer, PongPlayer, NeutralPlayer, BasePlayer, object] + assert ConfusedPlayer.mro() == [ConfusedPlayer, PongPlayer, NeutralPlayer, BasePlayer, object] # `IndecisivePlayer` methods are resolved from child to parent like this - assert IndecisivePlayer.mro() == [ - IndecisivePlayer, NeutralPlayer, PongPlayer, BasePlayer, object] + assert IndecisivePlayer.mro() == [IndecisivePlayer, NeutralPlayer, PongPlayer, BasePlayer, object] # Show `ConfusedPlayer` method resolution in action assert ConfusedPlayer().ping_pong() == ["pINg", "ping", "PONG", "PONG"] diff --git a/ultimatepython/advanced/regex.py b/ultimatepython/advanced/regex.py index 28584c3c..365ad861 100644 --- a/ultimatepython/advanced/regex.py +++ b/ultimatepython/advanced/regex.py @@ -4,6 +4,7 @@ This module shows a few examples of how to use the `re` package to search predefined text snippets stored in module-level constants. """ + import re # Module-level constants diff --git a/ultimatepython/advanced/thread.py b/ultimatepython/advanced/thread.py index c4352b66..49914a81 100644 --- a/ultimatepython/advanced/thread.py +++ b/ultimatepython/advanced/thread.py @@ -20,6 +20,7 @@ https://realpython.com/python-gil/ https://wiki.python.org/moin/GlobalInterpreterLock """ + import time from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime diff --git a/ultimatepython/advanced/weak_ref.py b/ultimatepython/advanced/weak_ref.py index 40bcafa0..689969bb 100644 --- a/ultimatepython/advanced/weak_ref.py +++ b/ultimatepython/advanced/weak_ref.py @@ -4,6 +4,7 @@ up-to-date as it explicitly sets up and implicitly tears down servers as the program enters and leaves a function scope. """ + import weakref from uuid import uuid4 @@ -67,9 +68,7 @@ def setup_and_teardown_servers(registry): assert ( registry.server_count == len(_CLOUD_APPS) * len(_CLOUD_APP_COMPONENTS) - == len([(app, server) - for app, servers in app_servers.items() - for server in servers]) + == len([(app, server) for app, servers in app_servers.items() for server in servers]) ) # What's fascinating is that servers go away when we leave the diff --git a/ultimatepython/classes/abstract_class.py b/ultimatepython/classes/abstract_class.py index 7da2b364..9b377cd9 100644 --- a/ultimatepython/classes/abstract_class.py +++ b/ultimatepython/classes/abstract_class.py @@ -9,6 +9,7 @@ https://www.python.org/dev/peps/pep-3119/ """ + from abc import ABC, abstractmethod diff --git a/ultimatepython/classes/basic_class.py b/ultimatepython/classes/basic_class.py index c28521e1..a72ca7a9 100644 --- a/ultimatepython/classes/basic_class.py +++ b/ultimatepython/classes/basic_class.py @@ -3,6 +3,7 @@ combined as one logical entity. This module defines a basic car class, creates a car instance and uses it for demonstration purposes. """ + from inspect import isfunction, ismethod, signature diff --git a/ultimatepython/classes/encapsulation.py b/ultimatepython/classes/encapsulation.py index 2794add1..1cdb31df 100644 --- a/ultimatepython/classes/encapsulation.py +++ b/ultimatepython/classes/encapsulation.py @@ -6,6 +6,7 @@ attributes from outside the class. Instead, users must use methods to access and modify attributes. """ + import secrets # Module-level constant diff --git a/ultimatepython/classes/inheritance.py b/ultimatepython/classes/inheritance.py index b922ef70..5a7053f9 100644 --- a/ultimatepython/classes/inheritance.py +++ b/ultimatepython/classes/inheritance.py @@ -5,6 +5,7 @@ class that inherits from vehicle, then creates a truck class that inherits from car and use it for demonstration purposes. """ + from inspect import isfunction, ismethod diff --git a/ultimatepython/classes/iterator_class.py b/ultimatepython/classes/iterator_class.py index 2035b73e..56352c8c 100644 --- a/ultimatepython/classes/iterator_class.py +++ b/ultimatepython/classes/iterator_class.py @@ -128,10 +128,7 @@ def employee_generator(top_employee): def main(): # Manager with two direct reports - manager = Employee("Max Doe", "Engineering Manager", [ - Employee("John Doe", "Software Engineer", []), - Employee("Jane Doe", "Software Engineer", []) - ]) + manager = Employee("Max Doe", "Engineering Manager", [Employee("John Doe", "Software Engineer", []), Employee("Jane Doe", "Software Engineer", [])]) # We should provide the same three employees in the same order regardless # of whether we use the iterator class or the generator function diff --git a/ultimatepython/data_structures/comprehension.py b/ultimatepython/data_structures/comprehension.py index 76afc783..d85d8ed9 100644 --- a/ultimatepython/data_structures/comprehension.py +++ b/ultimatepython/data_structures/comprehension.py @@ -29,10 +29,7 @@ def main(): # Dictionary comprehension can map each word to its length dict_comp = {word: len(word) for word in words} assert len(dict_comp) == len(words) - assert dict_comp == {"cat": 3, - "mice": 4, - "horse": 5, - "bat": 3} + assert dict_comp == {"cat": 3, "mice": 4, "horse": 5, "bat": 3} # Comprehensions can also be used with inline conditionals to # get filtered values from the original list. In this example, diff --git a/ultimatepython/data_structures/deque.py b/ultimatepython/data_structures/deque.py index 451b05ed..a0ee53d1 100644 --- a/ultimatepython/data_structures/deque.py +++ b/ultimatepython/data_structures/deque.py @@ -4,6 +4,7 @@ like a list. This module highlights those differences and shows how a deque can be used as a LIFO stack and a FIFO queue. """ + from collections import deque diff --git a/ultimatepython/data_structures/dict.py b/ultimatepython/data_structures/dict.py index eea04b42..8e0e4a2e 100644 --- a/ultimatepython/data_structures/dict.py +++ b/ultimatepython/data_structures/dict.py @@ -3,6 +3,7 @@ access, modify, remove and extend key-value pairs with this data structure. """ + import math # Module-level constants @@ -12,10 +13,7 @@ def main(): # Let's create a dictionary with student keys and GPA values - student_gpa = {"john": 3.5, - "jane": _GPA_MAX, - "bob": 2.8, - "mary": 3.2} + student_gpa = {"john": 3.5, "jane": _GPA_MAX, "bob": 2.8, "mary": 3.2} # There are four student records in this dictionary assert len(student_gpa) == 4 diff --git a/ultimatepython/data_structures/namedtuple.py b/ultimatepython/data_structures/namedtuple.py index 3e10710b..daf4c9fb 100644 --- a/ultimatepython/data_structures/namedtuple.py +++ b/ultimatepython/data_structures/namedtuple.py @@ -3,6 +3,7 @@ with named fields, similar to a class but lightweight and immutable. Named tuples are created using the namedtuple function from the collections module. """ + from collections import namedtuple diff --git a/ultimatepython/syntax/bitwise.py b/ultimatepython/syntax/bitwise.py index ddd4559b..2451963e 100644 --- a/ultimatepython/syntax/bitwise.py +++ b/ultimatepython/syntax/bitwise.py @@ -6,8 +6,8 @@ def main(): # Define some integer values for demonstration - a = 5 # Binary: 0101 - b = 3 # Binary: 0011 + a = 5 # Binary: 0101 + b = 3 # Binary: 0011 # Bitwise AND (&) operator compares each bit of two integers and returns 1 # if both bits are 1, otherwise returns 0 diff --git a/ultimatepython/syntax/conditional.py b/ultimatepython/syntax/conditional.py index 67537b32..f3c468be 100644 --- a/ultimatepython/syntax/conditional.py +++ b/ultimatepython/syntax/conditional.py @@ -58,7 +58,7 @@ def main(): if 0 < x_add_two < 2: ran_6 = False # skip: if else: - ran_6 = True # run + ran_6 = True # run assert ran_6 is True diff --git a/ultimatepython/syntax/expression.py b/ultimatepython/syntax/expression.py index 0ad19eb2..6dd3679f 100644 --- a/ultimatepython/syntax/expression.py +++ b/ultimatepython/syntax/expression.py @@ -2,6 +2,7 @@ This module shows how to create new integers by applying math expressions on existing integers. """ + import math @@ -30,7 +31,7 @@ def main(): # Powers of an integer can be leveraged too. If more features are # needed, then leverage the builtin `math` library or a third-party # library. Otherwise, we have to build our own math library - assert x * 2 ** 3 == 8 + assert x * 2**3 == 8 if __name__ == "__main__": diff --git a/ultimatepython/syntax/variable.py b/ultimatepython/syntax/variable.py index ddd3ce8d..caa2059c 100644 --- a/ultimatepython/syntax/variable.py +++ b/ultimatepython/syntax/variable.py @@ -3,6 +3,7 @@ a program. This module shows how to define variables and make assertions about the state of each defined variable. """ + import math From 717de0c198b4891c9aeac196d8053e8aa8448ba8 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:04:32 -0700 Subject: [PATCH 139/178] Apply LLM tweaks to de and es translations --- README.de.md | 12 ++++++------ README.es.md | 15 +++++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/README.de.md b/README.de.md index d03f2eff..4ba6e39b 100644 --- a/README.de.md +++ b/README.de.md @@ -37,12 +37,12 @@ Dies sind die Hauptziele bei der Erstellung dieses Leitfadens: 🏆 **Als Ressource fungieren** für Python-Neulinge, die es vorziehen, praktisch zu lernen. Dieses Repository enthält eine Sammlung von eigenständigen Modulen, die in einer IDE -wie [PyCharm](https://www.jetbrains.com/pycharm/) und im Browser wie -[Replit](https://replit.com/languages/python3). Wleches wie ein einfaches Terminal -mit den Beispielen funktioniert. Die meisten Zeilen haben sorgfältig ausgearbeitete Kommentare, die den Leser -Schritt für Schritt durch das Programm führen. Die Benutzer werden ermutigt, den -Quellcode überall zu ändern, solange die "Haupt"-Routinen nicht gelöscht werden und -[run successfully](runner.py) nach jeder Änderung. + wie [PyCharm](https://www.jetbrains.com/pycharm/) oder im Browser via + [Replit](https://replit.com/languages/python3) ausgeführt werden können. Ein Terminal funktioniert + ebenfalls gut für die Beispiele. Die meisten Zeilen enthalten sorgfälltig formulierte Kommentare, die den Leser + Schritt für Schritt durch die Abläufe führen. Benutzer werden ermutigt, den Quellcode zu ändern, + sofern die `main`-Routinen nicht entfernt werden und die Programme nach Änderungen weiterhin erfolgreich + ausgeführt werden (siehe `runner.py`). 🏆 **Als reiner Leitfaden dienen** für diejenigen, die die wichtigsten Python-Konzepte wiederholen möchten. Wo nur [builtin libraries](https://docs.python.org/3/library/) genutzt werden, so dass diff --git a/README.es.md b/README.es.md index e0025fd7..aef40a24 100644 --- a/README.es.md +++ b/README.es.md @@ -34,14 +34,13 @@ Espero ver a más personas aprendiendo Python y persiguiendo su pasión a travé Estos son los objetivos principales de esta guía: -🏆 **Servir como un recurso** para principiantes de Python que prefieren aprender por su cuenta. -Este repositorio enumera una colección de módulos independientes que pueden ser ejecutados en -un IDE como [PyCharm](https://www.jetbrains.com/pycharm/) e incluso en el navegador, como -[Repl.it](https://repl.it/languages/python3). Incluso una terminal antigua funcionará igual de bien -con los ejemplos. La mayoría de las líneas de código tienen comentarios útiles que ayudan a guiar -al lector para entender paso a paso el proceso que el programa está ejecutando. Se anima a los usuarios -a que modifiquen el código fuente en cualquier parte siempre y cuando las rutinas principales (`main`) -se eliminen y se [ejecuten con éxito](runner.py) tras cada cambio. +🏆 **Servir como un recurso** para principiantes de Python que prefieren aprender de forma práctica. +Este repositorio contiene una colección de módulos independientes que pueden ejecutarse en +un IDE como [PyCharm](https://www.jetbrains.com/pycharm/) y en el navegador, como +[Replit](https://replit.com/languages/python3). Incluso una terminal sencilla funcionará con los ejemplos. +La mayoría de las líneas de código tienen comentarios útiles que guían al lector paso a paso. +Se anima a los usuarios a modificar el código fuente en cualquier parte siempre y cuando las rutinas +principales (`main`) no se eliminen y los programas se ejecuten con éxito tras cada cambio (ver `runner.py`). 🏆 **Servir como una guía pura** para aquellos que quieren reforzar los conceptos base de Python. Se utilizan sólo las [librerías integradas](https://docs.python.org/3/library/) para que From e9a0313c711bc33ec835124f424f67ef37c24bca Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:22:58 -0700 Subject: [PATCH 140/178] Enforce 4-space indent to Markdown --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 0c2bca81..3be246be 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true -[*.{py,toml}] +[*.{py,toml,md}] indent_size = 4 indent_style = space From 5fd8f6d4715ddf0c9cc60fbbb1a5656329ab2356 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:31:30 -0700 Subject: [PATCH 141/178] Add guidance on README translations --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e5b09ec..b9aeccf6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,4 +119,8 @@ We're excited to see what you bring to the table! Your contributions are making Please don't hesitate to reach out if you have any questions. Your contributions, no matter how small, are making a big difference! 🌟🐍💥 +## 🌍 README translations + +Friendly note: please update `README.md` (English) first — it's the source of truth. If you can, mirror important changes (headings, badges, install steps, examples) in the corresponding `README..md` files so translations stay current. If you can't, no worries — just add a short note in your PR listing which translation files need updates and a one-line summary of the change (for example: "added examples section" or "updated install command"). Translators and maintainers will follow up. Small typo fixes or minor formatting tweaks usually don't require translation updates. Thanks — your help keeps the docs welcoming for everyone! 🙏 + ## Feel the Pythonic Energy - Contribute Now!🔥 From 5c0480991a012626db73b9b925b00f3680b427cf Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:35:16 -0700 Subject: [PATCH 142/178] Shorten content for translation section --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b9aeccf6..21f4c4b1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,6 +121,6 @@ Please don't hesitate to reach out if you have any questions. Your contributions ## 🌍 README translations -Friendly note: please update `README.md` (English) first — it's the source of truth. If you can, mirror important changes (headings, badges, install steps, examples) in the corresponding `README..md` files so translations stay current. If you can't, no worries — just add a short note in your PR listing which translation files need updates and a one-line summary of the change (for example: "added examples section" or "updated install command"). Translators and maintainers will follow up. Small typo fixes or minor formatting tweaks usually don't require translation updates. Thanks — your help keeps the docs welcoming for everyone! 🙏 +Please update `README.md` (English) first - it's the source of truth. If you can, mirror important changes like link updates in the corresponding `README..md` files so translations stay current. If you can't, no worries — just add a short note in your PR listing which translation files need updates. Thanks - your help keeps the docs welcoming for everyone! 🙏 ## Feel the Pythonic Energy - Contribute Now!🔥 From 35f1faee404581a19a97c0e723381b4a34ef87cf Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:36:00 -0700 Subject: [PATCH 143/178] Add formatting tweak to contrib docs --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21f4c4b1..aaa87332 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -123,4 +123,4 @@ Please don't hesitate to reach out if you have any questions. Your contributions Please update `README.md` (English) first - it's the source of truth. If you can, mirror important changes like link updates in the corresponding `README..md` files so translations stay current. If you can't, no worries — just add a short note in your PR listing which translation files need updates. Thanks - your help keeps the docs welcoming for everyone! 🙏 -## Feel the Pythonic Energy - Contribute Now!🔥 +## Feel the Pythonic Energy - Contribute Now! 🔥 From 6809655511d435ec38ac900bc10708fb13eb7a28 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:48:40 -0700 Subject: [PATCH 144/178] Apply type hinting across most modules --- ultimatepython/advanced/async.py | 8 +- ultimatepython/advanced/context_manager.py | 11 +- ultimatepython/advanced/date_time.py | 12 +- ultimatepython/advanced/decorator.py | 11 +- ultimatepython/advanced/file_handling.py | 10 +- ultimatepython/advanced/thread.py | 9 +- ultimatepython/classes/abstract_class.py | 24 ++-- ultimatepython/classes/basic_class.py | 10 +- ultimatepython/classes/encapsulation.py | 16 +-- ultimatepython/classes/exception_class.py | 4 +- ultimatepython/classes/inheritance.py | 20 +-- ultimatepython/classes/iterator_class.py | 12 +- .../data_structures/comprehension.py | 2 +- ultimatepython/data_structures/defaultdict.py | 2 +- ultimatepython/data_structures/deque.py | 2 +- ultimatepython/data_structures/dict.py | 2 +- ultimatepython/data_structures/heap.py | 124 +++++++++--------- ultimatepython/data_structures/list.py | 2 +- ultimatepython/data_structures/namedtuple.py | 2 +- ultimatepython/data_structures/set.py | 2 +- ultimatepython/data_structures/string.py | 2 +- ultimatepython/data_structures/tuple.py | 2 +- ultimatepython/syntax/bitwise.py | 2 +- ultimatepython/syntax/conditional.py | 2 +- ultimatepython/syntax/expression.py | 2 +- ultimatepython/syntax/function.py | 10 +- ultimatepython/syntax/loop.py | 2 +- ultimatepython/syntax/variable.py | 2 +- 28 files changed, 157 insertions(+), 152 deletions(-) diff --git a/ultimatepython/advanced/async.py b/ultimatepython/advanced/async.py index ea324a83..366828f1 100644 --- a/ultimatepython/advanced/async.py +++ b/ultimatepython/advanced/async.py @@ -31,12 +31,12 @@ def _is_valid_record(record): return record.queued_at < record.started_at -def _current_time(): +def _current_time() -> datetime: """Return current time that is timezone-naive.""" return datetime.now() -async def start_job(job_id, delay): +async def start_job(job_id: str, delay: float) -> JobRecord: """Start job ID after a certain amount of delay.""" queue_time = _current_time() await asyncio.sleep(delay) @@ -44,7 +44,7 @@ async def start_job(job_id, delay): return JobRecord(job_id, queue_time, start_time) -async def schedule_jobs(): +async def schedule_jobs() -> None: """Schedule jobs concurrently.""" # Start a job which also represents a coroutine single_job = start_job(uuid4().hex, _DELAY_SMALL) @@ -77,7 +77,7 @@ async def schedule_jobs(): assert all(_is_valid_record(record) for record in batch_records) -def main(): +def main() -> None: asyncio.run(schedule_jobs()) diff --git a/ultimatepython/advanced/context_manager.py b/ultimatepython/advanced/context_manager.py index 5abcef6d..09285431 100644 --- a/ultimatepython/advanced/context_manager.py +++ b/ultimatepython/advanced/context_manager.py @@ -8,6 +8,7 @@ from contextlib import contextmanager from io import StringIO +from typing import Generator # Simple directory with file contents _FILESYSTEM = { @@ -18,7 +19,7 @@ @contextmanager -def file(filename): +def file(filename: str) -> Generator[StringIO, None, None]: """File context manager. This is the function variant of the context manager. Context managers @@ -42,19 +43,19 @@ class FileHandler: class or simply write a function. """ - def __init__(self, filename): + def __init__(self, filename: str) -> None: self.io_buffer = StringIO(_FILESYSTEM[filename]) - def __enter__(self): + def __enter__(self) -> StringIO: """Pass the buffer to the context block.""" return self.io_buffer - def __exit__(self, *args): + def __exit__(self, *args) -> None: """Close the buffer unconditionally.""" self.io_buffer.close() -def main(): +def main() -> None: # An example of a function-based context manager with file("a.txt") as txt_buffer: assert txt_buffer.read() == "Hello World" diff --git a/ultimatepython/advanced/date_time.py b/ultimatepython/advanced/date_time.py index c70453ce..c8dc71a5 100644 --- a/ultimatepython/advanced/date_time.py +++ b/ultimatepython/advanced/date_time.py @@ -26,7 +26,7 @@ from datetime import datetime, timezone -def convert_dt_to_utc_epoch(dt): +def convert_dt_to_utc_epoch(dt: datetime) -> int: """Convert datetime to UTC epoch seconds. Note that the timestamp method assumes that an offset-naive @@ -36,27 +36,27 @@ def convert_dt_to_utc_epoch(dt): return dt.timestamp() -def convert_utc_epoch_to_dt(epoch): +def convert_utc_epoch_to_dt(epoch: int) -> datetime: """Convert UTC epoch seconds to datetime.""" return datetime.fromtimestamp(epoch, tz=timezone.utc) -def convert_dt_timezone(dt, tz): +def convert_dt_timezone(dt: datetime, tz: timezone) -> datetime: """Convert datetime timezone.""" return dt.astimezone(tz=tz) -def get_utc_now_as_dt(): +def get_utc_now_as_dt() -> datetime: """Get current UTC time as datetime.""" return datetime.now(tz=timezone.utc) -def get_utc_now_as_epoch(): +def get_utc_now_as_epoch() -> int: """Get current UTC time as epoch seconds.""" return convert_dt_to_utc_epoch(get_utc_now_as_dt()) -def main(): +def main() -> None: # Create offset-naive datetime naive_dt = datetime.now() assert naive_dt.tzinfo is None diff --git a/ultimatepython/advanced/decorator.py b/ultimatepython/advanced/decorator.py index 5527140b..e4561c9b 100644 --- a/ultimatepython/advanced/decorator.py +++ b/ultimatepython/advanced/decorator.py @@ -6,12 +6,13 @@ """ from functools import wraps +from typing import Any, Callable # Module-level constants _MASKING = "*" -def run_with_stringy(fn): +def run_with_stringy(fn: Callable[[str], str]) -> Callable[[Any], Any]: """Run a string function with a string or a collection of strings. We define a custom decorator that allows us to convert a function whose @@ -40,7 +41,7 @@ def run_with_stringy(fn): """ @wraps(fn) - def wrapper(obj): + def wrapper(obj: Any) -> Any: """Apply wrapped function to a string or a collection. This looks like a policy-based engine which runs a `return` statement @@ -65,14 +66,14 @@ def wrapper(obj): @run_with_stringy -def hide_content(content): +def hide_content(content: str) -> str: """Hide half of the string content.""" start_point = len(content) // 2 num_of_asterisks = len(content) // 2 + len(content) % 2 return content[:start_point] + _MASKING * num_of_asterisks -def _is_hidden(obj): +def _is_hidden(obj: Any) -> bool: """Check whether string or collection is hidden.""" if isinstance(obj, str): return _MASKING in obj @@ -81,7 +82,7 @@ def _is_hidden(obj): return all(_is_hidden(value) for value in obj) -def main(): +def main() -> None: # There is so much plain-text data out in the open insecure_data = [ {"username": "johndoe", "country": "USA"}, # User information diff --git a/ultimatepython/advanced/file_handling.py b/ultimatepython/advanced/file_handling.py index c3a0cd39..489d33d1 100644 --- a/ultimatepython/advanced/file_handling.py +++ b/ultimatepython/advanced/file_handling.py @@ -13,34 +13,34 @@ _TARGET_FILE = "sample.txt" -def read_file(filename): +def read_file(filename: str) -> str: """Read content from existing file.""" with open(filename, "r") as file: content = file.read() return content -def write_file(filename, content): +def write_file(filename: str, content: str) -> str: """Write content to new file.""" with open(filename, "w") as file: file.write(content) return f"Content written to '{filename}'." -def append_file(filename, content): +def append_file(filename: str, content: str) -> str: """Append content to existing file.""" with open(filename, "a") as file: file.write(content) return f"Content appended to '{filename}'." -def delete_file(filename): +def delete_file(filename: str) -> str: """Delete content of existing file.""" os.remove(filename) return f"'{filename}' has been deleted." -def main(): +def main() -> None: result = write_file(_TARGET_FILE, "This is a test.") assert result == f"Content written to '{_TARGET_FILE}'." diff --git a/ultimatepython/advanced/thread.py b/ultimatepython/advanced/thread.py index 49914a81..095c792e 100644 --- a/ultimatepython/advanced/thread.py +++ b/ultimatepython/advanced/thread.py @@ -24,18 +24,19 @@ import time from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime +from typing import Callable, Iterable, Set # Module-level constants _MULTIPLY_DELAY = 0.01 # delay is long enough for threads to be faster -def multiply_by_two(item): +def multiply_by_two(item: int) -> int: """This multiplication has a small delay.""" time.sleep(_MULTIPLY_DELAY) return item * 2 -def run_thread_workers(work, data): +def run_thread_workers(work: Callable[[int], int], data: Iterable[int]) -> Set[int]: """Run thread workers that invoke work on each data element. The inspiration for this function comes directly from an example @@ -43,7 +44,7 @@ def run_thread_workers(work, data): https://docs.python.org/3/library/concurrent.futures.html """ - results = set() + results: Set[int] = set() # We can use a with statement to ensure workers are cleaned up promptly with ThreadPoolExecutor() as executor: @@ -55,7 +56,7 @@ def run_thread_workers(work, data): return results -def main(): +def main() -> None: original_data = {num for num in range(5)} expected_data = {(item * 2) for item in original_data} diff --git a/ultimatepython/classes/abstract_class.py b/ultimatepython/classes/abstract_class.py index 9b377cd9..eef63d2e 100644 --- a/ultimatepython/classes/abstract_class.py +++ b/ultimatepython/classes/abstract_class.py @@ -20,20 +20,20 @@ class Employee(ABC): can work and relax is different from another type of employee. """ - def __init__(self, name, title): + def __init__(self, name: str, title: str) -> None: self.name = name self.title = title - def __str__(self): + def __str__(self) -> str: return self.name @abstractmethod - def do_work(self): + def do_work(self) -> str: """Do something for work.""" raise NotImplementedError @abstractmethod - def do_relax(self): + def do_relax(self) -> str: """Do something to relax.""" raise NotImplementedError @@ -49,14 +49,14 @@ class Engineer(Employee): is something that a manager prefers not to do. """ - def __init__(self, name, title, skill): + def __init__(self, name: str, title: str, skill: str) -> None: super().__init__(name, title) self.skill = skill - def do_work(self): + def do_work(self) -> str: return f"{self} is coding in {self.skill}" - def do_relax(self): + def do_relax(self) -> str: return f"{self} is watching YouTube" def do_refactor(self): @@ -73,22 +73,22 @@ class is concrete. Notice that a manager has direct reports and engineer. """ - def __init__(self, name, title, direct_reports): + def __init__(self, name: str, title: str, direct_reports: list) -> None: super().__init__(name, title) self.direct_reports = direct_reports - def do_work(self): + def do_work(self) -> str: return f"{self} is meeting up with {len(self.direct_reports)} reports" - def do_relax(self): + def do_relax(self) -> str: return f"{self} is taking a trip to the Bahamas" - def do_hire(self): + def do_hire(self) -> str: """Do the hard work of hiring employees, unlike engineers.""" return f"{self} is hiring employees" -def main(): +def main() -> None: # Declare two engineers engineer_john = Engineer("John Doe", "Software Engineer", "Android") engineer_jane = Engineer("Jane Doe", "Software Engineer", "iOS") diff --git a/ultimatepython/classes/basic_class.py b/ultimatepython/classes/basic_class.py index a72ca7a9..9c9216e4 100644 --- a/ultimatepython/classes/basic_class.py +++ b/ultimatepython/classes/basic_class.py @@ -15,27 +15,27 @@ class Car: class definition. """ - def __init__(self, make, model, year, miles): + def __init__(self, make: str, model: str, year: int, miles: float) -> None: """Constructor logic.""" self.make = make self.model = model self.year = year self.miles = miles - def __repr__(self): + def __repr__(self) -> str: """Formal representation for developers.""" return f"" - def __str__(self): + def __str__(self) -> str: """Informal representation for users.""" return f"{self.make} {self.model} ({self.year})" - def drive(self, rate_in_mph): + def drive(self, rate_in_mph: int) -> str: """Drive car at a certain rate in MPH.""" return f"{self} is driving at {rate_in_mph} MPH" -def main(): +def main() -> None: # Create a car with the provided class constructor car = Car("Bumble", "Bee", 2000, 200000.0) diff --git a/ultimatepython/classes/encapsulation.py b/ultimatepython/classes/encapsulation.py index 1cdb31df..568738e3 100644 --- a/ultimatepython/classes/encapsulation.py +++ b/ultimatepython/classes/encapsulation.py @@ -15,7 +15,7 @@ class BankAccount: - def __init__(self, account_holder_name): + def __init__(self, account_holder_name: str) -> None: """ In Python, a class attribute can be made private by prefixing it with two underscores. This makes it inaccessible to users outside the class. @@ -33,14 +33,14 @@ def __init__(self, account_holder_name): self.__account_number = secrets.randbelow(10**10) # generate a random account number of 10 digits. self.__balance = 0 - def deposit(self, balance): + def deposit(self, balance: int) -> None: """ The deposit function is used to add new balance to the account. The provided balance is added to the existing balance. """ self.__balance += int(balance) - def withdraw(self, balance): + def withdraw(self, balance: int) -> None: """ The withdrawal method is used to deduct the balance from the account. In case there is insufficient balance, or the input is invalid, @@ -53,13 +53,13 @@ def withdraw(self, balance): self.__balance -= balance - def get_balance(self): + def get_balance(self) -> int: """ This function returns the available balance in the account. """ return self.__balance - def get_account_number(self): + def get_account_number(self) -> int: """ The account number is generated randomly when a new instance of the class is created. Since the attribute is also private, it cannot be accessed directly from outside the class. @@ -70,14 +70,14 @@ def get_account_number(self): """ return self.__account_number - def __set_account_number(self, number): + def __set_account_number(self, number: int) -> None: """ This is a private method. Similar to private variables, private methods also cannot be accessed outside the class. """ self.__account_number = number - def remove_account_details(self): + def remove_account_details(self) -> None: """ This method is used to reset the account details. Here, the __set_account_number function is private. @@ -91,7 +91,7 @@ def remove_account_details(self): self.account_holder_name = "" -def main(): +def main() -> None: # Account names constants. user1 = "John Doe" user2 = "Jane Doe" diff --git a/ultimatepython/classes/exception_class.py b/ultimatepython/classes/exception_class.py index b70ad2b7..560926d7 100644 --- a/ultimatepython/classes/exception_class.py +++ b/ultimatepython/classes/exception_class.py @@ -39,7 +39,7 @@ class DivisionError(CustomError): """ -def divide_positive_numbers(dividend, divisor): +def divide_positive_numbers(dividend: int, divisor: int) -> int: """Divide a positive number by another positive number. Writing a program in this style is considered defensive programming. @@ -54,7 +54,7 @@ def divide_positive_numbers(dividend, divisor): return dividend // divisor -def main(): +def main() -> None: # Exception classes are no different from concrete classes in that # they all have inheritance baked in assert issubclass(DivisionError, CustomError) diff --git a/ultimatepython/classes/inheritance.py b/ultimatepython/classes/inheritance.py index 5a7053f9..166d40a9 100644 --- a/ultimatepython/classes/inheritance.py +++ b/ultimatepython/classes/inheritance.py @@ -17,22 +17,22 @@ class Vehicle: the core concepts that are associated with a class definition. """ - def __init__(self, make, model, year, miles): + def __init__(self, make: str, model: str, year: int, miles: float) -> None: """Construct a vehicle with make, model, year, and miles.""" self.make = make self.model = model self.year = year self.miles = miles - def __repr__(self): + def __repr__(self) -> str: """Return the formal representation of a vehicle.""" return f"" - def __str__(self): + def __str__(self) -> str: """Return the informal representation of a vehicle.""" return f"{self.make} {self.model} ({self.year})" - def drive(self, rate_in_mph): + def drive(self, rate_in_mph: int) -> str: """Drive a vehicle at a certain rate in MPH.""" return f"{self} is driving at {rate_in_mph} MPH" @@ -50,12 +50,12 @@ class Car(Vehicle): output than the vehicle. """ - def __init__(self, make, model, year, miles): + def __init__(self, make: str, model: str, year: int, miles: float) -> None: """Construct a car with make, model, year, miles, and wheels.""" super().__init__(make, model, year, miles) self.wheels = 4 - def __repr__(self): + def __repr__(self) -> str: """Return the formal representation of a car.""" return f"" @@ -68,21 +68,21 @@ class Truck(Vehicle): car and the vehicle. """ - def __init__(self, make, model, year, miles): + def __init__(self, make: str, model: str, year: int, miles: float) -> None: """Construct a truck with make, model, year, miles, and wheels.""" super().__init__(make, model, year, miles) self.wheels = 6 - def __repr__(self): + def __repr__(self) -> str: """Return the formal representation of a truck.""" return f"" - def drive(self, rate_in_mph): + def drive(self, rate_in_mph: int) -> str: """Drive a truck at a certain rate in MPH.""" return f"{self} is driving a truck at {rate_in_mph} MPH" -def main(): +def main() -> None: # Create a vehicle with the provided class constructor vehicle = Vehicle("Mistery Machine", "Van", 1969, 100000.0) diff --git a/ultimatepython/classes/iterator_class.py b/ultimatepython/classes/iterator_class.py index 56352c8c..859ee326 100644 --- a/ultimatepython/classes/iterator_class.py +++ b/ultimatepython/classes/iterator_class.py @@ -32,7 +32,7 @@ class Employee: https://en.wikipedia.org/wiki/Design_Patterns """ - def __init__(self, name, title, direct_reports): + def __init__(self, name: str, title: str, direct_reports: list) -> None: self.name = name self.title = title self.direct_reports = direct_reports @@ -65,16 +65,16 @@ class EmployeeIterator: https://en.wikipedia.org/wiki/Iterator_pattern """ - def __init__(self, employee): + def __init__(self, employee: Employee) -> None: """Constructor logic.""" self.employees_to_visit = [employee] self.employees_visited = set() - def __iter__(self): + def __iter__(self) -> "EmployeeIterator": """Iterator is self by convention.""" return self - def __next__(self): + def __next__(self) -> Employee: """Return the next employee available. The logic may seem complex, but it's actually a common algorithm @@ -94,7 +94,7 @@ def __next__(self): return employee -def employee_generator(top_employee): +def employee_generator(top_employee: Employee): """Employee generator. It is essentially the same logic as above except constructed as a @@ -126,7 +126,7 @@ def employee_generator(top_employee): yield employee -def main(): +def main() -> None: # Manager with two direct reports manager = Employee("Max Doe", "Engineering Manager", [Employee("John Doe", "Software Engineer", []), Employee("Jane Doe", "Software Engineer", [])]) diff --git a/ultimatepython/data_structures/comprehension.py b/ultimatepython/data_structures/comprehension.py index d85d8ed9..daae75ff 100644 --- a/ultimatepython/data_structures/comprehension.py +++ b/ultimatepython/data_structures/comprehension.py @@ -4,7 +4,7 @@ """ -def main(): +def main() -> None: # One interesting fact about data structures is that we can build # them with comprehensions. Let's explain how the first one works: # we just want to create zeros so our expression is set to `0` diff --git a/ultimatepython/data_structures/defaultdict.py b/ultimatepython/data_structures/defaultdict.py index 096bf567..944d5387 100644 --- a/ultimatepython/data_structures/defaultdict.py +++ b/ultimatepython/data_structures/defaultdict.py @@ -11,7 +11,7 @@ _EPS = 0.000001 -def main(): +def main() -> None: # Let's create a defaultdict with student keys and GPA values. The first # parameter is called default_factory, and it is the initialization value for # first use of a key. It can be a common type or a function diff --git a/ultimatepython/data_structures/deque.py b/ultimatepython/data_structures/deque.py index a0ee53d1..4b215ad1 100644 --- a/ultimatepython/data_structures/deque.py +++ b/ultimatepython/data_structures/deque.py @@ -8,7 +8,7 @@ from collections import deque -def main(): +def main() -> None: # A list is identical to a vector where a new array is created when # there are too many elements in the old array, and the old array # elements are moved over to the new array one-by-one. The time diff --git a/ultimatepython/data_structures/dict.py b/ultimatepython/data_structures/dict.py index 8e0e4a2e..5ce62ac2 100644 --- a/ultimatepython/data_structures/dict.py +++ b/ultimatepython/data_structures/dict.py @@ -11,7 +11,7 @@ _GPA_MAX = 4.0 -def main(): +def main() -> None: # Let's create a dictionary with student keys and GPA values student_gpa = {"john": 3.5, "jane": _GPA_MAX, "bob": 2.8, "mary": 3.2} diff --git a/ultimatepython/data_structures/heap.py b/ultimatepython/data_structures/heap.py index 8a640d8a..057b0868 100644 --- a/ultimatepython/data_structures/heap.py +++ b/ultimatepython/data_structures/heap.py @@ -1,62 +1,62 @@ -import heapq - - -def main(): - # Define the list of numbers - nums = [3, 1, 4, 1, 5] - - # Creating a min-heap - min_heap = [] - for num in nums: - heapq.heappush(min_heap, num) - assert min_heap[0] == 1 # The root of the heap is the smallest element - - # Pop the smallest element - smallest = heapq.heappop(min_heap) - assert smallest == 1 - - # Adding a new element - heapq.heappush(min_heap, 5) - assert min_heap[0] == 1 # The root remains the smallest element - - # Creating a max-heap - max_heap = [] - for num in nums: - heapq.heappush(max_heap, -num) # Negate numbers for a max-heap - assert -max_heap[0] == 5 # The root of the heap is the largest element - - # Pop the largest element - largest = -heapq.heappop(max_heap) - assert largest == 5 - - # Converting a list to a heap in-place - data = [3, 1, 4, 1, 5] - heapq.heapify(data) - assert data[0] == 1 # The root is the smallest element - - # Extending a heap - more_data = [2, 6, 5] - for item in more_data: - heapq.heappush(data, item) - assert data[0] == 1 # The root is still the smallest element - - # Using heap for sorting - sorted_data = [heapq.heappop(data) for _ in range(len(data))] - assert sorted_data == [1, 1, 2, 3, 4, 5, 5, 6] - - # Getting the n smallest or largest elements from a list - n_smallest = heapq.nsmallest(3, nums) # Get the 3 smallest elements - assert n_smallest == [1, 1, 3] - - n_largest = heapq.nlargest(3, nums) # Get the 3 largest elements - assert n_largest == [5, 4, 3] - - # Merging multiple sorted lists into a single sorted list using a heap - list1 = [1, 3, 5, 7] - list2 = [2, 4, 6, 8] - merged_list = list(heapq.merge(list1, list2)) - assert merged_list == [1, 2, 3, 4, 5, 6, 7, 8] - - -if __name__ == "__main__": - main() +import heapq + + +def main() -> None: + # Define the list of numbers + nums = [3, 1, 4, 1, 5] + + # Creating a min-heap + min_heap = [] + for num in nums: + heapq.heappush(min_heap, num) + assert min_heap[0] == 1 # The root of the heap is the smallest element + + # Pop the smallest element + smallest = heapq.heappop(min_heap) + assert smallest == 1 + + # Adding a new element + heapq.heappush(min_heap, 5) + assert min_heap[0] == 1 # The root remains the smallest element + + # Creating a max-heap + max_heap = [] + for num in nums: + heapq.heappush(max_heap, -num) # Negate numbers for a max-heap + assert -max_heap[0] == 5 # The root of the heap is the largest element + + # Pop the largest element + largest = -heapq.heappop(max_heap) + assert largest == 5 + + # Converting a list to a heap in-place + data = [3, 1, 4, 1, 5] + heapq.heapify(data) + assert data[0] == 1 # The root is the smallest element + + # Extending a heap + more_data = [2, 6, 5] + for item in more_data: + heapq.heappush(data, item) + assert data[0] == 1 # The root is still the smallest element + + # Using heap for sorting + sorted_data = [heapq.heappop(data) for _ in range(len(data))] + assert sorted_data == [1, 1, 2, 3, 4, 5, 5, 6] + + # Getting the n smallest or largest elements from a list + n_smallest = heapq.nsmallest(3, nums) # Get the 3 smallest elements + assert n_smallest == [1, 1, 3] + + n_largest = heapq.nlargest(3, nums) # Get the 3 largest elements + assert n_largest == [5, 4, 3] + + # Merging multiple sorted lists into a single sorted list using a heap + list1 = [1, 3, 5, 7] + list2 = [2, 4, 6, 8] + merged_list = list(heapq.merge(list1, list2)) + assert merged_list == [1, 2, 3, 4, 5, 6, 7, 8] + + +if __name__ == "__main__": + main() diff --git a/ultimatepython/data_structures/list.py b/ultimatepython/data_structures/list.py index 44cc9f23..194a7096 100644 --- a/ultimatepython/data_structures/list.py +++ b/ultimatepython/data_structures/list.py @@ -5,7 +5,7 @@ """ -def main(): +def main() -> None: # This is a list of strings where # "a" is a string at index 0 and # "e" is a string at index 4 diff --git a/ultimatepython/data_structures/namedtuple.py b/ultimatepython/data_structures/namedtuple.py index daf4c9fb..146ac204 100644 --- a/ultimatepython/data_structures/namedtuple.py +++ b/ultimatepython/data_structures/namedtuple.py @@ -7,7 +7,7 @@ from collections import namedtuple -def main(): +def main() -> None: # Named Tuple Attributes: # - namedtuple: Callable from collections to define a named tuple # - Point: A named tuple type with fields "x" and "y" diff --git a/ultimatepython/data_structures/set.py b/ultimatepython/data_structures/set.py index ba4286a8..3b6d94ba 100644 --- a/ultimatepython/data_structures/set.py +++ b/ultimatepython/data_structures/set.py @@ -5,7 +5,7 @@ """ -def main(): +def main() -> None: # Let's define one `set` for starters simple_set = {0, 1, 2} diff --git a/ultimatepython/data_structures/string.py b/ultimatepython/data_structures/string.py index a58ebae1..d2be2469 100644 --- a/ultimatepython/data_structures/string.py +++ b/ultimatepython/data_structures/string.py @@ -8,7 +8,7 @@ _DELIMITER = " | " -def main(): +def main() -> None: # Strings are some of the most robust data structures around content = "Ultimate Python study guide" diff --git a/ultimatepython/data_structures/tuple.py b/ultimatepython/data_structures/tuple.py index 3dc2da1d..784f6ada 100644 --- a/ultimatepython/data_structures/tuple.py +++ b/ultimatepython/data_structures/tuple.py @@ -5,7 +5,7 @@ """ -def main(): +def main() -> None: # This is a tuple of integers immutable = (1, 2, 3, 4) diff --git a/ultimatepython/syntax/bitwise.py b/ultimatepython/syntax/bitwise.py index 2451963e..b26f25b8 100644 --- a/ultimatepython/syntax/bitwise.py +++ b/ultimatepython/syntax/bitwise.py @@ -4,7 +4,7 @@ """ -def main(): +def main() -> None: # Define some integer values for demonstration a = 5 # Binary: 0101 b = 3 # Binary: 0011 diff --git a/ultimatepython/syntax/conditional.py b/ultimatepython/syntax/conditional.py index f3c468be..197c5ec5 100644 --- a/ultimatepython/syntax/conditional.py +++ b/ultimatepython/syntax/conditional.py @@ -4,7 +4,7 @@ """ -def main(): +def main() -> None: x = 1 x_add_two = x + 2 diff --git a/ultimatepython/syntax/expression.py b/ultimatepython/syntax/expression.py index 6dd3679f..9822af09 100644 --- a/ultimatepython/syntax/expression.py +++ b/ultimatepython/syntax/expression.py @@ -6,7 +6,7 @@ import math -def main(): +def main() -> None: # This is a simple integer x = 1 diff --git a/ultimatepython/syntax/function.py b/ultimatepython/syntax/function.py index ef47b01a..72b3df1f 100644 --- a/ultimatepython/syntax/function.py +++ b/ultimatepython/syntax/function.py @@ -5,8 +5,10 @@ in an interesting way. """ +from typing import Callable -def add(x, y): + +def add(x: object, y: object) -> object: """Add two objects together to produce a new object. Two differences between `add` and `main` are that: @@ -17,7 +19,7 @@ def add(x, y): return x + y -def sum_until(fn, n): +def sum_until(fn: Callable[[int], int], n: int) -> int: """Sum function results from 0 until n - 1. This expects a function to be provided as its first input and an integer @@ -33,7 +35,7 @@ def sum_until(fn, n): return total -def without_parameters(): +def without_parameters() -> None: """A function that does not accept parameters and does not return a value.""" pass @@ -43,7 +45,7 @@ def sum(x: int, y: int) -> int: return x + y -def main(): +def main() -> None: # The `add` function can be used for numbers as expected add_result_int = add(1, 2) assert add_result_int == 3 diff --git a/ultimatepython/syntax/loop.py b/ultimatepython/syntax/loop.py index 00aa8622..c7747695 100644 --- a/ultimatepython/syntax/loop.py +++ b/ultimatepython/syntax/loop.py @@ -11,7 +11,7 @@ """ -def main(): +def main() -> None: # This is a `for` loop that iterates on values 0..4 and adds each # value to `total`. It leverages the `range` iterator. Providing # a single integer implies that the start point is 0, the end point diff --git a/ultimatepython/syntax/variable.py b/ultimatepython/syntax/variable.py index caa2059c..36cb3df7 100644 --- a/ultimatepython/syntax/variable.py +++ b/ultimatepython/syntax/variable.py @@ -7,7 +7,7 @@ import math -def main(): +def main() -> None: # Here are the main literal types to be aware of a = 1 b = 2.0 From e19a4b8bb58ec396d17fdd77046a8c0549f6112f Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 21:56:56 -0700 Subject: [PATCH 145/178] Use natural set type for thread.py --- ultimatepython/advanced/thread.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ultimatepython/advanced/thread.py b/ultimatepython/advanced/thread.py index 095c792e..61522e79 100644 --- a/ultimatepython/advanced/thread.py +++ b/ultimatepython/advanced/thread.py @@ -24,7 +24,7 @@ import time from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime -from typing import Callable, Iterable, Set +from typing import Callable, Iterable # Module-level constants _MULTIPLY_DELAY = 0.01 # delay is long enough for threads to be faster @@ -36,7 +36,7 @@ def multiply_by_two(item: int) -> int: return item * 2 -def run_thread_workers(work: Callable[[int], int], data: Iterable[int]) -> Set[int]: +def run_thread_workers(work: Callable[[int], int], data: Iterable[int]) -> set[int]: """Run thread workers that invoke work on each data element. The inspiration for this function comes directly from an example @@ -44,7 +44,7 @@ def run_thread_workers(work: Callable[[int], int], data: Iterable[int]) -> Set[i https://docs.python.org/3/library/concurrent.futures.html """ - results: Set[int] = set() + results: set[int] = set() # We can use a with statement to ensure workers are cleaned up promptly with ThreadPoolExecutor() as executor: From bd3ced729b01b551a4478eeba92e0611c1afddf1 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 22:04:21 -0700 Subject: [PATCH 146/178] Fix replit link across translations --- README.es.md | 2 +- README.fr.md | 2 +- README.ko.md | 2 +- README.zh_tw.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.es.md b/README.es.md index aef40a24..1590fb43 100644 --- a/README.es.md +++ b/README.es.md @@ -52,7 +52,7 @@ recomendado si tu objetivo es convertirte en un verdadero ## Empezando -[![Run on Repl.it](https://repl.it/badge/github/huangsam/ultimate-python)](https://repl.it/github/huangsam/ultimate-python) +[![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) Haz clic en la imagen de arriba para crear un ambiente de trabajo en el navegador sin necesidad de tener Git y Python instalados en tu ordenador local. Si estos requisitos ya se cumplen, diff --git a/README.fr.md b/README.fr.md index a940b449..cc264cc2 100644 --- a/README.fr.md +++ b/README.fr.md @@ -57,7 +57,7 @@ si ton objectif est de devenir un véritable ## Pour commencer -[![Exécuter sur Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) +[![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) Clique sur le badge ci-dessus pour lancer un environnement fonctionnel dans ton navigateur sans avoir besoin d’installer Git ou Python localement.  diff --git a/README.ko.md b/README.ko.md index 37f923bf..e779bd23 100644 --- a/README.ko.md +++ b/README.ko.md @@ -45,7 +45,7 @@ print("Ultimate Python 학습 가이드") ## 시작하기 -[![Run on Replit](https://repl.it/badge/github/huangsam/ultimate-python)](https://repl.it/github/huangsam/ultimate-python) +[![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) 로컬 컴퓨터에 Git 및 Python을 설치하지 않고도 브라우저에서 작업 환경을 시작하려면 위의 배지를 클릭하세요. 이러한 요구 사항이 이미 충족된 경우, 저장소를 바로 clone해도 됩니다. diff --git a/README.zh_tw.md b/README.zh_tw.md index c69391dd..f664316f 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -41,7 +41,7 @@ print("Ultimate Python 學習大綱") ## 學習之旅 -[![Run on Repl.it](https://repl.it/badge/github/huangsam/ultimate-python)](https://repl.it/github/huangsam/ultimate-python) +[![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) 單擊上面的徽章就可在瀏覽器中啟動工作環境,而無需在電腦上額外安裝Git和Python。當你完成啟動,請複製這存儲庫。 當你可以開啟你所複製存儲庫後,您就準備好Python學習之旅!善用每個模組,請細讀註解並嘗試運行模組代碼。 From bf21c55a7ef04a7923ca2225d6dd320cec127422 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 22:05:13 -0700 Subject: [PATCH 147/178] Update python dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index bbc1c0d6..244d59d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ coverage==7.10.7 -isort==6.0.1 -ruff==0.13.2 +isort==7.0.0 +ruff==0.14.0 From a5e4d693c0106770a9f69027eb477ec2de997249 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 22:15:03 -0700 Subject: [PATCH 148/178] Fix mypy edge cases across modules --- ultimatepython/advanced/date_time.py | 6 ++--- ultimatepython/advanced/meta_class.py | 2 +- ultimatepython/classes/iterator_class.py | 2 +- ultimatepython/data_structures/deque.py | 2 +- ultimatepython/data_structures/heap.py | 4 ++-- ultimatepython/data_structures/list.py | 2 +- ultimatepython/data_structures/namedtuple.py | 8 +++++-- ultimatepython/syntax/function.py | 25 ++++++++++---------- 8 files changed, 28 insertions(+), 23 deletions(-) diff --git a/ultimatepython/advanced/date_time.py b/ultimatepython/advanced/date_time.py index c8dc71a5..7b46bbdd 100644 --- a/ultimatepython/advanced/date_time.py +++ b/ultimatepython/advanced/date_time.py @@ -26,7 +26,7 @@ from datetime import datetime, timezone -def convert_dt_to_utc_epoch(dt: datetime) -> int: +def convert_dt_to_utc_epoch(dt: datetime) -> float: """Convert datetime to UTC epoch seconds. Note that the timestamp method assumes that an offset-naive @@ -36,7 +36,7 @@ def convert_dt_to_utc_epoch(dt: datetime) -> int: return dt.timestamp() -def convert_utc_epoch_to_dt(epoch: int) -> datetime: +def convert_utc_epoch_to_dt(epoch: float) -> datetime: """Convert UTC epoch seconds to datetime.""" return datetime.fromtimestamp(epoch, tz=timezone.utc) @@ -51,7 +51,7 @@ def get_utc_now_as_dt() -> datetime: return datetime.now(tz=timezone.utc) -def get_utc_now_as_epoch() -> int: +def get_utc_now_as_epoch() -> float: """Get current UTC time as epoch seconds.""" return convert_dt_to_utc_epoch(get_utc_now_as_dt()) diff --git a/ultimatepython/advanced/meta_class.py b/ultimatepython/advanced/meta_class.py index da49f6c6..51fe51ba 100644 --- a/ultimatepython/advanced/meta_class.py +++ b/ultimatepython/advanced/meta_class.py @@ -33,7 +33,7 @@ class ModelMeta(type): """ # Model table registry - tables = {} + tables: dict[str, "ModelTable"] = {} def __new__(mcs, name, bases, attrs): """Factory for modifying the defined class at runtime. diff --git a/ultimatepython/classes/iterator_class.py b/ultimatepython/classes/iterator_class.py index 859ee326..9ee96e0d 100644 --- a/ultimatepython/classes/iterator_class.py +++ b/ultimatepython/classes/iterator_class.py @@ -68,7 +68,7 @@ class EmployeeIterator: def __init__(self, employee: Employee) -> None: """Constructor logic.""" self.employees_to_visit = [employee] - self.employees_visited = set() + self.employees_visited: set[str] = set() def __iter__(self) -> "EmployeeIterator": """Iterator is self by convention.""" diff --git a/ultimatepython/data_structures/deque.py b/ultimatepython/data_structures/deque.py index 4b215ad1..e1a8abf4 100644 --- a/ultimatepython/data_structures/deque.py +++ b/ultimatepython/data_structures/deque.py @@ -20,7 +20,7 @@ def main() -> None: # Check out the source code for a list and a deque here: # https://github.com/python/cpython/blob/3.8/Objects/listobject.c # https://github.com/python/cpython/blob/3.8/Modules/_collectionsmodule.c - dq = deque() + dq: deque[int] = deque() for i in range(1, 5): # Similar to adding a new node to the right of the linked list diff --git a/ultimatepython/data_structures/heap.py b/ultimatepython/data_structures/heap.py index 057b0868..b6c83259 100644 --- a/ultimatepython/data_structures/heap.py +++ b/ultimatepython/data_structures/heap.py @@ -6,7 +6,7 @@ def main() -> None: nums = [3, 1, 4, 1, 5] # Creating a min-heap - min_heap = [] + min_heap: list[int] = [] for num in nums: heapq.heappush(min_heap, num) assert min_heap[0] == 1 # The root of the heap is the smallest element @@ -20,7 +20,7 @@ def main() -> None: assert min_heap[0] == 1 # The root remains the smallest element # Creating a max-heap - max_heap = [] + max_heap: list[int] = [] for num in nums: heapq.heappush(max_heap, -num) # Negate numbers for a max-heap assert -max_heap[0] == 5 # The root of the heap is the largest element diff --git a/ultimatepython/data_structures/list.py b/ultimatepython/data_structures/list.py index 194a7096..54245da4 100644 --- a/ultimatepython/data_structures/list.py +++ b/ultimatepython/data_structures/list.py @@ -94,7 +94,7 @@ def main() -> None: # Let's check if these lists are empty assert len(numbers) == 5 - empty_list = [] + empty_list: list[object] = [] assert len(empty_list) == 0 assert not empty_list assert len([None]) == 1 diff --git a/ultimatepython/data_structures/namedtuple.py b/ultimatepython/data_structures/namedtuple.py index 146ac204..b396f043 100644 --- a/ultimatepython/data_structures/namedtuple.py +++ b/ultimatepython/data_structures/namedtuple.py @@ -5,13 +5,14 @@ """ from collections import namedtuple +from typing import Any def main() -> None: # Named Tuple Attributes: # - namedtuple: Callable from collections to define a named tuple # - Point: A named tuple type with fields "x" and "y" - Point = namedtuple("Point", ["x", "y"]) + Point = namedtuple("Point", ["x", "y"]) # type: Any # Named Tuple Fields: # - x and y: Fields of the named tuple Point representing coordinates @@ -35,7 +36,10 @@ def main() -> None: # Attempt to change the "x" field of point1 (raises an error) access_immutable_error = False try: - point1.x = 5 + # Direct assignment to a namedtuple field is not allowed (immutable). + # Use setattr to demonstrate an attempted write at runtime while + # keeping static analyzers from treating it as a real attribute write. + setattr(point1, "x", 5) # will raise AttributeError on namedtuple except AttributeError: access_immutable_error = True assert access_immutable_error is True diff --git a/ultimatepython/syntax/function.py b/ultimatepython/syntax/function.py index 72b3df1f..0ab84c9d 100644 --- a/ultimatepython/syntax/function.py +++ b/ultimatepython/syntax/function.py @@ -5,10 +5,10 @@ in an interesting way. """ -from typing import Callable +from typing import Any, Callable -def add(x: object, y: object) -> object: +def add(x: Any, y: Any) -> Any: """Add two objects together to produce a new object. Two differences between `add` and `main` are that: @@ -35,14 +35,15 @@ def sum_until(fn: Callable[[int], int], n: int) -> int: return total -def without_parameters() -> None: - """A function that does not accept parameters and does not return a value.""" - pass +def without_parameters() -> object: + """A function that does not accept parameters and does not return a value. - -def sum(x: int, y: int) -> int: - """A function that accepts parameters and has type hints.""" - return x + y + The return type is annotated as `object` to allow callers that assert + on the returned value (e.g. `assert without_parameters() is None`) without + triggering static checker complaints about a function annotated as + returning None being used as a value. + """ + return None def main() -> None: @@ -64,11 +65,11 @@ def main() -> None: # We can see the `sum_until` docstring by accessing the `__doc__` magic # attribute! Remember this - everything in Python is an object - assert "includes this docstring!" in sum_until.__doc__ + # `__doc__` may be None in some environments, coalesce to an empty string + assert "includes this docstring!" in (sum_until.__doc__ or "") - # Call a few more functions to show that they are valid + # Call a function without parameters assert without_parameters() is None - assert sum(1, 2) == 3 if __name__ == "__main__": From 681a3548af0f01623c88b132490e3f9c6d977abe Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 22:21:02 -0700 Subject: [PATCH 149/178] Remove unused import from namedtuple --- ultimatepython/data_structures/namedtuple.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ultimatepython/data_structures/namedtuple.py b/ultimatepython/data_structures/namedtuple.py index b396f043..dec56c8a 100644 --- a/ultimatepython/data_structures/namedtuple.py +++ b/ultimatepython/data_structures/namedtuple.py @@ -5,7 +5,6 @@ """ from collections import namedtuple -from typing import Any def main() -> None: From ce764d33ce7b69c849878881e6420814d3f59ba2 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 22:26:10 -0700 Subject: [PATCH 150/178] Update python ci version to 3.14 (#141) --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a822f646..c31000d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,16 +11,16 @@ permissions: jobs: python-build: - name: Python 3.13 + name: Python 3.14 runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python 3.13 + - name: Set up Python 3.14 uses: actions/setup-python@v5 with: - python-version: '3.13' + python-version: '3.14' - name: Install dependencies run: | python -m pip install --upgrade pip From bd27858811d0dadfd856904d7c7f8b67ffa0d9f5 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 11 Oct 2025 22:29:31 -0700 Subject: [PATCH 151/178] Add mypy to CI flow (#142) --- .github/workflows/ci.yml | 3 +++ requirements.txt | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c31000d4..c3854946 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,9 @@ jobs: - name: Lint with ruff run: | ruff check + - name: Type check with mypy + run: | + mypy ultimatepython - name: Run tests and report with coverage run: | coverage run runner.py diff --git a/requirements.txt b/requirements.txt index 244d59d3..d2606155 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ coverage==7.10.7 isort==7.0.0 ruff==0.14.0 +mypy==1.18.2 From 503ec95203d52aad1f92aaf0787c1d82ae5d36a8 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 13 Oct 2025 01:57:43 -0700 Subject: [PATCH 152/178] Add type hints to runner.py --- runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runner.py b/runner.py index afcfabb1..8f4c0dec 100644 --- a/runner.py +++ b/runner.py @@ -13,17 +13,17 @@ _RUNNER_MAIN = "main" -def success_text(text): +def success_text(text) -> str: """Get success text.""" return f"{_STYLE_SUCCESS}{bold_text(text)}{_STYLE_END}" -def bold_text(text): +def bold_text(text) -> str: """Get bold text.""" return f"{_STYLE_BOLD}{text}{_STYLE_END}" -def main(): +def main() -> None: print(bold_text(f"Start {root_name} runner")) for item in walk_packages(root_path, f"{root_name}."): From a27a2d3b2962a8cbdb51c45cdad7227a805acb77 Mon Sep 17 00:00:00 2001 From: Vini Antunes <57882903+ViniViniAntunes@users.noreply.github.com> Date: Wed, 22 Oct 2025 10:16:29 -0300 Subject: [PATCH 153/178] Add README.pt_br.md with Brazilian Portuguese translation (#143) Co-authored-by: Vini Antunes --- README.md | 3 +- README.pt_br.md | 160 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 README.pt_br.md diff --git a/README.md b/README.md index b1c9d7ef..f676c39b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ print("Ultimate Python study guide") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python diff --git a/README.pt_br.md b/README.pt_br.md new file mode 100644 index 00000000..981d6acc --- /dev/null +++ b/README.pt_br.md @@ -0,0 +1,160 @@ +# Ultimate Python - O seu guia de estudos de Python definitivo + +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/huangsam/ultimate-python/ci.yml)](https://github.com/huangsam/ultimate-python/actions) +[![Code Coverage](https://img.shields.io/codecov/c/github/huangsam/ultimate-python)](https://codecov.io/gh/huangsam/ultimate-python) +[![Quality Gate Status](https://img.shields.io/sonar/quality_gate/huangsam_ultimate-python?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=huangsam_ultimate-python) +[![License](https://img.shields.io/github/license/huangsam/ultimate-python)](https://github.com/huangsam/ultimate-python/blob/main/LICENSE) +[![r/Python](https://img.shields.io/badge/reddit-original_post-red)](https://www.reddit.com/r/Python/comments/inllmf/ultimate_python_study_guide/) + +Guia de estudo definitivo de Python para iniciantes e profissionais. 🐍 🐍 🐍 + +```python +print("Ultimate Python - O seu guia de estudos de Python definitivo") +``` + +[English](README.md) | +[한국어](README.ko.md) | +[繁体中文](README.zh_tw.md) | +[Español](README.es.md) | +[Deutsch](README.de.md) | +[Français](README.fr.md) | +[हिन्दी](README.hi.md) | +[Português - BR](README.pt_br.md) + +Ultimate Python - O seu guia de estudos de Python definitivo + +## Motivação + +Eu criei este repositório a fim de compartilhar o que eu aprendi sobre o [básico de Python](https://www.python.org/) nos último 5+ anos de uso como graduado universitário, um empregado em uma empresa de grande porte e um contribuidor de repositórios open-source como [Celery](https://github.com/celery/celery) e +[Full Stack Python](https://github.com/mattmakai/fullstackpython.com). +Eu estou ansiono para ver mais pessoas aprendendo Python e buscando suas paixões através disso. 🎓 + +## Objetivos + +Aqui estão os principais objetivos da criação deste guia: + +🏆 **Servir como um recurso** para iniciantes em Python que preferem aprender na prática. +Este repositório possui uma coleção de módulos autônomos que podem ser executados em um IDE como [PyCharm](https://www.jetbrains.com/pycharm/) e no navegador como [Replit](https://replit.com/languages/python3). Até mesmo um terminal simples funcionará com os exemplos. +A maioria das linhas possui comentários cuidadosamente elaborados que guiam o leitor passo a passo sobre o que os programas estão fazendo. Usuários são incentivados a modificar o código fonte em qualquer lugar, desde que as rotinas `main` não sejam excluídas e [sejam executadas com sucesso](runner.py) após cada alteração. + +🏆 **Servir como um guia prático** para aqueles que queiram revisitar os conceitos básicos de Python. +Apenas [blibliotecas internas](https://docs.python.org/3/library/) são utilizadas para que esses conceitos possam ser transmitidos sem a sobrecarga de conceitos específicos de domínio. +Dessa forma, bibliotecas e frameworks populares de código aberto (como por exemplo `sqlalchemy`, `requests`, +`pandas`) não são instalados. No entanto, ler o código fonte desses estruturas é inspirador e altamente recomendado se o seu objetivo é se tornar um verdadeiro [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista). + +## Começando + +[![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) + +Click no emblema acima para criar um ambiente de trabalho no navegador sem a necessidade de instalar Git e Python na sua máquina local. Se esses requisitos já forem atendidos (se você já tem isso instalado), sinta-se à vontade para clonar o repositório diretamente. + +Uma vez que o repositório esteja acessível você está pronto para aprender com os módulos independentes. Para aproveitar ao máximo cada módulo, leia o código do módulo e execute-o. + +Existem duas maneiras de rodar os módulos: + +1. Execute um módulo único: `python ultimatepython/syntax/variable.py` +2. Execute todos os módulos: `python runner.py` + +## Índice + +📚 = Recurso externo, +🍰 = Tópico para iniciantes, +🤯 = Tópico avançado + +1. **Sobre Python** + - Visão geral: [O que é Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) + - Filosofia de design: [O zen do Python](https://www.python.org/dev/peps/pep-0020/) ( 📚 ) + - Guia de estilo: [Guia de estilo para código Python](https://www.python.org/dev/peps/pep-0008/) ( 📚, 🤯 ) + - Modelo de dados: [Modelo de dados](https://docs.python.org/3/reference/datamodel.html) ( 📚, 🤯 ) + - Biblioteca padrão: [A Biblioteca padrão do Python](https://docs.python.org/3/library/) ( 📚, 🤯 ) + - Funções integradas: [Funções integradas](https://docs.python.org/3/library/functions.html) ( 📚 ) +2. **Sintaxe** + - Variável: [Literais integrados](ultimatepython/syntax/variable.py) ( 🍰 ) + - Expressão: [Operações numéricas](ultimatepython/syntax/expression.py) ( 🍰 ) + - Bitwise: [Operadores bitwise](ultimatepython/syntax/bitwise.py) ( 🍰 ), [Complemento de Um/Dois](https://www.geeksforgeeks.org/difference-between-1s-complement-representation-and-2s-complement-representation-technique/) ( 📚 ) + - Condicional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) + - Loop/Laço: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) + - Função: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) +3. **Estrutura de dados** + - Lista: [Operações de lista](ultimatepython/data_structures/list.py) ( 🍰 ) + - Tupla: [Operações de tuplas](ultimatepython/data_structures/tuple.py) + - Conjunto: [Operações de conjuntos](ultimatepython/data_structures/set.py) + - Dicionário: [Operações de dicionários](ultimatepython/data_structures/dict.py) ( 🍰 ) + - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) + - String: [Operações de String](ultimatepython/data_structures/string.py) ( 🍰 ) + - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) + - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) + - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Time complexity: [Operações de cPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) +4. **Classes** + - O básico de classes: [Definição de classe](ultimatepython/classes/basic_class.py) ( 🍰 ) + - Herança: [Herança](ultimatepython/classes/inheritance.py) ( 🍰 ) + - Classe abstrata: [Definição de classe abstrata](ultimatepython/classes/abstract_class.py) + - Classe de exceção: [Definição de Classe de exceção](ultimatepython/classes/exception_class.py) + - Classe Iterator: [Definição de classe Iterator | yield](ultimatepython/classes/iterator_class.py) ( 🤯 ) + - Encapsulamento: [Definição de encapsulamento](ultimatepython/classes/encapsulation.py) +5. **Avançado** + - Decorator: [Definição de decorator | wraps](ultimatepython/advanced/decorator.py) ( 🤯 ) + - Manuseio de arquivos: [Manuseio de arquivos](ultimatepython/advanced/file_handling.py) ( 🤯 ) + - Gerenciador de contexto: [Gerenciador de contexto](ultimatepython/advanced/context_manager.py) ( 🤯 ) + - Ordem de resolução do método: [mro](ultimatepython/advanced/mro.py) ( 🤯 ) + - Mixin: [Definição de mixin](ultimatepython/advanced/mixin.py) ( 🤯 ) + - Metaclass: [Definição de metaclass](ultimatepython/advanced/meta_class.py) ( 🤯 ) + - Thread: [ThreadPoolExecutor](ultimatepython/advanced/thread.py) ( 🤯 ) + - Asyncio: [async | await](ultimatepython/advanced/async.py) ( 🤯 ) + - Referência fraca: [weakref](ultimatepython/advanced/weak_ref.py) ( 🤯 ) + - Benchmark: [cProfile | pstats](ultimatepython/advanced/benchmark.py) ( 🤯 ) + - Mocking: [MagicMock | PropertyMock | patch](ultimatepython/advanced/mocking.py) ( 🤯 ) + - Expressões regulares (regexp): [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) + - Formato de dados: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) + - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + +## Recursos adicionais + +👔 = Recurso para entrevista, +🧪 = Exemplos de código, +🧠 = Ideias para projetos + +### Repositórios GitHub + +Continue aprendendo lendo outros recursos bem conceituados. + +- [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) ( 👔 , 🧪 ) +- [faif/python-patterns](https://github.com/faif/python-patterns) ( 👔 , 🧪 ) +- [geekcomputers/Python](https://github.com/geekcomputers/Python) ( 🧪 ) +- [trekhleb/homemade-machine-learning](https://github.com/trekhleb/homemade-machine-learning) ( 🧪 ) +- [karan/Projects](https://github.com/karan/Projects) ( 🧠 ) +- [MunGell/awesome-for-beginners](https://github.com/MunGell/awesome-for-beginners) ( 🧠 ) +- [vinta/awesome-python](https://github.com/vinta/awesome-python) +- [academic/awesome-datascience](https://github.com/academic/awesome-datascience) +- [josephmisiti/awesome-machine-learning](https://github.com/josephmisiti/awesome-machine-learning) +- [ZuzooVn/machine-learning-for-software-engineers](https://github.com/ZuzooVn/machine-learning-for-software-engineers) +- [30-seconds/30-seconds-of-python](https://github.com/30-seconds/30-seconds-of-python) ( 🧪 ) +- [ml-tooling/best-of-python](https://github.com/ml-tooling/best-of-python) +- [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) +- [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +- [microsoft/ML-For-Beginners](https://github.com/microsoft/ML-For-Beginners) ( 🧪 ) +- [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) +- [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) + +### Prática interativa + +Continue praticando para que suas habilidades de codificação não enferrujem. + +- [codechef.com](https://www.codechef.com/) ( 👔 ) +- [codeforces.com](https://codeforces.com/) +- [codementor.io](https://www.codementor.io) ( 🧠 ) +- [coderbyte.com](https://www.coderbyte.com/) ( 👔 ) +- [codewars.com](https://www.codewars.com/) +- [exercism.io](https://exercism.io/) +- [geeksforgeeks.org](https://www.geeksforgeeks.org/) ( 👔 ) +- [hackerearth.com](https://www.hackerearth.com/) +- [hackerrank.com](https://www.hackerrank.com/) ( 👔 ) +- [kaggle.com](https://www.kaggle.com/) ( 🧠 ) +- [labex.io](https://labex.io/exercises/python)( 🧪 ) +- [leetcode.com](https://leetcode.com/) ( 👔 ) +- [projecteuler.net](https://projecteuler.net/) +- [replit.com](https://replit.com/) +- [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) +- [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) +- [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) From 3a0b08891000a5a976e6716a7f36a3f3c261509c Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 22 Oct 2025 06:19:43 -0700 Subject: [PATCH 154/178] Ref Brazil translation in all markdown files --- README.de.md | 3 ++- README.es.md | 3 ++- README.fr.md | 3 ++- README.hi.md | 3 ++- README.ko.md | 3 ++- README.pt_br.md | 2 +- README.zh_tw.md | 3 ++- 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.de.md b/README.de.md index 4ba6e39b..cade723d 100644 --- a/README.de.md +++ b/README.de.md @@ -18,7 +18,8 @@ print("Ultimativer Python-Lernführer") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python diff --git a/README.es.md b/README.es.md index 1590fb43..21f86cf3 100644 --- a/README.es.md +++ b/README.es.md @@ -18,7 +18,8 @@ print("Guía de estudio 'Python Definitivo'") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python diff --git a/README.fr.md b/README.fr.md index cc264cc2..7686950e 100644 --- a/README.fr.md +++ b/README.fr.md @@ -18,7 +18,8 @@ print("Guide d’étude Python ultime") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python diff --git a/README.hi.md b/README.hi.md index 73058e8b..fd8146ef 100644 --- a/README.hi.md +++ b/README.hi.md @@ -18,7 +18,8 @@ print("Ultimate Python study guide") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python diff --git a/README.ko.md b/README.ko.md index e779bd23..0d21ea09 100644 --- a/README.ko.md +++ b/README.ko.md @@ -18,7 +18,8 @@ print("Ultimate Python 학습 가이드") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python diff --git a/README.pt_br.md b/README.pt_br.md index 981d6acc..7e927900 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -19,7 +19,7 @@ print("Ultimate Python - O seu guia de estudos de Python definitivo") [Deutsch](README.de.md) | [Français](README.fr.md) | [हिन्दी](README.hi.md) | -[Português - BR](README.pt_br.md) +[Português - Brasil](README.pt_br.md) Ultimate Python - O seu guia de estudos de Python definitivo diff --git a/README.zh_tw.md b/README.zh_tw.md index f664316f..209de162 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -18,7 +18,8 @@ print("Ultimate Python 學習大綱") [Español](README.es.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | -[हिन्दी](README.hi.md) +[हिन्दी](README.hi.md) | +[Português - Brasil](README.pt_br.md) Ultimate Python From 45a84c3f5c8746388433ede6e6dcff46ae5a7001 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 22 Oct 2025 06:23:28 -0700 Subject: [PATCH 155/178] Update print statement for Hindi translation --- README.hi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.hi.md b/README.hi.md index fd8146ef..9a1cc4e4 100644 --- a/README.hi.md +++ b/README.hi.md @@ -9,7 +9,7 @@ नए और पेशेवर लोगों के लिए अल्टीमेट पायथन अध्ययन गाइड। 🐍 🐍 🐍 ```python -print("Ultimate Python study guide") +print("Ultimate Python स्टडी गाइड") ``` [English](README.md) | From db2be165bed9344f288eee8c3704cb974e85e634 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 22 Oct 2025 06:25:14 -0700 Subject: [PATCH 156/178] Update python dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d2606155..414f69ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.10.7 +coverage==7.11.0 isort==7.0.0 -ruff==0.14.0 +ruff==0.14.1 mypy==1.18.2 From ed201c67a7faa1c19e999cedd57dc1cae90c3430 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 22 Oct 2025 06:46:28 -0700 Subject: [PATCH 157/178] Update github action versions --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3854946..c3704f11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,9 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python 3.14 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.14' - name: Install dependencies From 4d3483f66435b0dd5380f9dd1c41112e100dc137 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 1 Nov 2025 19:26:20 -0700 Subject: [PATCH 158/178] Update ruff to 0.14.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 414f69ca..06528589 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ coverage==7.11.0 isort==7.0.0 -ruff==0.14.1 +ruff==0.14.3 mypy==1.18.2 From 331c392deccc3f8a4a3009dd18916bf41a773f9b Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 1 Nov 2025 20:39:07 -0700 Subject: [PATCH 159/178] Add stargazers visual at README bottom --- README.de.md | 4 ++++ README.es.md | 4 ++++ README.fr.md | 4 ++++ README.hi.md | 4 ++++ README.ko.md | 4 ++++ README.md | 4 ++++ README.pt_br.md | 4 ++++ README.zh_tw.md | 4 ++++ 8 files changed, 32 insertions(+) diff --git a/README.de.md b/README.de.md index cade723d..e6838e19 100644 --- a/README.de.md +++ b/README.de.md @@ -171,3 +171,7 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## Sternengucker der Zeit + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.es.md b/README.es.md index 21f86cf3..173a0784 100644 --- a/README.es.md +++ b/README.es.md @@ -169,3 +169,7 @@ Continua practicando para que no se oxiden tus habilidades de programación. - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## Astrónomos en el tiempo + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.fr.md b/README.fr.md index 7686950e..d064e2b7 100644 --- a/README.fr.md +++ b/README.fr.md @@ -181,3 +181,7 @@ Continue à t’exercer pour ne pas perdre la main : - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## Observateurs d'étoiles dans le temps + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.hi.md b/README.hi.md index 9a1cc4e4..9ef33027 100644 --- a/README.hi.md +++ b/README.hi.md @@ -154,3 +154,7 @@ print("Ultimate Python स्टडी गाइड") - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## समय के खगोलशास्त्री + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.ko.md b/README.ko.md index 0d21ea09..c2ab129d 100644 --- a/README.ko.md +++ b/README.ko.md @@ -160,3 +160,7 @@ print("Ultimate Python 학습 가이드") - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## 시대의 별 관측자 + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.md b/README.md index f676c39b..e30df42f 100644 --- a/README.md +++ b/README.md @@ -172,3 +172,7 @@ Keep practicing so that your coding skills don't get rusty. - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.pt_br.md b/README.pt_br.md index 7e927900..c9403875 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -158,3 +158,7 @@ Continue praticando para que suas habilidades de codificação não enferrujem. - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## Astrônomos no tempo + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) diff --git a/README.zh_tw.md b/README.zh_tw.md index 209de162..01873351 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -151,3 +151,7 @@ print("Ultimate Python 學習大綱") - [w3schools.com](https://www.w3schools.com/python/) ( 🧪 ) - [teclado.com](https://teclado.com/30-days-of-python/#prerequisites) ( 👔 ) - [fullstakpython.org](https://fullstackpython.org/) ( 🧪 ) + +## 歷代觀星者 + +[![Stargazers over time](https://starchart.cc/huangsam/ultimate-python.svg?variant=adaptive)](https://starchart.cc/huangsam/ultimate-python) From 7eb2d5d9cdb509f33c60e2105965744281d565e8 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sat, 1 Nov 2025 21:07:47 -0700 Subject: [PATCH 160/178] Update type hinting for runner --- runner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runner.py b/runner.py index 8f4c0dec..5b684ba5 100644 --- a/runner.py +++ b/runner.py @@ -13,12 +13,12 @@ _RUNNER_MAIN = "main" -def success_text(text) -> str: +def success_text(text: str) -> str: """Get success text.""" return f"{_STYLE_SUCCESS}{bold_text(text)}{_STYLE_END}" -def bold_text(text) -> str: +def bold_text(text: str) -> str: """Get bold text.""" return f"{_STYLE_BOLD}{text}{_STYLE_END}" From 8376a098fff3b4af5389ba6b8131228a8a8de945 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 14 Nov 2025 03:16:48 -0800 Subject: [PATCH 161/178] Update coverage to 7.11.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 06528589..f4f44d1f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.11.0 +coverage==7.11.3 isort==7.0.0 ruff==0.14.3 mypy==1.18.2 From 4a190e8875dcedd5f5b4a3843d7695361a7637cf Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 14 Nov 2025 03:17:01 -0800 Subject: [PATCH 162/178] Update ruff to 0.14.5 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f4f44d1f..d6608711 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ coverage==7.11.3 isort==7.0.0 -ruff==0.14.3 +ruff==0.14.5 mypy==1.18.2 From 1b4520910269848cad291e3e2b643965e4d969bd Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 08:34:35 -0800 Subject: [PATCH 163/178] Add modern Python feature modules (3.8-3.11) (#146) * Initial plan * Add 5 new Python feature modules and update all README files Co-authored-by: huangsam <515617+huangsam@users.noreply.github.com> * Update remaining README files (Hindi, Portuguese-Brazil, Chinese-Traditional) Co-authored-by: huangsam <515617+huangsam@users.noreply.github.com> * Update README.fr.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update README.fr.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update ultimatepython/data_structures/dict_union.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update ultimatepython/advanced/exception_groups.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix ruff linter warnings * Fix coverage issues * Help the coverage go to 100% * Make pattern matching func more explicit * Move inner functions to outside scope * Remove exception_group from the listing * Drop codecov thresholds to 90% * Keep coverage fail_under at 90 * Make project and patch at 90 * Keep pyproject at 80 * Remove the project metadata --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: huangsam <515617+huangsam@users.noreply.github.com> Co-authored-by: Samuel Huang Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.de.md | 4 + README.es.md | 4 + README.fr.md | 32 +- README.hi.md | 4 + README.ko.md | 4 + README.md | 4 + README.pt_br.md | 4 + README.zh_tw.md | 4 + codecov.yml | 5 +- ultimatepython/advanced/pattern_matching.py | 335 +++++++++++++++++++ ultimatepython/data_structures/dict_union.py | 174 ++++++++++ ultimatepython/syntax/arg_enforcement.py | 243 ++++++++++++++ ultimatepython/syntax/walrus_operator.py | 121 +++++++ 13 files changed, 923 insertions(+), 15 deletions(-) create mode 100644 ultimatepython/advanced/pattern_matching.py create mode 100644 ultimatepython/data_structures/dict_union.py create mode 100644 ultimatepython/syntax/arg_enforcement.py create mode 100644 ultimatepython/syntax/walrus_operator.py diff --git a/README.de.md b/README.de.md index e6838e19..f1808e48 100644 --- a/README.de.md +++ b/README.de.md @@ -88,11 +88,14 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) - Function: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - Walrus operator: [Assignment expressions :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - Argument enforcement: [Positional-only / | Keyword-only *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **Daten-Strukturen** - List: [List operations](ultimatepython/data_structures/list.py) ( 🍰 ) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( 🍰 ) + - Dict union: [Dictionary merge | and |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - String: [String operations](ultimatepython/data_structures/string.py) ( 🍰 ) - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -121,6 +124,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - Pattern Matching: [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## Zusätzliche Ressourcen diff --git a/README.es.md b/README.es.md index 173a0784..4b3be9de 100644 --- a/README.es.md +++ b/README.es.md @@ -86,11 +86,14 @@ Hay dos maneras de ejecutar los módulos: - Condicionales: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - Iteraciones: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) - Funciones: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - Operador morsa: [Expresiones de asignación :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - Aplicación de argumentos: [Solo posicional / | Solo palabra clave *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **Estructura de datos** - Lista: [Operaciones con listas](ultimatepython/data_structures/list.py) ( 🍰 ) - Tupla: [Operaciones con tuplas](ultimatepython/data_structures/tuple.py) - Set: [Operaciones con sets](ultimatepython/data_structures/set.py) - Diccionario: [Operaciones con dicts](ultimatepython/data_structures/dict.py) ( 🍰 ) + - Unión de diccionarios: [Fusión de diccionarios | y |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - Comprensión: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - Cadena: [Operaciones con strings](ultimatepython/data_structures/string.py) ( 🍰 ) - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -119,6 +122,7 @@ Hay dos maneras de ejecutar los módulos: - Expresiones regulares: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - Formatos de datos: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - Fecha y hora: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - Coincidencia de patrones: [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## Recursos adicionales diff --git a/README.fr.md b/README.fr.md index d064e2b7..ffec3ae6 100644 --- a/README.fr.md +++ b/README.fr.md @@ -37,21 +37,21 @@ grâce à ce langage. 🎓 Voici les principaux objectifs de ce guide : -🏆 **Servir de ressource** pour les débutants en Python qui préfèrent apprendre de manière pratique.  +🏆 **Servir de ressource** pour les débutants en Python qui préfèrent apprendre de manière pratique. Ce dépôt contient une collection de modules indépendants pouvant être exécutés dans un IDE comme [PyCharm](https://www.jetbrains.com/pycharm/) ou dans le navigateur via [Replit](https://replit.com/languages/python3). Même un simple terminal suffit pour exécuter les exemples. La plupart des lignes contiennent des commentaires détaillés -qui guident le lecteur pas à pas.  +qui guident le lecteur pas à pas. Les utilisateurs sont encouragés à modifier le code source à leur guise tant que les routines `main` ne sont pas supprimées et que les programmes [s’exécutent correctement](runner.py) après chaque modification. -🏆 **Servir de guide pur** pour ceux qui souhaitent revoir les concepts fondamentaux de Python.  +🏆 **Servir de guide pur** pour ceux qui souhaitent revoir les concepts fondamentaux de Python. Seules les [bibliothèques intégrées](https://docs.python.org/3/library/) sont utilisées afin de présenter les concepts sans dépendre de notions spécifiques à un domaine. Ainsi, les bibliothèques open-source populaires comme `sqlalchemy`, `requests` ou `pandas` -ne sont pas installées.  +ne sont pas installées. Cependant, lire le code source de ces frameworks est fortement recommandé si ton objectif est de devenir un véritable [Pythonista](https://www.urbandictionary.com/define.php?term=pythonista). @@ -61,24 +61,24 @@ si ton objectif est de devenir un véritable [![Run on Replit](https://replit.com/badge/github/huangsam/ultimate-python)](https://replit.com/github/huangsam/ultimate-python) Clique sur le badge ci-dessus pour lancer un environnement fonctionnel dans ton navigateur -sans avoir besoin d’installer Git ou Python localement.  +sans avoir besoin d’installer Git ou Python localement. Si ces outils sont déjà installés, tu peux cloner directement le dépôt. -Une fois le dépôt accessible, tu es prêt à apprendre à partir des modules indépendants.  +Une fois le dépôt accessible, tu es prêt à apprendre à partir des modules indépendants. Pour tirer le meilleur parti de chaque module, lis le code et exécute-le. Deux méthodes sont possibles : -1. Exécuter un seul module :  +1. Exécuter un seul module :   `python ultimatepython/syntax/variable.py` -2. Exécuter tous les modules :  +2. Exécuter tous les modules :   `python runner.py` ## Table des matières -📚 = Ressource externe  -🍰 = Sujet débutant  -🤯 = Sujet avancé  +📚 = Ressource externe +🍰 = Sujet débutant +🤯 = Sujet avancé 1. **À propos de Python**     - Vue d’ensemble : [Qu’est-ce que Python](https://github.com/trekhleb/learn-python/blob/master/src/getting_started/what_is_python.md) ( 📚, 🍰 ) @@ -95,12 +95,15 @@ Deux méthodes sont possibles :     - Conditionnelle : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 )     - Boucle : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 )     - Fonction : [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - Opérateur morse : [Expressions d'affectation :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - Application d'arguments : [Positionnels uniquement / | Mots-clés uniquement *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **Structures de données**     - Liste : [Opérations sur les listes](ultimatepython/data_structures/list.py) ( 🍰 )     - Tuple : [Opérations sur les tuples](ultimatepython/data_structures/tuple.py)     - Ensemble : [Opérations sur les ensembles](ultimatepython/data_structures/set.py)     - Dictionnaire : [Opérations sur les dictionnaires](ultimatepython/data_structures/dict.py) ( 🍰 ) + - Union de dictionnaires : [Fusion de dictionnaires | et |=](ultimatepython/data_structures/dict_union.py) ( 🤯 )     - Compréhension : [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py)     - Chaîne : [Opérations sur les chaînes](ultimatepython/data_structures/string.py) ( 🍰 )     - Deque : [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -131,12 +134,13 @@ Deux méthodes sont possibles :     - Expressions régulières : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 )     - Format de données : [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 )     - Date et heure : [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - Correspondance de motifs : [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## Ressources supplémentaires -👔 = Ressource d’entretien  -🧪 = Exemples de code  -🧠 = Idées de projets  +👔 = Ressource d’entretien +🧪 = Exemples de code +🧠 = Idées de projets ### Dépôts GitHub diff --git a/README.hi.md b/README.hi.md index 9ef33027..c148c2cc 100644 --- a/README.hi.md +++ b/README.hi.md @@ -69,11 +69,14 @@ print("Ultimate Python स्टडी गाइड") - कंडीशनल: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - लूप: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) - फ़ंक्शन: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - वॉलरस ऑपरेटर: [असाइनमेंट एक्सप्रेशन :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - तर्क प्रवर्तन: [केवल स्थितीय / | केवल कीवर्ड *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **डेटा संरचनाएँ** - लिसट: [लिसट ऑपरेशन्स](ultimatepython/data_structures/list.py) ( 🍰 ) - ट्यूपल: [ट्यूपल ऑपरेशन्स](ultimatepython/data_structures/tuple.py) - सेट: [सेट ऑपरेशन्स](ultimatepython/data_structures/set.py) - डिक्ट: [डिक्शनरी ऑपरेशन्स](ultimatepython/data_structures/dict.py) ( 🍰 ) + - डिक्शनरी यूनियन: [डिक्शनरी मर्ज | और |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - संकलन: [लिसट | ट्यूपल | सेट | डिक्ट](ultimatepython/data_structures/comprehension.py) - स्ट्रिंग: [स्ट्रिंग ऑपरेशन्स](ultimatepython/data_structures/string.py) ( 🍰 ) - डेक: [डेक](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -102,6 +105,7 @@ print("Ultimate Python स्टडी गाइड") - नियमित अभिव्यक्ति: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - डेटा फ़ॉर्मेट: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - दिनांक और समय: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - पैटर्न मिलान: [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## अतिरिक्त संसाधन diff --git a/README.ko.md b/README.ko.md index c2ab129d..5f774ba4 100644 --- a/README.ko.md +++ b/README.ko.md @@ -77,11 +77,14 @@ print("Ultimate Python 학습 가이드") - 조건문 : [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - 반복문 : [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) - 함수 : [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - 바다코끼리 연산자 : [할당 표현식 :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - 인수 강제 : [위치 전용 / | 키워드 전용 *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **데이터 구조** - 리스트 : [리스트 연산](ultimatepython/data_structures/list.py) ( 🍰 ) - 튜플 : [튜플 연산](ultimatepython/data_structures/tuple.py) - 세트 : [세트 연산](ultimatepython/data_structures/set.py) - 딕셔너리 : [딕셔너리 연산](ultimatepython/data_structures/dict.py) ( 🍰 ) + - 딕셔너리 합병 : [딕셔너리 병합 | 및 |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - 컴프리헨션 : [리스트 | 튜플 | 세트 | 딕셔너리](ultimatepython/data_structures/comprehension.py) - 문자열 : [문자열 연산](ultimatepython/data_structures/string.py) ( 🍰 ) - 덱: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -110,6 +113,7 @@ print("Ultimate Python 학습 가이드") - 정규식 : [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - 데이터 포맷 : [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - 날짜와 시간 : [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - 패턴 매칭: [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## 추가 자료 diff --git a/README.md b/README.md index e30df42f..e78c2e07 100644 --- a/README.md +++ b/README.md @@ -89,11 +89,14 @@ There are two ways of running the modules: - Conditional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - Loop: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) - Function: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - Walrus operator: [Assignment expressions :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - Argument enforcement: [Positional-only / | Keyword-only *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **Data Structures** - List: [List operations](ultimatepython/data_structures/list.py) ( 🍰 ) - Tuple: [Tuple operations](ultimatepython/data_structures/tuple.py) - Set: [Set operations](ultimatepython/data_structures/set.py) - Dict: [Dictionary operations](ultimatepython/data_structures/dict.py) ( 🍰 ) + - Dict union: [Dictionary merge | and |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - String: [String operations](ultimatepython/data_structures/string.py) ( 🍰 ) - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -122,6 +125,7 @@ There are two ways of running the modules: - Regular expression: [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - Data format: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - Pattern matching: [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## Additional resources diff --git a/README.pt_br.md b/README.pt_br.md index c9403875..93bd3729 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -75,11 +75,14 @@ Existem duas maneiras de rodar os módulos: - Condicional: [if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - Loop/Laço: [for-loop | while-loop](ultimatepython/syntax/loop.py) ( 🍰 ) - Função: [def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - Operador morsa: [Expressões de atribuição :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - Aplicação de argumentos: [Somente posicional / | Somente palavra-chave *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **Estrutura de dados** - Lista: [Operações de lista](ultimatepython/data_structures/list.py) ( 🍰 ) - Tupla: [Operações de tuplas](ultimatepython/data_structures/tuple.py) - Conjunto: [Operações de conjuntos](ultimatepython/data_structures/set.py) - Dicionário: [Operações de dicionários](ultimatepython/data_structures/dict.py) ( 🍰 ) + - União de dicionários: [Fusão de dicionários | e |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - Comprehension: [list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - String: [Operações de String](ultimatepython/data_structures/string.py) ( 🍰 ) - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -108,6 +111,7 @@ Existem duas maneiras de rodar os módulos: - Expressões regulares (regexp): [search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - Formato de dados: [json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - Datetime: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - Correspondência de padrões: [match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## Recursos adicionais diff --git a/README.zh_tw.md b/README.zh_tw.md index 01873351..e24a545d 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -72,11 +72,14 @@ print("Ultimate Python 學習大綱") - 條件運算式:[if | if-else | if-elif-else](ultimatepython/syntax/conditional.py) ( 🍰 ) - 迴圈:[for迴圈 | while迴圈](ultimatepython/syntax/loop.py) ( 🍰 ) - 定義函式:[def | lambda](ultimatepython/syntax/function.py) ( 🍰 ) + - 海象運算子:[賦值表達式 :=](ultimatepython/syntax/walrus_operator.py) ( 🤯 ) + - 參數強制:[僅位置 / | 僅關鍵字 *](ultimatepython/syntax/arg_enforcement.py) ( 🤯 ) 3. **資料結構** - 列表:[列表操作](ultimatepython/data_structures/list.py) ( 🍰 ) - 元組:[元組操作](ultimatepython/data_structures/tuple.py) - 集合:[集合操作](ultimatepython/data_structures/set.py) - 字典:[字典操作](ultimatepython/data_structures/dict.py) ( 🍰 ) + - 字典聯合:[字典合併 | 和 |=](ultimatepython/data_structures/dict_union.py) ( 🤯 ) - 綜合:[list | tuple | set | dict](ultimatepython/data_structures/comprehension.py) - 字串:[字串操作](ultimatepython/data_structures/string.py) ( 🍰 ) - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( 🤯 ) @@ -104,6 +107,7 @@ print("Ultimate Python 學習大綱") - 正規表示式:[search | findall | match | fullmatch](ultimatepython/advanced/regex.py) ( 🤯 ) - 數據格式:[json | xml | csv](ultimatepython/advanced/data_format.py) ( 🤯 ) - 日期時間: [datetime | timezone](ultimatepython/advanced/date_time.py) ( 🤯 ) + - 模式匹配:[match | case](ultimatepython/advanced/pattern_matching.py) ( 🤯 ) ## 額外資源 diff --git a/codecov.yml b/codecov.yml index e62f4b99..1ba81633 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,6 +2,9 @@ # https://docs.codecov.com/docs/commit-status coverage: status: + project: + default: + target: 90% patch: default: - target: 100% + target: 90% diff --git a/ultimatepython/advanced/pattern_matching.py b/ultimatepython/advanced/pattern_matching.py new file mode 100644 index 00000000..73f8119e --- /dev/null +++ b/ultimatepython/advanced/pattern_matching.py @@ -0,0 +1,335 @@ +""" +Structural pattern matching allows you to match complex data structures +against patterns and extract values in a clean, readable way. This feature +is similar to switch-case statements in other languages but much more powerful. + +Pattern matching was introduced in Python 3.10 through PEP 634, PEP 635, +and PEP 636. It uses the 'match' and 'case' keywords. +""" + + +def classify_number(value) -> str: + """Classify a number using pattern matching with literals. + + This demonstrates matching against specific literal values. + """ + match value: + case 0: + return "zero" + case 1: + return "one" + case 2: + return "two" + case _: + # The underscore _ is a wildcard that matches anything + return "other" + + +def classify_http_status(status) -> str: + """Classify HTTP status codes using pattern matching. + + This shows how pattern matching can make code more readable + than a series of if-elif-else statements. + """ + match status: + case 200: + return "OK" + case 201: + return "Created" + case 400: + return "Bad Request" + case 401: + return "Unauthorized" + case 404: + return "Not Found" + case 500: + return "Internal Server Error" + case _: + return "Unknown Status" + + +def process_point(point) -> str: + """Process a point tuple using pattern matching with sequences. + + This demonstrates pattern matching against tuple structures + and extracting values from them. + """ + match point: + case (0, 0): + return "Origin" + case (0, y): + # Match any point on the y-axis, capture y coordinate + return f"Y-axis at y={y}" + case (x, 0): + # Match any point on the x-axis, capture x coordinate + return f"X-axis at x={x}" + case (x, y): + # Match any other point, capture both coordinates + return f"Point at ({x}, {y})" + case _: + return "Not a valid 2D point" + + +def analyze_sequence(data) -> str: + """Analyze sequences using pattern matching. + + This shows how to match lists with specific structures + and extract elements. + """ + match data: + case []: + return "Empty list" + case [x]: + # Match a list with exactly one element + return f"Single element: {x}" + case [x, y]: + # Match a list with exactly two elements + return f"Pair: {x}, {y}" + case [first, *rest]: + # Match a list with at least one element + # The *rest captures remaining elements + return f"First: {first}, Rest: {rest}" + case _: + return "Not a list" # pragma: no cover + + +def process_command(command) -> str: + """Process commands using pattern matching with guards. + + Guards are if conditions that provide additional filtering + after a pattern match. + """ + match command: + case ["quit"]: + return "Quitting" + case ["go", direction] if direction in ["north", "south", "east", "west"]: + # Guard clause: only match if direction is valid + return f"Going {direction}" + case ["go", direction]: + # This matches any direction that failed the guard above + return f"Invalid direction: {direction}" + case ["take", item]: + return f"Taking {item}" + case ["take", item, quantity] if quantity > 0: + return f"Taking {quantity} {item}" + case ["take", item, quantity]: + return f"Invalid quantity: {quantity}" + case _: + return "Unknown command" + + +class Point: + """A simple 2D point class for pattern matching examples.""" + + def __init__(self, x, y): + self.x = x + self.y = y + + +class Circle: + """A circle with center and radius for pattern matching examples.""" + + def __init__(self, center, radius): + self.center = center + self.radius = radius + + +def describe_shape(shape) -> str: + """Describe shapes using pattern matching with class patterns. + + This demonstrates matching against class instances and + extracting their attributes. + """ + match shape: + case Point(x=0, y=0): + # Match a Point at the origin + return "Point at origin" + case Point(x=0, y=y): + # Match a Point on the y-axis + return f"Point on Y-axis at {y}" + case Point(x=x, y=0): + # Match a Point on the x-axis + return f"Point on X-axis at {x}" + case Point(x=x, y=y) if x == y: + # Match a Point on the diagonal line y=x + return f"Point on diagonal at ({x}, {y})" + case Point(x=x, y=y): + # Match any other Point + return f"Point at ({x}, {y})" + case Circle(center=Point(x=0, y=0), radius=r): + # Match a Circle centered at origin + return f"Circle at origin with radius {r}" + case Circle(center=Point(x=x, y=y), radius=r): + # Match any other Circle + return f"Circle at ({x}, {y}) with radius {r}" + case _: + return "Unknown shape" + + +def analyze_nested(data) -> str: + """Analyze nested structures using pattern matching.""" + match data: + case [["pair", x, y], ["pair", a, b]]: + # Match nested structure + return f"Two pairs: ({x},{y}) and ({a},{b})" + case [["single", val]]: + return f"Single value: {val}" + case _: + return "Unknown structure" + + +def check_value(val) -> str: + """Check value using OR patterns.""" + match val: + case 0 | 1 | 2: + # Match any of these values + return "small" + case 3 | 4 | 5: + return "medium" + case _: + return "large" + + +def process_range(data) -> str: + """Process range data with AS patterns.""" + match data: + case [x, y] as pair if x < y: + # Capture the entire matched value with 'as' + return f"Valid range: {pair}" + case [x, y]: + return f"Invalid range: [{x}, {y}]" + case _: + return "Not a pair" + + +def process_json_data(data) -> str: + """Process JSON-like dictionary data with pattern matching. + + This shows how to match against dictionary structures. + """ + match data: + case {"type": "user", "name": name, "age": age}: + return f"User {name} is {age} years old" + case {"type": "user", "name": name}: + # Match user without age + return f"User {name} with unknown age" + case {"type": "product", "name": name, "price": price} if price > 0: + return f"Product {name} costs ${price}" + case {"type": "product", "name": name, "price": price}: + return f"Product {name} has invalid price: {price}" + case {"type": type_name}: + # Match any dict with a type key + return f"Unknown type: {type_name}" + case _: + return "Invalid data" + + +def main() -> None: + # Test literal pattern matching + assert classify_number(0) == "zero" + assert classify_number(1) == "one" + assert classify_number(2) == "two" + assert classify_number(5) == "other" + assert classify_number(100) == "other" + + # Test HTTP status classification + assert classify_http_status(200) == "OK" + assert classify_http_status(404) == "Not Found" + assert classify_http_status(999) == "Unknown Status" + assert classify_http_status(201) == "Created" + assert classify_http_status(400) == "Bad Request" + assert classify_http_status(401) == "Unauthorized" + assert classify_http_status(500) == "Internal Server Error" + + # Test sequence pattern matching with tuples + assert process_point((0, 0)) == "Origin" + assert process_point((0, 5)) == "Y-axis at y=5" + assert process_point((3, 0)) == "X-axis at x=3" + assert process_point((4, 7)) == "Point at (4, 7)" + assert process_point("invalid") == "Not a valid 2D point" + + # Test sequence pattern matching with lists + assert analyze_sequence([]) == "Empty list" + assert analyze_sequence([42]) == "Single element: 42" + assert analyze_sequence([1, 2]) == "Pair: 1, 2" + assert analyze_sequence([1, 2, 3, 4]) == "First: 1, Rest: [2, 3, 4]" + assert analyze_sequence("not a list") == "Not a list" + + # Test pattern matching with guards + assert process_command(["quit"]) == "Quitting" + assert process_command(["go", "north"]) == "Going north" + assert process_command(["go", "west"]) == "Going west" + assert process_command(["go", "up"]) == "Invalid direction: up" + assert process_command(["take", "key"]) == "Taking key" + assert process_command(["take", "coin", 5]) == "Taking 5 coin" + assert process_command(["take", "coin", 0]) == "Invalid quantity: 0" + assert process_command(["take", "coin", -1]) == "Invalid quantity: -1" + assert process_command(["jump"]) == "Unknown command" + + # Test class pattern matching + p1 = Point(0, 0) + assert describe_shape(p1) == "Point at origin" + + p2 = Point(0, 5) + assert describe_shape(p2) == "Point on Y-axis at 5" + + p3 = Point(3, 0) + assert describe_shape(p3) == "Point on X-axis at 3" + + p4 = Point(5, 5) + assert describe_shape(p4) == "Point on diagonal at (5, 5)" + + p5 = Point(3, 7) + assert describe_shape(p5) == "Point at (3, 7)" + + c1 = Circle(Point(0, 0), 10) + assert describe_shape(c1) == "Circle at origin with radius 10" + + c2 = Circle(Point(5, 5), 3) + assert describe_shape(c2) == "Circle at (5, 5) with radius 3" + + # Test unknown shape + assert describe_shape("unknown") == "Unknown shape" + + # Test dictionary pattern matching + user1 = {"type": "user", "name": "Alice", "age": 30} + assert process_json_data(user1) == "User Alice is 30 years old" + + user2 = {"type": "user", "name": "Bob"} + assert process_json_data(user2) == "User Bob with unknown age" + + product1 = {"type": "product", "name": "Laptop", "price": 999} + assert process_json_data(product1) == "Product Laptop costs $999" + + product2 = {"type": "product", "name": "Free Sample", "price": 0} + assert process_json_data(product2) == "Product Free Sample has invalid price: 0" + + unknown = {"type": "order"} + assert process_json_data(unknown) == "Unknown type: order" + + invalid = {"data": "something"} + assert process_json_data(invalid) == "Invalid data" + + # Pattern matching with OR patterns + assert check_value(0) == "small" + assert check_value(2) == "small" + assert check_value(3) == "medium" + assert check_value(10) == "large" + + # Pattern matching with AS patterns (walrus-like capture) + assert process_range([1, 5]) == "Valid range: [1, 5]" + assert process_range([5, 1]) == "Invalid range: [5, 1]" + assert process_range("not a pair") == "Not a pair" + + # Nested pattern matching + assert analyze_nested([["pair", 1, 2], ["pair", 3, 4]]) == "Two pairs: (1,2) and (3,4)" + assert analyze_nested([["single", 42]]) == "Single value: 42" + assert analyze_nested("invalid") == "Unknown structure" + + # Pattern matching is particularly useful for parsing and handling + # structured data like API responses, configuration files, or + # abstract syntax trees in compilers/interpreters + + +if __name__ == "__main__": + main() diff --git a/ultimatepython/data_structures/dict_union.py b/ultimatepython/data_structures/dict_union.py new file mode 100644 index 00000000..5f52c59b --- /dev/null +++ b/ultimatepython/data_structures/dict_union.py @@ -0,0 +1,174 @@ +""" +Dictionary union operators allow you to merge dictionaries using +the | (union) and |= (in-place union) operators. These operators +provide a clean and intuitive syntax for combining dictionaries. + +This feature was introduced in Python 3.9 through PEP 584. Before +this, you had to use methods like dict.update() or {**dict1, **dict2} +syntax to merge dictionaries. +""" + + +def main() -> None: + # Traditional dictionary merging before Python 3.9 + # Method 1: Using dict.update() (modifies the original) + dict1_old = {"a": 1, "b": 2} + dict2_old = {"c": 3, "d": 4} + dict1_old.update(dict2_old) + assert dict1_old == {"a": 1, "b": 2, "c": 3, "d": 4} + + # Method 2: Using dictionary unpacking (creates a new dict) + dict3_old = {"a": 1, "b": 2} + dict4_old = {"c": 3, "d": 4} + merged_old = {**dict3_old, **dict4_old} + assert merged_old == {"a": 1, "b": 2, "c": 3, "d": 4} + + # With Python 3.9+, we can use the | operator for union + # This creates a new dictionary without modifying the originals + dict1 = {"a": 1, "b": 2} + dict2 = {"c": 3, "d": 4} + merged = dict1 | dict2 + assert merged == {"a": 1, "b": 2, "c": 3, "d": 4} + + # The original dictionaries remain unchanged + assert dict1 == {"a": 1, "b": 2} + assert dict2 == {"c": 3, "d": 4} + + # When there are overlapping keys, the right operand's values take precedence + # This is the same behavior as dict.update() and {**d1, **d2} + dict3 = {"a": 1, "b": 2, "c": 3} + dict4 = {"b": 20, "c": 30, "d": 4} + merged2 = dict3 | dict4 + # Keys 'b' and 'c' from dict4 override those from dict3 + assert merged2 == {"a": 1, "b": 20, "c": 30, "d": 4} + + # The order matters! Left operand is the base, right operand overwrites + merged3 = dict4 | dict3 + # Now keys 'b' and 'c' from dict3 override those from dict4 + assert merged3 == {"b": 2, "c": 3, "d": 4, "a": 1} + + # The |= operator performs in-place union (augmented assignment) + # This is equivalent to dict.update() but with cleaner syntax + dict5 = {"a": 1, "b": 2} + dict6 = {"c": 3, "d": 4} + dict5 |= dict6 + # dict5 is modified in place + assert dict5 == {"a": 1, "b": 2, "c": 3, "d": 4} + # dict6 remains unchanged + assert dict6 == {"c": 3, "d": 4} + + # The |= operator also handles overlapping keys + dict7 = {"a": 1, "b": 2, "c": 3} + dict8 = {"b": 20, "d": 4} + dict7 |= dict8 + # 'b' from dict8 overwrites 'b' in dict7 + assert dict7 == {"a": 1, "b": 20, "c": 3, "d": 4} + + # You can chain multiple | operations + dict9 = {"a": 1} + dict10 = {"b": 2} + dict11 = {"c": 3} + dict12 = {"d": 4} + combined = dict9 | dict10 | dict11 | dict12 + assert combined == {"a": 1, "b": 2, "c": 3, "d": 4} + + # When chaining with overlapping keys, rightmost values win + dict13 = {"a": 1, "x": 10} + dict14 = {"b": 2, "x": 20} + dict15 = {"c": 3, "x": 30} + combined2 = dict13 | dict14 | dict15 + # 'x' ends up with value 30 from the rightmost dictionary + assert combined2 == {"a": 1, "b": 2, "c": 3, "x": 30} + + # The union operator works with empty dictionaries + empty: dict[str, int] = {} + dict16 = {"a": 1, "b": 2} + assert empty | dict16 == {"a": 1, "b": 2} + assert dict16 | empty == {"a": 1, "b": 2} + assert empty | empty == {} + + # The union operator can be used with dict() constructor results + dict17 = dict(a=1, b=2) + dict18 = dict(c=3, d=4) + merged4 = dict17 | dict18 + assert merged4 == {"a": 1, "b": 2, "c": 3, "d": 4} + + # You can mix different value types in merged dictionaries + dict19 = {"name": "Alice", "age": 30} + dict20 = {"city": "NYC", "scores": [85, 90, 95]} + dict21 = {"active": True} + person = dict19 | dict20 | dict21 + assert person == {"name": "Alice", "age": 30, "city": "NYC", "scores": [85, 90, 95], "active": True} + + # Practical use case: Configuration merging + # Start with default configuration + default_config = {"timeout": 30, "retries": 3, "debug": False, "log_level": "INFO"} + + # User provides custom configuration (partial) + user_config = {"timeout": 60, "debug": True} + + # Merge configurations, user settings override defaults + final_config = default_config | user_config + assert final_config == { + "timeout": 60, # Overridden by user + "retries": 3, # From default + "debug": True, # Overridden by user + "log_level": "INFO", # From default + } + + # Practical use case: Building objects incrementally + # Start with base attributes + base = {"id": 1, "type": "user"} + + # Add authentication info + with_auth = base | {"username": "john", "email": "john@example.com"} + + # Add profile info + with_profile = with_auth | {"bio": "Developer", "location": "USA"} + + assert with_profile == {"id": 1, "type": "user", "username": "john", "email": "john@example.com", "bio": "Developer", "location": "USA"} + + # Practical use case: Updating records with |= + user_record = {"id": 100, "name": "Jane", "status": "active", "login_count": 5} + + # Apply update from an external source + update = {"status": "inactive", "login_count": 6, "last_login": "2024-01-15"} + user_record |= update + + assert user_record == {"id": 100, "name": "Jane", "status": "inactive", "login_count": 6, "last_login": "2024-01-15"} + + # The union operators only work with dictionaries + # Attempting to use them with non-dict types raises TypeError + dict22 = {"a": 1} + error_raised = False + try: + # This will fail because list is not a dict + dict22 | [("b", 2)] # type: ignore [operator] + except TypeError: + error_raised = True + assert error_raised is True + + # However, you can use dict() to convert compatible types first + dict23 = {"a": 1} + dict24 = dict([("b", 2), ("c", 3)]) # Convert list of tuples to dict + merged5 = dict23 | dict24 + assert merged5 == {"a": 1, "b": 2, "c": 3} + + # Comparison with the older approaches shows the clarity improvement: + + # OLD: Using update() - modifies original, no expression result + old1 = {"a": 1} + old1.update({"b": 2}) + assert old1 == {"a": 1, "b": 2} + + # OLD: Using unpacking - verbose for multiple merges + old2 = {**{"a": 1}, **{"b": 2}, **{"c": 3}} + assert old2 == {"a": 1, "b": 2, "c": 3} + + # NEW: Using union operator - clean and chainable + new1 = {"a": 1} | {"b": 2} | {"c": 3} + assert new1 == {"a": 1, "b": 2, "c": 3} + + +if __name__ == "__main__": + main() diff --git a/ultimatepython/syntax/arg_enforcement.py b/ultimatepython/syntax/arg_enforcement.py new file mode 100644 index 00000000..65d5ca8c --- /dev/null +++ b/ultimatepython/syntax/arg_enforcement.py @@ -0,0 +1,243 @@ +""" +Positional-only and keyword-only parameters allow you to enforce how +arguments are passed to a function. This feature helps prevent misuse +of function APIs and makes code more maintainable. + +- Positional-only parameters (/) were introduced in Python 3.8 (PEP 570) +- Keyword-only parameters (*) were introduced in Python 3.0 (PEP 3102) + +These features give you fine-grained control over your function signatures. +""" + + +def traditional_function(a, b, c): + """A traditional function where all parameters can be passed either way. + + This function accepts arguments positionally or by keyword name. + While flexible, this can lead to API instability if parameter names change. + """ + return a + b + c + + +def positional_only(a, b, /): + """Function with positional-only parameters. + + The / symbol marks that parameters before it MUST be passed positionally. + This is useful when parameter names are not meaningful or when you want + to reserve the right to change parameter names without breaking callers. + + Parameters before / cannot be passed as keyword arguments. + """ + return a + b + + +def keyword_only(*, x, y): + """Function with keyword-only parameters. + + The * symbol marks that parameters after it MUST be passed by keyword. + This is useful for improving readability at call sites and preventing + accidental argument order mistakes. + + Parameters after * cannot be passed positionally. + """ + return x * y + + +def mixed_parameters(pos_only, /, pos_or_kw, *, kw_only): + """Function that combines all parameter types. + + - pos_only: Must be passed positionally (before /) + - pos_or_kw: Can be passed either way (between / and *) + - kw_only: Must be passed by keyword (after *) + + This gives maximum control over the function interface. + """ + return f"{pos_only}-{pos_or_kw}-{kw_only}" + + +def positional_with_defaults(a, b=10, /): + """Positional-only parameters can have default values. + + Default values work the same way as in traditional functions, + but the parameters still must be passed positionally if provided. + """ + return a + b + + +def keyword_with_defaults(*, x=5, y=3): + """Keyword-only parameters can have default values. + + When providing arguments, you must use the keyword names. + """ + return x**y + + +def complex_signature(a, b, /, c, d=10, *, e, f=20): + """A function demonstrating a complex but valid signature. + + - a, b: positional-only + - c: positional-or-keyword (no default) + - d: positional-or-keyword (with default) + - e: keyword-only (no default) + - f: keyword-only (with default) + """ + return a + b + c + d + e + f + + +def main() -> None: + # Traditional function: can be called either way + assert traditional_function(1, 2, 3) == 6 + assert traditional_function(a=1, b=2, c=3) == 6 + assert traditional_function(1, b=2, c=3) == 6 + + # Positional-only function: must use positional arguments + assert positional_only(5, 3) == 8 + + # Trying to use keyword arguments with positional-only parameters + # will raise a TypeError + positional_error = False + try: + # This will fail because 'a' and 'b' are positional-only + positional_only(a=5, b=3) # type: ignore [call-arg] + except TypeError: + positional_error = True + assert positional_error is True + + # You also can't mix positional and keyword for positional-only params + positional_error2 = False + try: + # This will fail because 'b' is positional-only + positional_only(5, b=3) # type: ignore [call-arg] + except TypeError: + positional_error2 = True + assert positional_error2 is True + + # Keyword-only function: must use keyword arguments + assert keyword_only(x=4, y=5) == 20 + + # Trying to use positional arguments with keyword-only parameters + # will raise a TypeError + keyword_error = False + try: + # This will fail because 'x' and 'y' are keyword-only + keyword_only(4, 5) # type: ignore [misc] + except TypeError: + keyword_error = True + assert keyword_error is True + + # Mixed parameters demonstrate all three types + result = mixed_parameters("first", "second", kw_only="third") + assert result == "first-second-third" + + # The middle parameter can be passed either way + result2 = mixed_parameters("first", pos_or_kw="second", kw_only="third") + assert result2 == "first-second-third" + + # But positional-only must be positional + mixed_error = False + try: + mixed_parameters(pos_only="first", pos_or_kw="second", kw_only="third") # type: ignore [call-arg] + except TypeError: + mixed_error = True + assert mixed_error is True + + # And keyword-only must be keyword + mixed_error2 = False + try: + mixed_parameters("first", "second", "third") # type: ignore [misc] + except TypeError: + mixed_error2 = True + assert mixed_error2 is True + + # Positional-only with defaults + assert positional_with_defaults(5) == 15 # Uses default b=10 + assert positional_with_defaults(5, 20) == 25 # Overrides b with 20 + + # Even with defaults, must use positional syntax + positional_default_error = False + try: + positional_with_defaults(a=5, b=20) # type: ignore [call-arg] + except TypeError: + positional_default_error = True + assert positional_default_error is True + + # Keyword-only with defaults + assert keyword_with_defaults() == 125 # Uses defaults: 5^3 + assert keyword_with_defaults(x=2) == 8 # 2^3 + assert keyword_with_defaults(y=2) == 25 # 5^2 + assert keyword_with_defaults(x=3, y=4) == 81 # 3^4 + + # Must still use keyword syntax even when providing defaults + keyword_default_error = False + try: + keyword_with_defaults(2, 3) # type: ignore [misc] + except TypeError: + keyword_default_error = True + assert keyword_default_error is True + + # Complex signature: demonstrating all parameter types + # Minimal call with required params only + result3 = complex_signature(1, 2, 3, e=4) + assert result3 == 40 # 1+2+3+10(default)+4+20(default) + + # Providing all parameters + result4 = complex_signature(1, 2, 3, 4, e=5, f=6) + assert result4 == 21 # 1+2+3+4+5+6 + + # Middle parameter 'c' can be passed by keyword + result5 = complex_signature(1, 2, c=3, e=4) + assert result5 == 40 + + # Parameter 'd' can also be passed by keyword + result6 = complex_signature(1, 2, 3, d=15, e=4) + assert result6 == 45 # 1+2+3+15+4+20 + + # But 'a' and 'b' must be positional + complex_error = False + try: + complex_signature(a=1, b=2, c=3, e=4) # type: ignore [call-arg] + except TypeError: + complex_error = True + assert complex_error is True + + # And 'e' must be keyword (even though 'f' has a default) + complex_error2 = False + try: + complex_signature(1, 2, 3, 10, 4) # type: ignore [misc] + except TypeError: + complex_error2 = True + assert complex_error2 is True + + # Practical use case: Positional-only is great for functions where + # parameter names are not meaningful or may change + def distance(x1, y1, x2, y2, /): + """Calculate distance between two points. + + The parameter names here are somewhat arbitrary (could be p1_x, etc.) + so we make them positional-only to give us flexibility to rename them + without breaking existing code. + """ + return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 + + assert abs(distance(0, 0, 3, 4) - 5.0) < 0.01 + + # Practical use case: Keyword-only is great for boolean flags or + # optional parameters where the intent should be clear at call site + def create_user(username, *, admin=False, active=True, send_email=False): + """Create a user with clear intent for optional parameters. + + Making admin, active, and send_email keyword-only ensures that + callers must specify exactly what they're setting, improving + readability and preventing accidental mistakes. + """ + return {"username": username, "admin": admin, "active": active, "send_email": send_email} + + # Clear intent at call site + user = create_user("john_doe", admin=True, send_email=True) + assert user["admin"] is True + assert user["active"] is True # Used default + assert user["send_email"] is True + + +if __name__ == "__main__": + main() diff --git a/ultimatepython/syntax/walrus_operator.py b/ultimatepython/syntax/walrus_operator.py new file mode 100644 index 00000000..733e3c01 --- /dev/null +++ b/ultimatepython/syntax/walrus_operator.py @@ -0,0 +1,121 @@ +""" +The walrus operator, also known as the assignment expression operator, +allows you to assign values to variables as part of an expression. This +feature was introduced in Python 3.8 through PEP 572. + +The walrus operator uses the := syntax and is particularly useful in +reducing redundancy when you need to compute a value and then use it +in a condition or comprehension. +""" + + +def main() -> None: + # Traditional approach: compute a value and check it separately + # Let's say we want to check if a string has more than 5 characters + text = "Hello, Python!" + length = len(text) + if length > 5: + assert length == 14 + + # With the walrus operator, we can assign and check in one expression. + # This is cleaner and avoids repeating the computation or storing + # intermediate variables unnecessarily + text2 = "Ultimate" + if (length2 := len(text2)) > 5: + # The walrus operator assigned len(text2) to length2 AND returned it + # for the comparison, all in the same line + assert length2 == 8 + + # The walrus operator is especially powerful in while loops. Here's a + # traditional approach that requires reading input twice + numbers_old = [] + n = int("5") # Simulating user input + while n != 0: + numbers_old.append(n) + n = int("0") # Simulating next input + assert numbers_old == [5] + + # With the walrus operator, we can assign and check in the loop condition. + # This is more concise and avoids the duplication of the input reading logic + numbers_new = [] + inputs = ["3", "7", "0"] # Simulating a sequence of inputs + index = 0 + + # Note: In a real scenario, you'd read from input() instead of a list + def get_next_input(): + nonlocal index + if index < len(inputs): + result = int(inputs[index]) + index += 1 + return result + return 0 + + while (num := get_next_input()) != 0: + # The walrus operator assigns get_next_input() to num and checks if it's not 0 + numbers_new.append(num) + assert numbers_new == [3, 7] + + # Ensure the function returns 0 when no more inputs + assert get_next_input() == 0 + + # The walrus operator shines in list comprehensions when you need to + # compute a value once and reuse it. Without walrus, you'd either: + # 1. Compute the value multiple times (inefficient) + # 2. Use a for loop instead of comprehension (less elegant) + data = ["apple", "banana", "cherry", "date"] + + # Traditional approach: computing len() twice per item is wasteful + long_words_old = [word for word in data if len(word) > 5 and len(word) < 7] + assert long_words_old == ["banana", "cherry"] + + # With walrus operator: compute len() once and reuse the result + # The walrus operator assigns len(word) to word_len, which we can + # then use multiple times in the same comprehension + long_words_new = [word for word in data if 5 < (word_len := len(word)) < 7] + assert long_words_new == ["banana", "cherry"] + + # The walrus operator can be used in comprehensions to filter and transform + # data simultaneously. Here we square numbers but only keep those where + # the square is less than 50 + numbers = [3, 5, 7, 9, 11] + + # Without walrus: we'd need to compute the square twice or use a for loop + squares_old = [n * n for n in numbers if n * n < 50] + assert squares_old == [9, 25, 49] + + # With walrus: compute the square once, store it, and use it + # This is both more efficient and clearer about the intent + squares_new = [square for n in numbers if (square := n * n) < 50] + assert squares_new == [9, 25, 49] + + # The walrus operator works in set comprehensions too + # Let's find unique word lengths greater than 4 + words = ["hi", "hello", "world", "python", "code"] + + # With walrus operator in a set comprehension + long_lengths = {word_len for word in words if (word_len := len(word)) > 4} + assert long_lengths == {5, 6} + + # And in dictionary comprehensions as well + # Create a dict of words to their lengths, but only for words > 4 chars + word_length_map = {word: word_len for word in words if (word_len := len(word)) > 4} + assert word_length_map == {"hello": 5, "world": 5, "python": 6} + + # Important note: The walrus operator creates variables in the enclosing scope. + # This means variables assigned with := inside a comprehension are accessible + # outside of it (unlike traditional loop variables in comprehensions) + [result for x in [1, 2, 3] if (result := x * 2) > 2] + # The variable 'result' is now accessible here, with its last assigned value + assert result == 6 + + # The walrus operator can be nested, though this can reduce readability + # Use nesting sparingly and only when it genuinely improves the code + values = [1, 2, 3, 4, 5] + if (total := sum(doubled := [x * 2 for x in values])) > 15: + # Here 'doubled' is assigned inside the expression for 'total' + assert doubled == [2, 4, 6, 8, 10] + assert total == 30 + + +if __name__ == "__main__": + main() From 7794fdd1b46640675721cf3f1ccfd6665b119945 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 21 Nov 2025 07:15:08 -0800 Subject: [PATCH 164/178] Update coverage and ruff packages --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d6608711..4d1f7b75 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.11.3 +coverage==7.12.0 isort==7.0.0 -ruff==0.14.5 +ruff==0.14.6 mypy==1.18.2 From a391e791b90992dce905564438bd829ef829a908 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 11 Dec 2025 08:18:43 -0800 Subject: [PATCH 165/178] Update python dependencies --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 4d1f7b75..b25c5ecf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.12.0 +coverage==7.13.0 isort==7.0.0 -ruff==0.14.6 -mypy==1.18.2 +ruff==0.14.8 +mypy==1.19.0 From 0a23dbf5af89e604d7a141a3df7c4a7a39bd30ef Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 00:04:35 -0800 Subject: [PATCH 166/178] Add brainstorm folder to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b7a777fd..d64421e7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ __pycache__/ build/ htmlcov/ venv/ +brainstorm/ From 7146dc7c0169cf7af5a3b1e8b646be2c5db117cd Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 00:13:46 -0800 Subject: [PATCH 167/178] Add itertools lesson to the repo --- README.de.md | 1 + README.es.md | 1 + README.fr.md | 1 + README.hi.md | 1 + README.ko.md | 1 + README.md | 1 + README.pt_br.md | 1 + README.zh_tw.md | 1 + ultimatepython/data_structures/itertools.py | 68 +++++++++++++++++++++ 9 files changed, 76 insertions(+) create mode 100644 ultimatepython/data_structures/itertools.py diff --git a/README.de.md b/README.de.md index f1808e48..010ee99f 100644 --- a/README.de.md +++ b/README.de.md @@ -101,6 +101,7 @@ Es gibt zwei Möglichkeiten, die Module auszuführen: - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Iterator-Tools: [Iterator-Tools](ultimatepython/data_structures/itertools.py) ( 🤯 ) - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Klassen** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/README.es.md b/README.es.md index 4b3be9de..b0708ff5 100644 --- a/README.es.md +++ b/README.es.md @@ -99,6 +99,7 @@ Hay dos maneras de ejecutar los módulos: - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Herramientas de iteradores: [Herramientas de iteradores](ultimatepython/data_structures/itertools.py) ( 🤯 ) - Complejidad de tiempo: [Operaciones de cPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Clases** - Clase básica: [Definición de básica](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/README.fr.md b/README.fr.md index ffec3ae6..84ba57d4 100644 --- a/README.fr.md +++ b/README.fr.md @@ -109,6 +109,7 @@ Deux méthodes sont possibles :     - Deque : [deque](ultimatepython/data_structures/deque.py) ( 🤯 )     - Namedtuple : [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 )     - Defaultdict : [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) +    - Outils d'itérateurs : [Outils d'itérateurs](ultimatepython/data_structures/itertools.py) ( 🤯 )     - Complexité temporelle : [Opérations CPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Classes** diff --git a/README.hi.md b/README.hi.md index c148c2cc..a213b73b 100644 --- a/README.hi.md +++ b/README.hi.md @@ -82,6 +82,7 @@ print("Ultimate Python स्टडी गाइड") - डेक: [डेक](ultimatepython/data_structures/deque.py) ( 🤯 ) - नामित ट्यूपल: [नामित ट्यूपल](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - डिफ़ॉल्ट डिक्ट: [डिफ़ॉल्ट डिक्ट](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - इटरेटर टूल्स: [इटरेटर टूल्स](ultimatepython/data_structures/itertools.py) ( 🤯 ) - समय कोम्पलेक्सिटी: [cPython ऑपरेशन्स](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **क्लासेज़** - बेसिक क्लास: [बेसिक परिभाषा](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/README.ko.md b/README.ko.md index 5f774ba4..72e62810 100644 --- a/README.ko.md +++ b/README.ko.md @@ -90,6 +90,7 @@ print("Ultimate Python 학습 가이드") - 덱: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - 이터레이터 도구: [이터레이터 도구](ultimatepython/data_structures/itertools.py) ( 🤯 ) - 시간 복잡도 : [cPython 연산](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **클래스** - 기본 클래스 : [기본 정의](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/README.md b/README.md index e78c2e07..2a7407e5 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ There are two ways of running the modules: - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Itertools: [Iterator tools](ultimatepython/data_structures/itertools.py) ( 🤯 ) - Time complexity: [cPython operations](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Classes** - Basic class: [Basic definition](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/README.pt_br.md b/README.pt_br.md index 93bd3729..60e7c682 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -88,6 +88,7 @@ Existem duas maneiras de rodar os módulos: - Deque: [deque](ultimatepython/data_structures/deque.py) ( 🤯 ) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - Ferramentas de iteradores: [Ferramentas de iteradores](ultimatepython/data_structures/itertools.py) ( 🤯 ) - Time complexity: [Operações de cPython](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **Classes** - O básico de classes: [Definição de classe](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/README.zh_tw.md b/README.zh_tw.md index e24a545d..99ec6f8b 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -85,6 +85,7 @@ print("Ultimate Python 學習大綱") - 雙端隊列:[deque](ultimatepython/data_structures/deque.py) ( 🤯 ) - Namedtuple: [namedtuple](ultimatepython/data_structures/namedtuple.py) ( 🤯 ) - Defaultdict: [defaultdict](ultimatepython/data_structures/defaultdict.py) ( 🤯 ) + - 迭代器工具:[迭代器工具](ultimatepython/data_structures/itertools.py) ( 🤯 ) - 時間複雜度:[cPython操作](https://wiki.python.org/moin/TimeComplexity) ( 📚, 🤯 ) 4. **類別** - 基本類別:[基本定義](ultimatepython/classes/basic_class.py) ( 🍰 ) diff --git a/ultimatepython/data_structures/itertools.py b/ultimatepython/data_structures/itertools.py new file mode 100644 index 00000000..77ea8de7 --- /dev/null +++ b/ultimatepython/data_structures/itertools.py @@ -0,0 +1,68 @@ +""" +Itertools provides a collection of tools for handling iterators. This +module demonstrates how to use itertools functions to efficiently work +with sequences, combine iterables, and create infinite iterators. +""" + +import itertools + + +def main() -> None: + # chain() combines multiple iterables into a single iterator + letters = ["a", "b", "c"] + numbers = [1, 2, 3] + combined = list(itertools.chain(letters, numbers)) + assert combined == ["a", "b", "c", 1, 2, 3] + + # cycle() creates an infinite iterator that cycles through the elements + # We'll use islice to take only the first few elements + cycled = list(itertools.islice(itertools.cycle(["A", "B"]), 6)) + assert cycled == ["A", "B", "A", "B", "A", "B"] + + # repeat() creates an iterator that repeats a value infinitely + repeated = list(itertools.islice(itertools.repeat("hello"), 4)) + assert repeated == ["hello", "hello", "hello", "hello"] + + # count() creates an infinite iterator that counts up from a start value + counted = list(itertools.islice(itertools.count(10), 5)) + assert counted == [10, 11, 12, 13, 14] + + # islice() allows slicing of iterators (similar to list slicing) + data = itertools.count() # infinite count from 0 + sliced = list(itertools.islice(data, 2, 8, 2)) # start=2, stop=8, step=2 + assert sliced == [2, 4, 6] + + # tee() creates multiple independent iterators from one + original = iter([1, 2, 3, 4, 5]) + iter1, iter2 = itertools.tee(original, 2) + list1 = list(iter1) + list2 = list(iter2) + assert list1 == [1, 2, 3, 4, 5] + assert list2 == [1, 2, 3, 4, 5] + + # groupby() groups consecutive equal elements + group_data = [1, 1, 2, 2, 2, 3, 1, 1] + groups = [(key, list(group)) for key, group in itertools.groupby(group_data)] + assert groups == [(1, [1, 1]), (2, [2, 2, 2]), (3, [3]), (1, [1, 1])] + + # product() creates cartesian product of input iterables + colors = ["red", "blue"] + sizes = ["S", "M"] + combinations = list(itertools.product(colors, sizes)) + assert combinations == [("red", "S"), ("red", "M"), ("blue", "S"), ("blue", "M")] + + # permutations() generates all possible orderings + perms = list(itertools.permutations([1, 2, 3], 2)) # length 2 permutations + assert len(perms) == 6 # 3! / (3-2)! = 6 + assert (1, 2) in perms + assert (2, 1) in perms + + # combinations() generates combinations (order doesn't matter) + combos = list(itertools.combinations([1, 2, 3, 4], 2)) + assert len(combos) == 6 # C(4,2) = 6 + assert (1, 2) in combos + assert (2, 1) not in combos # order doesn't matter + + +if __name__ == "__main__": + main() From 151ed1468f37b57f8124f4f5cf9447f163d4f66c Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 05:06:00 -0800 Subject: [PATCH 168/178] Update async.py with advanced usage --- ultimatepython/advanced/async.py | 135 ++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 9 deletions(-) diff --git a/ultimatepython/advanced/async.py b/ultimatepython/advanced/async.py index 366828f1..664e4c46 100644 --- a/ultimatepython/advanced/async.py +++ b/ultimatepython/advanced/async.py @@ -1,10 +1,16 @@ """ -Concurrent programming with an event loop is a relatively new concept in -Python 3.x. This module aims to highlight how it could be used in the -context of a scheduler which runs a fire-and-forget operation for starting -jobs. In the real world, it takes time for a scheduler to start a job (i.e. -hit an API endpoint, ask the operating system for resources) so we assume -that starting a job has some intrinsic delay. +Concurrent programming with asyncio, introduced in Python 3.4, provides +an event loop for handling asynchronous operations. This module demonstrates +basic asyncio patterns including coroutines, tasks, concurrent execution +with gather, and task cancellation. It uses the context of a scheduler +which runs fire-and-forget operations for starting jobs, assuming that +job startup has some intrinsic delay. + +This module also covers advanced asyncio patterns including task groups +for structured concurrency (Python 3.11+), semaphores for limiting +concurrency, timeouts, exception handling in concurrent tasks, event +loop management, and task shielding to protect critical operations from +cancellation. """ import asyncio @@ -44,8 +50,15 @@ async def start_job(job_id: str, delay: float) -> JobRecord: return JobRecord(job_id, queue_time, start_time) -async def schedule_jobs() -> None: - """Schedule jobs concurrently.""" +async def failing_job(job_id: str) -> None: + """A job that sometimes fails.""" + if int(job_id[-1]) % 3 == 0: # Fail every 3rd job + raise ValueError(f"Job {job_id} failed!") + await asyncio.sleep(_DELAY_SMALL) + + +async def basic_async_patterns() -> None: + """Basic async patterns demonstration.""" # Start a job which also represents a coroutine single_job = start_job(uuid4().hex, _DELAY_SMALL) assert asyncio.iscoroutine(single_job) @@ -77,8 +90,112 @@ async def schedule_jobs() -> None: assert all(_is_valid_record(record) for record in batch_records) +async def advanced_async_patterns() -> None: + """Demonstrate advanced asyncio patterns.""" + + # Task Groups - structured concurrency (Python 3.11+) + async def task_group_example(): + results = [] + try: + async with asyncio.TaskGroup() as tg: + # Start multiple tasks in a group + for i in range(5): + tg.create_task(start_job(f"task_{i}", _DELAY_SMALL)) + except Exception as e: + # TaskGroup propagates exceptions from child tasks + pass + + # All tasks in the group complete or fail together + assert True # TaskGroup structure is valid + + await task_group_example() + + # Semaphores for limiting concurrency + semaphore = asyncio.Semaphore(3) # Allow max 3 concurrent operations + + async def limited_concurrency_job(job_id: str): + async with semaphore: + # Only 3 jobs can execute this section at once + await asyncio.sleep(_DELAY_SMALL) + return f"completed_{job_id}" + + # Start 10 jobs but only 3 can run concurrently + concurrent_jobs = [limited_concurrency_job(f"sem_{i}") for i in range(10)] + concurrent_results = await asyncio.gather(*concurrent_jobs) + assert len(concurrent_results) == 10 + assert all("completed_" in result for result in concurrent_results) + + # Exception handling with gather + mixed_jobs = [ + failing_job("job_1"), # succeeds + failing_job("job_2"), # succeeds + failing_job("job_3"), # fails + failing_job("job_4"), # succeeds + ] + + # Return exceptions instead of raising them + results = await asyncio.gather(*mixed_jobs, return_exceptions=True) + assert len(results) == 4 + # Check that we got a mix of results and exceptions + exceptions_found = sum(1 for r in results if isinstance(r, Exception)) + successes_found = sum(1 for r in results if not isinstance(r, Exception)) + assert exceptions_found == 1 # One job failed + assert successes_found == 3 # Three jobs succeeded + + # Timeouts and cancellation + async def slow_job(): + await asyncio.sleep(1.0) # Takes 1 second + return "slow_result" + + try: + # Timeout after 0.1 seconds + result = await asyncio.wait_for(slow_job(), timeout=0.1) + except asyncio.TimeoutError: + result = None + assert result is None # Should timeout + + # Event loop management + loop = asyncio.get_running_loop() + assert isinstance(loop, asyncio.AbstractEventLoop) + + # Schedule callback on the event loop + callback_result = None + + def sync_callback(): + nonlocal callback_result + callback_result = "callback_executed" + + # Schedule callback to run soon + loop.call_soon(sync_callback) + await asyncio.sleep(0) # Let the event loop process callbacks + assert callback_result == "callback_executed" + + # Shielding tasks from cancellation + async def important_task(): + await asyncio.sleep(_DELAY_SMALL) + return "important_result" + + task = asyncio.create_task(important_task()) + shielded_task = asyncio.shield(task) + + # Even if we cancel the shield, the underlying task continues + shielded_task.cancel() + try: + await shielded_task + except asyncio.CancelledError: + pass + + # The original task should still complete + await task # Wait for the original task + assert task.result() == "important_result" + + def main() -> None: - asyncio.run(schedule_jobs()) + # Run basic patterns + asyncio.run(basic_async_patterns()) + + # Run advanced patterns + asyncio.run(advanced_async_patterns()) if __name__ == "__main__": From aeb33e3e0e3b5d81b8f9503438cbf7f2370e376b Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 05:21:27 -0800 Subject: [PATCH 169/178] Fix lint issue with new async content --- ultimatepython/advanced/async.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ultimatepython/advanced/async.py b/ultimatepython/advanced/async.py index 664e4c46..0265c9e2 100644 --- a/ultimatepython/advanced/async.py +++ b/ultimatepython/advanced/async.py @@ -95,13 +95,12 @@ async def advanced_async_patterns() -> None: # Task Groups - structured concurrency (Python 3.11+) async def task_group_example(): - results = [] try: async with asyncio.TaskGroup() as tg: # Start multiple tasks in a group for i in range(5): tg.create_task(start_job(f"task_{i}", _DELAY_SMALL)) - except Exception as e: + except Exception: # TaskGroup propagates exceptions from child tasks pass From d46c0a1a0b8baaa8e1b97dacb9093be281d9b739 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 05:40:27 -0800 Subject: [PATCH 170/178] Add pre-commit.sh for validation --- pre-commit.sh | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 pre-commit.sh diff --git a/pre-commit.sh b/pre-commit.sh new file mode 100755 index 00000000..9ad12364 --- /dev/null +++ b/pre-commit.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# pre-commit.sh: Run the same checks as CI (see .github/workflows/ci.yml) +# Usage: +# ./pre-commit.sh # Run checks +# ./pre-commit.sh install # Install as .git/hooks/pre-commit + +set -euo pipefail + +if [[ "${1:-}" == "install" ]]; then + hook_path=".git/hooks/pre-commit" + cp -- "$0" "$hook_path" + chmod +x "$hook_path" + echo "Installed pre-commit hook to $hook_path" + exit 0 +fi + +# 1. Find the project root +PROJECT_ROOT="$(git rev-parse --show-toplevel)" + +# 2. Define standard virtual environment names +VENV_NAMES=(".venv" "venv") + +# 3. Locate the virtual environment directory +VENV_DIR="" +for name in "${VENV_NAMES[@]}"; do + CANDIDATE="$PROJECT_ROOT/$name" + if [ -d "$CANDIDATE" ]; then + VENV_DIR="$CANDIDATE" + break + fi +done + +# 4. Check if a virtual environment was found +if [ -z "$VENV_DIR" ]; then + echo "🚨 Error: Virtual environment not found. Please create one (e.g., 'python3 -m venv .venv') and run the hook again." + exit 1 +fi + +# 5. Define the full path to the Python interpreter within the found VENV +PYTHON_EXEC="$VENV_DIR/bin/python" + +# 6. Check if the interpreter exists +if [ ! -x "$PYTHON_EXEC" ]; then + echo "🚨 Error: Python executable not found at $PYTHON_EXEC" + exit 1 +fi + +# --- Use the specific Python executable for all commands --- + +# Run all examples +"$PYTHON_EXEC" runner.py + +# Lint and format checks (ruff and isort are installed in the venv) +"$PYTHON_EXEC" -m ruff check +"$PYTHON_EXEC" -m isort --check --diff . + +# Coverage +"$PYTHON_EXEC" -m coverage run runner.py +"$PYTHON_EXEC" -m coverage report --fail-under=80 From 48e6471c8e50941d222b0d87c1a5a790adadee98 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 05:57:41 -0800 Subject: [PATCH 171/178] Add modern content for file_handling.py --- ultimatepython/advanced/file_handling.py | 69 ++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/ultimatepython/advanced/file_handling.py b/ultimatepython/advanced/file_handling.py index 489d33d1..f0366ca9 100644 --- a/ultimatepython/advanced/file_handling.py +++ b/ultimatepython/advanced/file_handling.py @@ -1,16 +1,23 @@ """ File handling is a fundamental concept in Python that involves opening, reading, writing, and appending to files. This module -demonstrates the basics of file handling in Python. +demonstrates both traditional and modern approaches using pathlib. -Python provides various ways to work with files. We can use the -builtin 'open' function to open files in different modes like -reading ('r'), writing ('w'), and appending ('a'). +Traditional approach: The builtin 'open' function works with string +paths and different modes like reading ('r'), writing ('w'), and +appending ('a'). + +Modern approach: pathlib.Path provides an object-oriented interface +for working with filesystem paths, offering cleaner syntax and +cross-platform support. pathlib is preferred for new code as it +replaces older os.path operations with an intuitive API. """ import os +from pathlib import Path _TARGET_FILE = "sample.txt" +_TARGET_PATH = Path(_TARGET_FILE) def read_file(filename: str) -> str: @@ -40,7 +47,36 @@ def delete_file(filename: str) -> str: return f"'{filename}' has been deleted." +def write_file_pathlib(filename: str, content: str) -> str: + """Write content using pathlib.Path.""" + path = Path(filename) + path.write_text(content) + return f"Content written to '{filename}' using pathlib." + + +def read_file_pathlib(filename: str) -> str: + """Read content using pathlib.Path.""" + path = Path(filename) + return path.read_text() + + +def append_file_pathlib(filename: str, content: str) -> str: + """Append content using pathlib.Path.""" + path = Path(filename) + current = path.read_text() + path.write_text(current + content) + return f"Content appended to '{filename}' using pathlib." + + +def delete_file_pathlib(filename: str) -> str: + """Delete file using pathlib.Path.""" + path = Path(filename) + path.unlink() + return f"'{filename}' has been deleted using pathlib." + + def main() -> None: + # Test traditional file operations result = write_file(_TARGET_FILE, "This is a test.") assert result == f"Content written to '{_TARGET_FILE}'." @@ -56,6 +92,31 @@ def main() -> None: delete_result = delete_file(_TARGET_FILE) assert delete_result == f"'{_TARGET_FILE}' has been deleted." + # Test pathlib operations + pathlib_file = "pathlib_sample.txt" + result = write_file_pathlib(pathlib_file, "Pathlib is modern.") + assert result == f"Content written to '{pathlib_file}' using pathlib." + + content = read_file_pathlib(pathlib_file) + assert content == "Pathlib is modern." + + append_result = append_file_pathlib(pathlib_file, "\nIt's object-oriented.") + assert append_result == f"Content appended to '{pathlib_file}' using pathlib." + + content = read_file_pathlib(pathlib_file) + assert content == "Pathlib is modern.\nIt's object-oriented." + + # Test path operations with pathlib + path = Path(pathlib_file) + assert path.exists() + assert path.is_file() + assert path.suffix == ".txt" + assert path.stem == "pathlib_sample" + + delete_result = delete_file_pathlib(pathlib_file) + assert delete_result == f"'{pathlib_file}' has been deleted using pathlib." + assert not path.exists() + if __name__ == "__main__": main() From a4460330c1dbe097d89e0d1f6e35f97bf2f3deed Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Fri, 12 Dec 2025 05:58:52 -0800 Subject: [PATCH 172/178] Update file_handling lesson once more --- ultimatepython/advanced/file_handling.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ultimatepython/advanced/file_handling.py b/ultimatepython/advanced/file_handling.py index f0366ca9..e4908e20 100644 --- a/ultimatepython/advanced/file_handling.py +++ b/ultimatepython/advanced/file_handling.py @@ -17,7 +17,6 @@ from pathlib import Path _TARGET_FILE = "sample.txt" -_TARGET_PATH = Path(_TARGET_FILE) def read_file(filename: str) -> str: From cc9490aa769a89426dd038fd7c6b5b53e5c7e096 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 21 Dec 2025 22:48:20 -0800 Subject: [PATCH 173/178] Update CI job name to simply Python --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3704f11..4a24b3ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ permissions: jobs: python-build: - name: Python 3.14 + name: Python runs-on: ubuntu-latest steps: From 5616f95ecc7af1d9554790f70306b7276e386f73 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 21 Dec 2025 22:49:15 -0800 Subject: [PATCH 174/178] Update pip dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index b25c5ecf..3f45511b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ coverage==7.13.0 isort==7.0.0 -ruff==0.14.8 -mypy==1.19.0 +ruff==0.14.10 +mypy==1.19.1 From 45bb64b20b88a785446766fc8ae560f452ea7223 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Sun, 21 Dec 2025 23:14:30 -0800 Subject: [PATCH 175/178] Add author projects to all README files --- README.de.md | 9 +++++++++ README.es.md | 9 +++++++++ README.fr.md | 9 +++++++++ README.hi.md | 9 +++++++++ README.ko.md | 9 +++++++++ README.md | 9 +++++++++ README.pt_br.md | 9 +++++++++ README.zh_tw.md | 9 +++++++++ 8 files changed, 72 insertions(+) diff --git a/README.de.md b/README.de.md index 010ee99f..63937444 100644 --- a/README.de.md +++ b/README.de.md @@ -155,6 +155,15 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### Projekte des Autors + +Projekte, die ich mit Python erstellt habe und die zeigen, was man nach dem Erlernen dieser Konzepte erstellen kann: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — Ein Yelp-Klon, der Full-Stack mit Python zeigt ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — Pure Python Git Hooks-Bibliothek ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Retrieval-augmented Generation für Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Automatisierte Gmail-Bereinigung mit Python und ML ( 🧪 ) + ### Interaktive Übungen Üben Sie weiter, damit Ihre Programmierkenntnisse nicht einrosten. diff --git a/README.es.md b/README.es.md index b0708ff5..5ed3ac76 100644 --- a/README.es.md +++ b/README.es.md @@ -153,6 +153,15 @@ Sigue aprendiendo leyendo otros buenos recursos. - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### Proyectos del autor + +Proyectos que he creado con Python que muestran lo que puedes crear después de aprender estos conceptos: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — Un clon de Yelp que muestra full-stack con Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — Biblioteca de hooks de Git en Python puro ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Generación aumentada con recuperación para Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Limpieza automatizada de Gmail usando Python y ML ( 🧪 ) + ### Práctica interactiva Continua practicando para que no se oxiden tus habilidades de programación. diff --git a/README.fr.md b/README.fr.md index 84ba57d4..ab083cbd 100644 --- a/README.fr.md +++ b/README.fr.md @@ -165,6 +165,15 @@ Continue d’apprendre grâce à ces ressources bien établies : - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### Projets de l'auteur + +Projets que j'ai créés avec Python qui montrent ce que vous pouvez créer après avoir appris ces concepts : + +- [huangsam/chowist](https://github.com/huangsam/chowist) — Un clone de Yelp montrant le full-stack avec Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — Bibliothèque de hooks Git en Python pur ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Génération augmentée par récupération pour Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Nettoyage automatisé de Gmail avec Python et ML ( 🧪 ) + ### Pratique interactive Continue à t’exercer pour ne pas perdre la main : diff --git a/README.hi.md b/README.hi.md index a213b73b..f93615b1 100644 --- a/README.hi.md +++ b/README.hi.md @@ -138,6 +138,15 @@ print("Ultimate Python स्टडी गाइड") - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### लेखक की परियोजनाएँ + +Python से बनाई गई परियोजनाएं जो दिखाती हैं कि इन अवधारणाओं को सीखने के बाद आप क्या बना सकते हैं: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — Python के साथ फुल-स्टैक दिखाने वाला एक Yelp क्लोन ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — शुद्ध Python Git हुक लाइब्रेरी ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Wikipedia के लिए रिट्रीवल-ऑगमेंटेड जेनरेशन ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Python और ML का उपयोग करके स्वचालित Gmail सफाई ( 🧪 ) + ### इंटरैक्टिव प्रैक्टिस अभ्यास करते रहें ताकि आपकी कोडिंग कौशल खराब न हों। diff --git a/README.ko.md b/README.ko.md index 72e62810..932f7a69 100644 --- a/README.ko.md +++ b/README.ko.md @@ -144,6 +144,15 @@ print("Ultimate Python 학습 가이드") - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### 저자의 프로젝트 + +이러한 개념을 익힌 후 무엇을 만들 수 있는지 보여주는 Python으로 제작한 프로젝트들입니다: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — Python을 사용한 풀스택을 보여주는 Yelp 클론 ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — 순수 Python Git 훅 라이브러리 ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Wikipedia를 위한 검색 증강 생성 ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Python과 ML을 사용한 자동화된 Gmail 정리 ( 🧪 ) + ### 대화형 연습 코딩 실력이 녹슬지 않기 위해 계속 연습하세요. diff --git a/README.md b/README.md index 2a7407e5..40ffb9d9 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,15 @@ Keep learning by reading from other well-regarded resources. - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### Author projects + +Projects I've built with Python that showcase what you can create after learning these concepts: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — A Yelp clone showing full-stack with Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — Pure Python Git hooks library ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Retrieval-augmented generation for Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Automated Gmail cleanup using Python and ML ( 🧪 ) + ### Interactive practice Keep practicing so that your coding skills don't get rusty. diff --git a/README.pt_br.md b/README.pt_br.md index 60e7c682..ccb3ae46 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -142,6 +142,15 @@ Continue aprendendo lendo outros recursos bem conceituados. - [microsoft/Data-Science-For-Beginners](https://github.com/microsoft/Data-Science-For-Beginners) ( 🧪 ) - [Avik-Jain/100-Days-Of-ML-Code](https://github.com/Avik-Jain/100-Days-Of-ML-Code) ( 🧪 ) +### Projetos do autor + +Projetos que construí com Python que mostram o que você pode criar após aprender esses conceitos: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — Um clone do Yelp mostrando full-stack com Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — Biblioteca de hooks Git em Python puro ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Geração aumentada por recuperação para Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Limpeza automatizada do Gmail usando Python e ML ( 🧪 ) + ### Prática interativa Continue praticando para que suas habilidades de codificação não enferrujem. diff --git a/README.zh_tw.md b/README.zh_tw.md index 99ec6f8b..2e39f83c 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -135,6 +135,15 @@ print("Ultimate Python 學習大綱") - [practical-tutorials/project-based-learning](https://github.com/practical-tutorials/project-based-learning#python) - [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) ( 👔 ) +### 作者的專案 + +我用 Python 構建的專案,展示學習這些概念後可以創造的內容: + +- [huangsam/chowist](https://github.com/huangsam/chowist) — 使用 Python 展示全端的 Yelp 克隆專案 ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) — 純 Python Git hooks 庫 ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Wikipedia 的檢索增強生成 ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) — 使用 Python 和 ML 的自動化 Gmail 清理 ( 🧪 ) + ### 互動練習 繼續練習才能使您的編碼技能不會生疏。 From 76d58d599bee213dbfdd702f8fa544c74a75aae5 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Mon, 22 Dec 2025 10:17:39 -0800 Subject: [PATCH 176/178] Reformat the author projects --- README.de.md | 8 ++++---- README.es.md | 8 ++++---- README.fr.md | 10 +++++----- README.hi.md | 8 ++++---- README.ko.md | 8 ++++---- README.md | 8 ++++---- README.pt_br.md | 8 ++++---- README.zh_tw.md | 8 ++++---- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.de.md b/README.de.md index 63937444..23cac67d 100644 --- a/README.de.md +++ b/README.de.md @@ -159,10 +159,10 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. Projekte, die ich mit Python erstellt habe und die zeigen, was man nach dem Erlernen dieser Konzepte erstellen kann: -- [huangsam/chowist](https://github.com/huangsam/chowist) — Ein Yelp-Klon, der Full-Stack mit Python zeigt ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — Pure Python Git Hooks-Bibliothek ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Retrieval-augmented Generation für Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Automatisierte Gmail-Bereinigung mit Python und ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): Ein Yelp-Klon, der Full-Stack mit Python zeigt ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): Pure Python Git Hooks-Bibliothek ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Retrieval-augmented Generation für Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Automatisierte Gmail-Bereinigung mit Python und ML ( 🧪 ) ### Interaktive Übungen diff --git a/README.es.md b/README.es.md index 5ed3ac76..18a54913 100644 --- a/README.es.md +++ b/README.es.md @@ -157,10 +157,10 @@ Sigue aprendiendo leyendo otros buenos recursos. Proyectos que he creado con Python que muestran lo que puedes crear después de aprender estos conceptos: -- [huangsam/chowist](https://github.com/huangsam/chowist) — Un clon de Yelp que muestra full-stack con Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — Biblioteca de hooks de Git en Python puro ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Generación aumentada con recuperación para Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Limpieza automatizada de Gmail usando Python y ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): Un clon de Yelp que muestra full-stack con Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): Biblioteca de hooks de Git en Python puro ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Generación aumentada con recuperación para Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Limpieza automatizada de Gmail usando Python y ML ( 🧪 ) ### Práctica interactiva diff --git a/README.fr.md b/README.fr.md index ab083cbd..bf280648 100644 --- a/README.fr.md +++ b/README.fr.md @@ -26,7 +26,7 @@ print("Guide d’étude Python ultime") ## Motivation J’ai créé ce dépôt GitHub pour partager ce que j’ai appris sur le [cœur de Python](https://www.python.org/) -au cours de plus de 5 années d’utilisation — en tant que diplômé universitaire, employé +au cours de plus de 5 années d’utilisation: en tant que diplômé universitaire, employé dans de grandes entreprises et contributeur open-source à des dépôts tels que [Celery](https://github.com/celery/celery) et [Full Stack Python](https://github.com/mattmakai/fullstackpython.com). @@ -169,10 +169,10 @@ Continue d’apprendre grâce à ces ressources bien établies : Projets que j'ai créés avec Python qui montrent ce que vous pouvez créer après avoir appris ces concepts : -- [huangsam/chowist](https://github.com/huangsam/chowist) — Un clone de Yelp montrant le full-stack avec Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — Bibliothèque de hooks Git en Python pur ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Génération augmentée par récupération pour Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Nettoyage automatisé de Gmail avec Python et ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): Un clone de Yelp montrant le full-stack avec Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): Bibliothèque de hooks Git en Python pur ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Génération augmentée par récupération pour Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Nettoyage automatisé de Gmail avec Python et ML ( 🧪 ) ### Pratique interactive diff --git a/README.hi.md b/README.hi.md index f93615b1..bdd29f82 100644 --- a/README.hi.md +++ b/README.hi.md @@ -142,10 +142,10 @@ print("Ultimate Python स्टडी गाइड") Python से बनाई गई परियोजनाएं जो दिखाती हैं कि इन अवधारणाओं को सीखने के बाद आप क्या बना सकते हैं: -- [huangsam/chowist](https://github.com/huangsam/chowist) — Python के साथ फुल-स्टैक दिखाने वाला एक Yelp क्लोन ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — शुद्ध Python Git हुक लाइब्रेरी ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Wikipedia के लिए रिट्रीवल-ऑगमेंटेड जेनरेशन ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Python और ML का उपयोग करके स्वचालित Gmail सफाई ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): Python के साथ फुल-स्टैक दिखाने वाला एक Yelp क्लोन ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): शुद्ध Python Git हुक लाइब्रेरी ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Wikipedia के लिए रिट्रीवल-ऑगमेंटेड जेनरेशन ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Python और ML का उपयोग करके स्वचालित Gmail सफाई ( 🧪 ) ### इंटरैक्टिव प्रैक्टिस diff --git a/README.ko.md b/README.ko.md index 932f7a69..93a85907 100644 --- a/README.ko.md +++ b/README.ko.md @@ -148,10 +148,10 @@ print("Ultimate Python 학습 가이드") 이러한 개념을 익힌 후 무엇을 만들 수 있는지 보여주는 Python으로 제작한 프로젝트들입니다: -- [huangsam/chowist](https://github.com/huangsam/chowist) — Python을 사용한 풀스택을 보여주는 Yelp 클론 ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — 순수 Python Git 훅 라이브러리 ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Wikipedia를 위한 검색 증강 생성 ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Python과 ML을 사용한 자동화된 Gmail 정리 ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): Python을 사용한 풀스택을 보여주는 Yelp 클론 ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): 순수 Python Git 훅 라이브러리 ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Wikipedia를 위한 검색 증강 생성 ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Python과 ML을 사용한 자동화된 Gmail 정리 ( 🧪 ) ### 대화형 연습 diff --git a/README.md b/README.md index 40ffb9d9..bc65b7fa 100644 --- a/README.md +++ b/README.md @@ -160,10 +160,10 @@ Keep learning by reading from other well-regarded resources. Projects I've built with Python that showcase what you can create after learning these concepts: -- [huangsam/chowist](https://github.com/huangsam/chowist) — A Yelp clone showing full-stack with Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — Pure Python Git hooks library ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Retrieval-augmented generation for Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Automated Gmail cleanup using Python and ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): A Yelp clone showing full-stack with Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): Pure Python Git hooks library ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Retrieval-augmented generation for Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Automated Gmail cleanup using Python and ML ( 🧪 ) ### Interactive practice diff --git a/README.pt_br.md b/README.pt_br.md index ccb3ae46..2da9abba 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -146,10 +146,10 @@ Continue aprendendo lendo outros recursos bem conceituados. Projetos que construí com Python que mostram o que você pode criar após aprender esses conceitos: -- [huangsam/chowist](https://github.com/huangsam/chowist) — Um clone do Yelp mostrando full-stack com Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — Biblioteca de hooks Git em Python puro ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Geração aumentada por recuperação para Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — Limpeza automatizada do Gmail usando Python e ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): Um clone do Yelp mostrando full-stack com Python ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): Biblioteca de hooks Git em Python puro ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Geração aumentada por recuperação para Wikipedia ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): Limpeza automatizada do Gmail usando Python e ML ( 🧪 ) ### Prática interativa diff --git a/README.zh_tw.md b/README.zh_tw.md index 2e39f83c..9d1dd657 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -139,10 +139,10 @@ print("Ultimate Python 學習大綱") 我用 Python 構建的專案,展示學習這些概念後可以創造的內容: -- [huangsam/chowist](https://github.com/huangsam/chowist) — 使用 Python 展示全端的 Yelp 克隆專案 ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks) — 純 Python Git hooks 庫 ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain) — Wikipedia 的檢索增強生成 ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune) — 使用 Python 和 ML 的自動化 Gmail 清理 ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist): 使用 Python 展示全端的 Yelp 克隆專案 ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks): 純 Python Git hooks 庫 ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain): Wikipedia 的檢索增強生成 ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune): 使用 Python 和 ML 的自動化 Gmail 清理 ( 🧪 ) ### 互動練習 From de8d7183a327df9b84bf3d003852326ca57d4f5d Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 25 Dec 2025 10:06:27 -0800 Subject: [PATCH 177/178] Remove emojis from error messages in pre-commit.sh --- pre-commit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pre-commit.sh b/pre-commit.sh index 9ad12364..a9006951 100755 --- a/pre-commit.sh +++ b/pre-commit.sh @@ -32,7 +32,7 @@ done # 4. Check if a virtual environment was found if [ -z "$VENV_DIR" ]; then - echo "🚨 Error: Virtual environment not found. Please create one (e.g., 'python3 -m venv .venv') and run the hook again." + echo "Error: Virtual environment not found. Please create one (e.g., 'python3 -m venv .venv') and run the hook again." exit 1 fi @@ -41,7 +41,7 @@ PYTHON_EXEC="$VENV_DIR/bin/python" # 6. Check if the interpreter exists if [ ! -x "$PYTHON_EXEC" ]; then - echo "🚨 Error: Python executable not found at $PYTHON_EXEC" + echo "Error: Python executable not found at $PYTHON_EXEC" exit 1 fi From e2741ba4fe2d08afc665ad2b78085c3741beea0d Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Thu, 25 Dec 2025 10:09:07 -0800 Subject: [PATCH 178/178] Remove descriptions from author projects --- README.de.md | 8 ++++---- README.es.md | 8 ++++---- README.fr.md | 8 ++++---- README.hi.md | 8 ++++---- README.ko.md | 8 ++++---- README.md | 8 ++++---- README.pt_br.md | 8 ++++---- README.zh_tw.md | 8 ++++---- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/README.de.md b/README.de.md index 23cac67d..7ecfe09a 100644 --- a/README.de.md +++ b/README.de.md @@ -159,10 +159,10 @@ Lernen Sie weiter, indem Sie von anderen Quellen lesen. Projekte, die ich mit Python erstellt habe und die zeigen, was man nach dem Erlernen dieser Konzepte erstellen kann: -- [huangsam/chowist](https://github.com/huangsam/chowist): Ein Yelp-Klon, der Full-Stack mit Python zeigt ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): Pure Python Git Hooks-Bibliothek ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Retrieval-augmented Generation für Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Automatisierte Gmail-Bereinigung mit Python und ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### Interaktive Übungen diff --git a/README.es.md b/README.es.md index 18a54913..138ad36e 100644 --- a/README.es.md +++ b/README.es.md @@ -157,10 +157,10 @@ Sigue aprendiendo leyendo otros buenos recursos. Proyectos que he creado con Python que muestran lo que puedes crear después de aprender estos conceptos: -- [huangsam/chowist](https://github.com/huangsam/chowist): Un clon de Yelp que muestra full-stack con Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): Biblioteca de hooks de Git en Python puro ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Generación aumentada con recuperación para Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Limpieza automatizada de Gmail usando Python y ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### Práctica interactiva diff --git a/README.fr.md b/README.fr.md index bf280648..63698a55 100644 --- a/README.fr.md +++ b/README.fr.md @@ -169,10 +169,10 @@ Continue d’apprendre grâce à ces ressources bien établies : Projets que j'ai créés avec Python qui montrent ce que vous pouvez créer après avoir appris ces concepts : -- [huangsam/chowist](https://github.com/huangsam/chowist): Un clone de Yelp montrant le full-stack avec Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): Bibliothèque de hooks Git en Python pur ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Génération augmentée par récupération pour Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Nettoyage automatisé de Gmail avec Python et ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### Pratique interactive diff --git a/README.hi.md b/README.hi.md index bdd29f82..fdb77a67 100644 --- a/README.hi.md +++ b/README.hi.md @@ -142,10 +142,10 @@ print("Ultimate Python स्टडी गाइड") Python से बनाई गई परियोजनाएं जो दिखाती हैं कि इन अवधारणाओं को सीखने के बाद आप क्या बना सकते हैं: -- [huangsam/chowist](https://github.com/huangsam/chowist): Python के साथ फुल-स्टैक दिखाने वाला एक Yelp क्लोन ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): शुद्ध Python Git हुक लाइब्रेरी ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Wikipedia के लिए रिट्रीवल-ऑगमेंटेड जेनरेशन ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Python और ML का उपयोग करके स्वचालित Gmail सफाई ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### इंटरैक्टिव प्रैक्टिस diff --git a/README.ko.md b/README.ko.md index 93a85907..42c47f29 100644 --- a/README.ko.md +++ b/README.ko.md @@ -148,10 +148,10 @@ print("Ultimate Python 학습 가이드") 이러한 개념을 익힌 후 무엇을 만들 수 있는지 보여주는 Python으로 제작한 프로젝트들입니다: -- [huangsam/chowist](https://github.com/huangsam/chowist): Python을 사용한 풀스택을 보여주는 Yelp 클론 ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): 순수 Python Git 훅 라이브러리 ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Wikipedia를 위한 검색 증강 생성 ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Python과 ML을 사용한 자동화된 Gmail 정리 ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### 대화형 연습 diff --git a/README.md b/README.md index bc65b7fa..bcdc806b 100644 --- a/README.md +++ b/README.md @@ -160,10 +160,10 @@ Keep learning by reading from other well-regarded resources. Projects I've built with Python that showcase what you can create after learning these concepts: -- [huangsam/chowist](https://github.com/huangsam/chowist): A Yelp clone showing full-stack with Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): Pure Python Git hooks library ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Retrieval-augmented generation for Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Automated Gmail cleanup using Python and ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### Interactive practice diff --git a/README.pt_br.md b/README.pt_br.md index 2da9abba..1a6b20bd 100644 --- a/README.pt_br.md +++ b/README.pt_br.md @@ -146,10 +146,10 @@ Continue aprendendo lendo outros recursos bem conceituados. Projetos que construí com Python que mostram o que você pode criar após aprender esses conceitos: -- [huangsam/chowist](https://github.com/huangsam/chowist): Um clone do Yelp mostrando full-stack com Python ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): Biblioteca de hooks Git em Python puro ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Geração aumentada por recuperação para Wikipedia ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): Limpeza automatizada do Gmail usando Python e ML ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### Prática interativa diff --git a/README.zh_tw.md b/README.zh_tw.md index 9d1dd657..caba49bb 100644 --- a/README.zh_tw.md +++ b/README.zh_tw.md @@ -139,10 +139,10 @@ print("Ultimate Python 學習大綱") 我用 Python 構建的專案,展示學習這些概念後可以創造的內容: -- [huangsam/chowist](https://github.com/huangsam/chowist): 使用 Python 展示全端的 Yelp 克隆專案 ( 🧪 ) -- [huangsam/githooks](https://github.com/huangsam/githooks): 純 Python Git hooks 庫 ( 🧪 ) -- [huangsam/ragchain](https://github.com/huangsam/ragchain): Wikipedia 的檢索增強生成 ( 🧪 ) -- [huangsam/mailprune](https://github.com/huangsam/mailprune): 使用 Python 和 ML 的自動化 Gmail 清理 ( 🧪 ) +- [huangsam/chowist](https://github.com/huangsam/chowist) ( 🧪 ) +- [huangsam/githooks](https://github.com/huangsam/githooks) ( 🧪 ) +- [huangsam/ragchain](https://github.com/huangsam/ragchain) ( 🧪 ) +- [huangsam/mailprune](https://github.com/huangsam/mailprune) ( 🧪 ) ### 互動練習