School Commit Init
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
.vscode/
|
||||
@@ -0,0 +1,93 @@
|
||||
# 💻 Assignment 08
|
||||
## Requirements
|
||||
- Provide a menu-driven console-based user interface. Implementation details are up to you
|
||||
- Employ layered architecture and classes
|
||||
- Have at least 20 procedurally generated items in your application at startup
|
||||
- Provide specifications and **PyUnit test cases** for all non-UI classes and methods for the first functionality
|
||||
- Implement and use your own exception classes.
|
||||
- Deadline is **week 12**, with the exception of the undo-redo bonus.
|
||||
|
||||
## Bonus possibility (0.1p, deadline week 12)
|
||||
- 95% unit test code coverage for all modules except the UI (use *PyCharm Professional*, the *[coverage](https://coverage.readthedocs.io/en/coverage-5.3/)* or other modules)
|
||||
|
||||
## Bonus possibility (0.2p, deadline week 12)
|
||||
- Implement a graphical user interface, in addition to the required menu-driven UI
|
||||
- The program can be started with either UI
|
||||
|
||||
## Bonus possibility (0.2p, deadline week 14)
|
||||
- Unlimited undo/redo functionality. Each step will undo/redo the previous operation performed by the user. Undo/redo operations must cascade and have a memory-efficient implementation (no superfluous list copying) based on the [command design pattern](https://refactoring.guru/design-patterns/command)
|
||||
|
||||
## Problem Statements
|
||||
### 1. Students Register Management
|
||||
A faculty stores information about:
|
||||
- **Student**: `student_id`, `name`
|
||||
- **Discipline**: `discipline_id`, `name`
|
||||
- **Grade**: `discipline_id`, `student_id`, `grade_value`
|
||||
|
||||
Create an application to:
|
||||
1. Manage students and disciplines. The user can add, remove, update, and list both students and disciplines.
|
||||
2. Grade students at a given discipline. Any student may receive one or several grades at any discipline. Deleting a student also removes their grades. Deleting a discipline deletes all grades at that discipline for all students.
|
||||
3. Search for disciplines/students based on ID or name/title. The search must work using case-insensitive, partial string matching, and must return all matching disciplines/students.
|
||||
4. Create statistics:
|
||||
- All students failing at one or more disciplines (students having an average <5 for a discipline are failing it)
|
||||
- Students with the best school situation, sorted in descending order of their aggregated average (the average between their average grades per discipline)
|
||||
- All disciplines at which there is at least one grade, sorted in descending order of the average grade(s) received by all students
|
||||
|
||||
### 2. Student Lab Assignment
|
||||
Write an application that manages student lab assignments for a discipline. The application will store:
|
||||
- **Student**: `student_id`, `name`, `group`
|
||||
- **Assignment**: `assignment_id`, `description`, `deadline`
|
||||
- **Grade**: `assignment_id`, `student_id`, `grade_value`
|
||||
|
||||
Create an application that allows to:
|
||||
1. Manage students and assignments. The user can add, remove, update, and list both students and assignments.
|
||||
2. Give assignments to a student or a group of students. In case an assignment is given to a group of students, every student in the group will receive it. In case there are students who were previously given that assignment, it will not be assigned again.
|
||||
3. Grade student for a given assignment. When grading, the program must allow the user to select the assignment that is graded, from the student’s list of ungraded assignments. A student’s grade for a given assignment cannot be changed. Deleting a student removes their assignments. Deleting an assignment also removes all grades at that assignment.
|
||||
4. Create statistics:
|
||||
- All students who received a given assignment, ordered descending by grade.
|
||||
- All students who are late in handing in at least one assignment. These are all the students who have an ungraded assignment for which the deadline has passed.
|
||||
- Students with the best school situation, sorted in descending order of the average grade received for all graded assignments.
|
||||
|
||||
### 3. Movie Rental
|
||||
Write an application for movie rentals. The application will store:
|
||||
- **Movie**: `movie_id`, `title`, `description`, `genre`
|
||||
- **Client**: `client_id`, `name`
|
||||
- **Rental**: `rental_id`, `movie_id`, `client_id`, `rented_date`, `due_date`, `returned_date`
|
||||
|
||||
Create an application which allows to:
|
||||
1. Manage clients and movies. The user can add, remove, update, and list both clients and movies.
|
||||
2. Rent or return a movie. A client can rent a movie until a given date, as long as they have no rented movies that passed their due date for return. A client can return a rented movie at any time.
|
||||
3. Search for clients or movies using any one of their fields (e.g. movies can be searched for using id, title, description or genre). The search must work using case-insensitive, partial string matching, and must return all matching items.
|
||||
4. Create statistics:
|
||||
- Most rented movies. This will provide the list of movies, sorted in descending order of the number of days they were rented.
|
||||
- Most active clients. This will provide the list of clients, sorted in descending order of the number of movie rental days they have (e.g. having 2 rented movies for 3 days each counts as 2 x 3 = 6 days).
|
||||
- Late rentals. All the movies that are currently rented, for which the due date for return has passed, sorted in descending order of the number of days of delay.
|
||||
|
||||
### 4. Library
|
||||
Write an application for a book library. The application will store:
|
||||
- **Book**: `book_id`, `title`, `author`
|
||||
- **Client**: `client_id`, `name`
|
||||
- **Rental**: `rental_id`, `book_id`, `client_id`, `rented_date`, `returned_date`
|
||||
|
||||
Create an application to:
|
||||
1. Manage clients and books. The user can add, remove, update, and list both clients and books.
|
||||
2. Rent or return a book. A client can rent an available book. A client can return a rented book at any time. Only available books (those which are not currently rented) can be rented.
|
||||
3. Search for clients or books using any one of their fields (e.g. books can be searched for using id, title or author). The search must work using case-insensitive, partial string matching, and must return all matching items.
|
||||
4. Create statistics:
|
||||
- Most rented books. This will provide the list of books, sorted in descending order of the number of times they were rented.
|
||||
- Most active clients. This will provide the list of clients, sorted in descending order of the number of book rental days they have (e.g. having 2 rented books for 3 days each counts as 2 x 3 = 6 days).
|
||||
- Most rented author. This provides the list of book authors, sorted in descending order of the number of rentals their books have.
|
||||
|
||||
### 5. Activity Planner
|
||||
The following information is stored in a personal activity planner:
|
||||
- **Person**: `person_id`, `name`, `phone_number`
|
||||
- **Activity**: `activity_id`, `person_id` - list, `date`, `time`, `description`
|
||||
|
||||
Create an application to:
|
||||
1. Manage persons and activities. The user can add, remove, update, and list both persons and activities.
|
||||
2. Add/remove activities. Each activity can be performed together with one or several other persons, who are already in the user’s planner. Activities must not overlap (user cannot have more than one activity at a given time).
|
||||
3. Search for persons or activities. Persons can be searched for using name or phone number. Activities can be searched for using date/time or description. The search must work using case-insensitive, partial string matching, and must return all matching items.
|
||||
4. Create statistics:
|
||||
- Activities for a given date. List the activities for a given date, in the order of their start time.
|
||||
- Busiest days. This will provide the list of upcoming dates with activities, sorted in ascending order of the free time in that day (all intervals with no activities).
|
||||
- Activities with a given person. List all upcoming activities to which a given person will participate.
|
||||
@@ -0,0 +1,16 @@
|
||||
from src.ui.ui import UI
|
||||
from src.repository.students_repo import StudentsRepo
|
||||
from src.repository.assignments_repo import AssignmentsRepo
|
||||
from src.repository.grades_repo import GradesRepo
|
||||
from src.services.services import Services
|
||||
|
||||
def main():
|
||||
students_repo = StudentsRepo("src/data/students.json")
|
||||
assignments_repo = AssignmentsRepo("src/data/assignments.json")
|
||||
grades_repo = GradesRepo("src/data/grades.json")
|
||||
services = Services(students_repo,assignments_repo,grades_repo)
|
||||
ui = UI(services)
|
||||
ui.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"assignment_id": "1",
|
||||
"description": "Science Assignment",
|
||||
"deadline": {
|
||||
"year": 2022,
|
||||
"month": 12,
|
||||
"day": 15
|
||||
}
|
||||
},
|
||||
{
|
||||
"assignment_id": "2",
|
||||
"description": "Math Assignment",
|
||||
"deadline": {
|
||||
"year": 2023,
|
||||
"month": 10,
|
||||
"day": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"assignment_id": "3",
|
||||
"description": "English Assignment",
|
||||
"deadline": {
|
||||
"year": 2023,
|
||||
"month": 3,
|
||||
"day": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"assignment_id": "4",
|
||||
"description": "History Assignment",
|
||||
"deadline": {
|
||||
"year": 2022,
|
||||
"month": 10,
|
||||
"day": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"assignment_id": "5",
|
||||
"description": "Art Assignment",
|
||||
"deadline": {
|
||||
"year": 2023,
|
||||
"month": 2,
|
||||
"day": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"assignment_id": "2",
|
||||
"student_id": "A002",
|
||||
"grade_value": 10.0
|
||||
},
|
||||
{
|
||||
"assignment_id": "2",
|
||||
"student_id": "A007",
|
||||
"grade_value": 8.5
|
||||
},
|
||||
{
|
||||
"assignment_id": "2",
|
||||
"student_id": "A008",
|
||||
"grade_value": 4.0
|
||||
},
|
||||
{
|
||||
"assignment_id": "2",
|
||||
"student_id": "A009",
|
||||
"grade_value": null
|
||||
},
|
||||
{
|
||||
"assignment_id": "4",
|
||||
"student_id": "A003",
|
||||
"grade_value": 7.5
|
||||
},
|
||||
{
|
||||
"assignment_id": "4",
|
||||
"student_id": "A010",
|
||||
"grade_value": null
|
||||
}
|
||||
]
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"student_id": "A001",
|
||||
"name": "John Doe",
|
||||
"group": "A1"
|
||||
},
|
||||
{
|
||||
"student_id": "A002",
|
||||
"name": "Jack Black",
|
||||
"group": "C"
|
||||
},
|
||||
{
|
||||
"student_id": "A003",
|
||||
"name": "Justin Cole",
|
||||
"group": "E"
|
||||
},
|
||||
{
|
||||
"student_id": "A004",
|
||||
"name": "Johnny Depp",
|
||||
"group": "A1"
|
||||
},
|
||||
{
|
||||
"student_id": "A005",
|
||||
"name": "Mike Smith",
|
||||
"group": "A1"
|
||||
},
|
||||
{
|
||||
"student_id": "A006",
|
||||
"name": "Dan Brown",
|
||||
"group": "A1"
|
||||
},
|
||||
{
|
||||
"student_id": "A007",
|
||||
"name": "Walter White",
|
||||
"group": "C"
|
||||
},
|
||||
{
|
||||
"student_id": "A008",
|
||||
"name": "Saul Goodman",
|
||||
"group": "C"
|
||||
},
|
||||
{
|
||||
"student_id": "A009",
|
||||
"name": "Jesse Pinkman",
|
||||
"group": "C"
|
||||
},
|
||||
{
|
||||
"student_id": "A010",
|
||||
"name": "Anna Henrietta",
|
||||
"group": "E"
|
||||
}
|
||||
]
|
||||
+1
@@ -0,0 +1 @@
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
from datetime import date
|
||||
|
||||
class Assignment():
|
||||
def __init__(self, assignment_id: str, description: str, deadline: date) -> None:
|
||||
self.__assignment_id = assignment_id
|
||||
self.__description = description
|
||||
self.__deadline = deadline
|
||||
|
||||
def get_assignment_id(self) -> str:
|
||||
return self.__assignment_id
|
||||
|
||||
def get_description(self) -> str:
|
||||
return self.__description
|
||||
|
||||
def get_deadline(self) -> date:
|
||||
return self.__deadline
|
||||
|
||||
def set_assignment_id(self, assignment_id: str) -> None:
|
||||
self.__assignment_id = assignment_id
|
||||
|
||||
def set_description(self, description: str) -> None:
|
||||
self.__description = description
|
||||
|
||||
def set_deadline(self, deadline: date) -> None:
|
||||
self.__deadline = deadline
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Assignment ID: {self.__assignment_id} | Description: {self.__description} | Deadline: {self.__deadline.isoformat()}"
|
||||
|
||||
def toJson(self) -> dict:
|
||||
return {
|
||||
"assignment_id": self.__assignment_id,
|
||||
"description": self.__description,
|
||||
"deadline": {
|
||||
"year": self.__deadline.year,
|
||||
"month": self.__deadline.month,
|
||||
"day": self.__deadline.day
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
from src.errors.errors import GradeValueAlreadySetError
|
||||
|
||||
|
||||
class Grade():
|
||||
def __init__(self, assignment_id: str, student_id: str, grade_value: float) -> None:
|
||||
self.__assignment_id = assignment_id
|
||||
self.__student_id = student_id
|
||||
self.__grade_value = grade_value
|
||||
|
||||
def get_assignment_id(self) -> str:
|
||||
return self.__assignment_id
|
||||
|
||||
def get_student_id(self) -> str:
|
||||
return self.__student_id
|
||||
|
||||
def get_grade_value(self) -> float:
|
||||
return self.__grade_value
|
||||
|
||||
def set_assignment_id(self, assignment_id: str) -> None:
|
||||
self.__assignment_id = assignment_id
|
||||
|
||||
def set_student_id(self, student_id: str) -> None:
|
||||
self.__student_id = student_id
|
||||
|
||||
def set_grade_value(self, grade_value: float) -> None:
|
||||
self.__grade_value = grade_value
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Assignment id: {self.__assignment_id}, student id: {self.__student_id}, grade value: {self.__grade_value}"
|
||||
|
||||
def toJson(self) -> dict:
|
||||
return {
|
||||
"assignment_id": self.__assignment_id,
|
||||
"student_id": self.__student_id,
|
||||
"grade_value": self.__grade_value
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
class Student():
|
||||
def __init__(self,student_id:str,name:str,group:str) -> None:
|
||||
self.__student_id = student_id
|
||||
self.__name = name
|
||||
self.__group = group
|
||||
|
||||
def get_student_id(self) -> str:
|
||||
return self.__student_id
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.__name
|
||||
|
||||
def get_group(self) -> str:
|
||||
return self.__group
|
||||
|
||||
def set_student_id(self,student_id:str) -> None:
|
||||
self.__student_id = student_id
|
||||
|
||||
def set_name(self,name:str) -> None:
|
||||
self.__name = name
|
||||
|
||||
def set_group(self,group:str) -> None:
|
||||
self.__group = group
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Student ID: {self.__student_id} | Name: {self.__name} | Group: {self.__group}"
|
||||
|
||||
def toJson(self) -> dict:
|
||||
return {
|
||||
"student_id":self.__student_id,
|
||||
"name":self.__name,
|
||||
"group":self.__group
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
class DuplicatingError(Exception):
|
||||
pass
|
||||
|
||||
class NonExistentError(Exception):
|
||||
pass
|
||||
|
||||
class StudentNotFoundError(NonExistentError):
|
||||
pass
|
||||
|
||||
class StudentAlreadyExistsError(DuplicatingError):
|
||||
pass
|
||||
|
||||
class AssignmentNotFoundError(NonExistentError):
|
||||
pass
|
||||
|
||||
class AssignmentAlreadyExistsError(DuplicatingError):
|
||||
pass
|
||||
|
||||
class GradeNotFoundError(NonExistentError):
|
||||
pass
|
||||
|
||||
class GradeAlreadyExistsError(DuplicatingError):
|
||||
pass
|
||||
|
||||
class GradeValueAlreadySetError(DuplicatingError):
|
||||
pass
|
||||
+1
@@ -0,0 +1 @@
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import json
|
||||
from datetime import date
|
||||
|
||||
from src.domain.assignment import Assignment
|
||||
from src.errors.errors import *
|
||||
|
||||
class AssignmentsRepo:
|
||||
"""
|
||||
Class that manages the assignments
|
||||
Reads and writes from a json file
|
||||
Attributes:
|
||||
__path: the path to the json file
|
||||
assignments: a list of assignments
|
||||
Methods:
|
||||
__load_from_file: loads the assignments from the json file
|
||||
__save_to_file: saves the assignments to the json file
|
||||
add_assignment: adds an assignment to the repository
|
||||
remove_assignment: removes an assignment from the repository
|
||||
update_assignment: updates an assignment from the repository
|
||||
list_assignments: returns a list of assignments
|
||||
get_assignment: returns an assignment
|
||||
is_an_assignment: returns True if the assignment is in the repository
|
||||
"""
|
||||
def __init__(self, path: str) -> None:
|
||||
self.__path = path
|
||||
self.assignments = []
|
||||
self.__load_from_file()
|
||||
|
||||
def __load_from_file(self) -> None:
|
||||
with open(self.__path, "r") as f:
|
||||
assignments = json.load(f)
|
||||
for assignment in assignments:
|
||||
self.assignments.append(Assignment(assignment["assignment_id"], assignment["description"], date(assignment["deadline"]["year"], assignment["deadline"]["month"], assignment["deadline"]["day"])))
|
||||
|
||||
def __save_to_file(self) -> None:
|
||||
assignments = []
|
||||
for assignment in self.assignments:
|
||||
assignments.append(assignment.toJson())
|
||||
with open(self.__path, "w") as f:
|
||||
json.dump(assignments, f, indent=4)
|
||||
|
||||
def add_assignment(self, assignment: Assignment) -> None:
|
||||
if assignment.get_assignment_id() in [assignment.get_assignment_id() for assignment in self.assignments]:
|
||||
raise AssignmentAlreadyExistsError("Assignment already exists")
|
||||
self.assignments.append(assignment)
|
||||
self.__save_to_file()
|
||||
|
||||
def remove_assignment(self, assignment_id: str) -> None:
|
||||
for assignment in self.assignments:
|
||||
if assignment.get_assignment_id() == assignment_id:
|
||||
self.assignments.remove(assignment)
|
||||
self.__save_to_file()
|
||||
return
|
||||
raise AssignmentNotFoundError("Assignment not found")
|
||||
|
||||
def update_assignment(self, assignment: Assignment) -> None:
|
||||
for assignment_in_list in self.assignments:
|
||||
if assignment_in_list.get_assignment_id() == assignment.get_assignment_id():
|
||||
assignment_in_list.set_description(assignment.get_description())
|
||||
assignment_in_list.set_deadline(assignment.get_deadline())
|
||||
self.__save_to_file()
|
||||
return
|
||||
raise AssignmentNotFoundError("Assignment not found")
|
||||
|
||||
def list_assignments(self) -> list[Assignment]:
|
||||
return self.assignments
|
||||
|
||||
def get_assignment(self, assignment_id: str) -> Assignment:
|
||||
for assignment in self.assignments:
|
||||
if assignment.get_assignment_id() == assignment_id:
|
||||
return assignment
|
||||
raise AssignmentNotFoundError("Assignment not found")
|
||||
|
||||
def is_an_assignment(self, assignment_id: str) -> bool:
|
||||
for assignment in self.assignments:
|
||||
if assignment.get_assignment_id() == assignment_id:
|
||||
return True
|
||||
return False
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
from src.domain.grade import Grade
|
||||
from src.errors.errors import *
|
||||
import json
|
||||
|
||||
class GradesRepo:
|
||||
def __init__(self,path) -> None:
|
||||
self.__path = path
|
||||
self.grades = []
|
||||
self.__load_from_file()
|
||||
|
||||
def __load_from_file(self) -> None:
|
||||
with open(self.__path,"r") as f:
|
||||
grades = json.load(f)
|
||||
for grade in grades:
|
||||
self.grades.append(Grade(grade["assignment_id"],grade["student_id"],grade["grade_value"]))
|
||||
|
||||
def __save_to_file(self) -> None:
|
||||
grades = []
|
||||
for grade in self.grades:
|
||||
grades.append(grade.toJson())
|
||||
with open(self.__path,"w") as f:
|
||||
json.dump(grades,f,indent=4)
|
||||
|
||||
def add_grade(self, grade: Grade) -> None:
|
||||
for grade_in_list in self.grades:
|
||||
if grade_in_list.get_student_id() == grade.get_student_id() and grade_in_list.get_assignment_id() == grade.get_assignment_id():
|
||||
raise GradeAlreadyExistsError("Grade already exists")
|
||||
self.grades.append(grade)
|
||||
self.__save_to_file()
|
||||
|
||||
def remove_grade(self, student_id: int, assignment_id: str) -> None:
|
||||
for grade in self.grades:
|
||||
if grade.get_student_id() == student_id and grade.get_assignment_id() == assignment_id:
|
||||
self.grades.remove(grade)
|
||||
self.__save_to_file()
|
||||
return
|
||||
raise GradeNotFoundError("Grade not found")
|
||||
|
||||
def update_grade(self, grade: Grade) -> None:
|
||||
for grade_in_list in self.grades:
|
||||
if grade_in_list.get_student_id() == grade.get_student_id() and grade_in_list.get_assignment_id() == grade.get_assignment_id():
|
||||
if grade.get_grade_value() != None:
|
||||
grade_in_list.set_grade_value(grade.get_grade_value())
|
||||
self.__save_to_file()
|
||||
return
|
||||
else:
|
||||
raise GradeValueAlreadySetError("Grade value already set")
|
||||
raise GradeNotFoundError("Grade not found")
|
||||
|
||||
def list_grades(self) -> list[Grade]:
|
||||
return self.grades
|
||||
|
||||
def is_a_grade(self, student_id: int, assignment_id: str) -> bool:
|
||||
for grade in self.grades:
|
||||
if grade.get_student_id() == student_id and grade.get_assignment_id() == assignment_id:
|
||||
return True
|
||||
return False
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
import json
|
||||
from src.domain.student import Student
|
||||
from src.errors.errors import *
|
||||
|
||||
class StudentsRepo():
|
||||
"""
|
||||
Class for the repository of students
|
||||
Reads and writes from a json file
|
||||
Attributes:
|
||||
__path: the path to the json file
|
||||
students: a list of students
|
||||
Methods:
|
||||
__load_from_file: loads the students from the json file
|
||||
__save_to_file: saves the students to the json file
|
||||
add_student: adds a student to the repository
|
||||
remove_student: removes a student from the repository
|
||||
update_student: updates a student from the repository
|
||||
list_students: returns a list of students
|
||||
is_a_student: returns True if the student is in the repository
|
||||
"""
|
||||
def __init__(self,path:str) -> None:
|
||||
self.__path = path
|
||||
self.students = []
|
||||
self.__load_from_file()
|
||||
|
||||
def __load_from_file(self) -> None:
|
||||
with open(self.__path,"r") as f:
|
||||
students = json.load(f)
|
||||
for student in students:
|
||||
self.students.append(Student(student["student_id"],student["name"],student["group"]))
|
||||
|
||||
def __save_to_file(self) -> None:
|
||||
students = []
|
||||
for student in self.students:
|
||||
students.append(student.toJson())
|
||||
with open(self.__path,"w") as f:
|
||||
json.dump(students,f,indent=4)
|
||||
|
||||
def add_student(self, student: Student) -> None:
|
||||
if student.get_student_id() in [student.get_student_id() for student in self.students]:
|
||||
raise StudentAlreadyExistsError("Student already exists")
|
||||
self.students.append(student)
|
||||
self.__save_to_file()
|
||||
|
||||
|
||||
def remove_student(self, student_id: str) -> None:
|
||||
for student in self.students:
|
||||
if student.get_student_id() == student_id:
|
||||
self.students.remove(student)
|
||||
self.__save_to_file()
|
||||
return
|
||||
raise StudentNotFoundError("Student not found")
|
||||
|
||||
|
||||
def update_student(self, student: Student) -> None:
|
||||
for student_in_list in self.students:
|
||||
if student_in_list.get_student_id() == student.get_student_id():
|
||||
student_in_list.set_name(student.get_name())
|
||||
student_in_list.set_group(student.get_group())
|
||||
self.__save_to_file()
|
||||
return
|
||||
raise StudentNotFoundError("Student not found")
|
||||
|
||||
def list_students(self) -> list[Student]:
|
||||
return self.students
|
||||
|
||||
def is_a_student(self,student_id:str) -> bool:
|
||||
for student in self.students:
|
||||
if student.get_student_id() == student_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
from src.domain.student import Student
|
||||
from src.domain.assignment import Assignment
|
||||
from src.domain.grade import Grade
|
||||
from src.errors.errors import *
|
||||
from datetime import date
|
||||
|
||||
class Services:
|
||||
def __init__(self, students_repo, assignments_repo, grades_repo) -> None:
|
||||
self.__students_repo = students_repo
|
||||
self.__assignments_repo = assignments_repo
|
||||
self.__grades_repo = grades_repo
|
||||
|
||||
def add_student(self, student_id, name, group) -> None:
|
||||
"""
|
||||
Adds a student to the repository
|
||||
:param student_id: the id of the student
|
||||
:param name: the name of the student
|
||||
:param group: the group of the student
|
||||
:return: None
|
||||
"""
|
||||
student = Student(student_id, name, group)
|
||||
self.__students_repo.add_student(student)
|
||||
|
||||
def remove_student(self, student_id) -> None:
|
||||
"""
|
||||
Removes a student from the repository
|
||||
:param student_id: the id of the student
|
||||
:return: None
|
||||
"""
|
||||
self.__students_repo.remove_student(student_id)
|
||||
list_of_grades = self.__grades_repo.list_grades()
|
||||
for grade in list_of_grades:
|
||||
if grade.get_student_id() == student_id:
|
||||
self.__grades_repo.remove_grade(grade.get_student_id(), grade.get_assignment_id())
|
||||
|
||||
def update_student(self, student_id, name, group) -> None:
|
||||
"""
|
||||
Updates a student from the repository
|
||||
:param student_id: the id of the student
|
||||
:param name: the name of the student
|
||||
:param group: the group of the student
|
||||
:return: None
|
||||
"""
|
||||
student = Student(student_id, name, group)
|
||||
self.__students_repo.update_student(student)
|
||||
|
||||
def list_students(self) -> list[Student]:
|
||||
"""
|
||||
Returns a list of students
|
||||
:return: a list of students
|
||||
"""
|
||||
return self.__students_repo.list_students()
|
||||
|
||||
def add_assignment(self, assignment_id, description, deadline) -> None:
|
||||
"""
|
||||
Adds an assignment to the repository
|
||||
:param assignment_id: the id of the assignment
|
||||
:param description: the description of the assignment
|
||||
:param deadline: the deadline of the assignment
|
||||
:return: None
|
||||
"""
|
||||
assignment = Assignment(assignment_id, description, deadline)
|
||||
self.__assignments_repo.add_assignment(assignment)
|
||||
|
||||
def remove_assignment(self, assignment_id) -> None:
|
||||
"""
|
||||
Removes an assignment from the repository
|
||||
:param assignment_id: the id of the assignment
|
||||
:return: None
|
||||
"""
|
||||
self.__assignments_repo.remove_assignment(assignment_id)
|
||||
list_of_grades = self.__grades_repo.list_grades()
|
||||
for grade in list_of_grades:
|
||||
if grade.get_assignment_id() == assignment_id:
|
||||
self.__grades_repo.remove_grade(grade.get_student_id(), grade.get_assignment_id())
|
||||
|
||||
def update_assignment(self, assignment_id, description, deadline) -> None:
|
||||
"""
|
||||
Updates an assignment from the repository
|
||||
:param assignment_id: the id of the assignment
|
||||
:param description: the description of the assignment
|
||||
:param deadline: the deadline of the assignment
|
||||
:return: None
|
||||
"""
|
||||
assignment = Assignment(assignment_id, description, deadline)
|
||||
self.__assignments_repo.update_assignment(assignment)
|
||||
|
||||
def list_assignments(self) -> list[Assignment]:
|
||||
"""
|
||||
Returns a list of assignments
|
||||
:return: a list of assignments
|
||||
"""
|
||||
return self.__assignments_repo.list_assignments()
|
||||
|
||||
def give_assignment_to_student(self, student_id, assignment_id) -> None:
|
||||
"""
|
||||
Gives an assignment to a student
|
||||
:param student_id: the id of the student
|
||||
:param assignment_id: the id of the assignment
|
||||
:return: None
|
||||
"""
|
||||
if not self.__students_repo.is_a_student(student_id):
|
||||
raise StudentNotFoundError("Student not found")
|
||||
if not self.__assignments_repo.is_an_assignment(assignment_id):
|
||||
raise AssignmentNotFoundError("Assignment not found")
|
||||
|
||||
grade = Grade(assignment_id,student_id, None)
|
||||
self.__grades_repo.add_grade(grade)
|
||||
|
||||
def give_assignment_to_group(self, group, assignment_id) -> None:
|
||||
"""
|
||||
Gives an assignment to all students in a group
|
||||
:param group: the group of students
|
||||
:param assignment_id: the id of the assignment
|
||||
:return: None
|
||||
"""
|
||||
if not self.__assignments_repo.is_an_assignment(assignment_id):
|
||||
raise AssignmentNotFoundError("Assignment not found")
|
||||
students = self.__students_repo.list_students()
|
||||
for student in students:
|
||||
if student.get_group() == group:
|
||||
grade = Grade(assignment_id,student.get_student_id(), None)
|
||||
try:
|
||||
self.__grades_repo.add_grade(grade)
|
||||
except GradeAlreadyExistsError:
|
||||
pass
|
||||
|
||||
def list_grades(self) -> list[Grade]:
|
||||
return self.__grades_repo.list_grades()
|
||||
|
||||
def list_grades_for_student(self, student_id) -> list[Grade]:
|
||||
grades = self.__grades_repo.list_grades()
|
||||
grades_for_student = []
|
||||
for grade in grades:
|
||||
if grade.get_student_id() == student_id:
|
||||
grades_for_student.append(grade)
|
||||
return grades_for_student
|
||||
|
||||
def list_ungraded_assignments_for_student(self, student_id) -> list[Grade]:
|
||||
if not self.__students_repo.is_a_student(student_id):
|
||||
raise StudentNotFoundError("Student not found")
|
||||
grades = self.__grades_repo.list_grades()
|
||||
ungraded_assignments_for_student = []
|
||||
ungraded_assignments_id_for_student=[]
|
||||
for grade in grades:
|
||||
if grade.get_student_id() == student_id and grade.get_grade_value() == None:
|
||||
ungraded_assignments_id_for_student.append(grade.get_assignment_id())
|
||||
assignments = self.__assignments_repo.list_assignments()
|
||||
for assignment in assignments:
|
||||
if assignment.get_assignment_id() in ungraded_assignments_id_for_student:
|
||||
ungraded_assignments_for_student.append(assignment)
|
||||
return ungraded_assignments_for_student
|
||||
|
||||
def add_grade(self, student_id, assignment_id, grade) -> None:
|
||||
if not self.__students_repo.is_a_student(student_id):
|
||||
raise StudentNotFoundError("Student not found")
|
||||
if not self.__assignments_repo.is_an_assignment(assignment_id):
|
||||
raise AssignmentNotFoundError("Assignment not found")
|
||||
grade = Grade(assignment_id,student_id, grade)
|
||||
self.__grades_repo.update_grade(grade)
|
||||
|
||||
def list_students_with_assignment(self,assignment_id) -> list[Student]:
|
||||
students = self.__students_repo.list_students()
|
||||
students_with_assignment = []
|
||||
grades=sorted(self.__grades_repo.list_grades(), key=lambda grade: grade.get_grade_value() if grade.get_grade_value()!=None else 0 , reverse=True)
|
||||
for grade in grades:
|
||||
if grade.get_assignment_id() == assignment_id:
|
||||
for student in students:
|
||||
if student.get_student_id() == grade.get_student_id():
|
||||
students_with_assignment.append(student)
|
||||
return students_with_assignment
|
||||
|
||||
def list_students_late_on_assignment(self,assignment_id) -> list[Student]:
|
||||
students = self.__students_repo.list_students()
|
||||
students_late_on_assignment = []
|
||||
grades= self.__grades_repo.list_grades()
|
||||
for grade in grades:
|
||||
if grade.get_assignment_id() == assignment_id and grade.get_grade_value() == None and self.__assignments_repo.get_assignment(assignment_id).get_deadline() < date.today():
|
||||
for student in students:
|
||||
if student.get_student_id() == grade.get_student_id() :
|
||||
students_late_on_assignment.append(student)
|
||||
return students_late_on_assignment
|
||||
|
||||
def list_students_best_school_situation(self) -> list[Student]:
|
||||
students = self.__students_repo.list_students()
|
||||
students_best_school_situation = []
|
||||
grades=self.__grades_repo.list_grades()
|
||||
for student in students:
|
||||
sum_of_grades = 0
|
||||
number_of_grades = 0
|
||||
for grade in grades:
|
||||
if grade.get_student_id() == student.get_student_id() and grade.get_grade_value() != None:
|
||||
sum_of_grades += grade.get_grade_value()
|
||||
number_of_grades += 1
|
||||
if number_of_grades != 0:
|
||||
average = sum_of_grades / number_of_grades
|
||||
students_best_school_situation.append((student, average))
|
||||
students_best_school_situation = [student for student, average in sorted(students_best_school_situation, key=lambda student: student[1], reverse=True)]
|
||||
return students_best_school_situation
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
from src.errors.errors import *
|
||||
from src.services.services import Services
|
||||
from datetime import date
|
||||
import re
|
||||
|
||||
class UI():
|
||||
def __init__(self,service:Services) -> None:
|
||||
self.__service = service
|
||||
|
||||
def __print_menu(self) -> None:
|
||||
print("""
|
||||
1.Manage students
|
||||
2.Manage assignments
|
||||
3.Manage grades
|
||||
4.Statistics
|
||||
0.Exit
|
||||
""")
|
||||
|
||||
def __print_student_menu(self) -> None:
|
||||
print("""
|
||||
1.Add student
|
||||
2.Remove student
|
||||
3.Update student
|
||||
4.List students
|
||||
5.Back
|
||||
""")
|
||||
|
||||
def __print_assignment_menu(self) -> None:
|
||||
print("""
|
||||
1.Add assignment
|
||||
2.Remove assignment
|
||||
3.Update assignment
|
||||
4.List assignments
|
||||
5.Give assignment to a student
|
||||
6.Give assignment to a group of students
|
||||
7.Back
|
||||
""")
|
||||
|
||||
def __print_statistics_menu(self) -> None:
|
||||
print("""
|
||||
1.List students with a given assignment
|
||||
2.List students late on an assignment
|
||||
3.List students with the best school situation
|
||||
4.Back
|
||||
""")
|
||||
|
||||
def start(self) -> None:
|
||||
while True:
|
||||
self.__print_menu()
|
||||
command = input("Enter command: ")
|
||||
match command:
|
||||
case "1":
|
||||
self.__manage_students()
|
||||
case "2":
|
||||
self.__manage_assignments()
|
||||
case "3":
|
||||
self.__manage_grades()
|
||||
case "4":
|
||||
self.__statistics()
|
||||
case "0":
|
||||
break
|
||||
case _:
|
||||
print("Invalid command")
|
||||
|
||||
def __manage_students(self) -> None:
|
||||
while True:
|
||||
self.__print_student_menu()
|
||||
command = input("Enter command: ")
|
||||
match command:
|
||||
case "1":
|
||||
self.__add_student()
|
||||
case "2":
|
||||
self.__remove_student()
|
||||
case "3":
|
||||
self.__update_student()
|
||||
case "4":
|
||||
self.__list_students()
|
||||
case "5":
|
||||
break
|
||||
case _:
|
||||
print("Invalid command")
|
||||
|
||||
def __manage_assignments(self) -> None:
|
||||
while True:
|
||||
self.__print_assignment_menu()
|
||||
command = input("Enter command: ")
|
||||
match command:
|
||||
case "1":
|
||||
self.__add_assignment()
|
||||
case "2":
|
||||
self.__remove_assignment()
|
||||
case "3":
|
||||
self.__update_assignment()
|
||||
case "4":
|
||||
self.__list_assignments()
|
||||
case "5":
|
||||
self.__give_assignment_to_student()
|
||||
case "6":
|
||||
self.__give_assignment_to_group()
|
||||
case "7":
|
||||
break
|
||||
case _:
|
||||
print("Invalid command")
|
||||
|
||||
def __manage_grades(self) -> None:
|
||||
try:
|
||||
student_id = input("Enter student id: ")
|
||||
ungraded_assignments = self.__service.list_ungraded_assignments_for_student(student_id)
|
||||
if len(ungraded_assignments) == 0:
|
||||
print("Student has no ungraded assignments")
|
||||
return
|
||||
for i,assignment in enumerate(ungraded_assignments):
|
||||
print(f"{i+1}. {assignment}")
|
||||
command = input("Enter assignment number: ")
|
||||
if re.fullmatch("\d+",command) is None or int(command) < 1 or int(command) > len(ungraded_assignments):
|
||||
print("Invalid command")
|
||||
return
|
||||
assignment = ungraded_assignments[int(command)-1]
|
||||
grade = input("Enter grade: ")
|
||||
if re.fullmatch("\d+(.\d)?+",grade) is None or float(grade) < 1 or float(grade) > 10:
|
||||
print("Invalid grade")
|
||||
return
|
||||
self.__service.add_grade(student_id,assignment.get_assignment_id(),float(grade))
|
||||
except StudentNotFoundError as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def __statistics(self) -> None:
|
||||
while True:
|
||||
self.__print_statistics_menu()
|
||||
command = input("Enter command: ")
|
||||
match command:
|
||||
case "1":
|
||||
self.__list_students_with_assignment()
|
||||
case "2":
|
||||
self.__list_students_late_on_assignment()
|
||||
case "3":
|
||||
self.__list_students_best_school_situation()
|
||||
case "4":
|
||||
break
|
||||
case _:
|
||||
print("Invalid command")
|
||||
|
||||
def __add_student(self) -> None:
|
||||
student_id = input("Enter student id: ")
|
||||
name = input("Enter student name: ")
|
||||
group = input("Enter student group: ")
|
||||
if student_id == "" or name == "" or group == "":
|
||||
print("Invalid student")
|
||||
return
|
||||
try:
|
||||
self.__service.add_student(student_id, name, group)
|
||||
except StudentAlreadyExistsError as e:
|
||||
print(e)
|
||||
|
||||
def __remove_student(self) -> None:
|
||||
student_id = input("Enter student id: ")
|
||||
try:
|
||||
self.__service.remove_student(student_id)
|
||||
except StudentNotFoundError as e:
|
||||
print(e)
|
||||
|
||||
def __update_student(self) -> None:
|
||||
student_id = input("Enter student id: ")
|
||||
name = input("Enter student name: ")
|
||||
group = input("Enter student group: ")
|
||||
if student_id == "" or name == "" or group == "":
|
||||
print("Invalid student")
|
||||
return
|
||||
try:
|
||||
self.__service.update_student(student_id, name, group)
|
||||
except StudentNotFoundError as e:
|
||||
print(e)
|
||||
|
||||
def __list_students(self) -> None:
|
||||
students = self.__service.list_students()
|
||||
for student in students:
|
||||
print(student)
|
||||
|
||||
def __add_assignment(self) -> None:
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
description = input("Enter assignment description: ")
|
||||
day = input("Enter assignment deadline day: ")
|
||||
month = input("Enter assignment deadline month: ")
|
||||
year = input("Enter assignment deadline year: ")
|
||||
if assignment_id == "" or description == "" or day == "" or month == "" or year == "":
|
||||
print("Invalid assignment")
|
||||
return
|
||||
try:
|
||||
deadline = date(int(year), int(month), int(day))
|
||||
self.__service.add_assignment(assignment_id, description, deadline)
|
||||
except AssignmentAlreadyExistsError as e:
|
||||
print(e)
|
||||
except ValueError as e:
|
||||
print("Invalid date")
|
||||
|
||||
def __remove_assignment(self) -> None:
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
try:
|
||||
self.__service.remove_assignment(assignment_id)
|
||||
except AssignmentNotFoundError as e:
|
||||
print(e)
|
||||
|
||||
def __update_assignment(self) -> None:
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
description = input("Enter assignment description: ")
|
||||
day = input("Enter assignment deadline day: ")
|
||||
month = input("Enter assignment deadline month: ")
|
||||
year = input("Enter assignment deadline year: ")
|
||||
if assignment_id == "" or description == "" or day == "" or month == "" or year == "":
|
||||
print("Invalid assignment")
|
||||
return
|
||||
try:
|
||||
deadline = date(int(year), int(month), int(day))
|
||||
self.__service.update_assignment(assignment_id, description, deadline)
|
||||
except AssignmentNotFoundError as e:
|
||||
print(e)
|
||||
except ValueError as e:
|
||||
print("Invalid date")
|
||||
|
||||
def __list_assignments(self) -> None:
|
||||
assignments = self.__service.list_assignments()
|
||||
for assignment in assignments:
|
||||
print(assignment)
|
||||
|
||||
def __give_assignment_to_student(self) -> None:
|
||||
student_id = input("Enter student id: ")
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
try:
|
||||
self.__service.give_assignment_to_student(student_id, assignment_id)
|
||||
except StudentNotFoundError as e:
|
||||
print(e)
|
||||
except AssignmentNotFoundError as e:
|
||||
print(e)
|
||||
except GradeAlreadyExistsError as e:
|
||||
print(e)
|
||||
|
||||
def __give_assignment_to_group(self) -> None:
|
||||
group = input("Enter group: ")
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
try:
|
||||
self.__service.give_assignment_to_group(group, assignment_id)
|
||||
except AssignmentNotFoundError as e:
|
||||
print(e)
|
||||
|
||||
def __list_students_with_assignment(self) -> None:
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
students = self.__service.list_students_with_assignment(assignment_id)
|
||||
for student in students:
|
||||
print(student)
|
||||
|
||||
def __list_students_late_on_assignment(self) -> None:
|
||||
assignment_id = input("Enter assignment id: ")
|
||||
students = self.__service.list_students_late_on_assignment(assignment_id)
|
||||
for student in students:
|
||||
print(student)
|
||||
|
||||
def __list_students_best_school_situation(self) -> None:
|
||||
students = self.__service.list_students_best_school_situation()
|
||||
for student in students:
|
||||
print(student)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import unittest
|
||||
from datetime import date
|
||||
from src.services.services import Services
|
||||
from src.repository.students_repo import StudentsRepo
|
||||
from src.repository.assignments_repo import AssignmentsRepo
|
||||
from src.repository.grades_repo import GradesRepo
|
||||
|
||||
|
||||
|
||||
class Tester(unittest.TestCase):
|
||||
def __init__(self, methodName: str = ...) -> None:
|
||||
super().__init__(methodName)
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.service = Services(StudentsRepo("tests/test_students_file.json"), AssignmentsRepo("tests/test_assignments_file.json"), GradesRepo("tests/test_grades_file.json"))
|
||||
|
||||
def tearDown(self) -> None:
|
||||
return super().tearDown()
|
||||
|
||||
def test_student_repo(self):
|
||||
self.service.add_student("1","John", "911")
|
||||
self.assertEqual(self.service.list_students()[0].get_name(), "John")
|
||||
self.assertEqual(self.service.list_students()[0].get_student_id(), "1")
|
||||
self.assertEqual(self.service.list_students()[0].get_group(), "911")
|
||||
self.service.update_student("1", "Jack", "912")
|
||||
self.assertEqual(self.service.list_students()[0].get_name(), "Jack")
|
||||
self.assertEqual(self.service.list_students()[0].get_student_id(), "1")
|
||||
self.assertEqual(self.service.list_students()[0].get_group(), "912")
|
||||
self.service.remove_student("1")
|
||||
self.assertEqual(len(self.service.list_students()), 0)
|
||||
|
||||
def test_assignment_repo(self):
|
||||
self.service.add_assignment("1", "Assignment 1", date(2021, 2, 1))
|
||||
self.assertEqual(self.service.list_assignments()[0].get_assignment_id(), "1")
|
||||
self.assertEqual(self.service.list_assignments()[0].get_description(), "Assignment 1")
|
||||
self.assertEqual(self.service.list_assignments()[0].get_deadline(), date(2021, 2, 1))
|
||||
self.service.update_assignment("1", "Assignment 2", date(2021, 2, 2))
|
||||
self.assertEqual(self.service.list_assignments()[0].get_assignment_id(), "1")
|
||||
self.assertEqual(self.service.list_assignments()[0].get_description(), "Assignment 2")
|
||||
self.assertEqual(self.service.list_assignments()[0].get_deadline(), date(2021, 2, 2))
|
||||
self.service.remove_assignment("1")
|
||||
self.assertEqual(len(self.service.list_assignments()), 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
#python -m unittest discover -v -s tests -p "*test*.py"
|
||||
+1
@@ -0,0 +1 @@
|
||||
[]
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
[
|
||||
|
||||
]
|
||||
Reference in New Issue
Block a user