diff --git a/examples/manual_code/to_do_ex/note.md b/examples/manual_code/to_do_ex/note.md new file mode 100644 index 000000000..3561c80c3 --- /dev/null +++ b/examples/manual_code/to_do_ex/note.md @@ -0,0 +1,15 @@ +# Python vs. Jac: A Comparative Overview + +This code examples in both Python and Jac to illustrate the differences between the two languages. The primary focus is on the following features: + +1. Curly Braces Back +2. Keyword Changes (def → can) +3. DocString Discipline +4. Explicit Tuples +5. Dataclass Style Basis for OOP +6. No Gratuitous Self Usage +7. Variable Reference +8. Enumeration + +- Python implementation - [to_do.py](/examples/manual_code/to_do_ex/to_do.py) +- Jac basic implementation - [to_do.jac](/examples/manual_code/to_do_ex/to_do_v1.jac) diff --git a/examples/manual_code/to_do_ex/to_do.py b/examples/manual_code/to_do_ex/to_do.py new file mode 100644 index 000000000..03eba293f --- /dev/null +++ b/examples/manual_code/to_do_ex/to_do.py @@ -0,0 +1,127 @@ +import datetime + +# Enum for task status +from enum import Enum + + +class TaskStatus(Enum): + PENDING = "Pending" + COMPLETED = "Completed" + + +# Dataclass style for a Task +class Task: + def __init__(self, description, status=TaskStatus.PENDING): + """ + Initialize a task. + + Arguments: + description -- description of the task + status -- status of the task (Pending, Completed) + """ + self.description = description + self.status = status + self.created_at = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + +# Dataclass style for the ToDoList +class ToDoList: + def __init__(self): + """ + Initialize the to-do list. + """ + self.tasks = [] + + def add_task(self, description): + """ + Add a task to the to-do list. + Arguments: + description -- description of the task + """ + self.tasks.append(Task(description)) + + def view_tasks(self): + """ + View all tasks in the to-do list. + """ + for i, task in enumerate(self.tasks): + print( + f"{i+1}. {task.description} [{task.status.value}] (Created at: {task.created_at})" + ) + + def mark_completed(self, index): + """ + Mark a task as completed. + Arguments: + index -- index of the task to mark as completed + """ + if index < 0 or index >= len(self.tasks): + print("Invalid task number!") + return + self.tasks[index].status = TaskStatus.COMPLETED + + +# Function to display menu +def display_menu(): + """ + Display the menu options. + """ + print("To-Do List Menu:") + print("1. Add Task") + print("2. View Tasks") + print("3. Mark Task as Completed") + print("4. Exit") + + +# Function to handle user input +def handle_input(): + """ + Handle user input for menu options. + """ + to_do_list = ToDoList() + while True: + display_menu() + choice = input("Enter your choice (1-4): ") or "4" + if choice == "1": + description = input("Enter task description: ") or "" + to_do_list.add_task(description) + elif choice == "2": + to_do_list.view_tasks() + elif choice == "3": + index = int(input("Enter task number to mark as completed: ") or "-1") - 1 + to_do_list.mark_completed(index) + elif choice == "4": + print("Exiting...") + break + else: + print("Invalid choice! Please enter a number between 1 and 4.") + + +# Entry point of the app +if __name__ == "__main__": + handle_input() + +# # Unit Tests +# def test_add_task(): +# to_do_list = ToDoList() +# to_do_list.add_task("Test Task") +# assert len(to_do_list.tasks) == 1 +# assert to_do_list.tasks[0].description == "Test Task" + +# def test_mark_completed(): +# to_do_list = ToDoList() +# to_do_list.add_task("Test Task") +# to_do_list.mark_completed(0) +# assert to_do_list.tasks[0].status == TaskStatus.COMPLETED + +# def test_invalid_task_number(): +# to_do_list = ToDoList() +# to_do_list.add_task("Test Task") +# to_do_list.mark_completed(1) +# assert to_do_list.tasks[0].status == TaskStatus.PENDING + +# # Running unit tests +# test_add_task() +# test_mark_completed() +# test_invalid_task_number() +# print("All tests passed.") diff --git a/examples/manual_code/to_do_ex/to_do_v1.jac b/examples/manual_code/to_do_ex/to_do_v1.jac new file mode 100644 index 000000000..5f303e9b0 --- /dev/null +++ b/examples/manual_code/to_do_ex/to_do_v1.jac @@ -0,0 +1,105 @@ +import:py datetime; +import:py from enum { Enum } +import:py from random { randint } + +enum TaskStatus { + PENDING = "Pending", + COMPLETED = "Completed" +} + +""" +Initialize a task. +description -- description of the task +status -- status of the task (Pending, Completed) +""" +obj Task { + has description: str; + has status: TaskStatus = TaskStatus.PENDING; + has created_at: datetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"); +} + +"""Initialize the to-do list.""" +obj ToDoList { + has tasks: list = []; + + can add_task(description: str) { + self.tasks.append(Task(description)); + } + + can view_tasks() { + if self.tasks { + for (i, task) in enumerate(self.tasks) { + print( + f"{(i + 1)}{". "}{task.description}{" ["}{task.status.value}{"] (Created at: "}{task.created_at}{")"}" + ); + } + } else { + print("No tasks"); + } + } + + can mark_completed(index: int) { + if index < 0 or index >= len(self.tasks) { + print("Invalid task number!"); + } + self.tasks[index].status = TaskStatus.COMPLETED; + } +} + +can display_menu() { + print("To-Do List Menu:"); + print("1. Add Task"); + print("2. View Tasks"); + print("3. Mark Task as Completed"); + print("4. Exit"); +} + +can handle_input() { + to_do_list = ToDoList(); + + while True { + display_menu(); + choice = input("Enter your choice (1-4): ") or "4"; + if choice == "1" { + description = input("Enter task description: ") or ""; + to_do_list.add_task(description); + } elif choice == "2" { + to_do_list.view_tasks(); + } elif choice == "3" { + index = (int( + input("Enter task number to mark as completed: ") + or "-1" + ) - 1); + to_do_list.mark_completed(index); + } elif choice == "4" { + print("Exiting..."); + break; + } else { + print( + "Invalid choice! Please enter a number between 1 and 4." + ); + } + } +} +# can test_add_task() { +# to_do_list = ToDoList(); +# to_do_list.add_task("Test Task"); +# assert len(to_do_list.tasks) == 1; +# assert to_do_list.tasks[0].description == "Test Task"; +# } +# can test_mark_completed() { +# to_do_list = ToDoList(); +# to_do_list.add_task("Test Task"); +# to_do_list.mark_completed(0); +# assert to_do_list.tasks[0].status == TaskStatus.COMPLETED; +# } +# can test_invalid_task_number() { +# to_do_list = ToDoList(); +# to_do_list.add_task("Test Task"); +# to_do_list.mark_completed(1); +# assert to_do_list.tasks[0].status == TaskStatus.PENDING; +# } + +with entry { + handle_input(); +}