diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index b4f6e51..0000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(python main.py:*)", - "Bash(python -m pytest:*)" - ], - "deny": [], - "ask": [] - } -} diff --git a/main.py b/main.py index f91f902..337f6bd 100644 --- a/main.py +++ b/main.py @@ -11,8 +11,9 @@ def main(): parser = argparse.ArgumentParser(description='StudentHub - Manage your academic life') - parser.add_argument('command', choices=['add-assignment', 'list', 'complete', 'gpa', 'stats','pomodoro'], - help='Command to execute') + parser.add_argument('command', choices=['add-assignment', 'add-grade', 'list', 'complete', 'gpa', 'stats', 'export'], + help='Command to execute') + parser.add_argument('value', nargs='?', help='Value for the command') parser.add_argument('--deadline', help='Deadline in YYYY-MM-DD format') parser.add_argument('--subject', help='Subject name') @@ -20,7 +21,7 @@ def main(): parser.add_argument('--work',type=int,default=25) parser.add_argument('--break-minutes',type=int,default=5) parser.add_argument('--no-sound',action='store_true') - + parser.add_argument('--output', help='Output filename for export') args = parser.parse_args() @@ -40,6 +41,18 @@ def main(): return assignment = manager.add_assignment(args.value, deadline, args.subject) print(f"Added assignment: {assignment['title']}") + + elif args.command == 'add-grade': + if not args.subject or not args.value: + print("Error: Provide subject name and grade value") + return + + try: + grade_value = float(args.value) + manager.add_grade(args.subject, grade_value) + print(f"Grade added for {args.subject}: {grade_value}") + except ValueError: + print("Error: Grade must be a number") elif args.command == 'list': assignments = manager.list_assignments() @@ -74,6 +87,25 @@ def main(): ) timer.start(interactive=True) + elif args.command == 'export': + if not args.value: + print("Error: choose 'assignments' or 'grades'") + return + if not args.output: + print("Error: specify output with --output filename.csv") + return + + if args.value == "assignments": + manager.export_assignments(args.output) + print(f"Assignments exported to {args.output}") + + elif args.value == "grades": + manager.export_grades(args.output) + print(f"Grades exported to {args.output}") + + else: + print("Invalid export target. Use 'assignments' or 'grades'.") + manager.dump_manager() if __name__ == '__main__': diff --git a/student_manager.py b/student_manager.py index e52ca4e..55db588 100644 --- a/student_manager.py +++ b/student_manager.py @@ -3,7 +3,7 @@ """ from datetime import datetime -from utils import calculate_days_remaining, validate_grade, get_priority_level, save_to_json, load_from_json +from utils import calculate_days_remaining, validate_grade, get_priority_level, save_to_json, load_from_json, export_to_csv class StudentManager: @@ -111,6 +111,30 @@ def get_statistics(self): 'pending': total_assignments - completed, 'gpa': self.calculate_gpa() } + + def export_assignments(self, filename): + """Export assignments to CSV""" + cleaned = [] + for a in self.assignments: + cleaned.append({ + "title": a["title"], + "deadline": a["deadline"].strftime("%Y-%m-%d"), + "subject": a["subject"], + "completed": a["completed"], + "created_at": a["created_at"].strftime("%Y-%m-%d") + }) + export_to_csv(cleaned, filename) + + def export_grades(self, filename): + """Export grades to CSV""" + cleaned = [] + for g in self.grades: + cleaned.append({ + "subject": g["subject"], + "grade": g["grade"], + "date": g["date"].strftime("%Y-%m-%d") + }) + export_to_csv(cleaned, filename) def _ser_object(self): """ @@ -135,4 +159,4 @@ def _deser_object(cls, data): manager = cls() manager.assignments = data.get("Assignments", []) manager.grades = data.get("Grades", []) - return manager \ No newline at end of file + return manager diff --git a/utils.py b/utils.py index b8e8e53..e3b995a 100644 --- a/utils.py +++ b/utils.py @@ -4,6 +4,7 @@ from datetime import datetime import json +import csv import os class DateTimeEncoder(json.JSONEncoder): @@ -95,4 +96,17 @@ def get_priority_level(days_remaining): elif days_remaining <= 7: return "MEDIUM" else: - return "LOW" \ No newline at end of file + return "LOW" + +def export_to_csv(data, filename, headers=None): + """Export list of dicts to CSV""" + if not data: + raise ValueError("No data to export") + + if headers is None: + headers = list(data[0].keys()) + + with open(filename, "w", newline="") as f: + writer = csv.DictWriter(f, fieldnames=headers) + writer.writeheader() + writer.writerows(data)