From 0e63bbcb3b80e03e6f611323b10b493a71516980 Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Sun, 1 Oct 2023 20:36:56 -0700 Subject: [PATCH 01/15] Add sample code files --- .../01_type_hints_for_one_piece_of_data.py | 13 ++++++ ..._type_hints_for_multiple_pieces_of_data.py | 13 ++++++ .../03_type_hints_for_callback.py | 15 +++++++ .../04_type_hints_for_factory_function.py | 25 ++++++++++++ .../05_type_hints_for_generator.py | 32 +++++++++++++++ .../06_type_aliases.py | 12 ++++++ .../07_static_type_checking.py | 5 +++ python-type-hints-multiple-types/README.md | 40 +++++++++++++++++++ .../requirements.txt | 4 ++ 9 files changed, 159 insertions(+) create mode 100644 python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py create mode 100644 python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py create mode 100644 python-type-hints-multiple-types/03_type_hints_for_callback.py create mode 100644 python-type-hints-multiple-types/04_type_hints_for_factory_function.py create mode 100644 python-type-hints-multiple-types/05_type_hints_for_generator.py create mode 100644 python-type-hints-multiple-types/06_type_aliases.py create mode 100644 python-type-hints-multiple-types/07_static_type_checking.py create mode 100644 python-type-hints-multiple-types/README.md create mode 100644 python-type-hints-multiple-types/requirements.txt diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py new file mode 100644 index 0000000000..a49c5bf527 --- /dev/null +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -0,0 +1,13 @@ +from typing import Union + +def parse_email(email_address: str) -> str | None: + if "@" in email_address: + username, domain = email_address.split("@") + return username + return None + +def parse_email(email_address: str) -> Union[str, None]: + if "@" in email_address: + username, domain = email_address.split("@") + return username + return None \ No newline at end of file diff --git a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py new file mode 100644 index 0000000000..6e96f4145e --- /dev/null +++ b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py @@ -0,0 +1,13 @@ +from typing import Tuple, Union + +def parse_email(email_address: str) -> tuple[str, str] | None: + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None + +def parse_email(email_address: str) -> Union[Tuple[str, str], None]: + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None diff --git a/python-type-hints-multiple-types/03_type_hints_for_callback.py b/python-type-hints-multiple-types/03_type_hints_for_callback.py new file mode 100644 index 0000000000..2084314a0b --- /dev/null +++ b/python-type-hints-multiple-types/03_type_hints_for_callback.py @@ -0,0 +1,15 @@ +from collections.abc import Callable +from typing import Any + +def apply_func( + func: Callable[..., Any], *args: Any +) -> Any: + return func(*args) + +def parse_email(email_address: str) -> tuple[str, str] | None: + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None + +apply_funct(parse_email, "claudia@realpython.com") \ No newline at end of file diff --git a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py new file mode 100644 index 0000000000..46cbd5448a --- /dev/null +++ b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py @@ -0,0 +1,25 @@ +import functools +import time +from collections.abc import Callable +from typing import Any + +def timeit(function: Callable[..., Any]) -> Callable[..., Any]: + @functools.wraps(function) + def wrapper(*args, **kwargs): + start = time.perf_counter() + result = function(*args, **kwargs) + end = time.perf_counter() + print(f"{function.__name__}() finished in {end - start:.10f}s") + return result + + return wrapper + +@timeit +def parse_email(email_address: str) -> tuple[str, str] | None: + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None + +username, domain = parse_email("claudia@realpython.com") +print(username, domain) \ No newline at end of file diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py new file mode 100644 index 0000000000..cd12201cea --- /dev/null +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -0,0 +1,32 @@ +from collections.abc import Generator, Iterable, Iterator + +def parse_email() -> Generator[tuple[str, str], str, str]: + sent = yield "", "" + while sent != "": + if "@" in sent: + username, domain = sent.split("@") + sent = yield username, domain + else: + sent = yield "invalid email" + return "Done" + +generator = parse_email() +next(generator) +generator.send("claudia@realpython.com") +generator.send("realpython") +try: + generator.send("") +except StopIteration as ex: + print(ex.value) + +def parse_emails(emails: list[str]) -> Iterator[tuple[str, str]]: + for email in emails: + if "@" in email: + username, domain = email.split("@") + yield username, domain + +def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: + for email in emails: + if "@" in email: + username, domain = email.split("@") + yield username, domain \ No newline at end of file diff --git a/python-type-hints-multiple-types/06_type_aliases.py b/python-type-hints-multiple-types/06_type_aliases.py new file mode 100644 index 0000000000..2aac62b300 --- /dev/null +++ b/python-type-hints-multiple-types/06_type_aliases.py @@ -0,0 +1,12 @@ +from typing import TypeAlias + +EmailComponents = tuple[str, str] | None + +def parse_email(email_address: str) -> EmailComponents: + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None + +EmailComponents: TypeAlias = tuple[str, str] | None +type EmailComponents = tuple[str, str] | None \ No newline at end of file diff --git a/python-type-hints-multiple-types/07_static_type_checking.py b/python-type-hints-multiple-types/07_static_type_checking.py new file mode 100644 index 0000000000..1786078ed4 --- /dev/null +++ b/python-type-hints-multiple-types/07_static_type_checking.py @@ -0,0 +1,5 @@ +def parse_email(email_address: str) -> tuple[str, str] | None: + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None \ No newline at end of file diff --git a/python-type-hints-multiple-types/README.md b/python-type-hints-multiple-types/README.md new file mode 100644 index 0000000000..9ac6e78af5 --- /dev/null +++ b/python-type-hints-multiple-types/README.md @@ -0,0 +1,40 @@ + +# How to Use Type Hints for Multiple Return Types in Python + +This folder contains sample code for the [How to Use Type Hints for Multiple Return Types in Python](https://realpython.com/python-type-hints-multiple-types/) tutorial on Real Python. + +## Installation + +Some of the code requires the following third-party libraries: + +- [`mypy`](https://pypi.org/project/mypy/) + +To install them into a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/), type the following commands: + +```shell +$ python3 -m venv venv/ +$ source venv/bin/activate +(venv) $ python -m pip install -r requirements.txt +``` + +## Running + +### 01_type_hints_for_one_piece_of_data + + +### 02_type_hints_for_multiple_pieces_of_data + + +### 03_type_hints_for_callback + + +### 04_type_hints_for_factory_function + + +### 05_type_hints_for_generator + + +### 06_type_aliases + + +### 07_static_type_checking \ No newline at end of file diff --git a/python-type-hints-multiple-types/requirements.txt b/python-type-hints-multiple-types/requirements.txt new file mode 100644 index 0000000000..987a758147 --- /dev/null +++ b/python-type-hints-multiple-types/requirements.txt @@ -0,0 +1,4 @@ +mypy==1.5.1 +mypy-extensions==1.0.0 +tomli==2.0.1 +typing_extensions==4.8.0 From be759a287f2dd9dcbdf95e45525ee198b290af32 Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Sun, 1 Oct 2023 20:41:01 -0700 Subject: [PATCH 02/15] Adding extra lines --- .../01_type_hints_for_one_piece_of_data.py | 2 ++ .../02_type_hints_for_multiple_pieces_of_data.py | 2 ++ .../03_type_hints_for_callback.py | 3 +++ .../04_type_hints_for_factory_function.py | 3 +++ .../05_type_hints_for_generator.py | 4 ++++ python-type-hints-multiple-types/06_type_aliases.py | 3 +++ 6 files changed, 17 insertions(+) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index a49c5bf527..999da740c8 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -1,11 +1,13 @@ from typing import Union + def parse_email(email_address: str) -> str | None: if "@" in email_address: username, domain = email_address.split("@") return username return None + def parse_email(email_address: str) -> Union[str, None]: if "@" in email_address: username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py index 6e96f4145e..3c403d1be7 100644 --- a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py +++ b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py @@ -1,11 +1,13 @@ from typing import Tuple, Union + def parse_email(email_address: str) -> tuple[str, str] | None: if "@" in email_address: username, domain = email_address.split("@") return username, domain return None + def parse_email(email_address: str) -> Union[Tuple[str, str], None]: if "@" in email_address: username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/03_type_hints_for_callback.py b/python-type-hints-multiple-types/03_type_hints_for_callback.py index 2084314a0b..cef2a20c1f 100644 --- a/python-type-hints-multiple-types/03_type_hints_for_callback.py +++ b/python-type-hints-multiple-types/03_type_hints_for_callback.py @@ -1,15 +1,18 @@ from collections.abc import Callable from typing import Any + def apply_func( func: Callable[..., Any], *args: Any ) -> Any: return func(*args) + def parse_email(email_address: str) -> tuple[str, str] | None: if "@" in email_address: username, domain = email_address.split("@") return username, domain return None + apply_funct(parse_email, "claudia@realpython.com") \ No newline at end of file diff --git a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py index 46cbd5448a..63cda4bce8 100644 --- a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py +++ b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py @@ -3,6 +3,7 @@ from collections.abc import Callable from typing import Any + def timeit(function: Callable[..., Any]) -> Callable[..., Any]: @functools.wraps(function) def wrapper(*args, **kwargs): @@ -14,6 +15,7 @@ def wrapper(*args, **kwargs): return wrapper + @timeit def parse_email(email_address: str) -> tuple[str, str] | None: if "@" in email_address: @@ -21,5 +23,6 @@ def parse_email(email_address: str) -> tuple[str, str] | None: return username, domain return None + username, domain = parse_email("claudia@realpython.com") print(username, domain) \ No newline at end of file diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index cd12201cea..4923e91a91 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -1,5 +1,6 @@ from collections.abc import Generator, Iterable, Iterator + def parse_email() -> Generator[tuple[str, str], str, str]: sent = yield "", "" while sent != "": @@ -10,6 +11,7 @@ def parse_email() -> Generator[tuple[str, str], str, str]: sent = yield "invalid email" return "Done" + generator = parse_email() next(generator) generator.send("claudia@realpython.com") @@ -19,12 +21,14 @@ def parse_email() -> Generator[tuple[str, str], str, str]: except StopIteration as ex: print(ex.value) + def parse_emails(emails: list[str]) -> Iterator[tuple[str, str]]: for email in emails: if "@" in email: username, domain = email.split("@") yield username, domain + def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: for email in emails: if "@" in email: diff --git a/python-type-hints-multiple-types/06_type_aliases.py b/python-type-hints-multiple-types/06_type_aliases.py index 2aac62b300..e2fcd67e46 100644 --- a/python-type-hints-multiple-types/06_type_aliases.py +++ b/python-type-hints-multiple-types/06_type_aliases.py @@ -1,12 +1,15 @@ from typing import TypeAlias + EmailComponents = tuple[str, str] | None + def parse_email(email_address: str) -> EmailComponents: if "@" in email_address: username, domain = email_address.split("@") return username, domain return None + EmailComponents: TypeAlias = tuple[str, str] | None type EmailComponents = tuple[str, str] | None \ No newline at end of file From ff56848c2451229e17bf5d9c85f918831cfc8d13 Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Sun, 1 Oct 2023 20:46:44 -0700 Subject: [PATCH 03/15] convert indentation to spaces --- .../01_type_hints_for_one_piece_of_data.py | 3 +- .../03_type_hints_for_callback.py | 14 ++++---- .../04_type_hints_for_factory_function.py | 24 ++++++------- .../05_type_hints_for_generator.py | 36 +++++++++---------- .../06_type_aliases.py | 8 ++--- .../07_static_type_checking.py | 8 ++--- 6 files changed, 46 insertions(+), 47 deletions(-) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index 999da740c8..d0cd9bebdc 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -12,4 +12,5 @@ def parse_email(email_address: str) -> Union[str, None]: if "@" in email_address: username, domain = email_address.split("@") return username - return None \ No newline at end of file + return None + \ No newline at end of file diff --git a/python-type-hints-multiple-types/03_type_hints_for_callback.py b/python-type-hints-multiple-types/03_type_hints_for_callback.py index cef2a20c1f..ca779fa29d 100644 --- a/python-type-hints-multiple-types/03_type_hints_for_callback.py +++ b/python-type-hints-multiple-types/03_type_hints_for_callback.py @@ -2,17 +2,15 @@ from typing import Any -def apply_func( - func: Callable[..., Any], *args: Any -) -> Any: - return func(*args) +def apply_func(func: Callable[..., Any], *args: Any) -> Any: + return func(*args) def parse_email(email_address: str) -> tuple[str, str] | None: - if "@" in email_address: - username, domain = email_address.split("@") - return username, domain - return None + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None apply_funct(parse_email, "claudia@realpython.com") \ No newline at end of file diff --git a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py index 63cda4bce8..377f064cfe 100644 --- a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py +++ b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py @@ -5,23 +5,23 @@ def timeit(function: Callable[..., Any]) -> Callable[..., Any]: - @functools.wraps(function) - def wrapper(*args, **kwargs): - start = time.perf_counter() - result = function(*args, **kwargs) - end = time.perf_counter() - print(f"{function.__name__}() finished in {end - start:.10f}s") - return result + @functools.wraps(function) + def wrapper(*args, **kwargs): + start = time.perf_counter() + result = function(*args, **kwargs) + end = time.perf_counter() + print(f"{function.__name__}() finished in {end - start:.10f}s") + return result - return wrapper + return wrapper @timeit def parse_email(email_address: str) -> tuple[str, str] | None: - if "@" in email_address: - username, domain = email_address.split("@") - return username, domain - return None + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None username, domain = parse_email("claudia@realpython.com") diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index 4923e91a91..359318931b 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -2,14 +2,14 @@ def parse_email() -> Generator[tuple[str, str], str, str]: - sent = yield "", "" - while sent != "": - if "@" in sent: - username, domain = sent.split("@") - sent = yield username, domain - else: - sent = yield "invalid email" - return "Done" + sent = yield "", "" + while sent != "": + if "@" in sent: + username, domain = sent.split("@") + sent = yield username, domain + else: + sent = yield "invalid email" + return "Done" generator = parse_email() @@ -17,20 +17,20 @@ def parse_email() -> Generator[tuple[str, str], str, str]: generator.send("claudia@realpython.com") generator.send("realpython") try: - generator.send("") + generator.send("") except StopIteration as ex: - print(ex.value) + print(ex.value) def parse_emails(emails: list[str]) -> Iterator[tuple[str, str]]: - for email in emails: - if "@" in email: - username, domain = email.split("@") - yield username, domain + for email in emails: + if "@" in email: + username, domain = email.split("@") + yield username, domain def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: - for email in emails: - if "@" in email: - username, domain = email.split("@") - yield username, domain \ No newline at end of file + for email in emails: + if "@" in email: + username, domain = email.split("@") + yield username, domain \ No newline at end of file diff --git a/python-type-hints-multiple-types/06_type_aliases.py b/python-type-hints-multiple-types/06_type_aliases.py index e2fcd67e46..6750c734bb 100644 --- a/python-type-hints-multiple-types/06_type_aliases.py +++ b/python-type-hints-multiple-types/06_type_aliases.py @@ -5,10 +5,10 @@ def parse_email(email_address: str) -> EmailComponents: - if "@" in email_address: - username, domain = email_address.split("@") - return username, domain - return None + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None EmailComponents: TypeAlias = tuple[str, str] | None diff --git a/python-type-hints-multiple-types/07_static_type_checking.py b/python-type-hints-multiple-types/07_static_type_checking.py index 1786078ed4..71288fc299 100644 --- a/python-type-hints-multiple-types/07_static_type_checking.py +++ b/python-type-hints-multiple-types/07_static_type_checking.py @@ -1,5 +1,5 @@ def parse_email(email_address: str) -> tuple[str, str] | None: - if "@" in email_address: - username, domain = email_address.split("@") - return username, domain - return None \ No newline at end of file + if "@" in email_address: + username, domain = email_address.split("@") + return username, domain + return None \ No newline at end of file From 718312b76c192e40a04f8667c14ef1b601ed8d5a Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Sun, 1 Oct 2023 20:49:14 -0700 Subject: [PATCH 04/15] Add new lines --- .../01_type_hints_for_one_piece_of_data.py | 1 - python-type-hints-multiple-types/03_type_hints_for_callback.py | 2 +- .../04_type_hints_for_factory_function.py | 2 +- python-type-hints-multiple-types/05_type_hints_for_generator.py | 2 +- python-type-hints-multiple-types/06_type_aliases.py | 1 - python-type-hints-multiple-types/07_static_type_checking.py | 2 +- 6 files changed, 4 insertions(+), 6 deletions(-) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index d0cd9bebdc..31f1d7688a 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -13,4 +13,3 @@ def parse_email(email_address: str) -> Union[str, None]: username, domain = email_address.split("@") return username return None - \ No newline at end of file diff --git a/python-type-hints-multiple-types/03_type_hints_for_callback.py b/python-type-hints-multiple-types/03_type_hints_for_callback.py index ca779fa29d..8a269c1225 100644 --- a/python-type-hints-multiple-types/03_type_hints_for_callback.py +++ b/python-type-hints-multiple-types/03_type_hints_for_callback.py @@ -13,4 +13,4 @@ def parse_email(email_address: str) -> tuple[str, str] | None: return None -apply_funct(parse_email, "claudia@realpython.com") \ No newline at end of file +apply_func(parse_email, "claudia@realpython.com") diff --git a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py index 377f064cfe..658e20dfa3 100644 --- a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py +++ b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py @@ -25,4 +25,4 @@ def parse_email(email_address: str) -> tuple[str, str] | None: username, domain = parse_email("claudia@realpython.com") -print(username, domain) \ No newline at end of file +print(username, domain) diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index 359318931b..62a14fbd31 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -33,4 +33,4 @@ def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: for email in emails: if "@" in email: username, domain = email.split("@") - yield username, domain \ No newline at end of file + yield username, domain diff --git a/python-type-hints-multiple-types/06_type_aliases.py b/python-type-hints-multiple-types/06_type_aliases.py index 6750c734bb..40286b5700 100644 --- a/python-type-hints-multiple-types/06_type_aliases.py +++ b/python-type-hints-multiple-types/06_type_aliases.py @@ -12,4 +12,3 @@ def parse_email(email_address: str) -> EmailComponents: EmailComponents: TypeAlias = tuple[str, str] | None -type EmailComponents = tuple[str, str] | None \ No newline at end of file diff --git a/python-type-hints-multiple-types/07_static_type_checking.py b/python-type-hints-multiple-types/07_static_type_checking.py index 71288fc299..9204b2f70d 100644 --- a/python-type-hints-multiple-types/07_static_type_checking.py +++ b/python-type-hints-multiple-types/07_static_type_checking.py @@ -2,4 +2,4 @@ def parse_email(email_address: str) -> tuple[str, str] | None: if "@" in email_address: username, domain = email_address.split("@") return username, domain - return None \ No newline at end of file + return None From 7d43039010643b03a2f8701f5bc35e226e45350c Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Mon, 2 Oct 2023 20:39:55 -0700 Subject: [PATCH 05/15] Addressing PR comments --- .../01_type_hints_for_one_piece_of_data.py | 10 ++++---- ..._type_hints_for_multiple_pieces_of_data.py | 10 ++++---- .../05_type_hints_for_generator.py | 10 ++++---- .../06_type_aliases.py | 5 +--- python-type-hints-multiple-types/README.md | 23 ------------------- .../requirements.txt | 1 - 6 files changed, 16 insertions(+), 43 deletions(-) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index 31f1d7688a..282cb2df3e 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -8,8 +8,8 @@ def parse_email(email_address: str) -> str | None: return None -def parse_email(email_address: str) -> Union[str, None]: - if "@" in email_address: - username, domain = email_address.split("@") - return username - return None +# def parse_email(email_address: str) -> Union[str, None]: +# if "@" in email_address: +# username, domain = email_address.split("@") +# return username +# return None diff --git a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py index 3c403d1be7..e5b787b7f7 100644 --- a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py +++ b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py @@ -8,8 +8,8 @@ def parse_email(email_address: str) -> tuple[str, str] | None: return None -def parse_email(email_address: str) -> Union[Tuple[str, str], None]: - if "@" in email_address: - username, domain = email_address.split("@") - return username, domain - return None +# def parse_email(email_address: str) -> Union[Tuple[str, str], None]: +# if "@" in email_address: +# username, domain = email_address.split("@") +# return username, domain +# return None diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index 62a14fbd31..97b61634b7 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -29,8 +29,8 @@ def parse_emails(emails: list[str]) -> Iterator[tuple[str, str]]: yield username, domain -def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: - for email in emails: - if "@" in email: - username, domain = email.split("@") - yield username, domain +# def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: +# for email in emails: +# if "@" in email: +# username, domain = email.split("@") +# yield username, domain diff --git a/python-type-hints-multiple-types/06_type_aliases.py b/python-type-hints-multiple-types/06_type_aliases.py index 40286b5700..880fdd8cbb 100644 --- a/python-type-hints-multiple-types/06_type_aliases.py +++ b/python-type-hints-multiple-types/06_type_aliases.py @@ -1,7 +1,7 @@ from typing import TypeAlias -EmailComponents = tuple[str, str] | None +EmailComponents: TypeAlias = tuple[str, str] | None def parse_email(email_address: str) -> EmailComponents: @@ -9,6 +9,3 @@ def parse_email(email_address: str) -> EmailComponents: username, domain = email_address.split("@") return username, domain return None - - -EmailComponents: TypeAlias = tuple[str, str] | None diff --git a/python-type-hints-multiple-types/README.md b/python-type-hints-multiple-types/README.md index 9ac6e78af5..b420072179 100644 --- a/python-type-hints-multiple-types/README.md +++ b/python-type-hints-multiple-types/README.md @@ -1,4 +1,3 @@ - # How to Use Type Hints for Multiple Return Types in Python This folder contains sample code for the [How to Use Type Hints for Multiple Return Types in Python](https://realpython.com/python-type-hints-multiple-types/) tutorial on Real Python. @@ -16,25 +15,3 @@ $ python3 -m venv venv/ $ source venv/bin/activate (venv) $ python -m pip install -r requirements.txt ``` - -## Running - -### 01_type_hints_for_one_piece_of_data - - -### 02_type_hints_for_multiple_pieces_of_data - - -### 03_type_hints_for_callback - - -### 04_type_hints_for_factory_function - - -### 05_type_hints_for_generator - - -### 06_type_aliases - - -### 07_static_type_checking \ No newline at end of file diff --git a/python-type-hints-multiple-types/requirements.txt b/python-type-hints-multiple-types/requirements.txt index 987a758147..01bdb66600 100644 --- a/python-type-hints-multiple-types/requirements.txt +++ b/python-type-hints-multiple-types/requirements.txt @@ -1,4 +1,3 @@ mypy==1.5.1 mypy-extensions==1.0.0 -tomli==2.0.1 typing_extensions==4.8.0 From c507f1cd7ab150edef66c5f8e5256bef95a528f0 Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Mon, 2 Oct 2023 20:43:25 -0700 Subject: [PATCH 06/15] Commenting out unused imports --- .../01_type_hints_for_one_piece_of_data.py | 6 +++--- .../02_type_hints_for_multiple_pieces_of_data.py | 6 +++--- .../05_type_hints_for_generator.py | 5 ++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index 282cb2df3e..9d5d2403ff 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -1,6 +1,3 @@ -from typing import Union - - def parse_email(email_address: str) -> str | None: if "@" in email_address: username, domain = email_address.split("@") @@ -8,6 +5,9 @@ def parse_email(email_address: str) -> str | None: return None +# from typing import Union +# +# # def parse_email(email_address: str) -> Union[str, None]: # if "@" in email_address: # username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py index e5b787b7f7..0d7e534454 100644 --- a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py +++ b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py @@ -1,6 +1,3 @@ -from typing import Tuple, Union - - def parse_email(email_address: str) -> tuple[str, str] | None: if "@" in email_address: username, domain = email_address.split("@") @@ -8,6 +5,9 @@ def parse_email(email_address: str) -> tuple[str, str] | None: return None +# from typing import Tuple, Union +# +# # def parse_email(email_address: str) -> Union[Tuple[str, str], None]: # if "@" in email_address: # username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index 97b61634b7..fd1378a725 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -1,4 +1,4 @@ -from collections.abc import Generator, Iterable, Iterator +from collections.abc import Generator, Iterator def parse_email() -> Generator[tuple[str, str], str, str]: @@ -29,6 +29,9 @@ def parse_emails(emails: list[str]) -> Iterator[tuple[str, str]]: yield username, domain +# from collections.abc import Iterable +# +# # def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: # for email in emails: # if "@" in email: From f12f66a69c5982a04d66c1869baf12ca713e5de7 Mon Sep 17 00:00:00 2001 From: Claudia Ng Date: Mon, 2 Oct 2023 20:50:16 -0700 Subject: [PATCH 07/15] Remove trailing white space --- .../01_type_hints_for_one_piece_of_data.py | 2 -- .../02_type_hints_for_multiple_pieces_of_data.py | 2 -- python-type-hints-multiple-types/05_type_hints_for_generator.py | 2 -- 3 files changed, 6 deletions(-) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index 9d5d2403ff..d34f0dba50 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -6,8 +6,6 @@ def parse_email(email_address: str) -> str | None: # from typing import Union -# -# # def parse_email(email_address: str) -> Union[str, None]: # if "@" in email_address: # username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py index 0d7e534454..37a41c0b91 100644 --- a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py +++ b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py @@ -6,8 +6,6 @@ def parse_email(email_address: str) -> tuple[str, str] | None: # from typing import Tuple, Union -# -# # def parse_email(email_address: str) -> Union[Tuple[str, str], None]: # if "@" in email_address: # username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index fd1378a725..7013ac2c44 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -30,8 +30,6 @@ def parse_emails(emails: list[str]) -> Iterator[tuple[str, str]]: # from collections.abc import Iterable -# -# # def parse_emails(emails: Iterable[str]) -> Iterable[tuple[str, str]]: # for email in emails: # if "@" in email: From e144ed2aa481e84987eebae84681a9c3bf70f8bd Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Mon, 9 Oct 2023 11:43:54 +0200 Subject: [PATCH 08/15] Sample code for the article on documenting code with ChatGPT --- document-python-code-with-chatgpt/README.md | 3 + document-python-code-with-chatgpt/circle.py | 56 +++++++++++++++ .../code_explanation.py | 9 +++ .../docstring_1.py | 12 ++++ .../docstring_2.py | 71 +++++++++++++++++++ .../doctest_tests.py | 39 ++++++++++ document-python-code-with-chatgpt/prime.py | 27 +++++++ document-python-code-with-chatgpt/sorted.py | 29 ++++++++ .../usage_examples.py | 8 +++ 9 files changed, 254 insertions(+) create mode 100644 document-python-code-with-chatgpt/README.md create mode 100644 document-python-code-with-chatgpt/circle.py create mode 100644 document-python-code-with-chatgpt/code_explanation.py create mode 100644 document-python-code-with-chatgpt/docstring_1.py create mode 100644 document-python-code-with-chatgpt/docstring_2.py create mode 100644 document-python-code-with-chatgpt/doctest_tests.py create mode 100644 document-python-code-with-chatgpt/prime.py create mode 100644 document-python-code-with-chatgpt/sorted.py create mode 100644 document-python-code-with-chatgpt/usage_examples.py diff --git a/document-python-code-with-chatgpt/README.md b/document-python-code-with-chatgpt/README.md new file mode 100644 index 0000000000..905694ee9b --- /dev/null +++ b/document-python-code-with-chatgpt/README.md @@ -0,0 +1,3 @@ +# Document Your Python Code and Projects With ChatGPT + +This folder provides the code examples for the Real Python tutorial [Document Your Python Code and Projects With ChatGPT](https://realpython.com/document-python-code-with-chatgpt/). diff --git a/document-python-code-with-chatgpt/circle.py b/document-python-code-with-chatgpt/circle.py new file mode 100644 index 0000000000..d4dcae8354 --- /dev/null +++ b/document-python-code-with-chatgpt/circle.py @@ -0,0 +1,56 @@ +"""Prompt +Write Numpy-style docstrings for the following class and its methods: + +class Circle: + def __init__(self, radius): + self.radius = radius + + def calculate_area(self): + return round(math.pi * self.radius ** 2, 2) +""" + +import math + + +# Output: +class Circle: + """ + A Circle class to perform some circle-related operations. + + Parameters + ---------- + radius : float + The radius of the circle. + + Attributes + ---------- + radius : float + The radius of the circle. + + Methods + ------- + calculate_area(): + Calculates the area of the circle. + """ + + def __init__(self, radius): + """ + Constructs all the necessary attributes for the circle object. + + Parameters + ---------- + radius : float + The radius of the circle. + """ + self.radius = radius + + def calculate_area(self): + """ + Calculate the area of the circle. + + Returns + ------- + float + The area of the circle rounded to 2 decimal places. + """ + return round(math.pi * self.radius**2, 2) diff --git a/document-python-code-with-chatgpt/code_explanation.py b/document-python-code-with-chatgpt/code_explanation.py new file mode 100644 index 0000000000..279269ff15 --- /dev/null +++ b/document-python-code-with-chatgpt/code_explanation.py @@ -0,0 +1,9 @@ +"""Prompt +Explain how the following function works: + +def find_extremes(iterable): + data = tuple(iterable) + if len(data) == 0: + raise ValueError("input iterable must not be empty") + return min(data), max(data) +""" diff --git a/document-python-code-with-chatgpt/docstring_1.py b/document-python-code-with-chatgpt/docstring_1.py new file mode 100644 index 0000000000..7e46e8d1eb --- /dev/null +++ b/document-python-code-with-chatgpt/docstring_1.py @@ -0,0 +1,12 @@ +""""Prompt +Write a single-line docstring for the following function: + +def add(a, b): + return a + b +""" + + +# Output: +def add(a, b): + """Return the sum of a and b.""" + return a + b diff --git a/document-python-code-with-chatgpt/docstring_2.py b/document-python-code-with-chatgpt/docstring_2.py new file mode 100644 index 0000000000..b576d82858 --- /dev/null +++ b/document-python-code-with-chatgpt/docstring_2.py @@ -0,0 +1,71 @@ +"""Propmt +Write a Google-style docstring for the following function: + +def add(a, b): + return a + b +""" + + +# Output: +def add(a, b): + """Sum two numbers. + + Args: + a (int or float): The first number. + b (int or float): The second number. + + Returns: + int or float: The sum of the two numbers. + """ + return a + b + + +"""Prompt +Write a Numpy-style docstring for the following function: + +def add(a, b): + return a + b +""" + + +# Output: +def add_(a, b): + """ + Sum two numbers. + + Parameters + ---------- + a : int or float + The first number to be added. + b : int or float + The second number to be added. + + Returns + ------- + int or float + The sum of a and b. + """ + return a + b + + +"""Prompt +Write a Sphinx-style docstring for the following function: + +def add(a, b): + return a + b +""" + + +# Output: +def add__(a, b): + """ + Calculate the sum of two numbers. + + :param a: The first number. + :type a: int or float + :param b: The second number. + :type b: int or float + :return: The sum of the two numbers. + :rtype: int or float + """ + return a + b diff --git a/document-python-code-with-chatgpt/doctest_tests.py b/document-python-code-with-chatgpt/doctest_tests.py new file mode 100644 index 0000000000..2544a34535 --- /dev/null +++ b/document-python-code-with-chatgpt/doctest_tests.py @@ -0,0 +1,39 @@ +"""Prompt +Write a Numpy-style docstring for the following function. +Add a section with usage examples as doctest tests: + +def add(a, b): + return a + b +""" + + +# Output: +def add(a, b): + """ + Add two numbers together. + + This function takes two numbers (either integers or floats) + as arguments and returns their sum. + + Parameters + ---------- + a : int or float + The first number to add. + b : int or float + The second number to add. + + Returns + ------- + int or float + The sum of the two input numbers. + + Examples + -------- + >>> add(1, 2) + 3 + >>> add(5.5, 2.5) + 8.0 + >>> add(100, -50) + 50 + """ + return a + b diff --git a/document-python-code-with-chatgpt/prime.py b/document-python-code-with-chatgpt/prime.py new file mode 100644 index 0000000000..f27ede4273 --- /dev/null +++ b/document-python-code-with-chatgpt/prime.py @@ -0,0 +1,27 @@ +"""Prompt +Write a Google-style docstring for a function that takes an +integer as an argument and determines whether it’s a primary +number. +""" + + +# Output: +def is_primary_number(n): + """ + Determines if an input integer is a primary number. + + This function takes an integer as an argument and checks + whether it is a primary number. A primary number is a + positive natural number greater than 1 that has no positive + integer divisors other than 1 and itself. + + Args: + n (int): The integer to check. + + Returns: + bool: True if the input integer is a primary number, + False otherwise. + + Raises: + ValueError: If n is less than or equal to 1. + """ diff --git a/document-python-code-with-chatgpt/sorted.py b/document-python-code-with-chatgpt/sorted.py new file mode 100644 index 0000000000..462d0ebfe8 --- /dev/null +++ b/document-python-code-with-chatgpt/sorted.py @@ -0,0 +1,29 @@ +"""Prompt +Write a Google-style docstring for a function with the following signature: + +sorted(iterable, key=None, reverse=False): +""" + + +# Output: +def sorted(iterable, key=None, reverse=False): + """ + Sorts objects from the provided iterable in ascending order + by default, descending order if 'reverse' is True. + + Args: + iterable (iterable): Iterable of comparable objects that + are to be sorted. + + key (Callable, optional): Specifies a function to extract + a comparison key from each element. + The iterable objects are sorted based on the keys extracted. + By default, the elements themselves are compared. + + reverse (bool, optional): If set to True, then the list + elements are sorted in descending order. + Default is False. + + Returns: + list: A new sorted list from the items in the iterable. + """ diff --git a/document-python-code-with-chatgpt/usage_examples.py b/document-python-code-with-chatgpt/usage_examples.py new file mode 100644 index 0000000000..cdde5ee066 --- /dev/null +++ b/document-python-code-with-chatgpt/usage_examples.py @@ -0,0 +1,8 @@ +"""Prompt +Write three usage examples for the following function. Add explanations to each example: + +def is_divisible(a, b): + if not a % b: + return True + return False +""" From a94cdcd848c6d916b2df48f5fb4b823a66b7614b Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Mon, 9 Oct 2023 11:47:01 +0200 Subject: [PATCH 09/15] Fix linter issues --- document-python-code-with-chatgpt/usage_examples.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/document-python-code-with-chatgpt/usage_examples.py b/document-python-code-with-chatgpt/usage_examples.py index cdde5ee066..3db413ab8c 100644 --- a/document-python-code-with-chatgpt/usage_examples.py +++ b/document-python-code-with-chatgpt/usage_examples.py @@ -1,5 +1,6 @@ """Prompt -Write three usage examples for the following function. Add explanations to each example: +Write three usage examples for the following function. +Add explanations to each example: def is_divisible(a, b): if not a % b: From 8be905bbd5a7f0d45162463cef3f0d2ab1a73229 Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Mon, 9 Oct 2023 11:50:36 +0200 Subject: [PATCH 10/15] Remove trailing spaces --- document-python-code-with-chatgpt/docstring_1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document-python-code-with-chatgpt/docstring_1.py b/document-python-code-with-chatgpt/docstring_1.py index 7e46e8d1eb..110858255a 100644 --- a/document-python-code-with-chatgpt/docstring_1.py +++ b/document-python-code-with-chatgpt/docstring_1.py @@ -2,7 +2,7 @@ Write a single-line docstring for the following function: def add(a, b): - return a + b + return a + b """ From 7e3162ae2c0d8ce7f4760aa0184211ac5e26bb6d Mon Sep 17 00:00:00 2001 From: Leodanis Pozo Ramos Date: Tue, 10 Oct 2023 11:17:01 +0200 Subject: [PATCH 11/15] TR updates, first round --- document-python-code-with-chatgpt/interval.py | 30 +++++++++++++++++++ document-python-code-with-chatgpt/sorted.py | 29 ------------------ 2 files changed, 30 insertions(+), 29 deletions(-) create mode 100644 document-python-code-with-chatgpt/interval.py delete mode 100644 document-python-code-with-chatgpt/sorted.py diff --git a/document-python-code-with-chatgpt/interval.py b/document-python-code-with-chatgpt/interval.py new file mode 100644 index 0000000000..168114869f --- /dev/null +++ b/document-python-code-with-chatgpt/interval.py @@ -0,0 +1,30 @@ +"""Prompt +Write a Google-style docstring for a function with the following signature: + +def in_interval(number, start, end): +""" + + +# Output: +def in_interval(number, start, end): + """ + Checks if a given number is within a specified interval. + + This function takes three arguments: a number, and the start + and end points of an interval. + It checks whether the given number falls within the specified + interval or not. + + Args: + number (int or float): The number to check. + start (int or float): The starting point of the interval. + end (int or float): The ending point of the interval. + + Returns: + bool: True if the given number falls within the interval, + False otherwise. + + Raises: + ValueError: If the start is larger than the end, or if + the number, start, or end are not numbers. + """ diff --git a/document-python-code-with-chatgpt/sorted.py b/document-python-code-with-chatgpt/sorted.py deleted file mode 100644 index 462d0ebfe8..0000000000 --- a/document-python-code-with-chatgpt/sorted.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Prompt -Write a Google-style docstring for a function with the following signature: - -sorted(iterable, key=None, reverse=False): -""" - - -# Output: -def sorted(iterable, key=None, reverse=False): - """ - Sorts objects from the provided iterable in ascending order - by default, descending order if 'reverse' is True. - - Args: - iterable (iterable): Iterable of comparable objects that - are to be sorted. - - key (Callable, optional): Specifies a function to extract - a comparison key from each element. - The iterable objects are sorted based on the keys extracted. - By default, the elements themselves are compared. - - reverse (bool, optional): If set to True, then the list - elements are sorted in descending order. - Default is False. - - Returns: - list: A new sorted list from the items in the iterable. - """ From 9b8b2556bfc0b578483f2299d451d5734aef9565 Mon Sep 17 00:00:00 2001 From: KateFinegan <95366190+KateFinegan@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:54:48 -0600 Subject: [PATCH 12/15] README LE --- python-type-hints-multiple-types/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python-type-hints-multiple-types/README.md b/python-type-hints-multiple-types/README.md index b420072179..2b3cdc3a6e 100644 --- a/python-type-hints-multiple-types/README.md +++ b/python-type-hints-multiple-types/README.md @@ -4,11 +4,11 @@ This folder contains sample code for the [How to Use Type Hints for Multiple Ret ## Installation -Some of the code requires the following third-party libraries: +Some of the code requires the following third-party library: - [`mypy`](https://pypi.org/project/mypy/) -To install them into a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/), type the following commands: +To install it into a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/), type the following commands: ```shell $ python3 -m venv venv/ From e6ba9580ac7a106e0c175d045dc77b4d6ec92443 Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Thu, 19 Oct 2023 23:52:12 +0200 Subject: [PATCH 13/15] Final QA (#451) --- .../01_type_hints_for_one_piece_of_data.py | 3 +++ .../02_type_hints_for_multiple_pieces_of_data.py | 3 +++ .../03_type_hints_for_callback.py | 13 ++++++++----- .../04_type_hints_for_factory_function.py | 13 ++++++++----- .../05_type_hints_for_generator.py | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py index d34f0dba50..8da0a92531 100644 --- a/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py +++ b/python-type-hints-multiple-types/01_type_hints_for_one_piece_of_data.py @@ -5,7 +5,10 @@ def parse_email(email_address: str) -> str | None: return None +# %% Python 3.9 and earlier + # from typing import Union +# # def parse_email(email_address: str) -> Union[str, None]: # if "@" in email_address: # username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py index 37a41c0b91..c0bfc13a70 100644 --- a/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py +++ b/python-type-hints-multiple-types/02_type_hints_for_multiple_pieces_of_data.py @@ -5,7 +5,10 @@ def parse_email(email_address: str) -> tuple[str, str] | None: return None +# %% Python 3.9 and earlier + # from typing import Tuple, Union +# # def parse_email(email_address: str) -> Union[Tuple[str, str], None]: # if "@" in email_address: # username, domain = email_address.split("@") diff --git a/python-type-hints-multiple-types/03_type_hints_for_callback.py b/python-type-hints-multiple-types/03_type_hints_for_callback.py index 8a269c1225..d65ee6df33 100644 --- a/python-type-hints-multiple-types/03_type_hints_for_callback.py +++ b/python-type-hints-multiple-types/03_type_hints_for_callback.py @@ -1,16 +1,19 @@ from collections.abc import Callable -from typing import Any +from typing import ParamSpec, TypeVar +P = ParamSpec("P") +T = TypeVar("T") -def apply_func(func: Callable[..., Any], *args: Any) -> Any: - return func(*args) +def apply_func(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: + return func(*args, **kwargs) -def parse_email(email_address: str) -> tuple[str, str] | None: + +def parse_email(email_address: str) -> tuple[str, str]: if "@" in email_address: username, domain = email_address.split("@") return username, domain - return None + return "", "" apply_func(parse_email, "claudia@realpython.com") diff --git a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py index 658e20dfa3..c2b8afc52c 100644 --- a/python-type-hints-multiple-types/04_type_hints_for_factory_function.py +++ b/python-type-hints-multiple-types/04_type_hints_for_factory_function.py @@ -1,12 +1,15 @@ import functools import time from collections.abc import Callable -from typing import Any +from typing import ParamSpec, TypeVar +P = ParamSpec("P") +T = TypeVar("T") -def timeit(function: Callable[..., Any]) -> Callable[..., Any]: + +def timeit(function: Callable[P, T]) -> Callable[P, T]: @functools.wraps(function) - def wrapper(*args, **kwargs): + def wrapper(*args: P.args, **kwargs: P.kwargs): start = time.perf_counter() result = function(*args, **kwargs) end = time.perf_counter() @@ -17,11 +20,11 @@ def wrapper(*args, **kwargs): @timeit -def parse_email(email_address: str) -> tuple[str, str] | None: +def parse_email(email_address: str) -> tuple[str, str]: if "@" in email_address: username, domain = email_address.split("@") return username, domain - return None + return "", "" username, domain = parse_email("claudia@realpython.com") diff --git a/python-type-hints-multiple-types/05_type_hints_for_generator.py b/python-type-hints-multiple-types/05_type_hints_for_generator.py index 7013ac2c44..fab68bd2ef 100644 --- a/python-type-hints-multiple-types/05_type_hints_for_generator.py +++ b/python-type-hints-multiple-types/05_type_hints_for_generator.py @@ -8,7 +8,7 @@ def parse_email() -> Generator[tuple[str, str], str, str]: username, domain = sent.split("@") sent = yield username, domain else: - sent = yield "invalid email" + sent = yield "ERROR", "invalid email" return "Done" From f855fff03cde1f0f21135da7556a7e9664184556 Mon Sep 17 00:00:00 2001 From: KateFinegan <95366190+KateFinegan@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:50:01 -0600 Subject: [PATCH 14/15] Numpy -> NumPy --- document-python-code-with-chatgpt/circle.py | 2 +- document-python-code-with-chatgpt/doctest_tests.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/document-python-code-with-chatgpt/circle.py b/document-python-code-with-chatgpt/circle.py index d4dcae8354..d9940822e2 100644 --- a/document-python-code-with-chatgpt/circle.py +++ b/document-python-code-with-chatgpt/circle.py @@ -1,5 +1,5 @@ """Prompt -Write Numpy-style docstrings for the following class and its methods: +Write NumPy-style docstrings for the following class and its methods: class Circle: def __init__(self, radius): diff --git a/document-python-code-with-chatgpt/doctest_tests.py b/document-python-code-with-chatgpt/doctest_tests.py index 2544a34535..4430d9a6bf 100644 --- a/document-python-code-with-chatgpt/doctest_tests.py +++ b/document-python-code-with-chatgpt/doctest_tests.py @@ -1,5 +1,5 @@ """Prompt -Write a Numpy-style docstring for the following function. +Write a NumPy-style docstring for the following function. Add a section with usage examples as doctest tests: def add(a, b): From 851111486577f24fe711a62c3b81e53b2983f633 Mon Sep 17 00:00:00 2001 From: Geir Arne Hjelle Date: Fri, 20 Oct 2023 12:43:14 +0200 Subject: [PATCH 15/15] Final QA (#452) --- document-python-code-with-chatgpt/prime.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/document-python-code-with-chatgpt/prime.py b/document-python-code-with-chatgpt/prime.py index f27ede4273..b7e9f21e1c 100644 --- a/document-python-code-with-chatgpt/prime.py +++ b/document-python-code-with-chatgpt/prime.py @@ -1,17 +1,17 @@ """Prompt Write a Google-style docstring for a function that takes an -integer as an argument and determines whether it’s a primary +integer as an argument and determines whether it’s a prime number. """ # Output: -def is_primary_number(n): +def is_prime_number(n): """ - Determines if an input integer is a primary number. + Determines if an input integer is a prime number. This function takes an integer as an argument and checks - whether it is a primary number. A primary number is a + whether it is a prime number. A prime number is a positive natural number greater than 1 that has no positive integer divisors other than 1 and itself. @@ -19,7 +19,7 @@ def is_primary_number(n): n (int): The integer to check. Returns: - bool: True if the input integer is a primary number, + bool: True if the input integer is a prime number, False otherwise. Raises: