diff --git a/.gitignore b/.gitignore index 3d5d40e..504fe76 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ # Created by https://www.toptal.com/developers/gitignore/api/node,go,java,intellij,visualstudiocode,haskell,erlang,elixir,rust # Edit at https://www.toptal.com/developers/gitignore?templates=node,go,java,intellij,visualstudiocode,haskell,erlang,elixir,rust +__pycache__/ +.idea/ ### Elixir ### /_build /cover diff --git a/projects/001-total-the-values/python/solution/daniele_fiocca/main.py b/projects/001-total-the-values/python/solution/daniele_fiocca/main.py new file mode 100644 index 0000000..4adc84c --- /dev/null +++ b/projects/001-total-the-values/python/solution/daniele_fiocca/main.py @@ -0,0 +1,16 @@ +def add_value(): + value = input("Insert a number") + + if value == "": + return 0.0 + else: + try: + number = float(value) + return number + add_value() + except ValueError: + print("Not a number") + return add_value() + + +total = add_value() +print("The total is", total) diff --git a/projects/002-recursive-decimal-to-binary/python/solution/daniele_fiocca/main.py b/projects/002-recursive-decimal-to-binary/python/solution/daniele_fiocca/main.py new file mode 100644 index 0000000..7353fd6 --- /dev/null +++ b/projects/002-recursive-decimal-to-binary/python/solution/daniele_fiocca/main.py @@ -0,0 +1,26 @@ +def decimal_to_binary(number): + + if number == 0: + return "0" + elif number == 1: + return "1" + else: + return decimal_to_binary(number // 2) + str(number % 2) + + +def main(): + try: + number = int(input("Enter a number: ")) + if number < 0: + raise ValueError("Number cannot be negative") + else: + binary = decimal_to_binary(number) + print(binary) + except ValueError: + print("Invalid input") + +main() + + + + diff --git a/projects/003-string-edit-distance/python/solution/daniele_fiocca/main.py b/projects/003-string-edit-distance/python/solution/daniele_fiocca/main.py new file mode 100644 index 0000000..fc909ed --- /dev/null +++ b/projects/003-string-edit-distance/python/solution/daniele_fiocca/main.py @@ -0,0 +1,14 @@ +def distance(s, t): + if len(s) == 0: + return len(t) + elif len(t) == 0: + return len(s) + else: + cost = 0 if s[-1] == t[-1] else 1 + d1 = distance(s[:-1], t) + 1 + d2 = distance(s, t[:-1]) + 1 + d3 = distance(s[:-1], t[:-1]) + cost + return min(d1, d2, d3) + + +print(distance("prototype", "probleming")) diff --git a/projects/final-project/solution/daniele_fiocca/data.py b/projects/final-project/solution/daniele_fiocca/data.py new file mode 100644 index 0000000..58de539 --- /dev/null +++ b/projects/final-project/solution/daniele_fiocca/data.py @@ -0,0 +1,3 @@ +from typing import List, Dict + +object_list: List[Dict[str, str]] = [] diff --git a/projects/final-project/solution/daniele_fiocca/index.py b/projects/final-project/solution/daniele_fiocca/index.py new file mode 100644 index 0000000..0e4837f --- /dev/null +++ b/projects/final-project/solution/daniele_fiocca/index.py @@ -0,0 +1,47 @@ +from recursive_modules import (add_object, recursive_delete_object, + recursive_environment_exploration, + recursive_modify_object, show_objects) +from utils import validated_menu_choice + + +def menu(): + try: + print("HOME OBJECTS REGISTRY\n") + print("1. Explore environment (recursive)") + print("2. Add single object") + print("3. Modify objects") + print("4. Delete objects") + print("5. Display all objects") + print("6. Exit") + + choice = validated_menu_choice( + "Choose an option", ["1", "2", "3", "4", "5", "6"] + ) + + if choice == "1": + print("Take note of all objects you see. Enter empty name to stop.") + recursive_environment_exploration() + menu() + elif choice == "2": + print("Manually add a single object:") + add_object() + menu() + elif choice == "3": + recursive_modify_object() + menu() + elif choice == "4": + recursive_delete_object() + menu() + elif choice == "5": + show_objects() + menu() + elif choice == "6": + print("Thanks for using. Goodbye") + return + except KeyboardInterrupt: + print("\nOperation interrupted. Returning to main menu...") + menu() + except Exception as e: + print(f"Unexpected error: {e}") + print("Returning to main menu...") + menu() diff --git a/projects/final-project/solution/daniele_fiocca/main.py b/projects/final-project/solution/daniele_fiocca/main.py new file mode 100644 index 0000000..dd853b6 --- /dev/null +++ b/projects/final-project/solution/daniele_fiocca/main.py @@ -0,0 +1,4 @@ +from index import menu + +if __name__ == "__main__": + menu() diff --git a/projects/final-project/solution/daniele_fiocca/recursive_modules.py b/projects/final-project/solution/daniele_fiocca/recursive_modules.py new file mode 100644 index 0000000..21c5745 --- /dev/null +++ b/projects/final-project/solution/daniele_fiocca/recursive_modules.py @@ -0,0 +1,165 @@ +from typing import Dict, List, Optional + +from utils import (confirm_operation, object_name_exists, validated_input, + validated_menu_choice) + +from data import object_list + + +def get_input() -> Optional[Dict[str, str]]: + name = validated_input("Enter object name (empty to stop)", False) + if not name: + return name + + if object_name_exists(name): + print(f"Warning: an object with name '{name}' already exists!") + if not confirm_operation("Do you want continue anyway?"): + return None + + category = validated_input("Enter category") + if category is None: + return None + + environment = validated_input("Enter environment/room") + if environment is None: + return None + + return {"name": name, "category": category, "environment": environment} + + +def recursive_environment_exploration() -> List[Dict[str, str]]: + try: + obj = get_input() + if not obj: + return object_list + else: + object_list.append(obj) + print(f"Object '{obj['name']}' added!") + return recursive_environment_exploration() + except KeyboardInterrupt: + print("\nOperation interrupted by user.") + return object_list + + +def show_objects(index: int = 0) -> None: + if not object_list: + print("No object to display.") + return + + if index == 0: + print(f"{'#':<3} {'Name':<20} {'Category':<20} {'Environment':<20}") + + if index >= len(object_list): + print(f"Total objects: {len(object_list)}") + return + + obj = object_list[index] + print( + f"{index + 1:<3} {obj['name']:<20} {obj['category']:<20} {obj['environment']:<20}" + ) + show_objects(index + 1) + + +def add_object() -> None: + try: + obj = get_input() + if obj: + object_list.append(obj) + print("Object added successfully!") + else: + print("Operation cancelled.") + except KeyboardInterrupt: + print("\nOperation interrupted by user.") + + +def recursive_object_index_search(searched_name: str, index: int = 0) -> int: + if not searched_name or not searched_name.strip(): + return -1 + if index >= len(object_list): + return -1 + if object_list[index]["name"].lower() == searched_name.lower(): + return index + return recursive_object_index_search(searched_name, index + 1) + + +def recursive_modify_object() -> None: + if not object_list: + print("No objects to modify.") + return + + try: + name_to_modify = validated_input("Enter name to search for") + if name_to_modify is None: + print("Operation cancelled.") + return + + object_index = recursive_object_index_search(name_to_modify) + + if object_index < 0 or object_index >= len(object_list): + print("Object not found.") + return + + obj = object_list[object_index] + print( + f"Object Found: {obj['name']} - {obj['category']} - {obj['environment']}" + ) + + print("\nMODIFY OBJECT") + print("1. Modify name") + print("2. Modify category") + print("3. Modify environment") + print("4. Stop modification") + + choice = validated_menu_choice("Choose what to modify", ["1", "2", "3", "4"]) + + if choice == "4": + return + elif choice == "1": + new_name = validated_input("Enter new name") + if new_name: + object_list[object_index]["name"] = new_name + print("Name modified successfully") + elif choice == "2": + new_category = validated_input("Enter new category") + if new_category: + object_list[object_index]["category"] = new_category + print("Category modified successfully.") + elif choice == "3": + new_environment = validated_input("Enter new environment") + if new_environment: + object_list[object_index]["environment"] = new_environment + if confirm_operation("Do you want to modify something else fot this object?"): + recursive_modify_object() + except KeyboardInterrupt: + print("\nOperation interrupted by user.") + + +def recursive_delete_object() -> None: + if not object_list: + print("No object to delete.") + return + + try: + name_to_delete = validated_input("Enter the name of the object to delete") + if name_to_delete is None: + print("Operation cancelled.") + return + + index = recursive_object_index_search(name_to_delete) + if index != -1: + obj = object_list[index] + print( + f"Object found: {obj['name']} - {obj['category']} - {obj['environment']}" + ) + + if confirm_operation("Are you sure you want delete this object?"): + deleted_object = object_list.pop(index) + print(f"Object '{deleted_object['name']}' deleted successfully!") + else: + print("Deletion cancelled") + else: + print("Object not found") + if confirm_operation("Do you want to search fot another object to delete?"): + recursive_delete_object() + except KeyboardInterrupt: + print("\nOperation interrupted by user.") diff --git a/projects/final-project/solution/daniele_fiocca/utils.py b/projects/final-project/solution/daniele_fiocca/utils.py new file mode 100644 index 0000000..581e680 --- /dev/null +++ b/projects/final-project/solution/daniele_fiocca/utils.py @@ -0,0 +1,44 @@ +from typing import List, Optional + +from data import object_list + + +def validated_input(message: str, required: bool = True) -> str: + value: str = input(message + ": ").strip() + + if value == "" and required: + print("This field is required. Please try again.") + return validated_input(message, required) + elif not value.replace(" ", "").isalnum() and not all( + c.isalnum() or c.isspace() for c in value + ): + print( + "Value contains invalid characters. Use only letters, numbers and spaces." + ) + return validated_input(message, required) + else: + return value + + +def validated_menu_choice(message: str, valid_options: List[str]) -> str: + choice: str = input(message + ": ").strip() + if choice in valid_options: + return choice + else: + print(f"Invalid choice. Available options: {', '.join(valid_options)}") + return validated_menu_choice(message, valid_options) + + +def confirm_operation(message: str) -> bool: + response: str = input(message + " (y/n): ").strip().lower() + if response in ["y", "yes"]: + return True + elif response in ["n", "no"]: + return False + else: + print("Enter 'y' for yes or 'n' for no.") + return confirm_operation(message) + + +def object_name_exists(name: str) -> bool: + return any(obj["name"].lower() == name.lower() for obj in object_list)