Hong-Phuc Bui
2024-05-13 84055e4d0cb58f94ac8e6be28885c7d51d13ef3a
Example for functions
3 files modified
7 files added
288 ■■■■■ changed files
.gitignore 3 ●●●● patch | view | raw | blame | history
funktion-modular/README.md 5 ●●●●● patch | view | raw | blame | history
funktion-modular/calendar/HOWTO.md 15 ●●●●● patch | view | raw | blame | history
funktion-modular/calendar/__pycache__/month_of_year.cpython-312.pyc patch | view | raw | blame | history
funktion-modular/calendar/__pycache__/test_month_of_year.cpython-312.pyc patch | view | raw | blame | history
funktion-modular/calendar/month_of_year-no-fn.py 90 ●●●●● patch | view | raw | blame | history
funktion-modular/calendar/month_of_year.py 99 ●●●●● patch | view | raw | blame | history
funktion-modular/calendar/test_month_of_year.py 25 ●●●●● patch | view | raw | blame | history
python-grundlage/Lissajous-np.py 16 ●●●● patch | view | raw | blame | history
python-grundlage/Lissajous-turtle.py 35 ●●●● patch | view | raw | blame | history
.gitignore
@@ -1,2 +1,3 @@
sandbox*
queens*
queens*
*.venv*
funktion-modular/README.md
New file
@@ -0,0 +1,5 @@
# README
1. One project one directory with unittest
2. Use typing annotation for every function.
funktion-modular/calendar/HOWTO.md
New file
@@ -0,0 +1,15 @@
# HOWTO
## Run unittest
* For all unittests in directory
```shell
python -m unittest
```
* For some files
```shell
python -m unittest -p '*_test.py'
```
funktion-modular/calendar/__pycache__/month_of_year.cpython-312.pyc
Binary files differ
funktion-modular/calendar/__pycache__/test_month_of_year.cpython-312.pyc
Binary files differ
funktion-modular/calendar/month_of_year-no-fn.py
New file
@@ -0,0 +1,90 @@
#! /usr/bin/env python
"""
Description:
    Programm zur Ausgabe einer Ansicht eines Monats wie gängige Kalender-Format
Usage:
```
$ python month_of_year-no-fn.py 12 2024
```
"""
from typing import Final
import sys
month: Final[int] = int(sys.argv[1])
year: Final[int] = int(sys.argv[2])
# Calender setup
weekdays: Final[tuple[str, ...]] = ("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")
first_day_of_week: Final[int] = 1  # it is monday, common in Europa
months: Final[tuple[ tuple[str, int], ...]] = (("", 0),
                                             ("Januar", 31), ("Februar", 28), ("März", 31),
                                             ("April", 30), ("Mai", 31), ("Juni", 30),
                                             ("July", 31), ("August", 31), ("September", 30),
                                             ("Oktober", 31), ("November", 30), ("Dezember", 31))
# calculate the weekday of the 1.st day of the given month
# Not possible to test next lines of code, since all variables are global
first_date: Final[int] = 1  # first day of the month
y0 = year - ((14 - month)//12)
x = y0 + (y0//4) - (y0//100) + (y0//400)
m0 = month + 12 * ((14 - month)//12) - 2
day_of_first_date = (first_date + x + (31 * m0) // 12) % 7
# test and comment out
# print(weekdays[first_day_of_month])
# calculate how many days of last month get places in the first week
# of this month
diff: Final[int] = (7 + day_of_first_date - first_day_of_week) % 7
# test and comment out
# print(diff)
# calculate how many days in the month
days_in_months = months[month][1]
# check leap year
if month == 2:
    if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
        days_in_months += 1
# print the calendar
column_width: Final[int] = 5  # at least 3, since days in month have at most 2 digits
calendar_width: Final[int] = 7 * column_width  # 7 days of a week, each day need 3 spaces
head_line = f"{months[month][0]} {year}"
fmt_head_line = f"{head_line}".center(calendar_width, '-')
# test and comment out
# print(fmt_head_line)
# calender_view is initialized with Headline
calendar_view: str = fmt_head_line + "\n"
# 7 weekdays
for d in weekdays:
    calendar_view += f"{d}".rjust(column_width, ' ')
# test and comment out
calendar_view += "\n"
# print(calendar_view)
# the empty columns in the first week of the month
for _ in range(diff, 0, -1):
    calendar_view += ("#"*(column_width-1) + "-")  # mark empty columns with some characters to let debug easier
# print the days in the first week
day = 1
days_in_first_week = ""
while day + diff <= 7:
    days_in_first_week += (f"{day}".rjust(column_width))
    day += 1
calendar_view += days_in_first_week + "\n"
while day <= days_in_months:
    calendar_view += (f"{day}".rjust(column_width))
    if (day + diff) % 7 == 0:  # reaches the last day of week
        calendar_view += "\n"
    day += 1
print(calendar_view)
funktion-modular/calendar/month_of_year.py
New file
@@ -0,0 +1,99 @@
#! /usr/bin/env python
"""
Description:
    Programm zur Ausgabe einer Ansicht eines Monats wie gängige Kalender-Format
Usage:
```
$ python month_of_year.py 12 2024
```
"""
from typing import Final
import sys
# Calender setup
weekdays: Final[tuple[str, ...]] = ("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")
first_day_of_week: Final[int] = 1  # it is monday, common in Europa
months: Final[tuple[ tuple[str, int], ...]] = (("", 0),
                                             ("Januar", 31), ("Februar", 28), ("März", 31),
                                             ("April", 30), ("Mai", 31), ("Juni", 30),
                                             ("July", 31), ("August", 31), ("September", 30),
                                             ("Oktober", 31), ("November", 30), ("Dezember", 31))
def is_leap_year(year: int) -> bool:
    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def weekday_of_date(day: int, month: int, year: int) -> int:
    y0 = year - ((14 - month) // 12)
    x = y0 + (y0 // 4) - (y0 // 100) + (y0 // 400)
    m0 = month + 12 * ((14 - month) // 12) - 2
    return (day + x +(31 * m0) // 12) % 7
def count_days_in_month(month: int, year: int) -> int:
    count_days = months[month][1]
    if month == 2 and is_leap_year(year): count_days += 1
    return count_days
def build_calendar_head(month: int, year: int, calendar_width: int, fill_char: str =' ') -> str:
    head_line = f"{months[month][0]} {year}"
    return head_line.center(calendar_width, fill_char)
def build_weekdays_line(column_width) -> str:
    wd_line = ""
    for i in range(0, 7):
        d = (i + first_day_of_week) % 7
        wd_line += f"{weekdays[d]}".rjust(column_width, ' ')
    return wd_line
def format_day(day: int, column_width: int) -> str:
    return f"{day}".rjust(column_width)
def build_month_view(month: int, year: int, column_width: int) -> str:
    month_view = ""
    day = 1
    # the first week
    day_of_first_date = weekday_of_date(day, month, year)
    # how many columns before the first day of this month
    diff = (7 + day_of_first_date - first_day_of_week) % 7
    # -> empty column
    for _ in range(diff, 0, -1):
        month_view += ("#"*(column_width - 1) + "-")
    # -> next days in the first week
    while day + diff <= 7:
        month_view += format_day(day, column_width)
        day += 1
    month_view += "\n"
    # next weeks
    days_in_month = count_days_in_month(month, year)
    while day <= days_in_month:
        month_view += format_day(day, column_width)
        if (day + diff) % 7 == 0: month_view += "\n"
        day += 1
    return month_view
def build_calendar(month: int, year: int, column_width: int = 3) -> str:
    calendar_width = 7 * column_width
    head_line = build_calendar_head(month, year, calendar_width, fill_char="-")
    calendar_view = f"{head_line}\n"
    weekdays_line = build_weekdays_line(column_width)
    calendar_view += f"{weekdays_line}\n"
    month_view = build_month_view(month, year, column_width)
    calendar_view += f"{month_view}\n"
    return calendar_view
if __name__ == "__main__":
    month = int(sys.argv[1])
    year = int(sys.argv[2])
    cal = build_calendar(month, year, 4)
    print(cal)
funktion-modular/calendar/test_month_of_year.py
New file
@@ -0,0 +1,25 @@
import unittest
import month_of_year as mofy
class MofyTestCase(unittest.TestCase):
    def test_2024_leapyear(self):
        year = 2024
        is_leap_year = mofy.is_leap_year(year)
        self.assertEqual(is_leap_year, True)
    def test_2000_leapyear(self):
        year = 2000
        is_leap_year = mofy.is_leap_year(year)
        self.assertEqual(is_leap_year, True)  # add assertion here
    def test_weekday_of_day(self):
        d, m, y = (1, 2, 2024)
        wd = mofy.weekday_of_date(d, m, y)
        self.assertEqual(wd, 4)
if __name__ == '__main__':
    unittest.main()
python-grundlage/Lissajous-np.py
@@ -1,5 +1,5 @@
#! /usr/bin/env python
import sys
from typing import Final
import numpy as np
from numpy import pi
@@ -7,12 +7,13 @@
amplitude: tuple[float, float] = (1, 1)
# frequent
omega: tuple[float, float] = (-1, -2)
# frequent, some values (-3, 5) (-3, 8) (3, 11)
omega: tuple[float, float] = (3, 11)
# phase
phi: tuple[float, float] = (pi/2, 3*pi/4)
N: Final[int] = 100
N: Final[int] = 360*2
T = np.linspace(0, 2*pi, num=N)
x = amplitude[0] * np.cos(omega[0]*T + phi[0])
y = amplitude[1] * np.cos(omega[1]*T + phi[1])
@@ -21,5 +22,12 @@
fig, ax = plt.subplots()
ax.plot(x, y, linewidth=2.0)
write_to_file = False
if write_to_file:
    output_dir = "../../2024/python-output"
    image_filename = f"{output_dir}/{sys.argv[0].replace('.py','.pdf')}"
    plt.savefig(image_filename)
plt.show()
python-grundlage/Lissajous-turtle.py
@@ -1,19 +1,19 @@
#! /usr/bin/env python
import sys
from typing import Final
from math import pi, cos
import turtle
amplitude: tuple[float, float] = (1, 1)
amplitude: Final[tuple[float, float]] = (1, 1)
# frequent
omega: tuple[float, float] = (-1, -2)
omega: Final[tuple[float, float]] = (3, 11)
# phase
phi: tuple[float, float] = (pi/2, 3*pi/4)
phi: Final[tuple[float, float]] = (pi/2, 3*pi/4)
# Diskretisieren
N: Final[int] = 360
step = (2*pi) / N
T = [k * step for k in range(N)]
step: Final = (2*pi) / N
T: Final = [k * step for k in range(N)]
points = [(
        amplitude[0] * cos(omega[0]*t + phi[0]),
        amplitude[1] * cos(omega[1]*t + phi[1])
@@ -22,18 +22,33 @@
# Plot with turtle
(canvaswidth, canvasheight) = turtle.screensize()
point_size = 3
point_size = 1.5
turtle.setup(width=canvaswidth + 5*point_size, height=canvaswidth + 5*point_size)
# scale up
x_factor = (canvaswidth / 2) / amplitude[0]
y_factor = (canvasheight / 2) / amplitude[1]
print(x_factor, y_factor)
# as fast as possible
turtle.speed(0)
turtle.pendown()
turtle.penup()
turtle.pensize(point_size)
for p in points:
    x = x_factor * p[0]
    y = y_factor * p[1]
    turtle.teleport(x, y)
    turtle.dot(point_size)
    #turtle.teleport(x, y)
    #turtle.dot(point_size)
    turtle.goto(x, y)
    turtle.pendown()
p0 = points[0]
turtle.goto(x_factor * p0[0], y_factor * p0[1])
write_to_file = False
if write_to_file:
    output_dir = "../../2024/python-output"
    image_filename = f"{output_dir}/{sys.argv[0].replace('.py','.eps')}"
    print(f"save file to {image_filename}")
    canvas_screen = turtle.getscreen().getcanvas()
    canvas_screen.postscript(file=image_filename)
turtle.done()