Python - from None to AI
  • License
  • Install
  • Python Versions
  • Python History
  • Links
  • References

Basics

  • 1. About
  • 2. Syntax
  • 3. Numeric
  • 4. Logic
  • 5. Strings
  • 6. Iterables
  • 7. Mappings
  • 8. Nested
  • 9. Unpack
  • 10. Conditional
  • 11. While
  • 12. For
  • 13. Comprehensions
  • 14. Files
  • 15. Functions
  • 16. Exceptions
  • 17. OOP
  • 18. Modules
  • 19. Recap

Intermediate

  • 1. About
  • 2. Syntax
  • 3. Star
  • 4. Enum
  • 5. Match
  • 6. Encoding
  • 7. Regex
    • 7.1. Regex Syntax About
    • 7.2. Regex Literal Character
    • 7.3. Regex Literal Alternative
    • 7.4. Regex Literal Enumeration
    • 7.5. Regex Literal Range
    • 7.6. Regex Syntax Dot
    • 7.7. Regex Anchor
    • 7.8. Regex Negation
    • 7.9. Regex Class Numeric
    • 7.10. Regex Class Whitespace
    • 7.11. Regex Class Boundary
    • 7.12. Regex Character Class
    • 7.13. Regex Quantifier Exact
    • 7.14. Regex Quantifier Greedy
    • 7.15. Regex Quantifier Lazy
    • 7.16. Regex Quantifier Recap
    • 7.17. Regex Positional Group
    • 7.18. Regex Named Group
    • 7.19. Regex Non-Capturing Group
    • 7.20. Regex Comment Group
    • 7.21. Regex Atomic Group
    • 7.22. Regex Backreference
    • 7.23. Regex Flag
    • 7.24. Regex Look Ahead/Behind
    • 7.25. Regex Flavors
    • 7.26. Regex Recap
    • 7.27. Regex RE Findall
    • 7.28. Regex RE Finditer
    • 7.29. Regex RE Search
      • 7.29.1. SetUp
      • 7.29.2. Problem
      • 7.29.3. Solution
      • 7.29.4. Result
      • 7.29.5. Methods
      • 7.29.6. Usage
      • 7.29.7. Use Case - 1
      • 7.29.8. Use Case - 2
      • 7.29.9. Use Case - 3
      • 7.29.10. Assignments
    • 7.30. Regex RE Match
    • 7.31. Regex RE Compile
    • 7.32. Regex RE Substitute
    • 7.33. Regex RE Split
    • 7.34. Regex Case Study
    • 7.35. Regex Cheatsheet
  • 8. Datetime
  • 9. Idiom
  • 10. Iterator
  • 11. OOP
  • 12. Serialization
  • 13. Pickle
  • 14. TOML
  • 15. CSV
  • 16. JSON
  • 17. Pathlib
  • 18. Logging
  • 19. Modules
  • 20. Recap

Advanced

  • 1. About
  • 2. Syntax
  • 3. Typing
  • 4. OOP Dataclass
  • 5. OOP Paradigm
  • 6. OOP Inheritance
  • 7. OOP Abstract
  • 8. OOP Metaprogramming
  • 9. OOP Accessors
  • 10. OOP Operator
  • 11. FP Paradigm
  • 12. FP Apply
  • 13. FP Patterns
  • 14. Generators
  • 15. Async Paradigm
  • 16. Async AsyncIO

Performance

  • 1. About
  • 2. Introduction
  • 3. Optimization
  • 4. Profiling
  • 5. Case Study
  • 6. Threading
  • 7. Multiprocessing
  • 8. Extensions

Testing

  • 1. About
  • 2. Random
  • 3. Syntax
  • 4. Doctest
  • 5. Unittest
  • 6. Recap

CI/CD

  • 1. DevTools
  • 2. Distribute
  • 3. Lint
  • 4. Quality
  • 5. Security
  • 6. Webdev

DevOps

  • 1. About
  • 2. Quality
  • 3. Tests
  • 4. Debugging

Database

  • 1. About
  • 2. Theory
  • 3. ORM
  • 4. Normalization
  • 5. NoSQL
  • 6. SQL
  • 7. SQLite3
  • 8. SQLAlchemy
  • 9. Case Study

Design Patterns

  • 1. About
  • 2. UML
  • 3. Decorators
  • 4. Creational
  • 5. Behavioral
  • 6. Structural

Numpy

  • 1. About
  • 2. Array
  • 3. Attributes
  • 4. Random
  • 5. Indexing
  • 6. Operations
  • 7. Methods
  • 8. Statistics
  • 9. Math
  • 10. Polynomial

Pandas

  • 1. About
  • 2. Read
  • 3. To
  • 4. Series
  • 5. DataFrame
  • 6. Date
  • 7. Case Study

Matplotlib

  • 1. About
  • 2. Figure
  • 3. Style
  • 4. Chart
  • 5. Case Study

Stdlib

  • 1. Modules
  • 2. Collections
  • 3. Math
  • 4. Locale
  • 5. XML
  • 6. Operating System
  • 7. String
  • 8. Builtin
  • 9. Type
  • 10. Loop
  • 11. TkInter

Network

  • 1. About
  • 2. Protocol
  • 3. Web
  • 4. Transport
  • 5. Case Study

Microservices

  • 1. About
  • 2. HTTP
  • 3. Microservices
  • 4. Auth

Django

  • 1. About
  • 2. Setup
  • 3. Settings
  • 4. Models
  • 5. Admin
  • 6. ORM
  • 7. Views
  • 8. Templates
  • 9. Templatetags
  • 10. Forms
  • 11. Manage
  • 12. Locale
  • 13. Middleware
  • 14. Utils
  • 15. Auth
  • 16. API
  • 17. Ninja
  • 18. Tests
  • 19. Apps
  • 20. Deploy

FastAPI

  • 1. About
  • 2. FastAPI
  • 3. Pydantic
  • 4. Database
  • 5. Auth
  • 6. DevOps
  • 7. Case Study

Data Science

  • 1. About
  • 2. Jupyter
  • 3. Python
  • 4. Visualization
  • 5. Scipy
  • 6. Geopandas

Machine Learning

  • 1. About
  • 2. Introduction
  • 3. Sklearn
  • 4. Model Quality
  • 5. Decision Trees
  • 6. Regressions
  • 7. K-Nearest Neighbors
  • 8. Bayes
  • 9. Support Vector Machines
  • 10. Clustering
  • 11. Neural Networks
  • 12. References
  • 13. Articles

Artificial Intelligence

  • 1. About

OOP

  • 1. Paradigm
  • 2. Python

Dragon

  • 1. English
  • 2. Polish
  • 3. ADR
Python - from None to AI
  • 1. About
  • 7.29. Regex RE Search

7.29. Regex RE Search

  • re.search()

  • Searches if pattern contains a string

  • Stops after first match

7.29.1. SetUp

>>> import re

7.29.2. Problem

  • Does the text contain any uppercase letters?

>>> from string import ascii_uppercase
>>>
>>> text = 'Hello World'
>>>
>>> result = False
>>> for letter in text:
...     if letter in ascii_uppercase:
...         result = True
...         break
>>>
>>> if result:
...     print('yes')
... else:
...     print('no')
yes

7.29.3. Solution

  • Does the text contain any uppercase letters?

>>> text = 'Hello World'
>>> result = re.search(r'[A-Z]', text)
>>>
>>> if result:
...     print('yes')
... else:
...     print('no')
yes

7.29.4. Result

  • re.search() -> re.Match | None - Optional re.Match

>>> text = 'Hello World'
>>>
>>> re.search(r'[A-Z]', text)
<re.Match object; span=(0, 1), match='H'>

7.29.5. Methods

>>> email = 'mwatney@nasa.gov'
>>> result = re.search(r'(?P<username>[a-z]+)@nasa.gov', email)

Position:

>>> result.span()
(0, 16)
>>>
>>> result.start()
0
>>>
>>> result.end()
16

Working with groups:

>>> result.group()
'mwatney@nasa.gov'
>>>
>>> result.group(0)
'mwatney@nasa.gov'
>>>
>>> result.group(1)
'mwatney'
>>>
>>> result.group('username')
'mwatney'
>>>
>>> result.groups()
('mwatney',)
>>>
>>> result.groupdict()
{'username': 'mwatney'}

Diagnostics:

>>> result.string
'mwatney@nasa.gov'
>>>
>>> result.re
re.compile('(?P<username>[a-z]+)@nasa.gov')

7.29.6. Usage

>>> text = 'Hello World'
>>> result = re.search(r'[A-Z]', text)
>>>
>>> if result:
...     print('found')
... else:
...     print('not found')
found

7.29.7. Use Case - 1

>>> import re
>>>
>>>
>>> def contains(pattern, text):
...     if re.search(pattern, text):
...         return True
...     else:
...         return False
>>>
>>>
>>> COMMIT_MESSAGE = 'MYPROJ-1337, MYPROJ-69 removed obsolete comments'
>>> jira_issuekey = r'[A-Z]{2,10}-[0-9]{1,6}'
>>> redmine_number = r'#[0-9]+'
>>>
>>> contains(jira_issuekey, COMMIT_MESSAGE)
True
>>> contains(redmine_number, COMMIT_MESSAGE)
False

7.29.8. Use Case - 2

>>> import re
>>>
>>>
>>> TEXT = 'We choose to go to the moon.'
>>>
>>> result = re.search(r'moon', TEXT)
>>>
>>> result
<re.Match object; span=(23, 27), match='moon'>
>>>
>>> result.span()
(23, 27)
>>>
>>> result.regs
((23, 27),)
>>>
>>> TEXT[23]
'm'
>>> TEXT[23:27]
'moon'

7.29.9. Use Case - 3

>>> import re
>>>
>>>
>>> TEXT = 'We choose to go to the moon.'
>>>
>>>
>>> result = re.search(r'Mars', TEXT)
>>>
>>> result.group()
Traceback (most recent call last):
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> result = re.search(r'Mars', TEXT)
>>> if result:
...     result.group()
>>>
>>>
>>> if result := re.search(r'Mars', TEXT):
...     result.group()

7.29.10. Assignments

# %% About
# - Name: RE Search Astronauts
# - Difficulty: easy
# - Lines: 6
# - Minutes: 5

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Define variables with start and end position in `DATA`:
#    - `result_a: tuple[int,int]` for 'Neil Armstrong'
#    - `result_b: tuple[int,int]` for 'Buzz Aldrin'
#    - `result_c: tuple[int,int]` for 'Michael Collins'
#    - `result_d: tuple[int,int]` for 'Mark Watney'
# 2. For each element return tuple i.e. `(10, 20)`
# 3. If element is not present in `DATA` assign `None`
# 4. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj zmienne z pozycją startu i końca w `DATA`:
#    - `result_a: tuple[int,int]` dla 'Neil Armstrong'
#    - `result_b: tuple[int,int]` dla 'Buzz Aldrin'
#    - `result_c: tuple[int,int]` dla 'Michael Collins'
#    - `result_d: tuple[int,int]` dla 'Mark Watney'
# 2. Dla każdego ciągu znaków zwracaj tuple np. `(10, 20)`
# 3. Jeżeli ciąg znaków nie jest obecny w `DATA` przypisz `None`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `re.search()`
# - `re.Match.span()`

# %% References
# [1] Wikipedia: Apollo 11
#     URL: https://en.wikipedia.org/wiki/Apollo_11
#     Year: 2019
#     Retrieved: 2019-12-14

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert result_a is not Ellipsis, \
'Assign result to variable: `result_a`'
>>> assert type(result_a) is not type(None), \
'Variable `result_a` has invalid type, cannot be None'
>>> assert type(result_a) is tuple, \
'Variable `result_a` has invalid type, should be tuple'
>>> assert all(type(x) is int for x in result_a), \
'All elements in variable `result_a`, should be int'
>>> assert len(result_a) == 2, \
'Variable `result_a` has invalid length, should be 2'

>>> assert result_b is not Ellipsis, \
'Assign result to variable: `result_b`'
>>> assert type(result_b) is not type(None), \
'Variable `result_b` has invalid type, cannot be None'
>>> assert type(result_b) is tuple, \
'Variable `result_b` has invalid type, should be tuple'
>>> assert all(type(x) is int for x in result_b), \
'All elements in variable `result_b`, should be int'
>>> assert len(result_b) == 2, \
'Variable `result_b` has invalid length, should be 2'

>>> assert result_c is not Ellipsis, \
'Assign result to variable: `result_c`'
>>> assert type(result_c) is not type(None), \
'Variable `result_c` has invalid type, cannot be None'
>>> assert type(result_c) is tuple, \
'Variable `result_c` has invalid type, should be tuple'
>>> assert all(type(x) is int for x in result_c), \
'All elements in variable `result_c`, should be int'
>>> assert len(result_c) == 2, \
'Variable `result_c` has invalid length, should be 2'

>>> assert result_d is not Ellipsis, \
'Assign result to variable: `result_d`'
>>> assert type(result_d) is type(None), \
'Variable `result_d` has invalid type, should be None'

>>> print(result_a)
(78, 92)
>>> print(result_b)
(116, 127)
>>> print(result_c)
(562, 577)
>>> print(result_d)
None
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports
import re

# %% Types
result_a: tuple[int,int] | None
result_b: tuple[int,int] | None
result_c: tuple[int,int] | None
result_d: tuple[int,int] | None

# %% Data
DATA = (
    "Apollo 11 was the spaceflight that first landed humans on the Moon. "
    "Commander Neil Armstrong and lunar module pilot Buzz Aldrin formed "
    "the American crew that landed the Apollo Lunar Module Eagle on "
    "July 20, 1969, at 20:17 UTC. Armstrong became the first person to "
    "step onto the lunar surface six hours and 39 minutes later on "
    "July 21 at 02:56 UTC; Aldrin joined him 19 minutes later. They spent "
    "about two and a quarter hours together outside the spacecraft, "
    "and they collected 47.5 pounds (21.5 kg) of lunar material to bring "
    "back to Earth. Command module pilot Michael Collins flew the command "
    "module Columbia alone in lunar orbit while they were on the Moon's "
    "surface. Armstrong and Aldrin spent 21 hours, 36 minutes on the "
    "lunar surface at a site they named Tranquility Base before lifting "
    "off to rejoin Columbia in lunar orbit. "
)

# %% Result
result_a = ...
result_b = ...
result_c = ...
result_d = ...

# %% About
# - Name: RE Search Moon Speech
# - Difficulty: easy
# - Lines: 5
# - Minutes: 8

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Use `re.search()` to find in text [1]
# 2. Define `result: str` containing paragraph starting with 'We choose to go to the moon'
# 3. Run doctests - all must succeed

# %% Polish
# 1. Użyj `re.search()` do znalezienia w tekście [1]
# 2. Zdefiniuj `result: str` zawierający tekst paragrafu zaczynający się od słów "We choose to go to the moon"
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% References
# [1] Kennedy, J.F. Moon Speech - Rice Stadium,
#     URL: http://er.jsc.nasa.gov/seh/ricetalk.htm
#     Year: 2019
#     Retrieved: 2019-12-14

# %% Hints
# - All HTML paragraphs starts with `<p>` and ends with `</p>`
# - In real life paragraphs parsing is more complex
# - `re.search()`
# - `re.DOTALL`
# - `re.Match.group()`

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert type(result) is str, 'result must be a str'
>>> assert not result.startswith('<p>'), 'result cannot start with <p>'
>>> assert not result.endswith('</p>'), 'result cannot end with </p>'

>>> print(result)
We choose to go to the moon. We choose to go to
the moon in this decade and do the other things, not because they
are easy, but because they are hard, because that goal will serve
to organize and measure the best of our energies and skills,because
that challenge is one that we are willing to accept, one we are
unwilling to postpone, and one which we intend to win, and the
others, too.
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports
import re

# %% Types
result: str

# %% Data
DATA = """<h1>TEXT OF PRESIDENT JOHN KENNEDY'S RICE STADIUM MOON SPEECH</h1>
<p>President Pitzer, Mr. Vice President, Governor,
CongressmanThomas, Senator Wiley, and Congressman Miller, Mr. Webb,
Mr.Bell, scientists, distinguished guests, and ladies and
gentlemen:</p><p>We choose to go to the moon. We choose to go to
the moon in this decade and do the other things, not because they
are easy, but because they are hard, because that goal will serve
to organize and measure the best of our energies and skills,because
that challenge is one that we are willing to accept, one we are
unwilling to postpone, and one which we intend to win, and the
others, too.</p><p>It is for these reasons that I regard the
decision last year to shift our efforts in space from low to high
gear as among the most important decisions that will be made during
my incumbency in the office of the Presidency.</p><p>In the last 24
hours we have seen facilities now being created for the greatest
and most complex exploration in man's history.We have felt the
ground shake and the air shattered by the testing of a Saturn C-1
booster rocket, many times as powerful as the Atlas which launched
John Glenn, generating power equivalent to 10,000 automobiles with
their accelerators on the floor.We have seen the site where the F-1
rocket engines, each one as powerful as all eight engines of the
Saturn combined, will be clustered together to make the advanced
Saturn missile, assembled in a new building to be built at Cape
Canaveral as tall as a48 story structure, as wide as a city block,
and as long as two lengths of this field.</p>
"""

# %% Result
result = ...

# %% About
# - Name: RE Search Time
# - Difficulty: easy
# - Lines: 4
# - Minutes: 3

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Use regular expressions to check `DATA` [1]
#    contains time in UTC (24 hour clock compliant with ISO-8601)
# 2. Define `result: str` with matched time
# 3. Use simplified checking `xx:xx UTC`,
#    where `x` is a digit
# 4. Text does not contain any invalid date
# 5. Run doctests - all must succeed

# %% Polish
# 1. Użyj wyrażeń regularnych do sprawdzenia czy `DATA` [1]
#    zawiera godzinę w UTC (format 24 godzinny zgodny z ISO-8601)
# 2. Zdefiniuj `result: str` ze znalezionym czasem
# 3. Użyj uproszczonego sprawdzania: `xx:xx UTC`,
#    gdzie `x` to dowolna cyfra
# 4. Tekst nie zawiera żadnej niepoprawnej godziny
# 5. Uruchom doctesty - wszystkie muszą się powieść

# %% References
# [1] Wikipedia Apollo 11,
#     URL: https://en.wikipedia.org/wiki/Apollo_11
#     Year: 2019
#     Retrieved: 2019-12-14

# %% Hints
# - `re.Match.group()`

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert type(result) is str, 'result must be a str'
>>> assert result.endswith('UTC'), 'result must contain timezone'

>>> result
'20:17 UTC'
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports
import re

# %% Types
result: str

# %% Data
DATA = """Apollo 11 was the American spaceflight that first landed
humans on the Moon. Commander (CDR) Neil Armstrong and lunar module
pilot (LMP) Buzz Aldrin landed the Apollo Lunar Module (LM) Eagle on
July 20th, 1969 at 20:17 UTC, and Armstrong became the first person
to step (EVA) onto the Moon's surface (EVA) 6 hours 39 minutes later,
on July 21st, 1969 at 02:56:15 UTC. Aldrin joined him 19 minutes later.
They spent 2 hours 31 minutes exploring the site they had named
Tranquility Base upon landing. Armstrong and Aldrin collected 47.5 pounds
(21.5 kg) of lunar material to bring back to Earth as pilot Michael Collins
(CMP) flew the Command Module (CM) Columbia in lunar orbit, and were on the
Moon's surface for 21 hours 36 minutes before lifting off to rejoin
Columbia."""

# %% Result
result = ...

# %% About
# - Name: RE Search Time
# - Difficulty: easy
# - Lines: 4
# - Minutes: 5

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Use regular expressions to check `DATA` [1]
#    contains time in UTC (24 hour clock compliant with ISO-8601)
# 2. Define `result: str` with matched time
# 3. Use real checking `xx:xx UTC`,
#    where `x` is a valid digit at the position
# 4. Text contains invalid date `24:56 UTC`
# 5. Run doctests - all must succeed

# %% Polish
# 1. Użyj wyrażeń regularnych do sprawdzenia czy `DATA` [1]
#    zawiera godzinę w UTC (format 24 godzinny zgodny z ISO-8601)
# 2. Zdefiniuj `result: str` ze znalezionym czasem
# 3. Użyj poprawnego sprawdzania: `xx:xx UTC`,
#    gdzie `x` to odpowiedni znak na danym miejscu
# 4. Tekst zawiera niepoprawną godzinę: `24:56 UTC`
# 5. Uruchom doctesty - wszystkie muszą się powieść

# %% References
# [1] Wikipedia Apollo 11,
#     URL: https://en.wikipedia.org/wiki/Apollo_11
#     Year: 2019
#     Retrieved: 2019-12-14

# %% Hints
# - `re.Match.group()`

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert type(result) is str, 'result must be a str'
>>> assert result.endswith('UTC'), 'result must contain timezone'

>>> result
'02:56 UTC'
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports
import re

# %% Types
result: str

# %% Data
DATA = """Apollo 11 was the American spaceflight that first landed
humans on the Moon. Commander (CDR) Neil Armstrong and lunar module
pilot (LMP) Buzz Aldrin landed the Apollo Lunar Module (LM) Eagle on
July 20th, 1969 at 24:17 UTC, and Armstrong became the first person
to step (EVA) onto the Moon's surface (EVA) 6 hours 39 minutes later,
on July 21st, 1969 at 02:56 UTC. Aldrin joined him 19 minutes later.
They spent 2 hours 31 minutes exploring the site they had named
Tranquility Base upon landing. Armstrong and Aldrin collected 47.5 pounds
(21.5 kg) of lunar material to bring back to Earth as pilot Michael Collins
(CMP) flew the Command Module (CM) Columbia in lunar orbit, and were on the
Moon's surface for 21 hours 36 minutes before lifting off to rejoin
Columbia."""

# %% Result
result = ...

Previous Next

© Copyright 2025, Matt Harasymczuk <matt@python3.info>, last update: 2025-05-31.