School Commit Init

This commit is contained in:
2024-08-31 12:07:21 +03:00
commit 0b130ee18c
2801 changed files with 4720552 additions and 0 deletions
@@ -0,0 +1,19 @@
class Expense():
def __init__(self,day,money,type_of_expense):
self.day=day
self.money=money
self.type_of_expense=type_of_expense
def get_day(self):
return self.day
def get_money(self):
return self.money
def get_type_of_expense(self):
return self.type_of_expense
def set_day(self,day):
self.day=day
def set_money(self,money):
self.money=money
def set_type_of_expense(self,type_of_expense):
self.type_of_expense=type_of_expense
def __str__(self) -> str:
return "Day: {} | Money: {} | Type: {} ".format(self.day,self.money,self.type_of_expense)
@@ -0,0 +1,25 @@
from ui.ui import ui
from repositories.textfile import TextFileRepository
from repositories.memory import MemoryRepository
from repositories.binaryfile import BinaryFileRepository
from repositories.jsonfile import JsonFileRepository
from repositories.database import DatabaseRepository
if __name__=="__main__":
repos={
"textfile":TextFileRepository,
"memory":MemoryRepository,
"binaryfile":BinaryFileRepository,
"jsonfile":JsonFileRepository,
"database":DatabaseRepository
}
repo=None
with open("src/settings.properties") as f:
for line in f:
if line.strip().startswith("repository"):
repo=repos.get(line.split("\"",3)[1].strip(),MemoryRepository)()
break
ui=ui(repo)
ui()
@@ -0,0 +1,57 @@
[
{
"day": 22,
"money": 7,
"type_of_expense": "Gas"
},
{
"day": 25,
"money": 90,
"type_of_expense": "Water"
},
{
"day": 11,
"money": 20,
"type_of_expense": "Netflix Subscription"
},
{
"day": 17,
"money": 14,
"type_of_expense": "Water"
},
{
"day": 9,
"money": 39,
"type_of_expense": "Water"
},
{
"day": 27,
"money": 4,
"type_of_expense": "Water"
},
{
"day": 27,
"money": 84,
"type_of_expense": "Electricity"
},
{
"day": 16,
"money": 63,
"type_of_expense": "Water"
},
{
"day": 20,
"money": 69,
"type_of_expense": "Electricity"
},
{
"day": 3,
"money": 19,
"type_of_expense": "Gas"
},
{
"day": 12,
"money": 432,
"type_of_expense": "gnwrjg"
}
]
@@ -0,0 +1,7 @@
25 90 Water
11 20 Netflix Subscription
9 39 Water
27 84 Electricity
16 63 Water
20 69 Electricity
3 19 Gas
@@ -0,0 +1,48 @@
from repositories.repository import Repository
import pickle
class BinaryFileRepository(Repository):
def __init__(self,path="src/memoryfiles/binarymemory.bin"):
self.file_path=path
self.previous_list_of_expenses=[]
with open(self.file_path,"ab") as f:
pass
def insert_element(self, expense):
"""
:params:
expense - Expense
The function appends the current state of the repo to the stack
The function takes the expense and dumps it into the file indicated by the file_path as a binary representation
"""
self.previous_list_of_expenses.append(self.get_elements())
with open(self.file_path,"ab") as f:
pickle.dump(expense,f)
def get_elements(self):
list_of_expenses=[]
with open(self.file_path,"rb") as f:
while True:
try:
list_of_expenses.append(pickle.load(f))
except EOFError:
break
return list_of_expenses
def filter_elements(self, value):
self.previous_list_of_expenses.append(self.get_elements())
list_of_expenses=[]
with open(self.file_path,"rb") as f:
while True:
try:
expense=pickle.load(f)
if expense.get_money()<value:
continue
list_of_expenses.append(expense)
except EOFError:
break
with open(self.file_path,"wb") as f:
for expense in list_of_expenses:
pickle.dump(expense,f)
def undo(self):
with open(self.file_path,"wb") as f:
for expense in self.previous_list_of_expenses.pop():
pickle.dump(expense,f)
@@ -0,0 +1,26 @@
from pymongo import MongoClient
from domain.domain import Expense
class DatabaseRepository():
def __init__(self):
self.connection_string="mongodb://DanielCujba:kT99aAmXD2DXXru@ac-72p9ntw-shard-00-00.c6jcmwa.mongodb.net:27017,ac-72p9ntw-shard-00-01.c6jcmwa.mongodb.net:27017,ac-72p9ntw-shard-00-02.c6jcmwa.mongodb.net:27017/?ssl=true&replicaSet=atlas-a0t2fd-shard-0&authSource=admin&retryWrites=true&w=majority"
self.client = MongoClient(self.connection_string)
self.db = self.client['FP']
self.collection=self.db['Expenses']
self.undos=[]
def insert_element(self,expense):
id_inserted=self.collection.insert_one(self.toJson(expense)).inserted_id
self.undos.append(id_inserted)
def get_elements(self):
return [Expense(int(element["day"]),int(element["money"]),element["type_of_expense"]) for element in self.collection.find()]
def filter_elements(self,value):
self.undos.append([el for el in self.collection.find({"money":{"$lt":value}})])
self.collection.delete_many({"money":{"$lt":value}})
def undo(self):
e=self.undos.pop()
if type(e)==list:
self.collection.insert_many(e)
else:
self.collection.delete_one({"_id":e})
def toJson(self,expense):
return {"day":expense.get_day(),"money":expense.get_money(),"type_of_expense":expense.get_type_of_expense()}
@@ -0,0 +1,35 @@
from repositories.repository import Repository
from domain.domain import Expense
import json
class JsonFileRepository(Repository):
def __init__(self):
self.file_path="src/memoryfiles/jsonmemory.json"
self.previous_list_of_expenses=[]
with open(self.file_path,"a") as f:
pass
def insert_element(self, expense):
expenses=None
with open(self.file_path,"r") as f:
expenses=json.load(f)
self.previous_list_of_expenses.append(expenses)
expenses.append(self.toJson(expense))
with open(self.file_path,"w") as f:
json.dump(expenses,f,indent=4)
def get_elements(self):
with open(self.file_path,"r") as f:
json_obj=json.load(f)
return [Expense(int(expense["day"]),int(expense["money"]),expense["type_of_expense"]) for expense in json_obj]
def filter_elements(self, value):
expenses=None
with open(self.file_path,"r") as f:
expenses=json.load(f)
self.previous_list_of_expenses.append(expenses)
expenses=[expense for expense in expenses if expense["money"]>=value]
with open(self.file_path,"w") as f:
json.dump(expenses,f,indent=4)
def undo(self):
with open(self.file_path,"w") as f:
json.dump(self.previous_list_of_expenses.pop(),f,indent=4)
def toJson(self,expense):
return {"day":expense.get_day(),"money":expense.get_money(),"type_of_expense":expense.get_type_of_expense()}
@@ -0,0 +1,28 @@
from repositories.repository import Repository
from domain.domain import Expense
import random
class MemoryRepository(Repository):
def __init__(self):
super().__init__()
self.list_of_expenses=self.generate_elements(10)
self.previous_list_of_expenses=[]
def insert_element(self,expense):
"""
:params:
expense - Expense
The function takes the current state of the repo and appends it to the stack
The function appends the expense to the current list of expenses
"""
self.previous_list_of_expenses.append(self.list_of_expenses)
self.list_of_expenses.append(expense)
def get_elements(self):
return self.list_of_expenses
def filter_elements(self,value):
self.previous_list_of_expenses.append(self.list_of_expenses)
self.list_of_expenses=list(filter(lambda x:x.get_money()>value,self.list_of_expenses))
def generate_elements(self,number)->list:
types={1:"Water",2:"Gas",3:"Electricity"}
return [Expense(random.randint(1,30),random.randint(1,100),types[random.randint(1,3)]) for _ in range(number)]
def undo(self):
self.list_of_expenses=self.previous_list_of_expenses.pop()
@@ -0,0 +1,13 @@
from domain.domain import Expense
class Repository():
def __init__(self):
pass
def get_elements(self):
pass
def insert_element(self,expense:Expense):
pass
def filter_elements(self,value:int):
pass
def undo():
pass
@@ -0,0 +1,45 @@
from repositories.repository import Repository
from domain.domain import Expense
class TextFileRepository(Repository):
def __init__(self,path="src/memoryfiles/textmemory.txt"):
self.file_path=path
self.previous_list_of_expenses=[]
with open(self.file_path,"a") as f:
pass
def insert_element(self, expense):
"""
:params:
expense - Expense
The function appends the current state of the repo on the stack
The function takes an expense and stores it in the format "{day} {money} {type_of_expense}" in the text file indicated by the file_path
"""
self.previous_list_of_expenses.append(self.get_elements())
with open(self.file_path,"a") as f:
f.write("{} {} {}\n".format(expense.get_day(),expense.get_money(),expense.get_type_of_expense()))
def get_elements(self):
list_of_expenses=[]
with open(self.file_path,"r") as f:
for line in f:
data=line.strip().split(' ',2)
list_of_expenses.append(Expense(int(data[0]),int(data[1]),data[2]))
return list_of_expenses
def filter_elements(self, value):
self.previous_list_of_expenses.append(self.get_elements())
list_of_expenses=[]
with open(self.file_path,'r') as f:
for line in f:
data=line.strip().split(' ',2)
if int(data[1])<value:
continue
list_of_expenses.append(Expense(int(data[0]),int(data[1]),data[2]))
with open(self.file_path,'w') as f:
for expense in list_of_expenses:
f.write("{} {} {}\n".format(expense.get_day(),expense.get_money(),expense.get_type_of_expense()))
def undo(self):
with open(self.file_path,'w') as f:
for expense in self.previous_list_of_expenses.pop():
f.write("{} {} {}\n".format(expense.get_day(),expense.get_money(),expense.get_type_of_expense()))
@@ -0,0 +1,31 @@
from domain.domain import Expense
from repositories.repository import Repository
class Services():
def __init__(self,repo:Repository) -> None:
self.repo=repo
self.undos=0
def add_expense(self,day,money,type_of_expense):
"""
:params:
day - integer between 1 and 30
money - positive integer
type_of_expense - string
The function creates a new Expense object and call the repository's insert_element method
The function increments the undo counter
"""
expense=Expense(day,money,type_of_expense)
self.repo.insert_element(expense)
self.undos+=1
def display_list(self):
return self.repo.get_elements()
def filter_list(self,value):
self.undos+=1
self.repo.filter_elements(value)
def undo(self):
if self.undos>0:
self.undos-=1
self.repo.undo()
else:
raise Exception("No more undos available")
@@ -0,0 +1,3 @@
{
repository: "database",
}
@@ -0,0 +1,52 @@
[
{
"day": 22,
"money": 7,
"type_of_expense": "Gas"
},
{
"day": 25,
"money": 90,
"type_of_expense": "Water"
},
{
"day": 11,
"money": 20,
"type_of_expense": "Netflix Subscription"
},
{
"day": 17,
"money": 14,
"type_of_expense": "Water"
},
{
"day": 9,
"money": 39,
"type_of_expense": "Water"
},
{
"day": 27,
"money": 4,
"type_of_expense": "Water"
},
{
"day": 27,
"money": 84,
"type_of_expense": "Electricity"
},
{
"day": 16,
"money": 63,
"type_of_expense": "Water"
},
{
"day": 20,
"money": 69,
"type_of_expense": "Electricity"
},
{
"day": 3,
"money": 19,
"type_of_expense": "Gas"
}
]
@@ -0,0 +1,10 @@
22 7 Gas
25 90 Water
11 20 Netflix Subscription
17 14 Water
9 39 Water
27 4 Water
27 84 Electricity
16 63 Water
20 69 Electricity
3 19 Gas
@@ -0,0 +1,47 @@
from repositories.textfile import TextFileRepository
from repositories.memory import MemoryRepository
from repositories.binaryfile import BinaryFileRepository
from domain.domain import Expense
import unittest
class UnitTester(unittest.TestCase):
def test_memory_repo(self):
repo=MemoryRepository()
list_of_expenses=repo.get_elements()
e=Expense(10,200,"Gucci")
list_of_expenses.append(e)
repo.insert_element(e)
self.assertEqual(list_of_expenses,repo.get_elements())
def test_textfile_repo(self):
repo=TextFileRepository(path="src/templetes/textmemory.bin")
e=Expense(10,200,"Gucci")
list_of_expenses=repo.get_elements()
repo.insert_element(e)
list_of_expenses.append(e)
repo_list=repo.get_elements()
self.assertEqual(len(list_of_expenses),len(repo_list))
for i in range(len(list_of_expenses)):
self.assertEqual(list_of_expenses[i].get_day(),repo_list[i].get_day())
self.assertEqual(list_of_expenses[i].get_money(),repo_list[i].get_money())
self.assertEqual(list_of_expenses[i].get_type_of_expense(),repo_list[i].get_type_of_expense())
repo.undo()
def test_binaryfile_repo(self):
repo=BinaryFileRepository(path="src/templetes/binarymemory.bin")
e=Expense(10,200,"Gucci")
list_of_expenses=repo.get_elements()
repo.insert_element(e)
list_of_expenses.append(e)
repo_list=repo.get_elements()
self.assertEqual(len(list_of_expenses),len(repo_list))
for i in range(len(list_of_expenses)):
self.assertEqual(list_of_expenses[i].get_day(),repo_list[i].get_day())
self.assertEqual(list_of_expenses[i].get_money(),repo_list[i].get_money())
self.assertEqual(list_of_expenses[i].get_type_of_expense(),repo_list[i].get_type_of_expense())
repo.undo()
if __name__=="__main__":
unittest.main()
@@ -0,0 +1,49 @@
from services.services import Services
import re
class ui():
def __init__(self,repo) -> None:
self.repo=repo
self.services=Services(self.repo)
def __call__(self) -> None:
while True:
print("""
Please select a command:
1. Add an expense
2. Display the list of expenses
3. Filter the list
4. Undo
0. Exit
""")
inp=input(">")
match inp:
case "1":
day=input("Please enter the day: ")
if not re.fullmatch("\d+",day) or int(day)<1 or int(day)>30:
print("Invalid day. Value must be an integer between 1 and 30")
continue
money=input("Please enter the amount of money: ")
if not re.fullmatch("\d+",money):
print("Invalid amount of money. Value must be a positive integer")
continue
type_of_expense=input("Please enter the type of expense: ")
self.services.add_expense(int(day),int(money),type_of_expense)
case "2":
for expense in self.services.display_list():
print(expense)
case "3":
value=input("Please enter a value: ")
if not re.fullmatch("\d+",value):
print("Invalid number. Value must be a positive integer")
continue
self.services.filter_list(int(value))
print("List filtered")
case "4":
try:
self.services.undo()
except Exception as e:
print(e)
case "0":
return
case _:
print("Invalid Command")