diff --git a/submissions/caaif43/project final/README.md b/submissions/caaif43/project final/README.md new file mode 100644 index 00000000..4baf28c0 --- /dev/null +++ b/submissions/caaif43/project final/README.md @@ -0,0 +1,180 @@ +# Library Management System (CLI) + +A small command-line Library Management System built with Python 3.10+. + +This project demonstrates the core concepts covered in Sections 1–6 of the Python Bootcamp, including: + +* Comments +* `print()` and `input()` +* Conditional statements (`if`, `elif`, `else`) +* Lists and loops +* Functions and `main()` +* File handling (UTF-8) +* Error handling with `try` / `except` +* Object-Oriented Programming (OOP) +* `@dataclass` +* `__str__()` methods +* Composition + +--- + +## Run the Project + +```bash +cd 07_final_project_library_management_system +python main.py +``` + +--- + +## Project Structure + +```text +07_final_project_library_management_system/ +│ +├── main.py +│ +├── models/ +│ └── books.py +│ +├── utils/ +│ └── storage.py +│ +├── data/ +│ └── books.txt +│ +└── README.md +``` + +--- + +## Features + +The system allows a librarian to: + +1. Add a new book +2. View all books +3. Remove a book +4. Search for a book by ID +5. Update book information +6. Save library data +7. Quit the application (automatically saves data) + +--- + +## Book Information + +Each book contains: + +* Book ID +* Title +* Author +* Year Published + +Example: + +```text +ID: 101 +Title: Python Basics +Author: Abdullahi hassan +Year: 2026 +``` + +--- + +## Data Storage + +All library data is stored in: + +```text +data/books.txt +``` + +The file uses UTF-8 encoding and a simple pipe-separated format. + +Example: + +```text +# Library Database +id|title|author|year +101|Python Basics|Abdullahi|2026 +``` + +### Notes + +* Lines beginning with `#` are treated as comments. +* The header row is ignored when loading data. +* Data is automatically loaded when the application starts. +* Data is automatically saved when the application exits. + +--- + +## Error Handling + +The project uses `try` / `except` blocks to prevent crashes caused by invalid user input. + +Examples: + +* Entering text instead of a numeric ID +* Entering an invalid publication year +* Loading a missing data file + +--- + +## OOP Concepts Used + +### Book Class + +Represents a single book in the library. + +Responsibilities: + +* Store book information +* Display formatted book details using `__str__()` + +### Library Class + +Represents the entire library collection. + +Responsibilities: + +* Store books in memory +* Add books +* Remove books +* Search books +* Manage library records + +This demonstrates **composition**, where a `Library` object contains multiple `Book` objects. + +--- + +## Technologies + +* Python 3.10+ +* Dataclasses +* File Handling +* UTF-8 Text Storage +* Command-Line Interface (CLI) + +--- + +## Learning Objectives + +After completing this project, students should be able to: + +* Build a complete CLI application +* Organize code into modules +* Work with classes and objects +* Read and write files +* Handle user input safely +* Apply Python best practices +* Create maintainable project structures + +--- + +## Author + +Abdullahi Hassan Shire + +Python Bootcamp Final Project +Library Management System diff --git a/submissions/caaif43/project final/data/calo.py b/submissions/caaif43/project final/data/calo.py new file mode 100644 index 00000000..fff4000d --- /dev/null +++ b/submissions/caaif43/project final/data/calo.py @@ -0,0 +1,38 @@ +def add(a,b) : + return a+b +def subtract (a,b) : + return a - b +def multiply (a,b): + return a*b +def divide (a,b): + if b == 0: + return "eber lama qeybin karo. !" + return a/b + + +def main(): + print("soo dhawow") + print("dooro mid:") + print("1. isku dar") + print("2. kala jarid") + print("3. isku dhufasho") + print("4. iskuqeybin") + while True: + doorsho = input ("dooro mid 1,2,3,4") + if doorsho in ['1','2','3','4']: + try: + num1 = float(input("gali number kowaad")) + num2 = float(input("gali number labaad")) + except ValueError: + print("fad;an kali number") + continue + if doorsho == '1': + print(f"numberka waa {add(num1,num2)}") + elif doorsho == '2': + print(f"numberka waa {subtract(num1,num2)}") + elif doorsho == '3': + print(f"numberka waa {multiply(num1,num2)}") + else: + if __name__("main"): + main() + diff --git a/submissions/caaif43/project final/data/members.txt b/submissions/caaif43/project final/data/members.txt new file mode 100644 index 00000000..6dd49777 --- /dev/null +++ b/submissions/caaif43/project final/data/members.txt @@ -0,0 +1,4 @@ +# Gym Members +id|member_name|membership_type +1|Ahmed|Premium +2|Asha|Standard \ No newline at end of file diff --git a/submissions/caaif43/project final/main.py b/submissions/caaif43/project final/main.py new file mode 100644 index 00000000..b678c9f9 --- /dev/null +++ b/submissions/caaif43/project final/main.py @@ -0,0 +1,128 @@ +#_final_project_gym_management_system/main.py +from models.members import Member, Gym +from utils.storage import load_members, save_members + + +gym = Gym() +gym.members = load_members() + + +def add_member(): + try: + member_id = int(input("Enter member ID: ")) + except ValueError: + print("Invalid ID") + return + + member_name = input("Enter member name: ") + membership_type = input("Enter membership type: ") + + member = Member(member_id, member_name, membership_type) + + gym.add_member(member) + + print("Member added successfully") + + +def list_members(): + if not gym.members: + print("No members found") + return + + for member in gym.members: + print(member) + + +def search_member(): + name = input("Enter member name: ") + + member = gym.search_member(name) + + if member: + print(member) + else: + print("Member not found") + + +def update_member(): + try: + member_id = int(input("Enter member ID: ")) + except ValueError: + print("Invalid ID") + return + + member = gym.get_member_by_id(member_id) + + if not member: + print("Member not found") + return + + new_name = input("Enter new name: ") + new_type = input("Enter new membership type: ") + + if new_name: + member.member_name = new_name + + if new_type: + member.membership_type = new_type + + print("Member updated successfully") + + +def remove_member(): + try: + member_id = int(input("Enter member ID to remove: ")) + except ValueError: + print("Invalid ID") + return + + if gym.remove_member(member_id): + print("Member removed") + else: + print("Member not found") + + +def main(): + while True: + + print("\n===== GYM MENU =====") + print("1. Add Member") + print("2. List Members") + print("3. Search Member") + print("4. Update Member") + print("5. Remove Member") + print("6. Save") + print("7. Quit") + + choice = input("Choose: ") + + if choice == "1": + add_member() + + elif choice == "2": + list_members() + + elif choice == "3": + search_member() + + elif choice == "4": + update_member() + + elif choice == "5": + remove_member() + + elif choice == "6": + save_members(gym.members) + print("Members saved") + + elif choice == "7": + save_members(gym.members) + print("Goodbye") + break + + else: + print("Invalid choice") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/submissions/caaif43/project final/models/__pycache__/members.cpython-313.pyc b/submissions/caaif43/project final/models/__pycache__/members.cpython-313.pyc new file mode 100644 index 00000000..7c22a5d9 Binary files /dev/null and b/submissions/caaif43/project final/models/__pycache__/members.cpython-313.pyc differ diff --git a/submissions/caaif43/project final/models/members.py b/submissions/caaif43/project final/models/members.py new file mode 100644 index 00000000..9164c8c7 --- /dev/null +++ b/submissions/caaif43/project final/models/members.py @@ -0,0 +1,45 @@ +from dataclasses import dataclass + + +@dataclass +class Member: + member_id: int + member_name: str + membership_type: str + + def __str__(self): + return f"{self.member_id} | {self.member_name} | {self.membership_type}" + + +class Gym: + def __init__(self): + self.members = [] + + def add_member(self, member): + self.members.append(member) + + def search_member(self, name): + for member in self.members: + + if member.member_name.lower() == name.lower(): + return member + + return None + + def get_member_by_id(self, member_id): + for member in self.members: + + if member.member_id == member_id: + return member + + return None + + def remove_member(self, member_id): + + member = self.get_member_by_id(member_id) + + if member: + self.members.remove(member) + return True + + return False \ No newline at end of file diff --git a/submissions/caaif43/project final/practic.py b/submissions/caaif43/project final/practic.py new file mode 100644 index 00000000..718ea3b3 --- /dev/null +++ b/submissions/caaif43/project final/practic.py @@ -0,0 +1,140 @@ +#number = input("Enter a number: ") + +# print(number) +# print("wuskjshsk") + +# city = "deynile" , "wadajir", "warta nabada" +# couter = 0 +# couter += 1 +# print(couter , city) + +# age = 88 +# al = 5.4 +# waa = "ware" +# dd = True +# print(type(dd)) +#input +# num1 = int(input("first number: ")) +# num2 = int(input("second number: ")) +# total = num1 + num2 +# print(total) + +# name = str(input("what is your name ")) +# color = str(input("what is your favorite color ")) + +# print(name , color) + +# a = 11 +# b = 2 +# c = a - b + +# print("a + b" , a + b) +# print("a - b" , c ) +# print("a ** b" , a ** b ) +# print("a // b" , a % b) + +# num1 = 12 +# # print(num1) +# num1 = num1 + 8 +# print(num1) + +# a = 5 +# b = 5 +# c = (a>b or b>a) + +# print(not c) +# score = 0 +# name = input("what is your name ") +# print("welcome" , name) +# print("q1= waa kuma casimada somali") +# answer = input() +# if answer .lower() == "muqdisho" : +# print("waa sax") +# score +=1 +# else: +# print("waa qalad") +# print("waa kuma madaxweynaha 9aad somali") +# answer = input() +# if answer .lower() == "farmaajo": +# print("waa sax") +# score +=1 + +# else: +# print("waa qalad") +# print("waa kuma madexweyanha hada") +# answer = input() +# if answer .lower() == "xassan" : +# print("waa sax") +# score +=1 +# else: +# print("waa qalad") + +# print(f"score : {score}") +# name = ["iidle" , "caaif" , "caadil"] +# print(name [0]) +# print(name [1:2]) +# name.remove ("caaif") +# print(name) +# name.append ("abdullahi") +# print(name) +# print( len(name)) + +# tuple +# rgb = (255, 128, 0) +# print(rgb[0]) + +# a, b, c = (1, 2, 3) +# print(a + b + c) + +# letters = {"a", "b", "a", "c", "b"} +# print(letters) +# print("intersection:", letters) + +# country = {"somali": "muqdisho", "diser" : 19} +# print(country ["somali"]) +# print(country["diser"]) +# print(country.get("xamr", "unknown")) +# country["diser"] = 22 +# print(country) + +# rang = ["saabir" , "hassan" , "shire"] +# for rang in rang: +# print(rang) + +# for c in "saabir": +# print(c) + +# for c in range(1,6): +# print(c) + +# g = 2 +# while g <= 99: +# print(g) +# g +=2 + +# for n in ["saabir" , "caaif" , "caafil" , "caadil"]: +# if n == "caadil": +# print("bis dheh :" ) +# break +# print(n) + +# nums = list(range(10)) +# print(nums[::2]) + +# words = ["apple", "banana", "orange"] + +# for index, word in enumerate(words): +# print(f"{index}: {word}") + + + +while True: + text = input("Type something (done to quit): ") + + if text == "done": + break + + print("You typed:", text) + + + diff --git a/submissions/caaif43/project final/utils/__pycache__/storage.cpython-313.pyc b/submissions/caaif43/project final/utils/__pycache__/storage.cpython-313.pyc new file mode 100644 index 00000000..1f15de8b Binary files /dev/null and b/submissions/caaif43/project final/utils/__pycache__/storage.cpython-313.pyc differ diff --git a/submissions/caaif43/project final/utils/storage.py b/submissions/caaif43/project final/utils/storage.py new file mode 100644 index 00000000..e95dd29b --- /dev/null +++ b/submissions/caaif43/project final/utils/storage.py @@ -0,0 +1,65 @@ +from models.members import Member + + +FILE_PATH = "data/members.txt" + + +def load_members(): + + members = [] + + try: + with open(FILE_PATH, "r", encoding="utf-8") as file: + + for line in file: + + line = line.strip() + + if not line: + continue + + if line.startswith("#"): + continue + + if line == "id|member_name|membership_type": + continue + + parts = line.split("|") + + if len(parts) != 3: + continue + + member_id = int(parts[0]) + member_name = parts[1] + membership_type = parts[2] + + member = Member( + member_id, + member_name, + membership_type + ) + + members.append(member) + + except FileNotFoundError: + pass + + return members + + +def save_members(members): + + with open(FILE_PATH, "w", encoding="utf-8") as file: + + file.write("# Gym Members\n") + file.write("id|member_name|membership_type\n") + + for member in members: + + line = ( + f"{member.member_id}|" + f"{member.member_name}|" + f"{member.membership_type}\n" + ) + + file.write(line) \ No newline at end of file