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: Optional initial database dictionary containing 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 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 = sorted(self.database["users"], key=lambda u: u["name"])
34 result = {"users": users}
35 return json.dumps(result)
36 else:
37 # Return only specified users
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 # Filter users by name
46 users = [user for user in self.database["users"] if user["name"] in user_names]
47
48 # Edge Case: Some requested users don't exist
49 # Non-existent users are simply not included in the response
50
51 # Sort by name
52 users = sorted(users, key=lambda u: u["name"])
53 result = {"users": users}
54 return json.dumps(result)
55 else:
56 raise ValueError(f"Unknown GET URL: {url}")
57
58 # Handled Edge Cases: Empty user list in payload, Some requested users don't exist
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 JSON string response.
70
71 Raises:
72 ValueError: If the URL is not recognized or if required data is missing.
73 """
74 if url == "/add":
75 if payload is None:
76 raise ValueError("Payload required for /add")
77
78 data = json.loads(payload)
79 user_name = data.get("user")
80
81 # Edge Case: Missing user name in payload
82 if user_name is None:
83 raise ValueError("User name required in payload")
84
85 # Edge Case: User already exists
86 for user in self.database["users"]:
87 if user["name"] == user_name:
88 raise ValueError(f"User {user_name} already exists")
89
90 # Create new user
91 new_user = {
92 "name": user_name,
93 "owes": {},
94 "owed_by": {},
95 "balance": 0.0
96 }
97
98 self.database["users"].append(new_user)
99 return json.dumps(new_user)
100
101 elif url == "/iou":
102 if payload is None:
103 raise ValueError("Payload required for /iou")
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 # Find lender and borrower
119 lender = None
120 borrower = None
121
122 for user in self.database["users"]:
123 if user["name"] == lender_name:
124 lender = user
125 if user["name"] == borrower_name:
126 borrower = user
127
128 # Edge Case: Lender or borrower does not exist
129 if lender is None:
130 raise ValueError(f"Lender {lender_name} does not exist")
131 if borrower is None:
132 raise ValueError(f"Borrower {borrower_name} does not exist")
133
134 # Edge Case: Negative amount
135 if amount < 0:
136 raise ValueError("Amount must be non-negative")
137
138 # Update owes and owed_by
139 # Update lender's owed_by
140 if borrower_name in lender["owed_by"]:
141 lender["owed_by"][borrower_name] += amount
142 else:
143 lender["owed_by"][borrower_name] = amount
144
145 # Update borrower's owes
146 if lender_name in borrower["owes"]:
147 borrower["owes"][lender_name] += amount
148 else:
149 borrower["owes"][lender_name] = amount
150
151 # Recalculate balances
152 lender_total_owed = sum(lender["owed_by"].values())
153 lender_total_owes = sum(lender["owes"].values())
154 lender["balance"] = lender_total_owed - lender_total_owes
155
156 borrower_total_owed = sum(borrower["owed_by"].values())
157 borrower_total_owes = sum(borrower["owes"].values())
158 borrower["balance"] = borrower_total_owed - borrower_total_owes
159
160 # Prepare response with updated users
161 updated_users = sorted([lender, borrower], key=lambda u: u["name"])
162 result = {"users": updated_users}
163 return json.dumps(result)
164 else:
165 raise ValueError(f"Unknown POST URL: {url}")
166
167 # Handled Edge Cases: Missing user name in payload, User already exists,
168 # Missing required fields in payload, Lender and borrower are the same person,
169 # Lender or borrower does not exist, Negative amount
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.