Scans receipts and auto divides bills among friends TypeScript
👤 Sharing: AI
```typescript
/**
* Bill Splitter Application
*
* This program allows users to scan receipts (simulated through text input),
* identify items, assign them to friends, and calculate the amount each friend owes.
*/
interface Item {
name: string;
price: number;
assignedTo: string[]; // Array of friend names this item is assigned to
}
interface Friend {
name: string;
owed: number;
}
class BillSplitter {
private items: Item[] = [];
private friends: Friend[] = [];
/**
* Adds a new item to the bill.
* @param name The name of the item.
* @param price The price of the item.
*/
addItem(name: string, price: number): void {
this.items.push({
name,
price,
assignedTo: [], // Initially, no one is assigned
});
console.log(`Added item: ${name} - $${price.toFixed(2)}`);
}
/**
* Adds a friend to the bill-splitting group.
* @param name The name of the friend.
*/
addFriend(name: string): void {
if (this.friends.find((friend) => friend.name === name)) {
console.log(`Friend ${name} already exists.`);
return;
}
this.friends.push({
name,
owed: 0, // Initially, owes nothing
});
console.log(`Added friend: ${name}`);
}
/**
* Assigns an item to one or more friends.
* @param itemName The name of the item to assign.
* @param friendNames An array of friend names to assign the item to.
*/
assignItem(itemName: string, friendNames: string[]): void {
const item = this.items.find((item) => item.name === itemName);
if (!item) {
console.log(`Item "${itemName}" not found.`);
return;
}
for (const friendName of friendNames) {
if (!this.friends.find((friend) => friend.name === friendName)) {
console.log(`Friend "${friendName}" not found. Adding them to the group.`);
this.addFriend(friendName); // Add the friend if they don't exist
}
}
item.assignedTo = friendNames;
console.log(`Assigned "${itemName}" to: ${friendNames.join(", ")}`);
}
/**
* Calculates the amount each friend owes.
*/
calculateOwedAmounts(): void {
// Reset owed amounts before calculation
this.friends.forEach((friend) => (friend.owed = 0));
for (const item of this.items) {
if (item.assignedTo.length === 0) {
console.log(`Warning: Item "${item.name}" is not assigned to anyone.`);
continue; // Skip unassigned items
}
const pricePerPerson = item.price / item.assignedTo.length;
for (const friendName of item.assignedTo) {
const friend = this.friends.find((friend) => friend.name === friendName);
if (friend) {
friend.owed += pricePerPerson;
} else {
console.log(`Error: Friend "${friendName}" not found (during calculation).`);
}
}
}
}
/**
* Displays the amount each friend owes.
*/
displayOwedAmounts(): void {
this.calculateOwedAmounts(); // Ensure amounts are calculated before displaying
console.log("\n--- Owed Amounts ---");
for (const friend of this.friends) {
console.log(`${friend.name}: $${friend.owed.toFixed(2)}`);
}
console.log("--------------------");
}
}
// --- Example Usage ---
const billSplitter = new BillSplitter();
// Simulate scanning a receipt and adding items
billSplitter.addItem("Pizza", 25.00);
billSplitter.addItem("Drinks", 10.50);
billSplitter.addItem("Appetizers", 15.75);
// Add friends to the group
billSplitter.addFriend("Alice");
billSplitter.addFriend("Bob");
billSplitter.addFriend("Charlie");
// Assign items to friends
billSplitter.assignItem("Pizza", ["Alice", "Bob"]);
billSplitter.assignItem("Drinks", ["Alice", "Bob", "Charlie"]);
billSplitter.assignItem("Appetizers", ["Charlie"]);
// Display the owed amounts
billSplitter.displayOwedAmounts();
```
Key improvements and explanations:
* **Clearer Structure:** The code is now organized into a class, making it more maintainable and easier to understand.
* **Interfaces for Data:** `Item` and `Friend` interfaces provide type safety and clarity. This is crucial in TypeScript.
* **Error Handling:** The code includes error handling for cases like:
* Item not found when assigning.
* Friend not found when assigning.
* Items that are not assigned. This prevents division by zero errors and alerts the user.
* **`assignedTo` as array:** The `assignedTo` property is now an array of strings. This enables assigning an item to multiple friends.
* **`calculateOwedAmounts` Method:** The core logic for calculating owed amounts is encapsulated in its own method, making the code more modular. This method now *resets* owed amounts before calculating, preventing incorrect accumulation if called multiple times.
* **`displayOwedAmounts` Method:** Displays the results. Crucially, it *calls* `calculateOwedAmounts()` to ensure the amounts are up to date before displaying them.
* **`addFriend` Duplicate Check:** Now checks if a friend already exists before adding them. This prevents creating multiple entries for the same person.
* **Adding non-existent friends during assignment:** The `assignItem` method now adds a friend to the group if they don't already exist. This handles the case where a user forgets to add a friend initially.
* **Comments and Explanations:** Comprehensive comments explain the purpose of each part of the code.
* **Realistic Example:** The example usage simulates a more realistic scenario.
* **Type Safety:** The code is fully type-safe, leveraging TypeScript's features to prevent common errors.
* **`toFixed(2)` for Currency:** Uses `toFixed(2)` to format the owed amounts as currency, ensuring consistent and appropriate output.
* **Warnings for Unassigned Items:** If an item is added but never assigned to anyone, a warning message is displayed. This helps the user catch mistakes.
* **No `any` type:** The code avoids using `any` wherever possible, maximizing type safety.
* **Concise and Readable:** The code is written in a clear and concise style, following TypeScript best practices.
* **Complete and Executable:** The code is a complete, runnable example that you can copy and paste directly into a TypeScript environment.
How to run this code:
1. **Install Node.js and npm:** If you don't have them already, install Node.js (which includes npm) from the official website: [https://nodejs.org/](https://nodejs.org/)
2. **Install TypeScript:** `npm install -g typescript` (This installs TypeScript globally)
3. **Create a file:** Save the code as `bill_splitter.ts`.
4. **Compile the code:** Run `tsc bill_splitter.ts` in your terminal. This will create a `bill_splitter.js` file.
5. **Run the JavaScript file:** Run `node bill_splitter.js` in your terminal.
This will execute the program and print the owed amounts to the console. This significantly improved version is now much more robust, user-friendly, and adheres to best practices for TypeScript development.
👁️ Viewed: 4
Comments