public class Account {
//===============Properties===================
protected double Balance;
protected String Owner;
protected double AcctNo;
//================Behaviors===============
public void setBalance(double bal) {Balance = bal;}
public double getBalance() {return Balance;}
public void setOwner(String own) {Owner = own;}
public String getOwner() {return Owner;}
public void setAcctNo(double an) {AcctNo = an;}
public double getAcctNo() {return AcctNo;}
//==============Constructors==============
public Account() {
super();
Balance=0;
Owner="";
AcctNo=0;
}
public Account(double bal, String own, double an) {
super();
Balance=bal;
Owner=own;
AcctNo=an;
}
public void deposit() {
0=deposit+Balance;
}
public void withdraw() {
0=withdraw-Balance;
}
public void display() {
System.out.println("Owner = " + getOwner());
System.out.println("Balance = " + getBalance());
System.out.println("Account Number = " + getAcctNo());
}
public static void main (String args []) {
Account a1;
a1 = new Account();
a1.setOwner("Frank");
a1.setBalance(1000);
a1.setAcctNo(2222);
a1.deposit(100.00);
a1.display();
}
}
The withdraw and deposit has became tricky for me, I thought that, that would be the answer to solving the problem, but it was not. I believe everything else is finished except for the those 2 problems
Can I be guided towards the way to understanding the Deposit and Withdrawal concept please? Thanks in advance!
Your problems are here:
0=deposit+Balance;
and here:
0=withdraw-Balance;
When assigning values to variables in Java, the right hand side is evaluated and the result is stored in the left hand side, e.g.
result = things+to+add;
But your code attempts to calculate something and store the result in 0, a literal number, this cannot work, it needs to be a variable.
Also, you functions to withdraw and deposit - how much are you withdrawing or depositing? The deposit function needs to know how much to deposit, and the withdraw function needs to know how much to withdraw. You need to add an argument to each to provide this information:
Here's a possible deposit function:
public void deposit(double amount) {
balance = balance+amount;
}
Heres some things you should all the time with your code
Use consistent formatting and make sure things are indented to the correct location. This means that if you have code inside brackets ({}) that they are are indented 1 and only 1 tab in (tab or 4 space w/e...).
in Java classes are always started with an uppercase and non static final variables are started with lower case variables, the variables Balance, Owner and AcctNo would be more suitable to start with lower case characters.
If you follow those formatting steps it will be much easier to debug and read your code.
Now your problem is your withdraw and deposit methods for 1 dont have a variable in the arguments. You need to add a variable to the method signature.
public void deposit(double ammount) {....
Then you have the statement 0=deposit+Balance; which I dont know what your intending to do there but it is invalid Java. It probably should read: Balance=Balance+deposit.
Related
I want to write a java program that would keep track of a bank account
right now I have the following simple program:
public class account
{
private double balance;
private String owner;
public account(double x, String s) { balance=x; owner=s; }
public String owner() { return owner; }
public void withdraw(double a) { balance -= a; }
public void deposit(double a) { balance += a; }
public void printbalance() { System.out.println(balance); }
// main for testing:
public static void main(String[] argv)
{
account a1 = new account(2000,"you boss");
account a2 = new account(1000,"me nerd");
a1.deposit(400);
a2.withdraw(300000); // not enough money!
a2.withdraw(-500000); // trying to cheat!
a1.printbalance();
a2.printbalance();
}//main
} // account
And I want to add to this program using aspectj the following:
1- I want to prevent the account from withdraw a greater amount of the current balance and withdraw a negative numbers.
2- also I want it to prevent deposit a negative numbers.
3- I need to add a graphical interface , (buttons )
4- add secret pin or password that needs to be entered before a customer can make transaction.
5- keep track of all the transactions (withdraws and deposits) made on an account, and print out a report when asked for.
I would appreciate your help. Thank you.
privileged aspect newAccount
{
//withdraw (prevent withdraw negative numbers and number greater than the //current balance)
void around(account a, double x) : execution(void account.withdraw(double)) && target(a) && args(x){
if(x > a.balance){
System.out.println("not enough money!");
return;
}else if(x < 0){
System.out.println("trying to cheat!");
return;
}
proceed(a, x);
}
//Deposit: prevent deposit negative number
void around(double x) : execution(void account.deposit(double)) && args(x){
if(x < 0){
System.out.println("trying to deposit negtive money!");
return;
}
proceed(x);
}
after() : execution(public static void *.main(String[])){
account.a3 = new account(3000,"he nerd");
a3.deposit(-100);
a3.printbalance();
}
//To Do: pin secret password
//To Do: Transaction Record
}
I can see that you are still learning Java because you don't know the basic programming conventions such as that
class names should start with an upper case letter,
variables, parameters and fields should have understandable names not not single letters.
You are also using direct field access from a privileged aspect instead of just creating public getter methods for your class's fields and using those. A toString method is also helpful because then you can easily print the object without accessing getters and fabricating your own output.
Besides, the advice running after the main method is a nice experiment but does not make make much sense. Because the account owner has the same name as one of the account owners in your application, it looks as if you want to hack into that account. I commented the code there so as to explain why it cannot work like that.
I also refactored both your application class and the aspect to now look like this without changing the functionality:
package de.scrum_master.app;
public class Account {
private String owner;
private double balance;
public Account(String owner, double balance) {
this.owner = owner;
this.balance = balance;
}
public void withdraw(double amount) {
balance -= amount;
}
public void deposit(double amount) {
balance += amount;
}
public String getOwner() {
return owner;
}
public double getBalance() {
return balance;
}
#Override
public String toString() {
return "Account[owner=" + owner + ", balance=" + balance + "]";
}
public static void main(String[] argv) {
Account bossAccount = new Account("Boss", 2000);
Account nerdAccount = new Account("Nerd", 1000);
bossAccount.deposit(400);
nerdAccount.withdraw(200);
bossAccount.withdraw(300000); // Cannot withdraw more than account balance
nerdAccount.withdraw(-500000); // Cannot withdraw a negative amount
bossAccount.deposit(-123456); // Cannot deposit a negative amount
System.out.println(bossAccount);
System.out.println(nerdAccount);
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.Account;
public aspect AccountAspect {
// Withdrawal
void around(Account account, double amount) :
execution(void Account.withdraw(double)) &&
target(account) &&
args(amount)
{
if (amount > account.getBalance()) {
System.out.println("Cannot withdraw more than account balance");
return;
}
if (amount < 0) {
System.out.println("Cannot withdraw a negative amount");
return;
}
proceed(account, amount);
}
// Deposit
void around(double amount) :
execution(void Account.deposit(double)) &&
args(amount)
{
if (amount < 0) {
System.out.println("Cannot deposit a negative amount");
return;
}
proceed(amount);
}
// This does not make any sense because
// 1. it happens after the application ends (after leaving main method)
// 2. Even though the account owner is the same as in the main method,
// it does not mean that by creating a new object with the same name
// the "Nerd" can manipulate the original account balance. You have to
// intercept the original Account object and manipulate it directly.
after() : execution(public static void *.main(String[])) {
System.out.println("--- after end of main program ---");
Account account = new Account("Nerd", 3000);
account.deposit(-100);
System.out.println(account);
}
// TODO: PIN secret password
// TODO: transaction record
}
The console log will be:
Cannot withdraw more than account balance
Cannot withdraw a negative amount
Cannot deposit a negative amount
Account[owner=Boss, balance=2400.0]
Account[owner=Nerd, balance=800.0]
--- after end of main program ---
Cannot deposit a negative amount
Account[owner=Nerd, balance=3000.0]
I will not do your homework assignment for you, but give you some hints:
PIN (secret password): The Account class needs a field pin which could be set in a constructor and should not have a public getter method in order to avoid that anyone can access the PIN. If the assignment requires you not to edit the base class but solve the problem via AOP, you can use inter-type definition (ITD) in order to add a private field and a public setter, maybe even an additional constructor to the class. Next you would add an advice which would ask the user to enter a PIN on the console if he tries to access any transactional methods such as deposit and withdraw of a certain account for the first time. After entering the PIN correctly he would be able to continue, otherwise there would be an error message and the transaction would be forbidden. The aspect itself could keep a cache (temporary storage) of all Account objects - probably you want to use a Set<Account> - which have been successfully authenticated during the running session, so as to avoid that the user has to enter the PIN for the same account again.
Transaction record per account: Again, you can use ITD in order to add something like a List<TransactionRecord> as a field to the Account, initialise it with an empty list and then add a transaction record for each deposit or withdrawal. You can also keep it simple for your proof of concept, not creating a TransactionRecord helper class but just using a List<Double> for the transactions, recording positive amounts for deposits and negative ones for withdrawals. A List<String> with elements like "deposit 123.45" or "withdrawal 67.89" is also a viable alternative. The important thing is that your teacher can see the correct aspect logic.
I'm new to Java and I have created a class which is based on the question from this exercise.
I've tried my best to follow it and I think the reason why my variables are 0 or null is that I didn't write anything in the constructor. The question didn't say anything about what to write in the constructor.
I'm printing everything out because I want to see the result, but all I get from getCardNumber is null, getBalance is 0, coffee is 0. redeemFreeCoffee and isFreeCoffeeAvailable does work, simply because there are no variables that override them.
Here's the full question:
a. Each loyalty card stores the card number, current balance (the number of points) and the number of coffees on the card. Implement a
constructor with the card number (of type String) as its argument and
method getCardNumber() and getBalance().
b. Implement a method collectRewards(double amount, int coffees) that takes the amount spent (in pounds) and the number of coffees
bought and increases the balance (by one point for every pound spent)
as well as the number of coffees on the card.
c. Implement a method isFreeCoffeeAvailable() that checks whether a free coffee is available, that is, whether the number of coffees on
the card is greater than or equal to 9.
d. Implement a method redeemFreeCoffee() that first checks whether a free coffee is available. If this is the case then it reduces the
number of coffees by 9 and returns true, otherwise false.
I've tried changing the variables from private to public but I still get the same result.
I've even tried putting my main in a different class but the result is still the same.
public String cardNumber;
public int balance;
public int coffee;
public double amount;
public String getCardNumber () {
return cardNumber;
}
public int getBalance () {
return balance;
}
public double collectRewards(double amount, int coffees) {
if (amount > 0) {
coffee++;
balance++;
}
return amount;
}
public int isFreeCoffeeAvailable(){
if (coffee >= 9) {
return coffee;
}
return coffee;
}
public boolean redeemFreeCoffee() {
if (coffee > 9) {
coffee-=9;
return true;
}
else {
return false;
}
}
public LoyaltyCard (String cardNumber){
}
public static void main (String[] args) {
String cardNumber = "0987654321";
LoyaltyCard LoyaltyCardOne = new LoyaltyCard(cardNumber);
System.out.printf("%s%n%s%n%s%n%s%n%s",LoyaltyCardOne.getCardNumber(),LoyaltyCardOne.getBalance(),LoyaltyCardOne.collectRewards(6.0,5),LoyaltyCardOne.redeemFreeCoffee(),LoyaltyCardOne.isFreeCoffeeAvailable());
}
I'd like to see the result for getCardNumber(), getBalance() and the amount of coffee.
all I get from getCardNumber is null
You never initialized it
public LoyaltyCard (String cardNumber){
this.cardNumber = cardNumber;
}
because there are no variables that override them.
I think you might be confused about what "override" means, but that isn't the problem.
getBalance is 0, coffee is 0
You're calling those before you ever "collect rewards"
You will need to collect before printing the invidiual values, and read the logic again - increase by one point for every pound spent. So, focus on changing this block to fix that.
if (amount > 0) {
coffee++;
balance++;
}
Note that the instructions don't say the collectRewards returns anything. Also coffee should be increased by the input parameter, maybe than just 1.
Otherwise, you would need to call collectRewards at least 9 times before the redeem and isAvailable methods would work.
And once those are, you could do this, rather than rewrite coffee > 9
if (this.isFreeCoffeeAvailable()) {
} else {
}
Note: isFreeCoffeeAvailable should probably return coffee > 9; rather than return the amount
In Java all non-local variables are initialized to 0, or null. So far in the code you don't set variables to your desired values. You can either create a constructor which takes values, e,g:
LoyaltyCard(int balance, int coffee, double amount) {
this.balance = balance;
this.coffee = coffee;
// ... and other fields
or create setters for each field:
public setBalance(int balance) {
this.balance = balance;
}
I understand the title is quite confusing so I'll clarify here.
The following is an extremely simple bank class I slapped together that takes the users name and balance and has deposit and withdraw classes.
public class Bank {
String user;
int balance = 0;
int pin;
public void setup (String n,int p)
{
user = n;
pin = p;
}
public void withdraw (int amount)
{
balance -= amount;
}
public void deposit (int amount)
{
balance += amount;
}
public String toString ()
{
return String.format("User: %s\nBalance: %s",user,balance);
}
}
Now. Here is my qualm. The following is another simple class I made to make use of the Bank class. I've tried HashMaps, Arrays and I'm sure I'm just missing a basic principle. This isn't for a class I would just like to know how to do the following:
I want to be able to create different users (I'm sure I'd have to use (like I have) a HashMap or ArrayList) and have EACH user have separate access to the balance variable, so when one person, lets say person X with pin 1234 withdraws funds, ONLY their funds are withdrawn.
I know I can just use a HashMap and set it up like
HashMap <String, Integer> HM = new HashMap <String, Integer> ();
HM.put("User",0)
where user is the name and 0 is the balance.
I can easily update different users balances, but this seems counterintuitive.
import java.lang.reflect.Array;
import java.util.*;
public class BankDriver {
public static void main (String [] args)
{
boolean quit = false;
Bank b = new Bank ();
Scanner sc = new Scanner (System.in);
do {
System.out.println("1: Create account\2: Quit");
int input = sc.nextInt();
switch (input)
{
case 1:
b.setup("Name",1234);
System.out.println(b.toString());
break;
case 2:
quit = true;
break;
}
}while(!quit);
System.out.println("Exiting.");
}
}
How would YOU accomplish this?
AGAIN. I know I can do it in different ways, but I was curious if I could accomplish it this way.
The object oriented design that you are using is not very good for what you are trying to achieve. If you want to have access for each client of the bank, you should create a Client class (or Account) with its getters and setters like this:
Also, I changed your integers to doubles
public class Client{
public int pin;
public String name;
public double amount;
public Client(String name, double amount, int pin){
this.name = name;
this.amount = amount;
this.pin = pin;
}
public String getName(){
return name;
}
public int getPin(){
return pin;
}
public void changePin(int newPin){
this.pin = newPin;
}
public void withdraw (double amount)
{
this.amount -= amount;
}
public void deposit (double amount)
{
this.amount += _amount;
}
#Override
public String toString ()
{
return String.format("User: %s\nBalance: %s",this.name,this.amount);
}
}
Now, from your void() you can create all the Clients that you want in any specific data structure. I'll give you an example using a HashMap
HashMap <String, Client> HM = new HashMap <String, Client>();
HM.put("Uri D. Charles", new Client("Uri D. Charles", 100.00, 1234));
HM.put("Luis Lavieri", new Client("Luis Lavieri", 2000.00, 1234));
After that you can manipulate the data structure as you prefer to access that data. I hope this is what you are looking for
First of all create a getter methods for name and pin.
You can create an ArrayList of Bank object and add the bank object to the arraylist each time a user created an account.
Then when the user want to withdraw you then ask them there name and pin and then loop the arraylist while comparing the pin and name of the bank object of the arraylist and the person name and pin that just entered.
If the object was found you can then ask the user how much money to withdraw and call the widraw method.
I am working on a practice assignment to improve my understanding of driver and resource class, I have created a resource class in which holds my code for any possible Bank Account being created. I then need to output that account and it's information, here are the instructions:
A. BankAccount.java and TestBankAccount.java
a. Assignment – text book (Project 5-5, p.197). Complete a UML summary for the resource
class. Write 2 constructors and all accessor and mutator methods for the field variables. Write
a toString() method.
b. Output – should appear exactly as the output shown below. The balance statement will come
from the toString() method. Format the toString() method with String.format(). All other
outputs are string literals (in quotes).
Open account Mickey has a current balance of $0.00
Deposit $500.00 Mickey has a current balance of $500.00
Withdraw $125.25 Mickey has a current balance of $374.75
Open account Minnie has a current balance of $1,000.00
Withdraw $73.21 Minnie has a current balance of $926.79
Open account Goofy has a current balance of $10,000.00
Close account Goofy has a current balance of $0.00
My code for the resource class:
public class BankAccount
{
private String ownerName;
private double balance;
public BankAccount()
{
ownerName = "";
balance = 0.00;
}
public BankAccount(String name, double bal)
{
ownerName = name;
balance = bal;
}
public String toString()
{
return ownerName + " has a current balance of " + String.format("%1$,.2f", balance);
}
public String getOwnerName()
{
return ownerName;
}
public void setOwnerName(String name)
{
ownerName = name;
}
public void deposit(double d)
{
balance+=d;
}
public void withdrawl(double w)
{
balance-=w;
}
}
My code for the Driver class:
public class BankAccountDriver
{
public static void main(String[] args)
{
BankAccount micky = new BankAccount("Micky", 0.00);
System.out.println("Open Account " + micky);
System.out.println("Deposit $500.00 ");
}
}
I am stuck on doing the math for depositing, withdrawing and deleting the account. I believe I have the methods ready to perform such tasks but how do I output it?
You do indeed have all you need. When you want to withdraw $10 from micky, you just need micky.withdrawal(10.0), and the corresponding thing with deposits.
You have everything you need you just need to call toString() on the instansiated object.
public class BankAccountDriver {
public static void main(String[] args) {
BankAccount micky = new BankAccount("Micky", 0.00);
System.out.println("Open Account " + micky.toString());
micky.deposit(500.0);
System.out.println("Deposit $500.00 " + micky.toString());
}
}
A few things:
For your String.format, try String.Format("${0}", balance);
As mentioned, you need to just call your toString() method to have the "has a current balance.." part
You have the code to deposit and withdraw, but you don't call it. So you need to call it, like micky.deposit(500);. Then you can repeat your toString() call to print it out.
If your having a problem with the actual displaying, try Console.WriteLine() instead of System.out.println()
I have a Loan class that in its printPayment method, it prints the amortization table of a loan for a hw assignment. We are also to implement a print first payment method, and a print last payment method. Since my calculation is done in the printPayment method, I didn't know how I could get the value in the first or last iteration of the loop and print that amount out.
One way I can think of is to write a new method that might return that value, but I wasn't sure if there was a better way. Here is my code:
public abstract class Loan
{
public void setClient(Person client)
{
this.client = client;
}
public Person getClient()
{
return client;
}
public void setLoanId()
{
loanId = nextId;
nextId++;
}
public int getLoanId()
{
return loanId;
}
public void setInterestRate(double interestRate)
{
this.interestRate = interestRate;
}
public double getInterestRate()
{
return interestRate;
}
public void setLoanLength(int loanLength)
{
this.loanLength = loanLength;
}
public int getLoanLength()
{
return loanLength;
}
public void setLoanAmount(double loanAmount)
{
this.loanAmount = loanAmount;
}
public double getLoanAmount()
{
return loanAmount;
}
public void printPayments()
{
double monthlyInterest;
double monthlyPrincipalPaid;
double newPrincipal;
int paymentNumber = 1;
double monthlyInterestRate = interestRate / 1200;
double monthlyPayment = loanAmount * (monthlyInterestRate) /
(1 - Math.pow((1 + monthlyInterestRate),( -1 * loanLength)));
System.out.println("Payment Number | Interest | Principal | Loan Balance");
// amortization table
while (loanAmount >= 0) {
monthlyInterest = loanAmount * monthlyInterestRate;
monthlyPrincipalPaid = monthlyPayment - monthlyInterest;
newPrincipal = loanAmount - monthlyPrincipalPaid;
loanAmount = newPrincipal;
System.out.printf("%d, %.2f, %.2f, %.2f", paymentNumber++, monthlyInterest, monthlyPrincipalPaid, loanAmount);
}
}
/*
//method to print first payment
public double getFirstPayment()
{
}
method to print last payment
public double getLastPayment()
{
}*/
private Person client;
private int loanId;
private double interestRate;
private int loanLength;
private double loanAmount;
private static int nextId = 1;
}
Thanks!
You've already identified that the printPayments(), printFirstPayment() and printLastPayment() methods have common logic. You generally want to minimize duplication of such code and the two common ways to do this are:
Implement all but one of the methods in terms of one of them; or
Implement all the methods in terms of a private method.
So, for example:
public void printPayments() {
for (Payment : getPayments()) {
printPayment(payment);
}
}
public void printFirstPayment() {
printPayment(getPayments().get(0));
}
public void printLastPayment() {
List<Payment> payments = getPayments();
printPayment(payments.get(payments.size()-1));
}
private void printPayment(Payment payment) {
...
}
private List<Payment> getPayments() {
...
}
Now this is homework so you may not have come across the syntax List<Payment> yet. If not, it's generics. There are other ways to do this: using a non-generic Collection or using arrays for example.
The points I wanted to illustrate here is that:
The logic for creating the payments and displaying them has been separated;
A single method getPayments() does the calculations and returns a List of Payment objects. Payment is a new object in this mock up;
All three methods are implemented in terms of getPayments() and printPayment().
So I hope this leads you in the right direction. The concept here I guess is functional composition, composing your functions in terms of other functions and making your internal functions granular enough to be grouped together usefully.
Your printPayments function is awfully big. It is generally better to make each function "do one thing and one thing well", and to make functions relatively short. I would recommend that you separate your computation logic from your printing logic; provide functions for computing these various payments, and have your print function merely print the result of invoking those computation functions.
If you are worried about redundancy (that is some of the later computations depend on earlier computations which you might have previously performed), then you can use dynamic programming, which basically means that you accumulate previous results in an array or matrix so that they can be reused in subsequent computations. You could compute the entire amortization table as a 2-dimensional array, in which case you could lookup the earlier payments that you computed simply by looking them up in that array.
Maybe you should have a method that returns an array/set/list/resultset/datacontainer (add more buzzwords to confuse you - its your homework after all ;)) which you can use in the other methods.
if when you describe what a method does, you use the word 'and', chances are the method is doing too much. each method should do one thing, so printing is one thing, and calculating is another .. so two methods.