viola

Finished
1import json
2
13class RestAPI:
24 def __init__(self, database: dict | None = None):
3 pass
4
5 """
6 Initialize the REST API with an optional database.
7
8 Args:
9 database: A dictionary containing initial user data.
10 """
11 if database is None:
12 self.database = {"users": []}
13 else:
14 self.database = database
15
516 def get(self, url: str, payload: str | None = None) -> str:
6 pass
7
17 """
18 Handle GET requests to the API.
19
20 Args:
21 url: The endpoint URL.
22 payload: Optional JSON payload.
23
24 Returns:
25 A JSON string response.
26
27 Raises:
28 ValueError: If the URL is not recognized.
29 """
30 if url == "/users":
31 if payload is None:
32 # Return all users sorted by name
33 users = [self._create_user_object(user) for user in self.database["users"]]
34 users.sort(key=lambda x: x["name"])
35 return json.dumps({"users": users})
36 else:
37 # Return specified users sorted by name
38 data = json.loads(payload)
39 user_names = data.get("users", [])
40
41 # Edge Case: Empty user list in payload
42 if not user_names:
43 return json.dumps({"users": []})
44
45 # Edge Case: Non-existent users in payload
46 users = []
47 for name in user_names:
48 user = self._find_user(name)
49 if user is not None:
50 users.append(self._create_user_object(user))
51
52 users.sort(key=lambda x: x["name"])
53 return json.dumps({"users": users})
54 else:
55 # Edge Case: Invalid URL
56 raise ValueError(f"Invalid URL: {url}")
57
58 # Handled Edge Cases: Empty user list in payload, Non-existent users in payload, Invalid URL
59
860 def post(self, url: str, payload: str | None = None) -> str:
9 pass
61 """
62 Handle POST requests to the API.
63
64 Args:
65 url: The endpoint URL.
66 payload: JSON payload.
67
68 Returns:
69 A JSON string response.
70
71 Raises:
72 ValueError: If the URL is not recognized or if there are issues with the payload.
73 """
74 if url == "/add":
75 if payload is None:
76 # Edge Case: Missing payload
77 raise ValueError("Payload is required for /add endpoint")
78
79 data = json.loads(payload)
80 user_name = data.get("user")
81
82 # Edge Case: Missing user name in payload
83 if user_name is None:
84 raise ValueError("User name is required in payload")
85
86 # Edge Case: User already exists
87 if self._find_user(user_name) is not None:
88 raise ValueError(f"User {user_name} already exists")
89
90 new_user = {
91 "name": user_name,
92 "owes": {},
93 "owed_by": {},
94 "balance": 0.0
95 }
96
97 self.database["users"].append(new_user)
98 return json.dumps(self._create_user_object(new_user))
99
100 elif url == "/iou":
101 if payload is None:
102 # Edge Case: Missing payload
103 raise ValueError("Payload is required for /iou endpoint")
104
105 data = json.loads(payload)
106 lender_name = data.get("lender")
107 borrower_name = data.get("borrower")
108 amount = data.get("amount")
109
110 # Edge Case: Missing required fields in payload
111 if lender_name is None or borrower_name is None or amount is None:
112 raise ValueError("Lender, borrower, and amount are required in payload")
113
114 # Edge Case: Lender and borrower are the same person
115 if lender_name == borrower_name:
116 raise ValueError("Lender and borrower cannot be the same person")
117
118 lender = self._find_user(lender_name)
119 borrower = self._find_user(borrower_name)
120
121 # Edge Case: Lender or borrower does not exist
122 if lender is None or borrower is None:
123 raise ValueError("Both lender and borrower must exist")
124
125 # Edge Case: Negative amount
126 if amount < 0:
127 raise ValueError("Amount must be non-negative")
128
129 # Update lender's owed_by
130 if borrower_name in lender["owed_by"]:
131 lender["owed_by"][borrower_name] += amount
132 else:
133 lender["owed_by"][borrower_name] = amount
134
135 # Update borrower's owes
136 if lender_name in borrower["owes"]:
137 borrower["owes"][lender_name] += amount
138 else:
139 borrower["owes"][lender_name] = amount
140
141 # Update balances
142 lender["balance"] += amount
143 borrower["balance"] -= amount
144
145 # Create response with updated user objects
146 updated_users = [
147 self._create_user_object(lender),
148 self._create_user_object(borrower)
149 ]
150 updated_users.sort(key=lambda x: x["name"])
151
152 return json.dumps({"users": updated_users})
153
154 else:
155 # Edge Case: Invalid URL
156 raise ValueError(f"Invalid URL: {url}")
157
158 # Handled Edge Cases: Missing payload, Missing user name in payload, User already exists,
159 # Missing required fields in payload, Lender and borrower are the same person,
160 # Lender or borrower does not exist, Negative amount, Invalid URL
161
162 def _find_user(self, name: str):
163 """
164 Find a user by name in the database.
165
166 Args:
167 name: The name of the user to find.
168
169 Returns:
170 The user dictionary if found, otherwise None.
171 """
172 for user in self.database["users"]:
173 if user["name"] == name:
174 return user
175 return None
176
177 def _create_user_object(self, user):
178 """
179 Create a user object for API responses.
180
181 Args:
182 user: The user dictionary from the database.
183
184 Returns:
185 A dictionary representing the user object for API responses.
186 """
187 # Calculate balance from owes and owed_by
188 total_owed = sum(user["owes"].values())
189 total_owed_by = sum(user["owed_by"].values())
190 balance = total_owed_by - total_owed
191
192 return {
193 "name": user["name"],
194 "owes": user["owes"],
195 "owed_by": user["owed_by"],
196 "balance": balance
197 }
198
199 # Handled Edge Cases: None in this helper function
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.