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 empty dict
6 self.database = database if database is not None else {"users": []}
7
58 def get(self, url: str, payload: str | None = None) -> str:
6 pass
7
9 # Edge Case: Handle invalid URL
10 if url != "/users":
11 return json.dumps({"error": "Invalid URL"})
12
13 # Parse payload if provided
14 if payload is not None:
15 try:
16 data = json.loads(payload)
17 except json.JSONDecodeError:
18 # Edge Case: Handle invalid JSON in payload
19 return json.dumps({"error": "Invalid JSON"})
20
21 # Edge Case: Handle missing 'users' key in payload
22 if "users" not in data:
23 return json.dumps({"error": "Missing users key"})
24
25 # Filter users based on provided list
26 user_names = data["users"]
27 users = [user for user in self.database["users"] if user["name"] in user_names]
28 # Sort by name
29 users.sort(key=lambda x: x["name"])
30 else:
31 # Return all users if no payload
32 users = self.database["users"].copy()
33 # Sort by name
34 users.sort(key=lambda x: x["name"])
35
36 return json.dumps({"users": users})
37 # Handled Edge Cases: Invalid URL, invalid JSON, missing 'users' key
38
839 def post(self, url: str, payload: str | None = None) -> str:
9 pass
40 # Edge Case: Handle missing payload
41 if payload is None:
42 return json.dumps({"error": "Payload required"})
43
44 # Parse payload
45 try:
46 data = json.loads(payload)
47 except json.JSONDecodeError:
48 # Edge Case: Handle invalid JSON in payload
49 return json.dumps({"error": "Invalid JSON"})
50
51 if url == "/add":
52 # Edge Case: Handle missing 'user' key
53 if "user" not in data:
54 return json.dumps({"error": "Missing user key"})
55
56 user_name = data["user"]
57
58 # Edge Case: Handle non-string user name
59 if not isinstance(user_name, str):
60 return json.dumps({"error": "User name must be a string"})
61
62 # Edge Case: Handle duplicate user - return existing user
63 for user in self.database["users"]:
64 if user["name"] == user_name:
65 return json.dumps(user)
66
67 # Create new user
68 new_user = {
69 "name": user_name,
70 "owes": {},
71 "owed_by": {},
72 "balance": 0.0
73 }
74
75 self.database["users"].append(new_user)
76 return json.dumps(new_user)
77 # Handled Edge Cases: Missing payload, invalid JSON, missing 'user' key, non-string user name, duplicate user
78
79 elif url == "/iou":
80 # Edge Case: Handle missing required keys
81 required_keys = ["lender", "borrower", "amount"]
82 for key in required_keys:
83 if key not in data:
84 return json.dumps({"error": f"Missing {key} key"})
85
86 lender_name = data["lender"]
87 borrower_name = data["borrower"]
88 amount = data["amount"]
89
90 # Edge Case: Handle non-string lender or borrower
91 if not isinstance(lender_name, str) or not isinstance(borrower_name, str):
92 return json.dumps({"error": "Lender and borrower must be strings"})
93
94 # Edge Case: Handle non-numeric amount
95 if not isinstance(amount, (int, float)):
96 return json.dumps({"error": "Amount must be a number"})
97
98 # Edge Case: Handle negative amount
99 if amount < 0:
100 return json.dumps({"error": "Amount must be positive"})
101
102 # Edge Case: Handle same lender and borrower
103 if lender_name == borrower_name:
104 return json.dumps({"error": "Lender and borrower cannot be the same"})
105
106 # Find lender and borrower
107 lender = None
108 borrower = None
109 for user in self.database["users"]:
110 if user["name"] == lender_name:
111 lender = user
112 elif user["name"] == borrower_name:
113 borrower = user
114
115 # Edge Case: Auto-create missing users
116 if lender is None:
117 lender = {
118 "name": lender_name,
119 "owes": {},
120 "owed_by": {},
121 "balance": 0.0
122 }
123 self.database["users"].append(lender)
124
125 if borrower is None:
126 borrower = {
127 "name": borrower_name,
128 "owes": {},
129 "owed_by": {},
130 "balance": 0.0
131 }
132 self.database["users"].append(borrower)
133
134 # Update owes and owed_by
135 # Update lender's owed_by
136 if borrower_name in lender["owed_by"]:
137 lender["owed_by"][borrower_name] += amount
138 else:
139 lender["owed_by"][borrower_name] = amount
140
141 # Update borrower's owes
142 if lender_name in borrower["owes"]:
143 borrower["owes"][lender_name] += amount
144 else:
145 borrower["owes"][lender_name] = amount
146
147 # Recalculate balances
148 lender_balance = 0.0
149 borrower_balance = 0.0
150
151 # Lender balance: amount owed by others minus amount owed to others
152 for owed_amount in lender["owed_by"].values():
153 lender_balance += owed_amount
154 for owes_amount in lender["owes"].values():
155 lender_balance -= owes_amount
156
157 # Borrower balance: amount owed by others minus amount owed to others
158 for owed_amount in borrower["owed_by"].values():
159 borrower_balance += owed_amount
160 for owes_amount in borrower["owes"].values():
161 borrower_balance -= owes_amount
162
163 lender["balance"] = lender_balance
164 borrower["balance"] = borrower_balance
165
166 # Return updated users, sorted by name
167 users = [lender, borrower]
168 users.sort(key=lambda x: x["name"])
169 return json.dumps({"users": users})
170 # Handled Edge Cases: Missing payload, invalid JSON, missing required keys, non-string lender/borrower,
171 # non-numeric amount, negative amount, same lender and borrower, lender or borrower not found
172
173 else:
174 # Edge Case: Handle invalid URL
175 return json.dumps({"error": "Invalid URL"})
176 # Handled Edge Cases: Invalid URL
177
178 def _get_user(self, name: str):
179 """Helper method to get a user by name"""
180 for user in self.database["users"]:
181 if user["name"] == name:
182 return user
183 return None
184 # Handled Edge Cases: User not found
Test NameStatus
test_lender_owes_borrower
Fail
test_lender_owes_borrower_less_than_new_loan
Fail
test_lender_owes_borrower_same_as_new_loan
Fail
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_no_users
Pass

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