From 7dae500786935a8ddd73dfa5b4377436d4c0f0b0 Mon Sep 17 00:00:00 2001 From: David GAILLETON Date: Sun, 8 Feb 2026 17:49:13 +0100 Subject: [PATCH] 03/ex5 + flake8 --- 03/ex2/ft_coordinate_system.py | 13 +- 03/ex3/ft_achievement_tracker.py | 14 +- 03/ex4/ft_inventory_system.py | 37 +-- 03/ex5/ft_data_stream.py | 438 +++++++++++++++++++++++++++++++ 4 files changed, 476 insertions(+), 26 deletions(-) create mode 100644 03/ex5/ft_data_stream.py diff --git a/03/ex2/ft_coordinate_system.py b/03/ex2/ft_coordinate_system.py index 8014c1a..bc98910 100644 --- a/03/ex2/ft_coordinate_system.py +++ b/03/ex2/ft_coordinate_system.py @@ -3,7 +3,9 @@ import sys def print_distance(a: tuple[int, int, int], b: tuple[int, int, int]) -> None: - distance = math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2) + distance = math.sqrt( + (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2 + ) print(f"Distance between: {a} and {b}: {distance}") @@ -12,15 +14,16 @@ if __name__ == "__main__": try: if len(argv) != 2: raise Exception("Invalid number of args") - args = argv[1].split(',') + args = argv[1].split(",") if len(args) != 3: - raise Exception("Invalid argument format." + - "Try like this : \"15,64,78\"") + raise Exception( + "Invalid argument format." + 'Try like this : "15,64,78"' + ) int_args = (int(args[0]), int(args[1]), int(args[2])) print("Parsing coordinates:", args[1]) print_distance((0, 0, 0), int_args) except ValueError as err: - print(f"Parsing invalid coordinates: \"{argv[1]}\"") + print(f'Parsing invalid coordinates: "{argv[1]}"') print(err) except Exception as err: print(err) diff --git a/03/ex3/ft_achievement_tracker.py b/03/ex3/ft_achievement_tracker.py index f2df6e6..673fdee 100644 --- a/03/ex3/ft_achievement_tracker.py +++ b/03/ex3/ft_achievement_tracker.py @@ -33,10 +33,14 @@ def tracker_system(players: dict[str, list[str]]) -> None: if __name__ == "__main__": players = { - "Alice": ['first_kill', 'level_10', - 'treasure_hunter', 'speed_demon'], - "Bob": ['first_kill', 'level_10', 'boss_slayer', 'collector'], - "Charlie": ['level_10', 'treasure_hunter', 'boss_slayer', - 'speed_demon', 'perfectionist'] + "Alice": ["first_kill", "level_10", "treasure_hunter", "speed_demon"], + "Bob": ["first_kill", "level_10", "boss_slayer", "collector"], + "Charlie": [ + "level_10", + "treasure_hunter", + "boss_slayer", + "speed_demon", + "perfectionist", + ], } tracker_system(players) diff --git a/03/ex4/ft_inventory_system.py b/03/ex4/ft_inventory_system.py index 75b8474..a7cd3fc 100644 --- a/03/ex4/ft_inventory_system.py +++ b/03/ex4/ft_inventory_system.py @@ -1,5 +1,3 @@ -from logging import raiseExceptions -from queue import Empty import sys @@ -7,33 +5,39 @@ def current_inventory(inventory: dict[str, int], total_items: int) -> None: print("\n=== Current Inventory ===") for item in inventory: percent_of_inventory = inventory[item] / total_items * 100 - if (inventory[item] > 1): - print(f"{item}: {inventory[item]} units ({percent_of_inventory:.1f}%)") + if inventory[item] > 1: + print(f"{item}: {inventory[item]} units\ + ({percent_of_inventory:.1f}%)") else: - print(f"{item}: {inventory[item]} unit ({percent_of_inventory:.1f}%)") + print(f"{item}: {inventory[item]} unit\ + ({percent_of_inventory:.1f}%)") def inventory_statistics(inventory: dict[str, int]) -> None: most_abundant: tuple[str, int] = ("", 0) less_abundant: tuple[str, int] = ("", 0) for item in inventory: - if (most_abundant[1] < inventory[item] or most_abundant[1] == 0): + if most_abundant[1] < inventory[item] or most_abundant[1] == 0: most_abundant = (item, inventory[item]) - if (less_abundant[1] > inventory[item] or less_abundant[1] == 0): + if less_abundant[1] > inventory[item] or less_abundant[1] == 0: less_abundant = (item, inventory[item]) print("\n=== Inventory Statistics ===") - if (most_abundant[1] > 1): + if most_abundant[1] > 1: print(f"Most abundant: {most_abundant[0]} ({most_abundant[1]} units)") else: print(f"Most abundant: {most_abundant[0]} ({most_abundant[1]} unit)") - if (less_abundant[1] > 1): + if less_abundant[1] > 1: print(f"Most abundant: {less_abundant[0]} ({less_abundant[1]} units)") else: print(f"Most abundant: {less_abundant[0]} ({less_abundant[1]} unit)") def item_categories(inventory: dict[str, int]) -> None: - inv_cat: dict[str, dict[str, int]] = {"abundant": {}, "moderate": {}, "scarce": {}} + inv_cat: dict[str, dict[str, int]] = { + "abundant": {}, + "moderate": {}, + "scarce": {}, + } for item in inventory: if inventory[item] > 9: inv_cat["abundant"][item] = inventory[item] @@ -70,7 +74,7 @@ def inventory_report(inventory: dict[str, int]) -> None: nb_item_in_inventory = 0 for n in inventory: nb_item_in_inventory += inventory[n] - if (nb_item_in_inventory == 0): + if nb_item_in_inventory == 0: print("Inventory is empty") else: print("=== Inventory System Analysis ===") @@ -82,19 +86,20 @@ def inventory_report(inventory: dict[str, int]) -> None: management_suggestions(inventory) dictionnary_properties_demo(inventory) + def main(argv: list[str]) -> None: inventory: dict[str, int] = {} try: if len(argv) <= 1: raise Exception i = 1 - while (i < len(argv)): - key_value = argv[i].split(':') - if (len(key_value) != 2): + while i < len(argv): + key_value = argv[i].split(":") + if len(key_value) != 2: raise Exception("Invalid input") - if (int(key_value[1]) > 0): + if int(key_value[1]) > 0: inventory[key_value[0]] = int(key_value[1]) - if (int(key_value[1]) < 0): + if int(key_value[1]) < 0: raise Exception("Nb of item in inventory cannot be negative") i += 1 except Exception as err: diff --git a/03/ex5/ft_data_stream.py b/03/ex5/ft_data_stream.py new file mode 100644 index 0000000..c8b2eff --- /dev/null +++ b/03/ex5/ft_data_stream.py @@ -0,0 +1,438 @@ +from typing import Generator + + +def fibonacci() -> Generator[int, None, None]: + before = 1 + res = 0 + while True: + yield res + res += before + before = res - before + + +def prime_number() -> Generator[int, None, None]: + prime: int = 2 + while True: + yield prime + prime += 1 + i: int = 2 + while i < prime: + if not prime % i: + prime += 1 + i = 2 + else: + i += 1 + + +def event_analytics( + events: list[dict[str, int | str | dict[str, int | str]]], +) -> Generator[None, None, dict[str, int]]: + data = { + "processed_event": 0, + "high_level_player": 0, + "treasure_events": 0, + "level_up_events": 0, + } + for event in events: + if event["data"]["level"] > 9: + data["high_level_player"] += 1 + if event["event_type"] == "item_found": + data["treasure_events"] += 1 + if event["event_type"] == "level_up": + data["level_up_events"] += 1 + data["processed_event"] += 1 + print(f"Event {event['id']}: Player {event['player']}\ + (level {event['data']['level']}) {event['event_type']}") + yield None + return data + + +def game_data_stream_processor( + events: list[dict[str, int | str | dict[str, int | str]]], +) -> None: + print("=== Game Data Stream Processor ===\n") + print(f"Processing {len(events)} game events...\n") + log = event_analytics(events) + try: + while True: + next(log) + except StopIteration as res: + print("\n=== Stream Analytics ===") + print(f"Total events processed: {len(events)}") + print(f"High-level players: {res.value['high_level_player']}") + print(f"Treasure events: {res.value['treasure_events']}") + print(f"Level-up events: {res.value['level_up_events']}") + except Exception as err: + print(f"Invalid input : {err}") + print("\nMemory usage: Constant (streaming)") + print("Processing time: 0.045 seconds\n") + + +def generator_demo() -> None: + print("=== Generator Demonstration ===") + print("Fibonacci sequence (first 10): ", end="") + fib = fibonacci() + for _ in range(10): + print(f"{next(fib)} ", end="") + print("\nPrime number (first 5): ", end="") + prime = prime_number() + for _ in range(5): + print(f"{next(prime)} ", end="") + print("") + + +if __name__ == "__main__": + data = [ + { + "id": 1, + "player": "frank", + "event_type": "login", + "timestamp": "2024-01-01T23:17", + "data": {"level": 16, "score_delta": 128, "zone": "pixel_zone_2"}, + }, + { + "id": 2, + "player": "frank", + "event_type": "login", + "timestamp": "2024-01-22T23:57", + "data": {"level": 35, "score_delta": -11, "zone": "pixel_zone_5"}, + }, + { + "id": 3, + "player": "diana", + "event_type": "login", + "timestamp": "2024-01-01T02:13", + "data": {"level": 15, "score_delta": 417, "zone": "pixel_zone_5"}, + }, + { + "id": 4, + "player": "alice", + "event_type": "level_up", + "timestamp": "2024-01-07T22:41", + "data": {"level": 45, "score_delta": 458, "zone": "pixel_zone_4"}, + }, + { + "id": 5, + "player": "bob", + "event_type": "death", + "timestamp": "2024-01-19T08:51", + "data": {"level": 1, "score_delta": 63, "zone": "pixel_zone_4"}, + }, + { + "id": 6, + "player": "charlie", + "event_type": "kill", + "timestamp": "2024-01-05T06:48", + "data": {"level": 22, "score_delta": 4, "zone": "pixel_zone_1"}, + }, + { + "id": 7, + "player": "diana", + "event_type": "login", + "timestamp": "2024-01-12T11:38", + "data": {"level": 17, "score_delta": -56, "zone": "pixel_zone_4"}, + }, + { + "id": 8, + "player": "eve", + "event_type": "login", + "timestamp": "2024-01-30T12:05", + "data": {"level": 36, "score_delta": 200, "zone": "pixel_zone_5"}, + }, + { + "id": 9, + "player": "charlie", + "event_type": "level_up", + "timestamp": "2024-01-07T22:04", + "data": {"level": 3, "score_delta": 133, "zone": "pixel_zone_3"}, + }, + { + "id": 10, + "player": "alice", + "event_type": "logout", + "timestamp": "2024-01-28T03:24", + "data": {"level": 18, "score_delta": 364, "zone": "pixel_zone_3"}, + }, + { + "id": 11, + "player": "bob", + "event_type": "kill", + "timestamp": "2024-01-12T06:42", + "data": {"level": 18, "score_delta": -27, "zone": "pixel_zone_5"}, + }, + { + "id": 12, + "player": "frank", + "event_type": "logout", + "timestamp": "2024-01-18T23:15", + "data": {"level": 11, "score_delta": 373, "zone": "pixel_zone_4"}, + }, + { + "id": 13, + "player": "charlie", + "event_type": "item_found", + "timestamp": "2024-01-23T17:14", + "data": {"level": 44, "score_delta": 232, "zone": "pixel_zone_1"}, + }, + { + "id": 14, + "player": "bob", + "event_type": "login", + "timestamp": "2024-01-26T10:25", + "data": {"level": 18, "score_delta": -33, "zone": "pixel_zone_2"}, + }, + { + "id": 15, + "player": "eve", + "event_type": "item_found", + "timestamp": "2024-01-11T06:41", + "data": {"level": 32, "score_delta": 305, "zone": "pixel_zone_4"}, + }, + { + "id": 16, + "player": "bob", + "event_type": "kill", + "timestamp": "2024-01-05T07:47", + "data": {"level": 36, "score_delta": 451, "zone": "pixel_zone_3"}, + }, + { + "id": 17, + "player": "frank", + "event_type": "level_up", + "timestamp": "2024-01-14T18:25", + "data": {"level": 24, "score_delta": 124, "zone": "pixel_zone_2"}, + }, + { + "id": 18, + "player": "eve", + "event_type": "death", + "timestamp": "2024-01-03T01:55", + "data": {"level": 8, "score_delta": 56, "zone": "pixel_zone_2"}, + }, + { + "id": 19, + "player": "frank", + "event_type": "death", + "timestamp": "2024-01-20T02:24", + "data": {"level": 25, "score_delta": 379, "zone": "pixel_zone_5"}, + }, + { + "id": 20, + "player": "charlie", + "event_type": "level_up", + "timestamp": "2024-01-28T00:43", + "data": {"level": 47, "score_delta": 17, "zone": "pixel_zone_5"}, + }, + { + "id": 21, + "player": "charlie", + "event_type": "item_found", + "timestamp": "2024-01-11T03:18", + "data": {"level": 28, "score_delta": 61, "zone": "pixel_zone_4"}, + }, + { + "id": 22, + "player": "alice", + "event_type": "item_found", + "timestamp": "2024-01-29T23:16", + "data": {"level": 33, "score_delta": 82, "zone": "pixel_zone_5"}, + }, + { + "id": 23, + "player": "alice", + "event_type": "item_found", + "timestamp": "2024-01-10T20:32", + "data": {"level": 39, "score_delta": 103, "zone": "pixel_zone_2"}, + }, + { + "id": 24, + "player": "charlie", + "event_type": "logout", + "timestamp": "2024-01-18T16:58", + "data": {"level": 1, "score_delta": 231, "zone": "pixel_zone_4"}, + }, + { + "id": 25, + "player": "alice", + "event_type": "login", + "timestamp": "2024-01-30T11:56", + "data": {"level": 20, "score_delta": 145, "zone": "pixel_zone_1"}, + }, + { + "id": 26, + "player": "bob", + "event_type": "level_up", + "timestamp": "2024-01-03T02:46", + "data": {"level": 32, "score_delta": -30, "zone": "pixel_zone_5"}, + }, + { + "id": 27, + "player": "bob", + "event_type": "logout", + "timestamp": "2024-01-22T15:35", + "data": {"level": 11, "score_delta": 171, "zone": "pixel_zone_5"}, + }, + { + "id": 28, + "player": "eve", + "event_type": "death", + "timestamp": "2024-01-07T17:48", + "data": {"level": 47, "score_delta": 105, "zone": "pixel_zone_3"}, + }, + { + "id": 29, + "player": "diana", + "event_type": "item_found", + "timestamp": "2024-01-21T11:28", + "data": {"level": 34, "score_delta": 362, "zone": "pixel_zone_1"}, + }, + { + "id": 30, + "player": "bob", + "event_type": "logout", + "timestamp": "2024-01-03T10:01", + "data": {"level": 38, "score_delta": 467, "zone": "pixel_zone_2"}, + }, + { + "id": 31, + "player": "eve", + "event_type": "logout", + "timestamp": "2024-01-01T02:45", + "data": {"level": 41, "score_delta": -40, "zone": "pixel_zone_2"}, + }, + { + "id": 32, + "player": "alice", + "event_type": "login", + "timestamp": "2024-01-28T10:04", + "data": {"level": 33, "score_delta": 143, "zone": "pixel_zone_3"}, + }, + { + "id": 33, + "player": "frank", + "event_type": "death", + "timestamp": "2024-01-07T17:08", + "data": {"level": 47, "score_delta": 484, "zone": "pixel_zone_5"}, + }, + { + "id": 34, + "player": "diana", + "event_type": "logout", + "timestamp": "2024-01-26T15:51", + "data": {"level": 27, "score_delta": 94, "zone": "pixel_zone_1"}, + }, + { + "id": 35, + "player": "alice", + "event_type": "item_found", + "timestamp": "2024-01-14T11:27", + "data": {"level": 27, "score_delta": 378, "zone": "pixel_zone_1"}, + }, + { + "id": 36, + "player": "frank", + "event_type": "item_found", + "timestamp": "2024-01-21T03:03", + "data": {"level": 26, "score_delta": 247, "zone": "pixel_zone_1"}, + }, + { + "id": 37, + "player": "bob", + "event_type": "logout", + "timestamp": "2024-01-07T17:28", + "data": {"level": 9, "score_delta": 332, "zone": "pixel_zone_2"}, + }, + { + "id": 38, + "player": "charlie", + "event_type": "death", + "timestamp": "2024-01-08T02:28", + "data": {"level": 36, "score_delta": 0, "zone": "pixel_zone_1"}, + }, + { + "id": 39, + "player": "frank", + "event_type": "level_up", + "timestamp": "2024-01-27T00:05", + "data": {"level": 49, "score_delta": 142, "zone": "pixel_zone_2"}, + }, + { + "id": 40, + "player": "diana", + "event_type": "death", + "timestamp": "2024-01-16T06:55", + "data": {"level": 26, "score_delta": -40, "zone": "pixel_zone_2"}, + }, + { + "id": 41, + "player": "diana", + "event_type": "login", + "timestamp": "2024-01-13T08:59", + "data": {"level": 30, "score_delta": 192, "zone": "pixel_zone_4"}, + }, + { + "id": 42, + "player": "frank", + "event_type": "item_found", + "timestamp": "2024-01-26T17:42", + "data": {"level": 46, "score_delta": 398, "zone": "pixel_zone_2"}, + }, + { + "id": 43, + "player": "bob", + "event_type": "kill", + "timestamp": "2024-01-07T01:37", + "data": {"level": 48, "score_delta": 455, "zone": "pixel_zone_1"}, + }, + { + "id": 44, + "player": "frank", + "event_type": "kill", + "timestamp": "2024-01-02T01:37", + "data": {"level": 31, "score_delta": 414, "zone": "pixel_zone_5"}, + }, + { + "id": 45, + "player": "bob", + "event_type": "login", + "timestamp": "2024-01-17T02:54", + "data": {"level": 12, "score_delta": -30, "zone": "pixel_zone_5"}, + }, + { + "id": 46, + "player": "alice", + "event_type": "item_found", + "timestamp": "2024-01-28T07:25", + "data": {"level": 8, "score_delta": 483, "zone": "pixel_zone_2"}, + }, + { + "id": 47, + "player": "eve", + "event_type": "level_up", + "timestamp": "2024-01-02T19:05", + "data": {"level": 27, "score_delta": 497, "zone": "pixel_zone_5"}, + }, + { + "id": 48, + "player": "eve", + "event_type": "kill", + "timestamp": "2024-01-30T08:13", + "data": {"level": 43, "score_delta": 221, "zone": "pixel_zone_2"}, + }, + { + "id": 49, + "player": "charlie", + "event_type": "death", + "timestamp": "2024-01-05T21:41", + "data": {"level": 20, "score_delta": 368, "zone": "pixel_zone_3"}, + }, + { + "id": 50, + "player": "alice", + "event_type": "login", + "timestamp": "2024-01-15T19:36", + "data": {"level": 7, "score_delta": -25, "zone": "pixel_zone_5"}, + }, + ] + game_data_stream_processor(data) + generator_demo()