future

Finished
1import json
2
13class RestAPI:
24 def __init__(self, database: dict | None = None):
3 pass
4
5 """
6 Initialize the REST API with a database.
7
8 Args:
9 database: A dictionary containing user data.
10 """
11 # Edge Case: Handle None database by initializing empty users list
12 self.database = database if database is not None else {"users": []}
13
514 def get(self, url: str, payload: str | None = None) -> str:
6 pass
7
15 """
16 Handle GET requests to the API.
17
18 Args:
19 url: The endpoint URL.
20 payload: Optional JSON payload.
21
22 Returns:
23 JSON string response.
24
25 Raises:
26 ValueError: If URL is not recognized.
27 """
28 # Edge Case: Handle /users endpoint
29 if url == "/users":
30 # Edge Case: Handle payload with specific users
31 if payload is not None:
32 data = json.loads(payload)
33 if "users" in data:
34 # Filter users and sort by name
35 users = [user for user in self.database["users"] if user["name"] in data["users"]]
36 users.sort(key=lambda x: x["name"])
37 return json.dumps({"users": users})
38 # Edge Case: Handle no payload (return all users)
39 users = sorted(self.database["users"], key=lambda x: x["name"])
40 return json.dumps({"users": users})
41 # Edge Case: Handle unknown URL
42 else:
43 raise ValueError(f"Unknown URL: {url}")
44 # Handled Edge Cases: /users endpoint, payload filtering, sorting, unknown URL
45
846 def post(self, url: str, payload: str | None = None) -> str:
9 pass
47 """
48 Handle POST requests to the API.
49
50 Args:
51 url: The endpoint URL.
52 payload: JSON payload.
53
54 Returns:
55 JSON string response.
56
57 Raises:
58 ValueError: If URL is not recognized or if there are validation errors.
59 """
60 # Edge Case: Handle missing payload
61 if payload is None:
62 raise ValueError("Payload is required")
63
64 data = json.loads(payload)
65
66 # Edge Case: Handle /add endpoint
67 if url == "/add":
68 # Edge Case: Handle missing user field
69 if "user" not in data:
70 raise ValueError("User field is required")
71
72 user_name = data["user"]
73
74 # Edge Case: Handle duplicate user
75 for user in self.database["users"]:
76 if user["name"] == user_name:
77 raise ValueError(f"User {user_name} already exists")
78
79 # Create new user
80 new_user = {
81 "name": user_name,
82 "owes": {},
83 "owed_by": {},
84 "balance": 0.0
85 }
86
87 self.database["users"].append(new_user)
88 return json.dumps(new_user)
89
90 # Edge Case: Handle /iou endpoint
91 elif url == "/iou":
92 # Edge Case: Handle missing required fields
93 required_fields = ["lender", "borrower", "amount"]
94 for field in required_fields:
95 if field not in data:
96 raise ValueError(f"Missing required field: {field}")
97
98 lender_name = data["lender"]
99 borrower_name = data["borrower"]
100 amount = data["amount"]
101
102 # Edge Case: Handle negative amount
103 if amount < 0:
104 raise ValueError("Amount must be non-negative")
105
106 # Edge Case: Handle same lender and borrower
107 if lender_name == borrower_name:
108 raise ValueError("Lender and borrower cannot be the same")
109
110 # Find lender and borrower
111 lender = None
112 borrower = None
113
114 for user in self.database["users"]:
115 if user["name"] == lender_name:
116 lender = user
117 elif user["name"] == borrower_name:
118 borrower = user
119
120 # Edge Case: Handle lender not found
121 if lender is None:
122 raise ValueError(f"User {lender_name} not found")
123
124 # Edge Case: Handle borrower not found
125 if borrower is None:
126 raise ValueError(f"User {borrower_name} not found")
127
128 # Handle debt offsetting logic for IOU creation
129 # When lender lends borrower amount, check for existing debt relationships
130
131 # Check if there's an existing debt relationship between lender and borrower
132 # If borrower already owes lender, this IOU cancels that debt
133 if lender_name in borrower["owes"] and borrower_name in lender["owed_by"]:
134 existing_debt = borrower["owes"][lender_name]
135 if existing_debt > amount:
136 # Existing debt is larger than IOU amount - reduce debt
137 borrower["owes"][lender_name] = existing_debt - amount
138 lender["owed_by"][borrower_name] = existing_debt - amount
139 elif existing_debt == amount:
140 # Existing debt equals IOU amount - cancel completely
141 del borrower["owes"][lender_name]
142 del lender["owed_by"][borrower_name]
143 else:
144 # Existing debt is smaller than IOU amount - reverse relationship
145 amount_diff = amount - existing_debt
146 del borrower["owes"][lender_name]
147 del lender["owed_by"][borrower_name]
148 lender["owes"][borrower_name] = amount_diff
149 borrower["owed_by"][lender_name] = amount_diff
150 # If lender already owes borrower, this IOU cancels that debt
151 elif borrower_name in lender["owes"] and lender_name in borrower["owed_by"]:
152 existing_debt = lender["owes"][borrower_name]
153 if existing_debt > amount:
154 # Existing debt is larger than IOU amount - reduce debt
155 lender["owes"][borrower_name] = existing_debt - amount
156 borrower["owed_by"][lender_name] = existing_debt - amount
157 elif existing_debt == amount:
158 # Existing debt equals IOU amount - cancel completely
159 del lender["owes"][borrower_name]
160 del borrower["owed_by"][lender_name]
161 else:
162 # Existing debt is smaller than IOU amount - reverse relationship
163 amount_diff = amount - existing_debt
164 del lender["owes"][borrower_name]
165 del borrower["owed_by"][lender_name]
166 lender["owed_by"][borrower_name] = amount_diff
167 borrower["owes"][lender_name] = amount_diff
168 # No existing relationship - create new debt (borrower owes lender)
169 else:
170 lender["owed_by"][borrower_name] = amount
171 borrower["owes"][lender_name] = amount
172
173 # Recalculate balances
174 lender_total_owed = sum(lender["owed_by"].values())
175 lender_total_owes = sum(lender["owes"].values())
176 lender["balance"] = lender_total_owed - lender_total_owes
177
178 borrower_total_owed = sum(borrower["owed_by"].values())
179 borrower_total_owes = sum(borrower["owes"].values())
180 borrower["balance"] = borrower_total_owed - borrower_total_owes
181
182 # Return updated users sorted by name
183 users = [lender, borrower]
184 users.sort(key=lambda x: x["name"])
185 return json.dumps({"users": users})
186
187 # Edge Case: Handle unknown URL
188 else:
189 raise ValueError(f"Unknown URL: {url}")
190 # Handled Edge Cases: /add endpoint, /iou endpoint, missing payload, missing fields,
191 # duplicate user, negative amount, same lender/borrower,
192 # user not found, unknown URL
193# Handled Edge Cases: None database, /users endpoint, payload filtering, sorting, unknown URL
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.