School Commit Init
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
|
||||
+19
@@ -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()
|
||||
|
||||
|
||||
+57
@@ -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"
|
||||
}
|
||||
]
|
||||
+7
@@ -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
|
||||
+48
@@ -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)
|
||||
|
||||
+26
@@ -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()}
|
||||
+35
@@ -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()}
|
||||
+28
@@ -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()
|
||||
+13
@@ -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
|
||||
+45
@@ -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()))
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
|
||||
+31
@@ -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")
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
repository: "database",
|
||||
}
|
||||
+52
@@ -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"
|
||||
}
|
||||
]
|
||||
+10
@@ -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 @@
|
||||
|
||||
@@ -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")
|
||||
Reference in New Issue
Block a user