joseph

Finished
1import json
2
13class RestAPI:
24 def __init__(self, database: dict | None = None):
3 pass
4
5 # Initialize the database with provided data or an empty structure
6 if database is None:
7 self.database = {"users": []}
8 else:
9 self.database = database
10
511 def get(self, url: str, payload: str | None = None) -> str:
6 pass
7
12 # Edge Case: Handle invalid URL
13 if url != "/users":
14 return json.dumps({"error": "Invalid URL"})
15
16 # Parse payload if provided
17 if payload is not None:
18 try:
19 data = json.loads(payload)
20 # Edge Case: Handle missing 'users' key in payload
21 if "users" not in data:
22 return json.dumps({"error": "Invalid payload"})
23
24 # Filter users based on the requested list
25 requested_users = data["users"]
26 users = [user for user in self.database["users"] if user["name"] in requested_users]
27 # Sort users by name
28 users.sort(key=lambda x: x["name"])
29 return json.dumps({"users": users})
30 except json.JSONDecodeError:
31 # Edge Case: Handle invalid JSON in payload
32 return json.dumps({"error": "Invalid JSON"})
33 else:
34 # Return all users sorted by name
35 users = sorted(self.database["users"], key=lambda x: x["name"])
36 return json.dumps({"users": users})
37
838 def post(self, url: str, payload: str | None = None) -> str:
9 pass
39 # Edge Case: Handle invalid URL
40 if url not in ["/add", "/iou"]:
41 return json.dumps({"error": "Invalid URL"})
42
43 # Edge Case: Handle missing payload
44 if payload is None:
45 return json.dumps({"error": "Payload required"})
46
47 try:
48 data = json.loads(payload)
49 except json.JSONDecodeError:
50 # Edge Case: Handle invalid JSON in payload
51 return json.dumps({"error": "Invalid JSON"})
52
53 if url == "/add":
54 # Edge Case: Handle missing 'user' key in payload
55 if "user" not in data:
56 return json.dumps({"error": "Missing user field"})
57
58 user_name = data["user"]
59
60 # Edge Case: Handle duplicate user creation
61 for user in self.database["users"]:
62 if user["name"] == user_name:
63 return json.dumps({"error": "User already exists"})
64
65 # Create new user
66 new_user = {
67 "name": user_name,
68 "owes": {},
69 "owed_by": {},
70 "balance": 0.0
71 }
72 self.database["users"].append(new_user)
73 return json.dumps(new_user)
74
75 elif url == "/iou":
76 # Edge Case: Handle missing required fields in IOU payload
77 required_fields = ["lender", "borrower", "amount"]
78 for field in required_fields:
79 if field not in data:
80 return json.dumps({"error": f"Missing {field} field"})
81
82 lender_name = data["lender"]
83 borrower_name = data["borrower"]
84 amount = data["amount"]
85
86 # Edge Case: Handle invalid amount type
87 if not isinstance(amount, (int, float)):
88 return json.dumps({"error": "Invalid amount"})
89
90 # Edge Case: Handle negative amount
91 if amount < 0:
92 return json.dumps({"error": "Amount must be positive"})
93
94 # Edge Case: Handle lender and borrower being the same person
95 if lender_name == borrower_name:
96 return json.dumps({"error": "Lender and borrower cannot be the same"})
97
98 # Find lender and borrower in database
99 lender = None
100 borrower = None
101
102 for user in self.database["users"]:
103 if user["name"] == lender_name:
104 lender = user
105 if user["name"] == borrower_name:
106 borrower = user
107
108 # Edge Case: Handle lender not found
109 if lender is None:
110 return json.dumps({"error": "Lender not found"})
111
112 # Edge Case: Handle borrower not found
113 if borrower is None:
114 return json.dumps({"error": "Borrower not found"})
115
116 # Update IOUs by properly netting amounts
117 # Get current amounts
118 lender_owes_borrower = lender["owes"].get(borrower_name, 0)
119 borrower_owes_lender = borrower["owes"].get(lender_name, 0)
120
121 # When lender lends to borrower, borrower owes lender more
122 # So we add amount to what borrower owes lender
123 new_borrower_owes_lender = borrower_owes_lender + amount
124
125 # Net out the amounts
126 if new_borrower_owes_lender > lender_owes_borrower:
127 # Borrower owes lender more than lender owes borrower
128 net_amount = new_borrower_owes_lender - lender_owes_borrower
129 # Clear all old entries for these two users
130 lender["owes"].pop(borrower_name, None)
131 lender["owed_by"].pop(borrower_name, None)
132 borrower["owes"].pop(lender_name, None)
133 borrower["owed_by"].pop(lender_name, None)
134 # Set new entries
135 lender["owed_by"][borrower_name] = net_amount
136 borrower["owes"][lender_name] = net_amount
137 elif new_borrower_owes_lender < lender_owes_borrower:
138 # Lender owes borrower more than borrower owes lender
139 net_amount = lender_owes_borrower - new_borrower_owes_lender
140 # Clear all old entries for these two users
141 lender["owes"].pop(borrower_name, None)
142 lender["owed_by"].pop(borrower_name, None)
143 borrower["owes"].pop(lender_name, None)
144 borrower["owed_by"].pop(lender_name, None)
145 # Set new entries
146 lender["owes"][borrower_name] = net_amount
147 borrower["owed_by"][lender_name] = net_amount
148 else:
149 # They cancel out completely
150 # Clear all old entries for these two users
151 lender["owes"].pop(borrower_name, None)
152 lender["owed_by"].pop(borrower_name, None)
153 borrower["owes"].pop(lender_name, None)
154 borrower["owed_by"].pop(lender_name, None)
155
156 # Recalculate balances
157 lender_total_owed = sum(lender["owed_by"].values())
158 lender_total_owes = sum(lender["owes"].values())
159 lender["balance"] = lender_total_owed - lender_total_owes
160
161 borrower_total_owed = sum(borrower["owed_by"].values())
162 borrower_total_owes = sum(borrower["owes"].values())
163 borrower["balance"] = borrower_total_owed - borrower_total_owes
164
165 # Return updated users sorted by name
166 updated_users = sorted([lender, borrower], key=lambda x: x["name"])
167 return json.dumps({"users": updated_users})
168 # Handled Edge Cases: Invalid URL, missing payload, invalid JSON, missing 'users' key, missing 'user' key, duplicate user creation, missing required fields in IOU payload, invalid amount type, negative amount, lender and borrower being the same person, lender not found, borrower not found
Test NameStatus
test_add_user
Pass
test_borrower_has_negative_balance
Pass
test_both_users_have_0_balance
Pass
test_get_single_user
Pass
test_lender_has_negative_balance
Pass
test_lender_owes_borrower
Pass
test_lender_owes_borrower_less_than_new_loan
Pass
test_lender_owes_borrower_same_as_new_loan
Pass
test_no_users
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.