JiaYou

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 self.database = database if database is not None else {"users": []}
12
513 def get(self, url: str, payload: str | None = None) -> str:
6 pass
7
14 """
15 Handle GET requests to the API.
16
17 Args:
18 url: The endpoint URL.
19 payload: Optional JSON payload.
20
21 Returns:
22 A JSON string response.
23 """
24 if url == "/users":
25 if payload is None:
26 # Return all users sorted by name
27 users = sorted(self.database["users"], key=lambda x: x["name"])
28 return json.dumps({"users": users})
29 else:
30 # Return specified users sorted by name
31 data = json.loads(payload)
32 user_names = data.get("users", [])
33
34 # Edge Case: Empty user list in payload
35 if not user_names:
36 return json.dumps({"users": []})
37
38 # Filter users by name
39 users = [user for user in self.database["users"] if user["name"] in user_names]
40 users = sorted(users, key=lambda x: x["name"])
41
42 # Edge Case: Some requested users don't exist
43 # (We just return the ones that do exist)
44
45 return json.dumps({"users": users})
46
47 # Edge Case: Invalid URL
48 return json.dumps({"error": "Invalid URL"})
49
850 def post(self, url: str, payload: str | None = None) -> str:
9 pass
51 """
52 Handle POST requests to the API.
53
54 Args:
55 url: The endpoint URL.
56 payload: JSON payload.
57
58 Returns:
59 A JSON string response.
60 """
61 if payload is None:
62 # Edge Case: Missing payload
63 return json.dumps({"error": "Payload required"})
64
65 data = json.loads(payload)
66
67 if url == "/add":
68 user_name = data.get("user")
69
70 # Edge Case: Missing user name
71 if not user_name:
72 return json.dumps({"error": "User name required"})
73
74 # Edge Case: User already exists
75 for user in self.database["users"]:
76 if user["name"] == user_name:
77 return json.dumps({"error": "User 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 self.database["users"].append(new_user)
87
88 return json.dumps(new_user)
89
90 elif url == "/iou":
91 lender_name = data.get("lender")
92 borrower_name = data.get("borrower")
93 amount = data.get("amount")
94
95 # Edge Case: Missing required fields
96 if not lender_name or not borrower_name or amount is None:
97 return json.dumps({"error": "Lender, borrower, and amount required"})
98
99 # Edge Case: Lender and borrower are the same
100 if lender_name == borrower_name:
101 return json.dumps({"error": "Lender and borrower cannot be the same"})
102
103 # Edge Case: Negative amount
104 if amount < 0:
105 return json.dumps({"error": "Amount must be positive"})
106
107 # Find lender and borrower
108 lender = None
109 borrower = None
110
111 for user in self.database["users"]:
112 if user["name"] == lender_name:
113 lender = user
114 elif user["name"] == borrower_name:
115 borrower = user
116
117 # Edge Case: Lender or borrower doesn't exist
118 if lender is None or borrower is None:
119 return json.dumps({"error": "Lender or borrower does not exist"})
120
121 # Update owes/owed_by relationships
122 # Handle existing debts between lender and borrower
123
124 # Get existing amounts
125 existing_lender_owes = lender["owes"].get(borrower_name, 0)
126 existing_lender_owed_by = lender["owed_by"].get(borrower_name, 0)
127
128 # Calculate net amount owed from borrower to lender
129 # If lender already owes borrower, this reduces the debt
130 # If borrower already owes lender, this increases the debt
131 net_amount = amount - existing_lender_owes + existing_lender_owed_by
132
133 # Remove old entries
134 if borrower_name in lender["owes"]:
135 del lender["owes"][borrower_name]
136 if borrower_name in lender["owed_by"]:
137 del lender["owed_by"][borrower_name]
138 if lender_name in borrower["owes"]:
139 del borrower["owes"][lender_name]
140 if lender_name in borrower["owed_by"]:
141 del borrower["owed_by"][lender_name]
142
143 # Add new entries based on net amount
144 if net_amount > 0:
145 # Borrower owes lender (positive net amount)
146 lender["owed_by"][borrower_name] = net_amount
147 borrower["owes"][lender_name] = net_amount
148 elif net_amount < 0:
149 # Lender owes borrower (negative net amount)
150 lender["owes"][borrower_name] = -net_amount
151 borrower["owed_by"][lender_name] = -net_amount
152 # If net_amount == 0, no entries needed (debt cancelled out)
153
154 # Recalculate balances
155 lender_total_owed = sum(lender["owed_by"].values())
156 lender_total_owes = sum(lender["owes"].values())
157 lender["balance"] = lender_total_owed - lender_total_owes
158
159 borrower_total_owed = sum(borrower["owed_by"].values())
160 borrower_total_owes = sum(borrower["owes"].values())
161 borrower["balance"] = borrower_total_owed - borrower_total_owes
162
163 # Return updated users sorted by name
164 users = sorted([lender, borrower], key=lambda x: x["name"])
165 return json.dumps({"users": users})
166
167 # Edge Case: Invalid URL
168 return json.dumps({"error": "Invalid URL"})
169
170 # Handled Edge Cases: Invalid URL, Missing payload, Missing user name, User already exists, Missing required fields, Lender and borrower are the same, Negative amount, Lender or borrower doesn't exist
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.