This repository was archived by the owner on May 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 83
solved split wise #17
Open
gdsoumya
wants to merge
1
commit into
workattech:master
Choose a base branch
from
gdsoumya:solved_split_wise
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| package com.soumya.splitwise; | ||
|
|
||
| import java.util.*; | ||
|
|
||
| // ExpenseManager : Handles the User Registration and Book keeping tasks. Core functionality of Split Wise. | ||
| public class ExpenseManager { | ||
|
|
||
| private Map<String, User> users; // Map of registered Users, uid:User | ||
| private Map<String, Float> expenses; // Map of Expenses "uid_borrower uid_lender":amount | ||
| private int userCount; // Keeps count of registered users | ||
|
|
||
| // Default Constructor | ||
| public ExpenseManager() { | ||
| users = new HashMap<>(); | ||
| expenses = new HashMap<>(); | ||
| userCount = 0; | ||
| } | ||
|
|
||
| // Register Users | ||
| public void registerUser(String name, String email, String mob_no) { | ||
| userCount++; | ||
| String uid="u"+userCount; | ||
| users.put(uid, new User(uid,name,email,mob_no)); | ||
| } | ||
|
|
||
| // Display all registered Users | ||
| public void displayRegisteredUsers() { | ||
| if(users.size()==0) { | ||
| System.out.println("No Users Registgered"); | ||
| return; | ||
| } | ||
| System.out.println("UID\t\tNAME\t\tEMAIL\t\t\tMOBILE NO."); | ||
| users.forEach((key, value)->{ | ||
| System.out.println(value.getUid()+"\t\t"+value.getName()+"\t\t"+value.getEmail()+"\t\t"+value.getMob_no()); | ||
| }); | ||
| } | ||
|
|
||
| // Add new or update "uid_borrower uid_lender":amount entry in expenses | ||
| private void registerExpense(String uid_borrow, String uid_lend, float amt) { | ||
| // If uid_lend has previous entry of owing money to uid_borrow | ||
| String key=uid_lend+" "+uid_borrow; | ||
| if(expenses.containsKey(key)) { | ||
| expenses.put(key, expenses.get(key)-amt); | ||
| if(expenses.get(key)==0) | ||
| expenses.remove(key); | ||
| } | ||
| else { | ||
| // If uid_borrow has previous entry of owing money to uid_lend | ||
| key=uid_borrow+" "+uid_lend; | ||
| if(expenses.containsKey(key)) | ||
| expenses.put(key, expenses.get(key)+amt); | ||
| else // Create entry | ||
| expenses.put(key, amt); | ||
| if(expenses.get(key)==0) // If amount==0 delete expense entry from the map | ||
| expenses.remove(key); | ||
| } | ||
| } | ||
|
|
||
| // Display all expense entries | ||
| private void showAllBalances() { | ||
| if(expenses.size()==0) { | ||
| System.out.println("No balances"); | ||
| return; | ||
| } | ||
| expenses.forEach((key, value) -> { | ||
| String usrs[] = key.split(" "); | ||
| User user1 = users.get(usrs[0]), user2=users.get(usrs[1]); | ||
| float val=(float)(Math.round(Math.abs(value) * Math.pow(10, 2)) / Math.pow(10, 2)); | ||
| if(value>0) | ||
| System.out.println(user1.getName()+" owes "+user2.getName()+": "+val); | ||
| else | ||
| System.out.println(user2.getName()+" owes "+user1.getName()+": "+val); | ||
| }); | ||
| } | ||
|
|
||
| // Display expense entries for specific user | ||
| private void showBalanceForUser(String uid) { | ||
| if(!users.containsKey(uid)) { | ||
| System.out.println("ERROR: Unknown User !"); | ||
| return; | ||
| } | ||
| int flag[]= {0}; | ||
| expenses.forEach((key, value) -> { | ||
| if(!key.contains(uid)) | ||
| return; | ||
| flag[0]++; | ||
| String usrs[] = key.split(" "); | ||
| User user1 = users.get(usrs[0]), user2=users.get(usrs[1]); | ||
| if(value>0) | ||
| System.out.println(user1.getName()+" owes "+user2.getName()+": "+value); | ||
| else | ||
| System.out.println(user2.getName()+" owes "+user1.getName()+": "+Math.abs(value)); | ||
| }); | ||
| if(flag[0]==0) | ||
| System.out.println("No balances"); | ||
| } | ||
|
|
||
| // Handles EXACT distribution flow | ||
| private String exactDistribute(String expense[], String uid, float amt, int share_count, int indx) { | ||
| float sum=(float) 0.0; | ||
| for(int i=indx+1;i<=indx+share_count;i++) | ||
| sum+=Float.parseFloat(expense[i]); | ||
| if(sum!=amt) | ||
| return "ERROR: Expenses do not Add Up !"; | ||
| for(int i=1,uindx=3,pindx=indx;i<=share_count;i++) | ||
| if(!expense[uindx+i].equals(uid)) | ||
| registerExpense(expense[uindx+i],uid,Float.parseFloat(expense[pindx+i])); | ||
| return "UPDATED"; | ||
|
|
||
| } | ||
|
|
||
| // Handles EQUAL distribution flow | ||
| private String equalDistribute(String expense[], String uid, float amt, int share_count, int indx) { | ||
| float val=amt/share_count; | ||
| for(int uindx=4;uindx<4+share_count;uindx++) | ||
| if(!expense[uindx].equals(uid)) | ||
| registerExpense(expense[uindx],uid,val); | ||
| return "UPDATED"; | ||
| } | ||
|
|
||
| // Handles PERCENT distribution flow | ||
| private String percentDistribute(String expense[], String uid, float amt, int share_count, int indx) { | ||
| float sum=(float) 0.0; | ||
| for(int i=indx+1;i<=indx+share_count;i++) | ||
| sum+=Float.parseFloat(expense[i]); | ||
| if(sum!=100.0) | ||
| return "ERROR: Expenses do not Add Up !"; | ||
| for(int i=1,uindx=3,pindx=indx;i<=share_count;i++) { | ||
| float val=(float) (amt*1.0*Float.parseFloat(expense[pindx+i])/100); | ||
| if(!expense[uindx+i].equals(uid)) | ||
| registerExpense(expense[uindx+i],uid,val); | ||
| } | ||
| return "UPDATED"; | ||
|
|
||
| } | ||
|
|
||
| // Handles SHARE distribution flow | ||
| private String shareDistribute(String expense[], String uid, float amt, int share_count, int indx) { | ||
| float sum=(float) 0.0; | ||
| for(int i=indx+1;i<=indx+share_count;i++) | ||
| sum+=Float.parseFloat(expense[i]); | ||
| for(int i=1,uindx=3,pindx=indx;i<=share_count;i++) { | ||
| float val=(float) (amt*1.0*Float.parseFloat(expense[pindx+i])/sum); | ||
| if(!expense[uindx+i].equals(uid)) | ||
| registerExpense(expense[uindx+i],uid,val); | ||
| } | ||
| return "UPDATED"; | ||
|
|
||
| } | ||
|
|
||
| // Driver for the EXPENSE flow, also performs data validation | ||
| private String computeExpenses(String expense[]) { | ||
| try { | ||
| String uid_lend=expense[1]; | ||
| if(!users.containsKey(uid_lend)) | ||
| return "ERROR: Unknown UID- "+uid_lend+" !"; | ||
| float amt = Float.parseFloat(expense[2]); | ||
| int share_count=Integer.parseInt(expense[3]); | ||
| int indx=4+share_count; | ||
| for(int uindx=4;uindx<4+share_count;uindx++) | ||
| if(!users.containsKey(expense[uindx])) | ||
| return "ERROR: Unknown UID- "+expense[uindx]+" !"; | ||
| if(expense[indx].equalsIgnoreCase("EQUAL")) { | ||
| return equalDistribute(expense, uid_lend, amt, share_count, indx); | ||
| } | ||
| else if(expense[indx].equalsIgnoreCase("EXACT")) { | ||
| return exactDistribute(expense, uid_lend, amt, share_count, indx); | ||
| } | ||
| else if(expense[indx].equalsIgnoreCase("PERCENT")) { | ||
| return percentDistribute(expense, uid_lend, amt, share_count, indx); | ||
| } | ||
| else if(expense[indx].equalsIgnoreCase("SHARE")) { | ||
| return shareDistribute(expense, uid_lend, amt, share_count, indx); | ||
| } | ||
| else | ||
| return "ERROR: Unknown Expense Code !"; | ||
| } | ||
| catch(ArrayIndexOutOfBoundsException e) { | ||
| return "ERROR: Malformed Input !"; | ||
| } | ||
|
|
||
| } | ||
|
|
||
| // Handler to parse the requests and call appropriate functions | ||
| public void handleRequest(String request) { | ||
|
|
||
| /* --DEBUGGING PURPOSE-- | ||
| * | ||
| * System.out.println("HANDLING REQUEST FOR : "+request); | ||
| * System.out.println(expenses); | ||
| */ | ||
| String req[]=request.split(" "),resp=""; | ||
| if(req[0].equalsIgnoreCase("EXPENSE")) { | ||
| if(!(resp=computeExpenses(req)).equals("UPDATED")) | ||
| System.out.println(resp); | ||
| } | ||
| else if(req[0].equalsIgnoreCase("SHOW")) { | ||
| if(req.length==1) | ||
| showAllBalances(); | ||
| else if(req.length==2) | ||
| showBalanceForUser(req[1]); | ||
| else | ||
| System.out.println("ERROR: Malformed Input !"); | ||
| } | ||
| else | ||
| System.out.println("ERROR: Malformed Input !"); | ||
| } | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package com.soumya.splitwise; | ||
|
|
||
| // Driver Application | ||
| public class SplitWiseApp { | ||
|
|
||
| public static void main(String[] args) { | ||
| // Initializing ExpenseManager Object | ||
| ExpenseManager expman = new ExpenseManager(); | ||
|
|
||
| // Hard Coded Users | ||
| expman.registerUser("User1", "user1@hello.com", "+918685483458"); | ||
| expman.registerUser("User2", "user2@hello.com", "+918085483643"); | ||
| expman.registerUser("User3", "user3@hello.com", "+919056783458"); | ||
| expman.registerUser("User4", "user4@hello.com", "+919885434258"); | ||
|
|
||
| // Display Registered Users with UID | ||
| expman.displayRegisteredUsers(); | ||
|
|
||
| // TEST - Taken from SAMPLE INPUT Section | ||
| expman.handleRequest("SHOW"); | ||
| expman.handleRequest("SHOW u1"); | ||
| // EQUAL | ||
| expman.handleRequest("EXPENSE u1 1000 4 u1 u2 u3 u4 EQUAL"); | ||
| expman.handleRequest("SHOW u4"); | ||
| expman.handleRequest("SHOW u1"); | ||
| // EXACT | ||
| expman.handleRequest("EXPENSE u1 1250 2 u2 u3 EXACT 370 880"); | ||
| expman.handleRequest("SHOW"); | ||
| // PERCENT | ||
| expman.handleRequest("EXPENSE u4 1200 4 u1 u2 u3 u4 PERCENT 40 20 20 20"); | ||
| expman.handleRequest("SHOW u1"); | ||
| expman.handleRequest("SHOW"); | ||
| // SHARE | ||
| expman.handleRequest("EXPENSE u4 1200 4 u1 u2 u3 u4 SHARE 2 1 1 1"); | ||
| expman.handleRequest("SHOW"); | ||
| } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package com.soumya.splitwise; | ||
|
|
||
| // Defines the characteristics of a user | ||
| public class User { | ||
|
|
||
| private String name,uid,email,mob_no; | ||
|
|
||
| public User(String uid, String name, String email, String mob_no) { | ||
| super(); | ||
| this.name = name; | ||
| this.uid = uid; | ||
| this.email = email; | ||
| this.mob_no = mob_no; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public String getUid() { | ||
| return uid; | ||
| } | ||
|
|
||
| public void setUid(String uid) { | ||
| this.uid = uid; | ||
| } | ||
|
|
||
| public String getEmail() { | ||
| return email; | ||
| } | ||
|
|
||
| public void setEmail(String email) { | ||
| this.email = email; | ||
| } | ||
|
|
||
| public String getMob_no() { | ||
| return mob_no; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use either camelCase or underscore_separated. not both. For java, best to go with camelCase |
||
| } | ||
|
|
||
| public void setMob_no(String mob_no) { | ||
| this.mob_no = mob_no; | ||
| } | ||
|
|
||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid variable names like expman