Skip to content
Snippets Groups Projects
Commit faccdf0e authored by Škoviera, Radoslav, Mgr., Ph.D.'s avatar Škoviera, Radoslav, Mgr., Ph.D.
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
.vscode/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm-project.org/#use-with-ide
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.ipynb_checkpoints/**
This diff is collapsed.
[project]
name = "pge_lectures"
version = "0.1.0"
description = "Default template for PDM package"
authors = [
{name = "radoskov", email = "radoslav.skoviera@cvut.cz"},
]
dependencies = ["ipython>=8.32.0", "ipykernel>=6.29.5", "jupyter>=1.1.1", "matplotlib>=3.10.0", "numpy>=2.2.3"]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "LGPLv3"}
[project.scripts]
run = "python_tutorial.__main__:main"
[tool.pdm]
distribution = false
%% Cell type:markdown id: tags:
For those who don't know, this is what is called a "Jupyter notebook". It is kind of like a web page that a mixes code and markdown formatted text. It is divided into "cells". Each cell can be either text cell (using markdown format) or code cell, containing executable Python code. When executed, the text cells simply render the formatted text. However, the code cells will actually run the code and print the result below that cell.
Important to keep in mind is that actual Python "kernel" is running in the background. Whatever you run, "stays" in the kernel (until it is stopped or restarted). For example, if you run a cell defining a variable `a = 3`, you can then use the variable in another cell, e.g., `b = a + 5` (without redefining it in that cell). However, the order of the cells in the document does not matter. What matters is the order in which you execute the cells. Therefore, if you run the cell containing `b = a + 5` before the cell containing `a = 3`, it will throw an error stating that variable `a` does not exist. Likewise, if you execute another cell with `a = 7`, it will rewrite the value of `a` and thus `b = a + 5` will result in `b` having a different value.
Keep this in mind when executing individual cells. My recommendation is to always run the cells in consecutive order and re-run them from the beginning again, if you close a file and open it later.
Lastly, we will use the `print()` function heavily. It simply prints whatever is in the brackets. Either a direct value or a result of an operation. E.g., `print(5 + a * 2)` will print `11` below the cell (provided a==3). Multiple prints within the same cell are simply stacked one after another.
Because it is "a live code", you can also modify it, play with it, to explore the examples yourself. Hopefully, this will help you understand everything more.
I hope everything is clear and it will prove useful to you.
%% Cell type:markdown id: tags:
## How to read this "book"
The book or Python guide is split into lessons and exercises. Lessons are mostly theoretical, though they contain code that you can change and execute to help you understand the lesson.
Exercises are meant to help you practice what you learned in the corresponding lesson.
%% Cell type:markdown id: tags:
## How to run this book
Since you are seeing this notebook, I guess you've already find a way to somehow view it. Nonetheless, here is a way to run it locally on your computer in "interactive" mode.
1) Clone the repo from Github (if you haven't already):
# TODO
2) CD into the cloned repo and install:
```{code-cell}
pip install .
```
3) Run the notebook:
```{code-cell}
python -m pge_lectures <lesson_number>
```
Substitute <lesson_number> with the number of the lesson you want to run. Alternatively, you can list all available lessons with:
```{code-cell}
python -m pge_lectures -l
```
import subprocess
import os
import argparse
from glob import iglob
def list_lessons(lesson_dir, desired_lesson_number=-1, exercise=False):
found_lessons = []
for lesson_notebook in iglob(os.path.join(lesson_dir, "lecture_*", "l[0-9]*_*.ipynb")):
lesson_number = int(os.path.basename(lesson_notebook).split('_')[0][1:])
if lesson_number == desired_lesson_number:
return lesson_notebook
else:
found_lessons.append(os.path.basename(lesson_notebook))
return found_lessons
def get_lesson(lesson_dir, desired_lesson_number, exercise=False):
# get lessons from the lessons directory
found_lessons = list_lessons(lesson_dir, desired_lesson_number, exercise)
if type(found_lessons) is str:
return found_lessons
available_lessons = '\n'.join([f'\t {i:d} - {lesson}' for i, lesson in enumerate(found_lessons, start=1)])
raise ValueError(f'Could not find lesson "{desired_lesson_number}". Available lessons:\n{available_lessons}')
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--port', default=8888, type=int)
parser.add_argument('lesson_number', type=int, nargs='?')
parser.add_argument('--list', '-l', action='store_true')
parser.add_argument('--exercise', '-e', action='store_true')
args = parser.parse_args()
package_root_dir = os.path.dirname(os.path.abspath(__file__))
# if args.exercise:
# notebook_dir = os.path.join(package_root_dir, 'exercises')
# else:
# notebook_dir = os.path.join(package_root_dir, 'lessons')
notebook_dir = package_root_dir
if args.list:
print(f"Available {'lessons' if not args.exercise else 'exercises'} (<number> - <name>):")
found_lessons = list_lessons(notebook_dir, exercise=args.exercise)
print('\n'.join([f"\t{i} - {os.path.basename(notebook)}" for i, notebook in enumerate(found_lessons, start=1)]))
return
# Run the first lesson if no lesson number is provided
if args.lesson_number is None or args.lesson_number == 0:
notebook_path = os.path.join(package_root_dir, '00_intro.ipynb')
else:
notebook_path = get_lesson(notebook_dir, args.lesson_number, exercise=args.exercise)
server = subprocess.Popen(['jupyter', 'notebook', '--no-browser', '--port', str(args.port), notebook_path])
# Wait for the server
try:
server.wait()
except KeyboardInterrupt:
server.terminate()
server.wait()
except BaseException:
server.kill()
raise
if __name__ == '__main__':
main()
import numpy as np
import timeit
import random
import concurrent.futures
import yaml
from multiprocessing import RLock
def is_sorted(lst):
return all(lst[i] <= lst[i+1] for i in range(len(lst)-1))
def bogosort(lst):
while not is_sorted(lst):
random.shuffle(lst)
return lst
LOCK = RLock()
def save_time_to_yaml(time, input_size):
LOCK.acquire()
with open('run_times.yaml', 'r+') as f:
existing_data = yaml.safe_load(f)
if existing_data is None:
existing_data = {}
existing_data[input_size] = time
f.seek(0)
yaml.dump(existing_data, f)
f.truncate()
LOCK.release()
def bogotimer(n):
iterations = 1
unordered_list = np.random.permutation(n).tolist()
timer = timeit.Timer(stmt=lambda: bogosort(unordered_list))
total_time = timer.timeit(number=iterations)
# Compute the average time per execution.
avg_time = total_time / iterations
save_time_to_yaml(avg_time, n)
print(f"Time for {n} elements: {avg_time}")
def parallel_for(items, func):
with concurrent.futures.ProcessPoolExecutor() as executor:
futures = [executor.submit(func, item) for item in items]
results = [future.result() for future in concurrent.futures.as_completed(futures)]
return results
N = 10
times = parallel_for(range(1, N), bogotimer)
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment