awesome

Finished
1import json
2
13class RestAPI:
24 def __init__(self, database: dict | None = None):
3 pass
4
5 # Edge Case: Handle None database by initializing 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 # Edge Case: Handle invalid payload format
17 if payload is not None:
18 try:
19 payload_data = json.loads(payload)
20 except json.JSONDecodeError:
21 return json.dumps({"error": "Invalid payload format"})
22
23 # Edge Case: Handle missing 'users' key in payload
24 if "users" not in payload_data:
25 return json.dumps({"error": "Missing 'users' key in payload"})
26
27 # Edge Case: Handle non-list 'users' value
28 if not isinstance(payload_data["users"], list):
29 return json.dumps({"error": "'users' must be a list"})
30
31 # Edge Case: Filter users that exist in database
32 requested_users = payload_data["users"]
33 users = [user for user in self.database["users"] if user["name"] in requested_users]
34 else:
35 # Edge Case: Return all users when no payload provided
36 users = self.database["users"]
37
38 # Sort users by name
39 users.sort(key=lambda x: x["name"])
40 return json.dumps({"users": users})
41
842 def post(self, url: str, payload: str | None = None) -> str:
9 pass
43 # Edge Case: Handle invalid payload format
44 if payload is None:
45 return json.dumps({"error": "Payload required"})
46
47 try:
48 payload_data = json.loads(payload)
49 except json.JSONDecodeError:
50 return json.dumps({"error": "Invalid payload format"})
51
52 if url == "/add":
53 # Edge Case: Handle missing 'user' key
54 if "user" not in payload_data:
55 return json.dumps({"error": "Missing 'user' key"})
56
57 # Edge Case: Handle non-string user name
58 if not isinstance(payload_data["user"], str):
59 return json.dumps({"error": "User name must be a string"})
60
61 # Edge Case: Handle duplicate user
62 for user in self.database["users"]:
63 if user["name"] == payload_data["user"]:
64 return json.dumps({"error": "User already exists"})
65
66 # Create new user
67 new_user = {
68 "name": payload_data["user"],
69 "owes": {},
70 "owed_by": {},
71 "balance": 0.0
72 }
73 self.database["users"].append(new_user)
74 return json.dumps(new_user)
75
76 elif url == "/iou":
77 # Edge Case: Handle missing required keys
78 required_keys = ["lender", "borrower", "amount"]
79 for key in required_keys:
80 if key not in payload_data:
81 return json.dumps({"error": f"Missing '{key}' key"})
82
83 # Edge Case: Handle incorrect data types
84 if not isinstance(payload_data["lender"], str) or not isinstance(payload_data["borrower"], str):
85 return json.dumps({"error": "Lender and borrower must be strings"})
86
87 # Edge Case: Handle negative amount
88 if not isinstance(payload_data["amount"], (int, float)) or payload_data["amount"] < 0:
89 return json.dumps({"error": "Amount must be a non-negative number"})
90
91 lender_name = payload_data["lender"]
92 borrower_name = payload_data["borrower"]
93 amount = float(payload_data["amount"])
94
95 # Find lender and borrower in database
96 lender = None
97 borrower = None
98 for user in self.database["users"]:
99 if user["name"] == lender_name:
100 lender = user
101 elif user["name"] == borrower_name:
102 borrower = user
103
104 # Edge Case: Handle lender and borrower being the same person
105 if lender_name == borrower_name:
106 # Return the user unchanged (no-op)
107 return json.dumps({"users": [lender]})
108
109 # Edge Case: Handle lender or borrower not existing
110 if lender is None or borrower is None:
111 return json.dumps({"error": "Lender or borrower does not exist"})
112
113 # Handle netting of reciprocal debts
114 # Check if there are existing debts in both directions
115 lender_owes_borrower = lender["owes"].get(borrower_name, 0.0)
116 borrower_owes_lender = borrower["owes"].get(lender_name, 0.0)
117
118 # Calculate net debt: positive means lender is owed, negative means borrower is owed
119 # If lender already owes borrower, that reduces what lender is owed
120 # If borrower already owes lender, that increases what lender is owed
121 net_debt = amount - lender_owes_borrower + borrower_owes_lender
122
123 # Clear existing debts
124 if borrower_name in lender["owes"]:
125 del lender["owes"][borrower_name]
126 if lender_name in borrower["owes"]:
127 del borrower["owes"][lender_name]
128 if borrower_name in lender["owed_by"]:
129 del lender["owed_by"][borrower_name]
130 if lender_name in borrower["owed_by"]:
131 del borrower["owed_by"][lender_name]
132
133 # Set up new net debt
134 if net_debt > 0:
135 # Lender is owed money
136 lender["owed_by"][borrower_name] = net_debt
137 borrower["owes"][lender_name] = net_debt
138 elif net_debt < 0:
139 # Borrower is owed money (negative debt means lender owes)
140 lender["owes"][borrower_name] = -net_debt
141 borrower["owed_by"][lender_name] = -net_debt
142 # If net_debt == 0, no debts are created (both are cleared)
143
144 # Recalculate balances
145 lender_total_owed = sum(lender["owed_by"].values())
146 lender_total_owes = sum(lender["owes"].values())
147 lender["balance"] = lender_total_owed - lender_total_owes
148
149 borrower_total_owed = sum(borrower["owed_by"].values())
150 borrower_total_owes = sum(borrower["owes"].values())
151 borrower["balance"] = borrower_total_owed - borrower_total_owes
152
153 # Return updated users sorted by name
154 updated_users = [lender, borrower]
155 updated_users.sort(key=lambda x: x["name"])
156 return json.dumps({"users": updated_users})
157
158 # Recalculate balances
159 lender_total_owed = sum(lender["owed_by"].values())
160 lender_total_owes = sum(lender["owes"].values())
161 lender["balance"] = lender_total_owed - lender_total_owes
162
163 borrower_total_owed = sum(borrower["owed_by"].values())
164 borrower_total_owes = sum(borrower["owes"].values())
165 borrower["balance"] = borrower_total_owed - borrower_total_owes
166
167 # Return updated users sorted by name
168 updated_users = [lender, borrower]
169 updated_users.sort(key=lambda x: x["name"])
170 return json.dumps({"users": updated_users})
171
172 else:
173 # Edge Case: Handle invalid URL
174 return json.dumps({"error": "Invalid URL"})
175
176 # Handled Edge Cases: None database, invalid URL, invalid payload format, missing 'users' key, non-list 'users' value,
177 # non-existent users in payload, missing 'user' key, non-string user name, duplicate user,
178 # missing required keys in /iou, incorrect data types, negative amount, same lender and borrower,
179 # non-existent lender or borrower
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.