hope

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 # Handle GET requests to /users endpoint
10 if url == "/users":
11 # Edge Case: Handle when no payload is provided - return all users
12 if payload is None:
13 # Create a copy of users to avoid modifying original data
14 users_copy = []
15 for user in self.database["users"]:
16 users_copy.append(self._create_user_response(user))
17 return json.dumps({"users": users_copy})
18
19 # Edge Case: Handle when payload is provided but not valid JSON
20 try:
21 data = json.loads(payload)
22 except json.JSONDecodeError:
23 return json.dumps({"error": "Invalid JSON payload"})
24
25 # Edge Case: Handle when 'users' key is missing from payload
26 if "users" not in data:
27 return json.dumps({"error": "Missing 'users' key in payload"})
28
29 # Edge Case: Handle when 'users' is not a list
30 if not isinstance(data["users"], list):
31 return json.dumps({"error": "'users' must be a list"})
32
33 # Filter users based on the requested names
34 requested_names = data["users"]
35 filtered_users = []
36
37 # Edge Case: Handle when requested user doesn't exist
38 for name in requested_names:
39 user = self._find_user(name)
40 if user is not None:
41 filtered_users.append(self._create_user_response(user))
42
43 # Sort users by name
44 filtered_users.sort(key=lambda u: u["name"])
45 return json.dumps({"users": filtered_users})
46
47 # Edge Case: Handle unknown endpoints
48 return json.dumps({"error": "Endpoint not found"})
49
850 def post(self, url: str, payload: str | None = None) -> str:
9 pass
51 # Handle POST requests to /add and /iou endpoints
52 if payload is None:
53 return json.dumps({"error": "Payload required"})
54
55 # Edge Case: Handle when payload is not valid JSON
56 try:
57 data = json.loads(payload)
58 except json.JSONDecodeError:
59 return json.dumps({"error": "Invalid JSON payload"})
60
61 if url == "/add":
62 # Edge Case: Handle when 'user' key is missing
63 if "user" not in data:
64 return json.dumps({"error": "Missing 'user' key"})
65
66 user_name = data["user"]
67
68 # Edge Case: Handle when user already exists
69 if self._find_user(user_name) is not None:
70 return json.dumps({"error": "User already exists"})
71
72 # Create new user
73 new_user = {
74 "name": user_name,
75 "owes": {},
76 "owed_by": {},
77 "balance": 0.0
78 }
79
80 self.database["users"].append(new_user)
81 return json.dumps(self._create_user_response(new_user))
82
83 elif url == "/iou":
84 # Edge Case: Handle missing required keys
85 required_keys = ["lender", "borrower", "amount"]
86 for key in required_keys:
87 if key not in data:
88 return json.dumps({"error": f"Missing '{key}' key"})
89
90 lender_name = data["lender"]
91 borrower_name = data["borrower"]
92 amount = data["amount"]
93
94 # Edge Case: Handle when amount is not a number
95 if not isinstance(amount, (int, float)):
96 return json.dumps({"error": "Amount must be a number"})
97
98 # Edge Case: Handle when amount is negative
99 if amount < 0:
100 return json.dumps({"error": "Amount must be positive"})
101
102 # Edge Case: Handle when lender or borrower doesn't exist
103 lender = self._find_user(lender_name)
104 borrower = self._find_user(borrower_name)
105
106 if lender is None or borrower is None:
107 return json.dumps({"error": "Both lender and borrower must exist"})
108
109 # Edge Case: Handle when lender and borrower are the same person
110 if lender_name == borrower_name:
111 return json.dumps({"error": "Lender and borrower cannot be the same person"})
112
113 # Update IOU records
114 # Update lender's owed_by
115 if borrower_name in lender["owed_by"]:
116 lender["owed_by"][borrower_name] += amount
117 else:
118 lender["owed_by"][borrower_name] = amount
119
120 # Update borrower's owes
121 if lender_name in borrower["owes"]:
122 borrower["owes"][lender_name] += amount
123 else:
124 borrower["owes"][lender_name] = amount
125
126 # Update balances
127 lender["balance"] += amount
128 borrower["balance"] -= amount
129
130 # Return updated user information
131 updated_users = [
132 self._create_user_response(lender),
133 self._create_user_response(borrower)
134 ]
135 updated_users.sort(key=lambda u: u["name"])
136
137 return json.dumps({"users": updated_users})
138
139 # Edge Case: Handle unknown endpoints
140 return json.dumps({"error": "Endpoint not found"})
141
142 def _find_user(self, name: str):
143 # Helper method to find a user by name
144 for user in self.database["users"]:
145 if user["name"] == name:
146 return user
147 return None
148
149 def _create_user_response(self, user: dict) -> dict:
150 # Helper method to create a user response object
151 # Calculate balance from owes and owed_by
152 total_owed = sum(user["owes"].values())
153 total_owed_by = sum(user["owed_by"].values())
154 balance = total_owed_by - total_owed
155
156 return {
157 "name": user["name"],
158 "owes": user["owes"],
159 "owed_by": user["owed_by"],
160 "balance": balance
161 }
162 # Handled Edge Cases: Initialization with None database, GET /users with no payload, GET /users with invalid JSON, GET /users missing 'users' key, GET /users with non-list 'users', GET /users with non-existent user, GET unknown endpoint, POST with no payload, POST with invalid JSON, POST /add missing 'user' key, POST /add user already exists, POST /iou missing keys, POST /iou non-numeric amount, POST /iou negative amount, POST /iou non-existent user, POST /iou lender equals borrower, POST unknown endpoint
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.