3 files modified
7 files added
| | |
| | | sandbox* |
| | | queens* |
| | | queens* |
| | | *.venv* |
New file |
| | |
| | | # README |
| | | |
| | | 1. One project one directory with unittest |
| | | 2. Use typing annotation for every function. |
| | | |
New file |
| | |
| | | # HOWTO |
| | | |
| | | ## Run unittest |
| | | |
| | | * For all unittests in directory |
| | | |
| | | ```shell |
| | | python -m unittest |
| | | ``` |
| | | |
| | | * For some files |
| | | |
| | | ```shell |
| | | python -m unittest -p '*_test.py' |
| | | ``` |
New file |
| | |
| | | #! /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) |
New file |
| | |
| | | #! /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) |
New file |
| | |
| | | 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() |
| | |
| | | #! /usr/bin/env python |
| | | |
| | | import sys |
| | | from typing import Final |
| | | import numpy as np |
| | | from numpy import pi |
| | |
| | | |
| | | |
| | | 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]) |
| | |
| | | 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() |
| | | |
| | | |
| | |
| | | #! /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]) |
| | |
| | | |
| | | # 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() |