diff --git a/bonus/bonus10.py b/bonus/bonus10.py new file mode 100644 index 0000000..3f859b5 --- /dev/null +++ b/bonus/bonus10.py @@ -0,0 +1,11 @@ +try: + width = float(input('Enter the rectangle width: ')) + length = float(input('Enter the rectangle length: ')) + + if width == length: + exit("It shouldn't be a square area calculation") + + area = width * length + print(area) +except ValueError: + print("It's expected numbers to be multiplied" ) \ No newline at end of file diff --git a/bonus/bonus11.py b/bonus/bonus11.py new file mode 100644 index 0000000..752a3bb --- /dev/null +++ b/bonus/bonus11.py @@ -0,0 +1,12 @@ +def get_average(): + with open('files/data.txt', 'r') as file: + data = file.readlines() + + values = data[1:] + values = [float(i) for i in values] + + average_local = sum(values) / len(values) + return average_local + +average = get_average() +print(average) \ No newline at end of file diff --git a/bonus/bonus12.py b/bonus/bonus12.py new file mode 100644 index 0000000..b6fd3c9 --- /dev/null +++ b/bonus/bonus12.py @@ -0,0 +1,17 @@ +feet_inches = input('Enter feet and inches: ') + +def convert(feet_inches): + parts = feet_inches.split(' ') + feet = float(parts[0]) + inches = float(parts[1]) + + meters = feet * 0.3048 + inches * 0.0254 + return meters + + +result = convert(feet_inches) + +if result < 1: + print('Kid is too small.') +else: + print('kid can use the slide.') \ No newline at end of file diff --git a/bonus/bonus13.py b/bonus/bonus13.py new file mode 100644 index 0000000..881d603 --- /dev/null +++ b/bonus/bonus13.py @@ -0,0 +1,23 @@ +feet_inches = input('Enter feet and inches: ') + + +def parse(feetinches): + parts = feetinches.split(' ') + feet = float(parts[0]) + inches = float(parts[1]) + return feet, inches + + +def convert(feet, inches): + meters = feet * 0.3048 + inches * 0.0254 + return meters + + +f, i = parse(feet_inches) +print('fi', f, i) +result = convert(f, i) + +if result < 1: + print('Kid is too small.') +else: + print('kid can use the slide.') \ No newline at end of file diff --git a/bonus/bonus14.py b/bonus/bonus14.py new file mode 100644 index 0000000..8346eac --- /dev/null +++ b/bonus/bonus14.py @@ -0,0 +1,15 @@ +from bonus.converters14 import convert +from bonus.parsers14 import parse + +feet_inches = input('Enter feet and inches: ') + +parsed = parse(feet_inches) + +result = convert(parsed['feet'], parsed['inches']) + +print(f"{parsed['feet']} feet and {parsed['inches']} is equals to {result}") + +if result < 1: + print('Kid is too small.') +else: + print('kid can use the slide.') \ No newline at end of file diff --git a/bonus/bonus15.py b/bonus/bonus15.py new file mode 100644 index 0000000..8346eac --- /dev/null +++ b/bonus/bonus15.py @@ -0,0 +1,15 @@ +from bonus.converters14 import convert +from bonus.parsers14 import parse + +feet_inches = input('Enter feet and inches: ') + +parsed = parse(feet_inches) + +result = convert(parsed['feet'], parsed['inches']) + +print(f"{parsed['feet']} feet and {parsed['inches']} is equals to {result}") + +if result < 1: + print('Kid is too small.') +else: + print('kid can use the slide.') \ No newline at end of file diff --git a/bonus/bonus16.py b/bonus/bonus16.py new file mode 100644 index 0000000..18f4a90 --- /dev/null +++ b/bonus/bonus16.py @@ -0,0 +1,30 @@ +import FreeSimpleGUI as fsg +from zip_creator import make_archive + +label1 = fsg.Text("Select files to compress") +input1 = fsg.Input() +choose_button1 = fsg.FilesBrowse("Choose", key="files") + +label2 = fsg.Text("Select destination folder") +input2 = fsg.Input() +choose_button2 = fsg.FolderBrowse("Choose", key="folder") + +compress_button = fsg.Button("Compress") +output_label = fsg.Text(key="output", text_color="#000022") + +window = fsg.Window("File Compressor", + layout=[[label1, input1, choose_button1], + [label2, input2, choose_button2], + [compress_button, output_label]]) + +while True: + event, values = window.read() + if event == fsg.WIN_CLOSED: + break + filepaths = values["files"].split(";") + folder = values["folder"] + make_archive(filepaths, folder) + window["output"].update(value="Compression completed!") + + +window.close() \ No newline at end of file diff --git a/bonus/bonus18.py b/bonus/bonus18.py new file mode 100644 index 0000000..0e37f30 --- /dev/null +++ b/bonus/bonus18.py @@ -0,0 +1,47 @@ +import FreeSimpleGUI as fsg +from zip_extractor import extract_archive + +fsg.theme('Black') + +label1 = fsg.Text("Select archive:") +input1 = fsg.Input() +choose_button1 = fsg.FileBrowse("Choose", key="archive") + +label2 = fsg.Text("Select dest. dir.:") +input2 = fsg.Input() +choose_button2 = fsg.FileBrowse("Choose", key="folder") + +extract_button = fsg.Button("Extract") +output_label = fsg.Text(key="output", text_color="green") + +window = fsg.Window("Archive Extractor", + layout=[[label1, input1, choose_button1], + [label2, input2, choose_button2], + [extract_button, output_label]]) + +while True: + event, values = window.read() + + match event: + case fsg.WIN_CLOSED: + break + + case "Extract": + archivepath = values["archive"] + dest_dir = values["folder"] + + if archivepath and dest_dir: + try: + extract_archive(archivepath, dest_dir) + window["output"].update(value="Extraction Completed!", text_color="green") + except FileNotFoundError: + window["output"].update(value="Error: Archive file not found.", text_color="red") + except PermissionError: + window["output"].update(value="Error: Permission denied.", text_color="red") + except Exception as e: + window["output"].update(value=f"Error: {e}", text_color="red") + else: + window["output"].update(value="Please select both archive and destination directory.", + text_color="red") + +window.close() \ No newline at end of file diff --git a/bonus/bonus9.py b/bonus/bonus9.py new file mode 100644 index 0000000..709fc28 --- /dev/null +++ b/bonus/bonus9.py @@ -0,0 +1,27 @@ +password = input('Enter new password ') + +result = [] + +if len(password) >= 8: + result.append(True) +else: + result.append(False) + +digit = False +for i in password: + if i.isdigit(): + digit = True + +result.append(digit) + +uppercase = False +for i in password: + if i.isupper(): + uppercase = True + +result.append(digit) + +if all(result): + print('Strong Password') +else: + print('Weak Password') \ No newline at end of file diff --git a/bonus/compressed.zip b/bonus/compressed.zip new file mode 100644 index 0000000..3edd9ad Binary files /dev/null and b/bonus/compressed.zip differ diff --git a/bonus/converters14.py b/bonus/converters14.py new file mode 100644 index 0000000..5cd32c5 --- /dev/null +++ b/bonus/converters14.py @@ -0,0 +1,3 @@ +def convert(feet, inches): + meters = feet * 0.3048 + inches * 0.0254 + return meters \ No newline at end of file diff --git a/bonus/dest/bonus1.py b/bonus/dest/bonus1.py new file mode 100644 index 0000000..e19606b --- /dev/null +++ b/bonus/dest/bonus1.py @@ -0,0 +1,7 @@ +print("Don't enter a title here") + +text = input('Enter a title: ') + +length = len(text) + +print('Length of:',length) \ No newline at end of file diff --git a/bonus/dest/bonus2.2.py b/bonus/dest/bonus2.2.py new file mode 100644 index 0000000..55c9f1d --- /dev/null +++ b/bonus/dest/bonus2.2.py @@ -0,0 +1,6 @@ +x = 1 + +while x <= 6: + print(x) + x = x + 1 + diff --git a/bonus/dest/compressed.zip b/bonus/dest/compressed.zip new file mode 100644 index 0000000..3edd9ad Binary files /dev/null and b/bonus/dest/compressed.zip differ diff --git a/bonus/parsers14.py b/bonus/parsers14.py new file mode 100644 index 0000000..e870e66 --- /dev/null +++ b/bonus/parsers14.py @@ -0,0 +1,5 @@ +def parse(feetinches): + parts = feetinches.split(' ') + feet = float(parts[0]) + inches = float(parts[1]) + return {'feet': feet, 'inches': inches} \ No newline at end of file diff --git a/bonus/questions.json b/bonus/questions.json new file mode 100644 index 0000000..3f83f1e --- /dev/null +++ b/bonus/questions.json @@ -0,0 +1,6 @@ +{"question_text":"What are dolphins?", + "alternatives": ["Amphibians", "Fish", "Mammals", "Birds"], + "correct_answer":3}, + {"question_text":"What occupies most of the Earth's surface?", + "alternatives": ["Land", "Water"], + "correct_answer":2}] \ No newline at end of file diff --git a/bonus/zip_creator.py b/bonus/zip_creator.py new file mode 100644 index 0000000..4181483 --- /dev/null +++ b/bonus/zip_creator.py @@ -0,0 +1,13 @@ +import zipfile +import pathlib + +def make_archive(filepaths, dest_dir): + dest_path = pathlib.Path(dest_dir, "compressed.zip") + with zipfile.ZipFile(dest_path, 'w') as archive: + for filepath in filepaths: + filepath = pathlib.Path(filepath) + archive.write(filepath, arcname=filepath.name) + + +if __name__ == "__main__": + make_archive(filepaths=["bonus1.py", "bonus2.2.py"], dest_dir="dest") \ No newline at end of file diff --git a/bonus/zip_extractor.py b/bonus/zip_extractor.py new file mode 100644 index 0000000..6238f8c --- /dev/null +++ b/bonus/zip_extractor.py @@ -0,0 +1,10 @@ +import zipfile + + +def extract_archive(archivepath, dest_dir): + with zipfile.ZipFile(archivepath, 'r') as archive: + archive.extractall(dest_dir) + +# if __name__ == "__main__": +# extract_archive(r"D:\Python\PythonProject\ToDoList\bonus\compressed.zip", +# r"D:\Python\PythonProject\ToDoList\bonus\dest") \ No newline at end of file diff --git a/cli.py b/cli.py new file mode 100644 index 0000000..4afb9df --- /dev/null +++ b/cli.py @@ -0,0 +1,57 @@ +# from modules.functions import get_todos, write_todos "not necessary functions. before get_todos and write_todos", but requires __init__.py inside modules directory +import time + +from modules import functions +import time + +now = time.strftime('%b %d, %Y %H:%M:%S') +print("It's", now) + +while True: + user_action = input('Type add, show or display, edit, complete, or exit: ') + user_action = user_action.strip() + + if user_action.startswith('add'): + todo = user_action[4:] + todos = functions.get_todos() + todos.append(todo.capitalize() + '\n') + functions.write_todos(todos) + + elif user_action.startswith('show') or user_action.startswith('display'): + todos = functions.get_todos() + for index, item in enumerate(todos): + item = item.strip('\n').capitalize() + print(f"{index + 1}. {item}") + + elif user_action.startswith('edit'): + try: + number = int(user_action[5:]) + number = number - 1 + todos = functions.get_todos() + new_todo = input('Enter new todo: ') + todos[number] = new_todo + '\n' + functions.write_todos(todos) + except ValueError: + print('Expected the number of the todo instead of a name.') + continue + + elif user_action.startswith('complete'): + try: + number = int(user_action[9:]) + todos = functions.get_todos() + index = number - 1 + todo_to_remove = todos[index].strip('\n') + todos.pop(index) + functions.write_todos(todos) + print(f'Todo {todo_to_remove} was removed from the list.') + except IndexError: + print("There's no item with that number.") + continue + + elif user_action.startswith('exit'): + break + + else: + print('Hey! You entered an unknown command.') + +print('Bye!') \ No newline at end of file diff --git a/experiments/e1.py b/experiments/e1.py new file mode 100644 index 0000000..ea3fcbf --- /dev/null +++ b/experiments/e1.py @@ -0,0 +1,7 @@ +import glob + +myfiles = glob.glob("../files/*.txt") + +for filepath in myfiles: + with open(filepath, 'r') as file: + print(file.read()) \ No newline at end of file diff --git a/experiments/e2_1.py b/experiments/e2_1.py new file mode 100644 index 0000000..b054922 --- /dev/null +++ b/experiments/e2_1.py @@ -0,0 +1,10 @@ +import csv + +with open("weather.csv", 'r') as file: + data = list(csv.reader(file)) + +city = input("Enter a city: ") + +for row in data[1:]: + if row[0] == city: + print(row[1]) \ No newline at end of file diff --git a/experiments/e3_1.oy.py b/experiments/e3_1.oy.py new file mode 100644 index 0000000..14a44b2 --- /dev/null +++ b/experiments/e3_1.oy.py @@ -0,0 +1,3 @@ +import shutil + +shutil.make_archive("output", "zip", "../files") \ No newline at end of file diff --git a/experiments/e4_1.py b/experiments/e4_1.py new file mode 100644 index 0000000..b054922 --- /dev/null +++ b/experiments/e4_1.py @@ -0,0 +1,10 @@ +import csv + +with open("weather.csv", 'r') as file: + data = list(csv.reader(file)) + +city = input("Enter a city: ") + +for row in data[1:]: + if row[0] == city: + print(row[1]) \ No newline at end of file diff --git a/experiments/output.zip b/experiments/output.zip new file mode 100644 index 0000000..e69de29 diff --git a/experiments/weather.csv b/experiments/weather.csv new file mode 100644 index 0000000..4c74369 --- /dev/null +++ b/experiments/weather.csv @@ -0,0 +1,3 @@ +"Station","Temperature" +"Kuala Lumpur","45" +"New York","20" \ No newline at end of file diff --git a/files/todos.txt b/files/todos.txt index e69de29..0a27ecd 100644 --- a/files/todos.txt +++ b/files/todos.txt @@ -0,0 +1,2 @@ +new todo + diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..5c285c1 --- /dev/null +++ b/gui.py @@ -0,0 +1,95 @@ +from modules import functions +import FreeSimpleGUI as sg +import time +import os + +if not os.path.exists("todos.txt"): + with open("todos.txt, 'w") as file: + pass + +sg.theme("Black") + +clock = sg.Text('', key='clock') +label = sg.Text("Type in a to-do", key='label') +input_box = sg.InputText(tooltip="Enter todo", key="todo") + +add_button = sg.Button( + image_source="imgs/add.png", + key="Add", size=10, + mouseover_colors="LightBlue2", + tooltip="Add a new to-do") + +list_box = sg.Listbox(values=functions.get_todos(), key='todos', + enable_events=True, size=(45, 10)) +edit_button = sg.Button( + image_source="imgs/edit.png", + key="Edit", size=10, + mouseover_colors="LightBlue2", + tooltip="Edit a to-do") +complete_button = sg.Button( + image_source="imgs/complete.png", + key="Complete", size=10, + mouseover_colors="LightBlue2", + tooltip="Complete a to-do") +exit_button = sg.Button( + image_source="imgs/exit.png", + key="Exit", size=10, + mouseover_colors="LightBlue2", + tooltip="Exit the app") + +layout = [ + [clock], + [label], + [input_box, add_button], + [list_box, edit_button, complete_button], + [exit_button] +] + +window = sg.Window('My To-Do App', layout=layout, font=('Helvetica', 20)) + +while True: + event, values = window.read(timeout=200) + window['clock'].update(value=time.strftime('%b %d, %Y %H:%M:%S')) + + + match event: + case "Add": + try: + todos = functions.get_todos() + new_todo = values['todo'] + "\n" + todos.append(new_todo) + functions.write_todos(todos) + window['todo'].update(value="") + window['todos'].update(values=todos) + except IndexError: + sg.popup("Please select an item first.", font=('Helvetica', 20)) + case "Edit": + try: + todo_to_edit = values['todos'][0] + new_todo = values['todo'] + + todos = functions.get_todos() + index = todos.index(todo_to_edit) + todos[index] = new_todo + functions.write_todos(todos) + window['todos'].update(values=todos) + except IndexError: + sg.popup("Please select an item first.", font=('Helvetica', 20)) + case "Complete": + try: + todo_to_complete = values['todos'][0] + todos = functions.get_todos() + todos.remove(todo_to_complete) + functions.write_todos(todos) + window['todos'].update(values=todos) + window['todo'].update(value='') + except IndexError: + sg.popup("Please select an item first.", font=('Helvetica', 20)) + case "Exit": + break + case 'todos': + window['todo'].update(value=values['todos'][0]) + case sg.WIN_CLOSED: + break + +window.close() \ No newline at end of file diff --git a/imgs/add.png b/imgs/add.png new file mode 100644 index 0000000..823d5ce Binary files /dev/null and b/imgs/add.png differ diff --git a/imgs/complete.png b/imgs/complete.png new file mode 100644 index 0000000..4f30162 Binary files /dev/null and b/imgs/complete.png differ diff --git a/imgs/edit.png b/imgs/edit.png new file mode 100644 index 0000000..27a6038 Binary files /dev/null and b/imgs/edit.png differ diff --git a/imgs/exit.png b/imgs/exit.png new file mode 100644 index 0000000..42e89b3 Binary files /dev/null and b/imgs/exit.png differ diff --git a/main.py b/main.py deleted file mode 100644 index 03f8247..0000000 --- a/main.py +++ /dev/null @@ -1,70 +0,0 @@ -while True: - # Get user input and strip space chars from it - user_action = input('Type add, show or display, edit, complete, or exit: ') - user_action = user_action.strip() - - match user_action: - case 'add': - todo = input('Enter a todo: ') + '\n' - - with open('files/todos.txt', 'r') as file: - todos = file.readlines() - - todos.append(todo.capitalize()) - - with open('files/todos.txt', 'w') as file: - file.writelines(todos) - - case 'show' | 'display': - with open('files/todos.txt', 'r') as file: - todos = file.readlines() - - # new_todos = [] - # for item in todos: - # new_item = item.strip('\n') - # new_todos.append(new_item) - - # new_todos = [item.strip('\n') for item in todos] - - for index, item in enumerate(todos): # new_todos for the previous two - item = item.strip('\n').capitalize() - row = f"{index + 1}. {item}" - print(row) - - case 'edit': - number = int(input('Enter the number of todo to edit: ')) - number = number - 1 - - with open('files/todos.txt', 'r') as file: - todos = file.readlines() - - new_todo = input('Enter new todo: ') - todos[number] = new_todo + '\n' - - with open('files/todos.txt', 'w') as file: - file.writelines(todos) - - case 'complete': - number = int(input('Enter the number of todo to complete: ')) - - with open('files/todos.txt', 'r') as file: - todos = file.readlines() - - index = number - 1 - todo_to_remove = todos[index].strip('\n') - - todos.pop(index) - - with open('files/todos.txt', 'w') as file: - file.writelines(todos) - - message = f'Todo {todo_to_remove} was removed from the list.' - print(message) - - case 'exit': - break - - case _: - print('Hey! You entered an unknown command.') - -print('Bye!') \ No newline at end of file diff --git a/modules/__init__.py b/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/modules/functions.py b/modules/functions.py new file mode 100644 index 0000000..a256723 --- /dev/null +++ b/modules/functions.py @@ -0,0 +1,16 @@ +FILEPATH = "files/todos.txt" + + +def get_todos(filepath=FILEPATH): + """ + Read a text file and return the list of + to-do items. + """ + with open(filepath, 'r') as file_local: + todos_local = file_local.readlines() + return todos_local + +def write_todos(todos_arg, filepath=FILEPATH): + """ Write the to-do items list in the text file. """ + with open(filepath, 'w') as file: + file.writelines(todos_arg) \ No newline at end of file diff --git a/programming design concepts.png b/programming design concepts.png new file mode 100644 index 0000000..ea48919 Binary files /dev/null and b/programming design concepts.png differ