In: Computer Science
Person class
You will implement the Person Class in Visual Studio. A person
object may be associated with multiple accounts. A person initiates
activities (deposits or withdrawal) against an account that is
captured in a transaction object.
A short description of each class member is given below:
Person
Class
Fields
- password : string
Properties
+ «C# property, setter private» IsAuthenticated :
bool
+ «C# property, setter absent» SIN : string
+ «C# property, setter absent» Name : string
Methods
+ «Constructor» Person(name : string, sin :
string)
+ Login(password : string) : void
+ Logout() : void
+ ToString() : string
Fields:
⦁ password – this private string field represents the
password of this person.
(N.B. Password are not normally stored as text but as a hash value.
A hashing function operates on the password and the result is
stored in the field. When a user supplies a password it is passed
through the same hashing function and the result is compared to the
value of the field.).
Properties:
⦁ SIN – this string property represents the sin number
of this person. This getter is public and setter is absent.
⦁ IsAuthenticated – this property is a bool
representing if this person is logged in with the correct password.
This is modified in the Login() and the Logout() methods. This is
an auto-implemented property, and the getter is public and setter
is private
⦁ Name – this property is a string representing the
name of this person. The getter is public and setter is
absent.
Methods:
⦁ public Person( string name, string sin ) – This
public constructor takes two parameters: a string representing the
name of the person and another string representing the SIN of this
person. It does the following:
⦁ The method assigns the arguments to the appropriate
fields.
⦁ It also sets the password to the first three letters
of the SIN. [use the Substring(start_position, length) method of
the string class]
⦁ public void Login( string password ) – This method
takes a string parameter representing the password and does the
following:
⦁ If the argument DOES NOT match the password field, it
does the following:
⦁ Sets the IsAuthenticated property to false
⦁ Creates an AccountException object using argument
AccountEnum.PASSWORD_INCORRECT
⦁ Throws the above exception
⦁ If the argument matches the password, it does the
following:
⦁ Sets the IsAuthenticated property is set to
true
This method does not display anything
⦁ public void Logout( ) – This is public method does
not take any parameters nor does it return a value.
This method sets the IsAuthenticated property to false
This method does not display anything
⦁ public override string ToString( )– This public
method overrides the same method of the Object class. It returns a
string representing the name of the person and if he is
authenticated or not.
ITransaction interface
You will implement the ITransaction Interface in Visual Studio. The
three sub classes implement this interface.
A short description of each class member is given below:
ITransaction
Interface
Methods
Withdraw(amount : double, person : Person) :
void
Deposit(amount : double, person : Person) : void
Methods:
⦁ void Withdraw(double amount, Person person).
⦁ void Deposit(double amount, Person person).
Transaction class
You will implement the Transaction Class in Visual Studio. The only
purpose of this class is to capture the data values for each
transaction. A short description of the class members is given
below:
All the properties are public with the setter absent.
Transaction
Class
Properties
+ «C# property, setter absent » AccountNumber :
string
+ «C# property, setter absent» Amount : double
+ «C# property, setter absent» Originator :
Person
+ «C# property, setter absent» Time : DateTime
Methods
+ «Constructor» Transaction(accountNumber : string,
amount : double, endBalance : double, person : Person, time :
DateTime)
+ ToString() : string
Properties:
All the properties are public with the setter absent
⦁ AccountNumber – this property is a string
representing the account number associated with this transaction.
The getter is public and the setter is absent.
⦁ Amount – this property is a double representing the
account of this transaction. The getter is public and the setter is
absent.
⦁ Originator – this property is a Person representing
the person initiating this transaction. The getter is public and
the setter is absent.
⦁ Time – this property is a DateTime (a .NET built-in
type) representing the time associated with this transaction. The
getter is public and the setter is absent.
Methods:
⦁ public Transaction( string accountNumber, double
amount, Person person, DateTime time ) – This public constructor
takes five arguments. It assigns the arguments to the appropriate
fields.
⦁ public override string ToString( ) – This method
overrides the same method of the Object class. It does not take any
parameter and it returns a string representing the account number,
name of the person, the amount and the time that this transition
was completed. [you may use ToShortTimeString() method of the
DateTime class]. You must include the word Deposit or Withdraw in
the output.
A better type would have been a struct instead of a class.
ExceptionEnum enum
You will implement this enum in Visual Studio. There are seven
members:
ACCOUNT_DOES_NOT_EXIST,
CREDIT_LIMIT_HAS_BEEN_EXCEEDED,
NAME_NOT_ASSOCIATED_WITH_ACCOUNT,
NO_OVERDRAFT,
PASSWORD_INCORRECT,
USER_DOES_NOT_EXIST,
USER_NOT_LOGGED_IN
The members are self-explanatory.
AccountException class
You will implement the AccountException Class in Visual Studio.
This inherits from the Exception Class to provide a custom
exception object for this application. It consists of seven strings
and two constructors:
AccountException
Class
→ Exception
Fields
Properties
Methods
+ «Constructor» AccountException(reason :
ExceptionEnum)
Fields:
There are no fields
Properties:
There are no properties
Methods:
⦁ AccountException( ExceptionEnum reason )– this public
constructor simply invokes the base constructor with an appropriate
argument. Use the ToString() of the enum type.
Working code implemented in C# and appropriate comments provided for better understanding:
Here I am attaching code for these files:
Source code for main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("---- START RUNING CODE FROM PROGRAM.CS
-----");
//testing the visa account
Console.WriteLine("\nAll acounts:");
Bank.PrintAccounts();
Console.WriteLine("----- PASSED PRINT ACCOUNTS -----");
Console.WriteLine("\nAll Users:");
Console.WriteLine();
Bank.PrintPersons();
Console.WriteLine();
Console.WriteLine("----- PASSED PRINT PERSONS -----");
Person p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
p0 = Bank.GetPerson("Narendra");
p1 = Bank.GetPerson("Ilia");
p2 = Bank.GetPerson("Tom");
p3 = Bank.GetPerson("Syed");
p4 = Bank.GetPerson("Arben");
p5 = Bank.GetPerson("Patrick");
p6 = Bank.GetPerson("Yin");
p7 = Bank.GetPerson("Hao");
p8 = Bank.GetPerson("Jake");
p9 = Bank.GetPerson("Joanne");
p10 = Bank.GetPerson("Nicoletta");
Console.WriteLine();
Console.WriteLine("----- PASSED PERSON REQUEST -----");
p0.Login("123");
p1.Login("234");
p2.Login("345");
p3.Login("456");
p4.Login("567");
p5.Login("678");
p6.Login("789");
p7.Login("890");
p10.Login("234");
p8.Login("901");
Console.WriteLine();
Console.WriteLine("----- PASSED LOGINS -----");
//a visa account
VisaAccount a = Bank.GetAccount("VS-100000") as VisaAccount;
a.DoPayment(1500, p0);
a.DoPurchase(200, p1);
a.DoPurchase(25, p2);
a.DoPurchase(15, p0);
a.DoPurchase(39, p1);
a.DoPayment(400, p0);
Console.WriteLine(a);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR VS-100000
-----");
VisaAccount aa =
(VisaAccount)Bank.GetAccount("VS-100001");
aa.DoPayment(500, p0);
aa.DoPurchase(25, p3);
aa.DoPurchase(20, p4);
aa.DoPurchase(15, p5);
Console.WriteLine(aa);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR VS-100001
-----");
//a saving account
ITransaction b = Bank.GetAccount("SV-100002") as
ITransaction;
b.Withdraw(300, p6);
b.Withdraw(32.90, p6);
b.Withdraw(50, p7);
b.Withdraw(111.11, p8);
Console.WriteLine(b);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100002
-----");
b = (SavingAccount)Bank.GetAccount("SV-100003");
b.Deposit(300, p3); //ok even though p3 is not a holder
b.Deposit(32.90, p2);
b.Deposit(50, p5);
b.Withdraw(111.11, p10);
Console.WriteLine(b);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100003
-----");
//a checking account
ITransaction c = Bank.GetAccount("CK-100004") as
ITransaction;
c.Deposit(33.33, p7);
c.Deposit(40.44, p7);
c.Withdraw(150, p2);
c.Withdraw(200, p4);
c.Withdraw(645, p6);
c.Withdraw(350, p6);
Console.WriteLine(c);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100004
-----");
c = Bank.GetAccount("CK-100005") as ITransaction;
c.Deposit(33.33, p8);
c.Deposit(40.44, p7);
c.Withdraw(450, p10);
c.Withdraw(500, p8);
c.Withdraw(645, p10);
c.Withdraw(850, p10);
Console.WriteLine(c);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100005
-----");
a = Bank.GetAccount("VS-100006") as VisaAccount;
a.DoPayment(700, p0);
a.DoPurchase(20, p3);
a.DoPurchase(10, p1);
a.DoPurchase(15, p1);
Console.WriteLine(a);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100006
-----");
b = (ITransaction)Bank.GetAccount("SV-100007");
b.Deposit(300, p3); //ok even though p3 is not a holder
b.Deposit(32.90, p2);
b.Deposit(50, p5);
b.Withdraw(111.11, p7);
Console.WriteLine(b);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100007
-----");
//The following will cause exception
Console.WriteLine("\n\nExceptions:");
try
{
p8.Login("911"); //incorrect password
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
p3.Logout();
a.DoPurchase(12.5, p3); //exception user is not logged in
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
a.DoPurchase(12.5, p0); //user is not associated with this
account
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
a.DoPurchase(5825, p4); //credit limit exceeded
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
c.Withdraw(1500, p6); //no overdraft
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
Bank.GetAccount("CK-100018"); //account does not exist
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
Bank.GetPerson("Trudeau"); //user does not exist
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
foreach (Account account in Bank.ACCOUNTS)
{
Console.WriteLine("\nBefore PrepareMonthlyReport()");
Console.WriteLine(account);
Console.WriteLine("\nAfter PrepareMonthlyReport()");
account.PrepareMonthlyReport(); //all transactions are cleared,
balance changes
Console.WriteLine(account);
}
}
}
}
Source code for Bank.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
static class Bank
{
// fields properties
public static readonly List<Account> ACCOUNTS;
public static readonly List<Person> USERS;
// constructor
static Bank()
{
//initialize the USERS collection
USERS = new List<Person>()
{
new Person("Narendra", "1234-5678"), //0
new Person("Ilia", "2345-6789"), //1
new Person("Tom", "3456-7890"), //2
new Person("Syed", "4567-8901"), //3
new Person("Arben", "5678-9012"), //4
new Person("Patrick", "6789-0123"), //5
new Person("Yin", "7890-1234"), //6
new Person("Hao", "8901-2345"), //7
new Person("Jake", "9012-3456"), //8
new Person("Joanne", "1224-5678"), //9
new Person("Nicoletta", "2344-6789"), //10
};
//initialize the ACCOUNTS collection
ACCOUNTS = new List<Account>()
{
new VisaAccount(), //VS-100000
new VisaAccount(150, -500), //VS-100001
new SavingAccount(5000), //SV-100002
new SavingAccount(), //SV-100003
new CheckingAccount(2000), //CK-100004
new CheckingAccount(1500, true), //CK-100005
new VisaAccount(50, -550), //VS-100006
new SavingAccount(1000), //SV-100007
};
//associate users with accounts
ACCOUNTS[0].AddUser(USERS[0]);
ACCOUNTS[0].AddUser(USERS[1]);
ACCOUNTS[0].AddUser(USERS[2]);
ACCOUNTS[1].AddUser(USERS[3]);
ACCOUNTS[1].AddUser(USERS[4]);
ACCOUNTS[1].AddUser(USERS[5]);
ACCOUNTS[2].AddUser(USERS[6]);
ACCOUNTS[2].AddUser(USERS[7]);
ACCOUNTS[2].AddUser(USERS[8]);
ACCOUNTS[3].AddUser(USERS[9]);
ACCOUNTS[3].AddUser(USERS[10]);
ACCOUNTS[4].AddUser(USERS[2]);
ACCOUNTS[4].AddUser(USERS[4]);
ACCOUNTS[4].AddUser(USERS[6]);
ACCOUNTS[5].AddUser(USERS[8]);
ACCOUNTS[5].AddUser(USERS[10]);
ACCOUNTS[6].AddUser(USERS[1]);
ACCOUNTS[6].AddUser(USERS[3]);
ACCOUNTS[7].AddUser(USERS[5]);
ACCOUNTS[7].AddUser(USERS[7]);
}
// methods - acitons
public static void PrintAccounts()
{
foreach (Account account in ACCOUNTS)
{
Console.WriteLine(account);
}
}
public static void PrintPersons()
{
foreach (Person person in USERS)
{
Console.WriteLine(person);
}
}
public static Person GetPerson(string name)
{
foreach (Person person in USERS)
{
if (person.Name == name)
{
Console.WriteLine(person);
return person;
}
}
throw new
AccountException(ExceptionEnum.USER_DOES_NOT_EXIST);
}
public static Account GetAccount(string number)
{
foreach (Account account in ACCOUNTS)
{
if (account.Number == number)
{
return account;
}
}
throw new
AccountException(ExceptionEnum.ACCOUNT_DOES_NOT_EXIST);
}
}
}
Source code for Person.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class Person
{
// fields and properties for person object
private string password;
public string SIN { get; }
public string Name { get; }
public bool IsAuthenticated { get; private set; }
// constructor for person object
public Person(string name, string SIN)
{
Name = name;
this.SIN = SIN;
password = SIN.Substring(0,3);
}
// methods - actions of the person class
public void Login(string password)
{
try
{
if (password != this.password)
{
IsAuthenticated = false;
throw new AccountException(ExceptionEnum.PASSWORD_INCORRECT);
}
else
{
IsAuthenticated = true;
Console.WriteLine($"{Name,-15}\thas logged IN.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void Logout()
{
IsAuthenticated = false;
Console.WriteLine($"{Name,-15}\thas logged OUT.");
}
public override string ToString()
{
return $"{Name}";
}
}
}
Source code for Account.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
abstract class Account
{
// fields and properties for the account class
public readonly List<Person> users = new
List<Person>();
public readonly List<Transaction> transactions = new
List<Transaction>();
private static int LAST_NUMBER = 100_000;
public double Balance { get; protected set; }
public double LowestBalance { get; protected set; }
public string Number { get; }
// constructor of the account class
public Account(string type, double balance)
{
Number = $"{type}{LAST_NUMBER}";
LAST_NUMBER++;
Balance = balance;
LowestBalance = balance;
}
// methos - actions of the account class
public void Deposit(double amount, Person person)
{
Balance += amount;
if (Balance < LowestBalance)
{
LowestBalance = Balance;
}
transactions.Add(new Transaction(Number, amount, person,
DateTime.Now));
}
public void AddUser(Person person)
{
users.Add(new Person(person.Name, person.SIN));
}
public bool IsUser(string name)
{
foreach (Person person in users)
{
if (person.Name == name)
{
return true;
}
}
return false;
}
public abstract void PrepareMonthlyReport();
public override string ToString()
{
return $"\n--- ACCOUNT INFO:\n" +
$"Account Number:\t{Number}\n" +
$"Users:\t\t{string.Join(", ", users)}\n" +
$"Balance:\t{Balance:C}\n";
}
}
}
Source code for SavingAccount.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class SavingAccount : Account, ITransaction
{
// fields and properties of the saving account class
private double COST_PER_TRANSACTION = 0.05;
private double INTEREST_RATE = 0.015;
// constructor for the savings account class
public SavingAccount(double balance = 0) : base("SV-",
balance)
{
}
// methods - acitons of the sabings account class
public new void Deposit(double amount, Person person)
{
base.Deposit(amount, person);
}
public void Withdraw(double amount, Person person)
{
// throwing exceptions as rules specifies
try
{
if (users.Contains<Person>(person) == true)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > Balance)
{
throw new AccountException(ExceptionEnum.NO_OVERDRAFT);
}
else
{
base.Deposit(amount * -1, person); // -1 to withdraw the amount of
the account
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public override void PrepareMonthlyReport()
{
double serviceCharge, interests;
serviceCharge = COST_PER_TRANSACTION * transactions.Count;
interests = INTEREST_RATE * LowestBalance / 12;
Balance = Balance + interests - serviceCharge;
transactions.Clear();
}
}
}
Source code for CheckingAccount.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class CheckingAccount : Account, ITransaction
{
// fields and properties of the checking account class
private double COST_PER_TRANSACTION = 0.05;
private double INTEREST_RATE = 0.005;
private bool hasOverDraft;
// constructor of the checking account class
public CheckingAccount(double balance = 0, bool hasOverDraft =
false) : base("CK-", balance) // takes the arguments from the
parent class 'account'
{
this.hasOverDraft = hasOverDraft;
}
// mthods - actions of the checking account class
public new void Deposit(double amount, Person person)
{
base.Deposit(amount, person); // calls the deposit method from the
parent class
}
public void Withdraw(double amount, Person person)
{
// throwing exceptions as rules specifies
try
{
if (users.Contains<Person>(person) == true)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > Balance || hasOverDraft == false)
{
throw new AccountException(ExceptionEnum.NO_OVERDRAFT);
}
else
{
base.Deposit(amount * -1, person); // -1 to withdraw the amount of
the account
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public override void PrepareMonthlyReport()
{
double serviceCharge, interests;
serviceCharge = COST_PER_TRANSACTION * transactions.Count;
interests = INTEREST_RATE * LowestBalance / 12;
Balance = Balance + interests - serviceCharge;
transactions.Clear();
}
}
}
Source code for Transaction.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
// interface for the transaction class
interface ITransaction
{
void Withdraw(double amount, Person person);
void Deposit(double amount, Person person);
}
class Transaction
{
// flieds and properties of the class transactions
public string AccountNumber { get; }
public double Amount { get; }
public Person Originator { get; }
public DateTime Time { get; }
// constructor for the transaction class
public Transaction(string accountNumber, double amount, Person
person, DateTime time)
{
AccountNumber = accountNumber;
Amount = amount;
Originator = person;
Time = time;
}
// methods - actions for the transaction class
public override string ToString()
{
return $"\n--- TRANSACTION INFO:\n" +
$"Date:\t\t\t{Time.ToShortTimeString()}\n" +
$"Name:\t\t\t{Originator}\n" +
$"Account Number:\t\t{AccountNumber}\n" +
$"Transaction:\t\t{Amount:C}\n";
}
}
}
Source code for VisaAccount.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class VisaAccount : Account, ITransaction
{
// fields and properties of visa account class
private double creditLimit;
private double INTEREST_RATE = 0.1995;
// constructor for visa account class
public VisaAccount(double balance = 0, double creditLimit = 1200) :
base("VS-", balance)
{
this.creditLimit = creditLimit;
}
// methods - acitons of the sabings account class
public void DoPayment(double amount, Person person)
{
base.Deposit(amount, person);
}
public void DoPurchase(double amount, Person person)
{
// throwing exceptions as rules specifies
try
{
// for (int i = 0; i < users.Count; i++)
//{
if (users.Contains<Person>(person) == true)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > creditLimit)
{
throw new
AccountException(ExceptionEnum.CREDIT_LIMIT_HAS_BEEN_EXCEEDED);
}
else
{
base.Deposit(-amount, person); // -1 to withdraw the amount of the
account
}
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
void ITransaction.Deposit(double amount, Person person)
{
base.Deposit(amount, person);
}
void ITransaction.Withdraw(double amount, Person person)
{
// throwing exceptions as rules specifies
if (users.Contains<Person>(person) == false)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > Balance)
{
throw new
AccountException(ExceptionEnum.CREDIT_LIMIT_HAS_BEEN_EXCEEDED);
}
else
{
base.Deposit(-amount, person); // -1 to withdraw the amount of the
account
}
}
public override void PrepareMonthlyReport()
{
double interests;
interests = INTEREST_RATE * LowestBalance / 12;
Balance = Balance - interests;
transactions.Clear();
}
}
}
Source code for AccountException.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
public enum ExceptionEnum
{
ACCOUNT_DOES_NOT_EXIST,
CREDIT_LIMIT_HAS_BEEN_EXCEEDED,
NAME_NOT_ASSOCIATED_WITH_ACCOUNT,
NO_OVERDRAFT,
PASSWORD_INCORRECT,
USER_DOES_NOT_EXIST,
USER_NOT_LOGGED_IN
}
class AccountException : Exception
{
public AccountException(ExceptionEnum reason) :
base(reason.ToString())
{
}
}
}
Sample Output Screenshots:
Hope it helps, if you like the answer give it a thumbs up. Thank you.