CodeGym /Courses /Java Collections /Big task: ATM software

Big task: ATM software

Java Collections
Level 9 , Lesson 15
Available

"Hi, Amigo!"

"Hello, Captain Squirrels, sir."

"You're a good student. Well done, soldier!"

"Today you have a new secret mission: master finances."

"Hooray!!! I already know what I'll spend the money on!!!"

"Don't relax yet, soldier! Mastering finances means writing a new secret ATM program.

Big task: ATM software - 1

"Go see Secret Agent IntelliJ IDEA. You'll receive all of the instructions there."

"It shall be done, Captain!"

10
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 1)
Let's write an ATM emulator. We will support the following operations: deposit money, withdraw money, and show the status of the ATM. We will also support multiple currencies. The ATM will operate using the banknotes we put into it.
10
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 2)
1. Create two static methods in ConsoleHelper: 1.1 writeMessage(String message), which will write our message to the console. 1.2 String readString(), which will read a string from the console and return it.
20
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 3)
1. Create CurrencyManipulator class that stores all the information about the selected currency. The class must have: 1.1 String currencyCode — currency code, i.e. USD. It consists of three letters. 1.2 Map denominations is a map of (denomination, quantity) pairs.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 4)
1. Let's decide what operation to start with. Think about it. The ATM doesn't have money yet, so we can't test INFO and WITHDRAW. We'll start with the DEPOSIT operation. We read the currency code from the console. Then we read the denomination and number of banknotes.
20
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 5)
1. In the previous task, we implemented the basic logic of the DEPOSIT operation. But we couldn't see the results. So, in the manipulator, create an int getTotalAmount() method that calculates the total amount for the selected currency. 2. Call the getTotalAmount() method in the main method.
20
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 6)
To refactor the code according to the Command pattern, you need to extract several logical blocks of code. For now, we have two such blocks: 1) code for the DEPOSIT operation, 2) code for the INFO operation. This code is in the main method. We need to get rid of it.
20
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 7)
Let's return to the Command pattern. 1. Create a command package. It will contain all classes with relevant logic. Think about the access modifier for each class in this package. 2. Create a Command interface with a void execute() method.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 8)
It's time to whip our main method into shape. It already has a bunch of stuff that shouldn't be there. 1. Move the logic from main to DepositCommand and InfoCommand. So what's happened to main? We have a loop, in which we ask the user for an operation and then call a method on the CommandExecutor.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 9)
Today we're going to tackle ExitCommand. 1. Implement the following logic in ExitCommand: 1.1. Ask whether the user really wants to exit. Provide the following options: yes (y) or no (n). 1.2. If the user confirms, then say goodbye.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 10)
Today we'll tackle WithdrawCommand. It's the most complex operation. 1. Implement the following algorithm for WithdrawCommand: 1.1. Read the currency code (the method already exists). 1.2. Get a manipulator for the specified currency.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 11)
Congratulations! You implemented WithdrawCommand! The main functionality is finished. Next you can do some polishing and make things pretty. Let's implement one sweet feature. We can get by without it, but it will make things more beautiful. I'm talking about verification of the user's credit card.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 12)
In part 11, we hardcoded the credit card number and PIN code used to allow working with our ATM. But we could have lots of users. We certainly won't hardcode them all! If we need to add another user, we would have to redeploy our application. There is a solution to this problem.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 13)
You've already figured out ResourceBundle! Cool! Now we can add localization, i.e. support for multiple languages. 1. In DepositCommand, ExitCommand, and InfoCommand, add a private ResourceBundle res field and initialize it with the appropriate resource.
40
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 14)
1. In LoginCommand and WithdrawCommand, add a private ResourceBundle res field and initialize it with the appropriate resource. For LoginCommand, use login_en.properties. For WithdrawCommand, use withdraw_en.properties. 2. Use common_en.properties to replace all the strings in ConsoleHelper.
10
Task
Java Collections, level 9, lesson 15
Locked
CashMachine (part 15)
1. In CashMachine, create a constant for the path to the resources. public static final String RESOURCE_PATH; Refactor the loading of all the ResourceBundles to use RESOURCE_PATH. 2. The CashMachine class should have no initialization of ResourceBundles.
Comments (11)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
matemate123 Level 50, Kraków, Poland
13 December 2023
This is the first project in which I haven't gotten pissed off even once. My favorite besides 2048 game and LogParser. Learning with pleasure.
matemate123 Level 50, Kraków, Poland
13 December 2023
PS: What is curious is that I had a bug in the WithdrawCommand class, which the validator didn't see. I found it by accident, when I test Strings from withdraw_en.properties. In my program for example if you deposit two banknotes 200 USD, you have 400 USD. When you want deposit 300 USD you have insufficient banknotes for that but next step if you ask about withdraw 400, ATM machine don't have money too! A bug was because in my public Map<Integer, Integer> withdrawAmount(int expectedAmount) method I had improper initialization temporary map:

Map<Integer, Integer> temp = denominations;
It change temp map when it try check if it can withdraw 300 USD but it point to the same object like denominations map. And when next ask to withdraw 400 which it must be possible in that situation, then occurs I have only one banknote 200, not two. In previous checking method I lost one banknote because I override denominations map. Initialization must be:

Map<Integer, Integer> temp = new TreeMap<>(Comparator.comparingInt(Integer::intValue).reversed());
        temp.putAll(denominations);
Code Gym bosses please restrict Validator for that problem.
Andrei Level 41
4 August 2021
Just finished this task. Very nice task, I really enjoyed it, I managed to do about 70-80% on my own which is quite a nice feeling. BUT boy oh boy, the validator on this thing is all over the place... the task seems to have been updated lately but the validator / solution have not been and they offer contradictory information. For example, on one task 2 conditions weren't validating. even though I made perfectly one of them, it still didn't validate that respective condition. However, when I did the second one then they both validated; which is quite confusing because at no time did the validator mention that the 2 conditions are dependent on each other. So this sends you into a spinning cycle of trying to find out what is wrong with that condition, if you are trying to do the conditions one after the other. Also, I spent about 10 minutes on the last task, because the validator wasn't accepting a condition that I had to resolve from a completely different class which was related to the class from the condition... it made me want to pull out the hair from my head.
Justin Smith Level 41, Greenfield, USA, United States
7 June 2023
I'm actually quite stuck at this time due to the validator. The program works as requested, but the validator crashes when tested. I think at this point I may just move one, hoping I have enough dark matter to get through the next chapter.
Andrei Level 41
9 June 2023
I've come to the conclusion that between 20 to 40 minutes of racking my brain for a task is sufficient to help the learning process. After that I'd just check the solution, try my best to understand it and then try to apply it without copy pasting it. This in time creates the correct way of thinking and solving problems gets easier because patterns start to form.
Justin Smith Level 41, Greenfield, USA, United States
9 June 2023
Yeah, I do the same. And when I do that, I make sure to type out the code instead of copy/pasting, to help commit it to memory better. Also I sometimes tweak it a little bit to fit my own coding style, as long as I'm not functionally changing the code.
MaGaby2280 Level 41, Guatemala City, Guatemala
2 August 2021
This was a hard task... lots of reading required... Took five days to complete it, but now it it time to move on thank God!
Denys Level 41, Ukraine
21 April 2021
14 task: Use "exact.amount.not.available" when you catch InsufficientFundsException. Use "not.enough.money" when !isAmountAvailable. You may have problems with WithdrawCommand connected with these two strings.
Juan Ma Level 41, Arauca, Colombia
4 July 2020
Task 9: In task 2 it says that InterruptedOperationException must be abstract, but to pass the third validator condition I had to remove it as abstract to pass. throw a new InterruptedOperationException (); instead of throw a new InterruptedOperationException () {};
fzw Level 41, West University Place, United States
13 May 2020
Task 10 We can't issue the same banknotes more than once, so if we find a valid option for issuing the money (item 2.1 is successful), then remove all these notes from the map in the manipulator. This does not mean we can only use at most 1 banknote of each domination to withdraw money! This simply means there is only one entry for each banknote in returned map.
Seb Level 41, Crefeld, Germany
28 February 2020
Not easy, but another really good task. Thanks, Captain! :-)