C#: How to find the total sum of arrays inside functions? - c#

I have to create a function that enables me to enter data for every customer in a hardware store. The data that I should enter for every customer is: first name, last name, product bought and its price. This data should be stored in an array. Have this function declare a 1D container, have the user initialise this 1D container with the above data, and have the function return this 1D container back to MAIN. In MAIN, invoke this function three times to create data for 3 customers.
Afterwards, I need to create another function that takes all three 1D containers of customer data from MAIN as parameters and adds up all the prices of the products they bought. Have this function return the total cost back to MAIN. (This is where I'm stuck.)
Lastly, I need to create a procedure that takes the total cost returned to MAIN as parameter and figures out if this total price(set to a simple integer) is a prime number:
if the value is prime, print: "Customers win the Price"
otherwise, print: "Customers won't get the price"
I am stuck on the second function, I tried to do a C-style for loop, but it doesn't work.
I tried to add these three prices as array positions with indices but nothing.
This is the code I have:
using System;
namespace ghghh
{
class Program
{
public static string [] inputData()
{
Console.WriteLine("Please enter your first name: ");
string FirstName = Console.ReadLine();
Console.WriteLine("Please enter your last name: ");
string LastName = Console.ReadLine();
Console.WriteLine("Please enter the product you ahve bought: ");
string product = Console.ReadLine();
Console.WriteLine("Please enter the price: ");
string price = Console.ReadLine();
string[] info = new string[4] { FirstName, LastName, product, price };
return info;
}
public static void sumOfPrice(string[] arr)
{
for(int i = 0; i<arr.Length; i++)
{
string sum = arr[i] + arr[i] + arr[i];
}
}
public static void isTotalCostPrime(int n)
{
if(n %2 == 0)
{
Console.WriteLine("Customers wont get get the prize.");
}
else
{
Console.WriteLine("Customers win the prize");
}
}
public static void Main (string[] args)
{
string[] final = inputData();
sumOfPrice(final);
}
}
}

Here you go with a partial solution to your problem. I made the prices decimal numbers (because most currencies are decimalized). That precludes your prime test at the end.
I also included a quantity. I was tempted to take out the first and last names for each item (since it requires a lot of typing). All in all, though, this should give you enough to get started.
I start with a POCO class to hold the purchased items (POCO stands for "Plain Old CLR Object"; it's a class that consists purely of properties. It's a bit like an old-fashioned C struct.
public class PurchasedItem
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
I separated the user interface out into a separate class (for reasons of separation of concerns). You could easily collapse this into a single class:
public class ItemUserInterface
{
public static PurchasedItem PromptForItem()
{
var purchasedItem = new PurchasedItem();
Console.Write("What is your First Name (or type \"exit\" if complete)? > ");
var firstName = Console.ReadLine();
if (firstName.Equals("exit", StringComparison.OrdinalIgnoreCase))
{
return null;
}
purchasedItem.FirstName = firstName;
Console.Write("What is your Last Name? > ");
purchasedItem.LastName = Console.ReadLine();
Console.Write("What did you purchase? > ");
purchasedItem.ProductName = Console.ReadLine();
purchasedItem.Quantity = PromptForInteger("How many did you buy");
purchasedItem.Price = PromptForDecimal("What was the price");
Console.WriteLine(""); //empty line
return purchasedItem;
}
public static void ShowPurchase (PurchasedItem item)
{
Console.WriteLine($"{item.FirstName} {item.LastName} bought {item.Quantity} of {item.ProductName} at {item.Price} each");
}
public static int PromptForInteger(string prompt)
{
while (true)
{
Console.Write(prompt + " > ");
var entered = Console.ReadLine();
if (int.TryParse(entered, out var result))
{
return result;
}
//otherwise error
Console.WriteLine("Sorry, you must enter a proper integer value");
}
}
public static decimal PromptForDecimal(string prompt)
{
while (true)
{
Console.Write(prompt + " > ");
var entered = Console.ReadLine();
if (decimal.TryParse(entered, out var result))
{
return result;
}
//otherwise error
Console.WriteLine("Sorry, you must enter a proper decimal value");
}
}
}
By the way, while (true) will loop forever unless you do something like return or break out of the loop. Notice that I prompt the user over and over again until he/she enters a correctly formatted number (for the number entries).
Finally, here's my Main routine:
var itemsList = new List<PurchasedItem>();
while (true)
{
var item = ItemUserInterface.PromptForItem();
if (item == null)
{
break;
}
itemsList.Add(item);
}
// at this point, everything is entered
var totalPurchasePrice = 0.00m;
var totalItemsCount = 0;
foreach (var item in itemsList)
{
ItemUserInterface.ShowPurchase(item);
totalPurchasePrice += (item.Quantity * item.Price);
totalItemsCount += item.Quantity;
}
Console.WriteLine($"Purchase Summary: {itemsList.Count} different items ({totalItemsCount} total items) for {totalPurchasePrice:C}");
Console.ReadLine(); //pause
}
If I run this program the output looks like:
What is your First Name (or type "exit" if complete)? > Fly
What is your Last Name? > Dog57
What did you purchase? > Cabbage
How many did you buy > 2
What was the price > 1.99
What is your First Name (or type "exit" if complete)? > Fly
What is your Last Name? > Dog57
What did you purchase? > Hammer
How many did you buy > 6
What was the price > abc
Sorry, you must enter a proper decimal value
What was the price > 10.55
What is your First Name (or type "exit" if complete)? > exit
Fly Dog57 bought 2 of Cabbage at 1.99 each
Fly Dog57 bought 6 of Hammer at 10.55 each
Purchase Summary: 2 different items (8 total items) for $67.28

Related

Overriding the Pokemon name

I have Pokemon.cs here:
using System;
using System.Collections.Generic;
namespace PokemonPocket{
public class PokemonMaster{
public string Name {get;set;}
public int NoToEvolve {get; set;}
public string EvolveTo {get; set;}
public PokemonMaster(string name, int noToEvolve, string evolveTo){
this.Name = name;
this.NoToEvolve = noToEvolve;
this.EvolveTo = evolveTo;
}
}
}
and I have created this program here called Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
namespace PokemonPocket
{
class Program
{
static void Main(string[] args)
{
//PokemonMaster list for checking pokemon evolution availability.
List<PokemonMaster> pokemonMasters = new List<PokemonMaster>(){
new PokemonMaster("Pikachu", 2, "Raichu"),
new PokemonMaster("Eevee", 3, "Flareon"),
new PokemonMaster("Charmander", 1, "Charmeleon")
};
// Use "Environment.Exit(0);" if you want to implement an exit of the console program
PokemonMenu(pokemonMasters);
}
static void PokemonMenu(List<PokemonMaster> pokemans)
{
// From now on myDictionary is available for any menu option
var myDictionary = new Dictionary<string, string>();
while (true)
{ // <- loop until exit option (key 'Q') is pressed
Console.WriteLine("Welcome to Pokemon Pocket App!");
Console.WriteLine("(1). Add Pokemon to my pocket");
Console.WriteLine("(2). List Pokemon(s) in my pocket");
Console.WriteLine("(3). Check if I can evolve Pokemon");
Console.WriteLine("(4). Evolve Pokemon\n");
Console.Write("Please only enter [1,2,3,4] or Q to exit:");
char menu = Convert.ToChar(Console.ReadLine());
if (menu == '1')
{ //Part 1
Console.Write("Enter Pokemon Name :");
string name = Console.ReadLine();
Console.Write("Enter Pokemon HP : ");
int hp = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Pokemon EXP : ");
int exp = Convert.ToInt32(Console.ReadLine());
if (myDictionary.Count <= 0)
{
myDictionary.Add("Pokemon's Name", name);
myDictionary.Add("Pokemon's HP", hp.ToString());
myDictionary.Add("Pokemon's EXP", exp.ToString());
Console.WriteLine("Pokemon has been added!");
}
}
else if (menu == '2')
{ //Part 2
foreach (var v in myDictionary)
Console.WriteLine(string.Format("{1}: {0}", v.Value, v.Key));
}
else if (menu == '3') //Part 3
{
if (!myDictionary.TryGetValue("Pokemon's Name", out var myPokemon))
{
// No pokemon in pocket so just exit
Console.WriteLine("You have no pokemon!");
continue;
}
var matchedPokemon = pokemans.Find(p => p.Name == myPokemon);
if (matchedPokemon != default)
{
Console.WriteLine("Can evolve a pokeman!");
Console.WriteLine($"{matchedPokemon.Name} --> {matchedPokemon.EvolveTo}");
}
}
else if (menu == 'Q')
{
Console.WriteLine("App exited!");
Environment.Exit(0);
}
}
}
}
}
After adding the Pokemon in 1, when I input 2 this is what the program displays:
Pokemon's Name: Charmander
Pokemon's HP: 20
Pokemon's EXP: 30
When I input 4, I want the name to be overrided into Charmeleon, something like evolution in original Pokemon. Then when I input 2, I want it to display this:
Pokemon's Name: Charmeleon
Pokemon's HP: 0 //hp will become 0 when evolved
Pokemon's EXP: 0 //hp will become 0 when evolved
Pokemon's Skill = Solar power //skill will now be there as original input doesnt have skill
How do i do so?
You won't be able to update it, but you could do something like
Read in the pokemon's Value (TryGetValue)
Remove the existing Key (Remove)
Add the value back in with the new key (the new name) (Add)
Because Key of a Dictionary cannot be updated

Printing list with additional text

Edit:
So currently I am creating a struct:
struct Coordinate
{
public string Name;
public int HP;
public int EXP;
public Coordinate(string name, int hp, int exp)
{
this.Name = name;
this.HP = hp;
this.EXP = exp;
}
}
}
I have also created this list:
var myList = new List<Coordinate>();
And this is a code i have been working on:
{Console.Write("name:");
string name = Console.ReadLine();
Console.Write("hp:");
int hp = Convert.ToInt32(Console.ReadLine());
Console.Write("exp:");
int exp = Convert.ToInt32(Console.ReadLine());
Coordinate point = new Coordinate(name, hp, exp);
Console.WriteLine("Pokemon's name: "+point.Name);
Console.WriteLine(point.HP); //output: hp inputed
Console.WriteLine(point.EXP); //output: 20
myList.Add(point);
}
else if (menu == '6'){ //need help here, want to print list
}
How to I add the list so that when I input 6, I want to write this:
Pokemon's name = Charmander
Pokemon's HP = 20
Pokemon's EXP = 40
This is probably incorrect:
if (myDictionary.Count <= 0)
{
myDictionary.Add("Pokemon's Name", name);
myDictionary.Add("Pokemon's HP", hp.ToString());
myDictionary.Add("Pokemon's EXP", exp.ToString());
myDictionary.Add("Pokemon's Skill", name);
Console.WriteLine("Pokemon has been added!");
}
First of all, it will only run the code if the dictionary is empty, so trying to add another pokemon will not do anything.
Secondly, it adds the pokemons properties as separate values in the dictionary. So if you remove the Count <= 0 check it will fail since keys are constants and have already been added. Regular dictionaries can only have a single value for a specific key.
You probably want to do the following:
Introduce a Pokemon-class with name, hp, exp and skill properties.
Replace myDictionary with a regular list of pokemons.
Remove the Count <= 0 check
If you only want to allow a single pokemon with a specific name you can keep the dictionary and change it to myDictionary[myPokemonName] = myPokemonObject. This will add a new pokemon, or overwrite any existing pokemon with the same name.

Trying to pass objects to an array and then search the array to return the object [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
So I'm trying to create a program that will allow me to enter object information to an array and then search that array for pieces of the object and return the object.
At this point I'm not sure if my objects are being put in to the array and if my calls are correct.
Ideally I want to populate the array of objects, then when the menu displays choose a search option. I will search the array of objects for a match and display the object(s) to that match.
I'm not sure where my mistake is as this is not returning my search options. Assistance finding it would be great. Thank you!
static void Main(string[] args)
{
Greeting();
WriteLine();
School [] newStudent = new School[4];
string firstName;
string lastName;
string major;
int id;
double gpa;
for (int i = 0; i < newStudent.Length; i++)
{
GetInfo(out firstName, out lastName, out major);
id = GetId();
gpa = GetGpa();
WriteLine();
newStudent[i] = new School(lastName, firstName, major, id, gpa);
}
DisplayMenu();
int menuOpt = GetChoice();
DoChoice(menuOpt, newStudent);
}
static void Greeting()
{
WriteLine("Student Input");
}
static void GetInfo(out string lastn, out string firstn, out string mjr)
{
Write("Enter student's last name: ");
lastn = ReadLine();
Write("Enter student's first name: ");
firstn = ReadLine();
Write("Enter student's major: ");
mjr = ReadLine();
}
static int GetId()
{
Write("Enter student's ID number: ");
int inum = int.Parse(ReadLine());
while (inum <= 0)
{
Write("ID number must be greater than 0. Please enter student's ID number: ");
inum = int.Parse(ReadLine());
}
return inum;
}
static double GetGpa()
{
Write("Enter student's GPA: ");
double sgpa = double.Parse(ReadLine());
while (sgpa < 0.0 || sgpa > 4.0)
{
Write("That's not a valid GPA. Try Again: ");
sgpa = double.Parse(ReadLine());
}
return sgpa;
}
static void DisplayMenu()
{
WriteLine("1. Search by Last Name");
WriteLine("2. Search by First Name");
WriteLine("3. Search by Major");
WriteLine("4. Quit");
}
static int GetChoice()
{
Write("What is your choice? ");
int select = int.Parse(ReadLine());
while (select < 1 || select > 4)
{
Write("That's not a valid choice. Try Again: ");
select = int.Parse(ReadLine());
}
return select;
}
static void DoChoice(int choice, params School [] nStudent)
{
switch (choice)
{
case 1:
FindLastName(nStudent);
break;
case 2:
break;
//more options will go here at a later date with their matching methods like case 1
}
}
static void FindLastName(params School [] findLName)
{
Write("What is the last name? ");
string findL = ReadLine();
int pos = Array.IndexOf(findLName, findL);
if (pos > -1)
{
PrintStudent(findLName[pos]);
}
else
{
Write("No results found with that last name {0}.", findL);
}
}
static void PrintStudent(School student1)
{
Write(student1.ToString());
}
class School
{
private string lname;
private string fname;
private double gpa;
private string major;
private int id;
public School (string ln, string fn, string maj, int ident, double grade)
{
lname = ln;
fname = fn;
major = maj;
id = ident;
gpa = grade;
}
public string Lname
{
get
{
return lname;
}
set
{
lname = value;
}
}
public string Fname
{
get
{
return fname;
}
set
{
fname = value;
}
}
public string Major
{
get
{
return major;
}
set
{
major = value;
}
}
public override string ToString()
{
string student = lname + ", " + fname + "; " + id + " " + major + " " + gpa.ToString("D2");
return student;
}
UPDATE!: So I have confirmed that my array is populating my objects, however I'm wondering if those values are being passed properly to my methods.
Currently trying to search the array of objects with my FindLastName() method is only returning the else statement as if the values in the array do not exist.
UPDATE 2: After making some suggested changes, I'm about 80% confident my error lies within this method.
static void FindLastName(params School [] findLName)
{
for (int i = 0; i < findLName.Length; i++)
{
WriteLine(findLName[i]);
}
// The above loop proves that the objects exist within the array after being passed to the method.
Write("What is the last name? ");
string findL = ReadLine();
School foundStudent = null;
for (int i = 0; i < findLName.Length; i++)
{
if (findLName[i].Lname == findL)
{
foundStudent = findLName[i];
break;
}
}
if (foundStudent != null)
{
PrintStudent(foundStudent);
}
else
{
Write("No results found with that last name {0}.", findL);
}
// When I run this it returns the else statement even though I am using a last name that exists within the array
It looks to me like you are passing the parameters to GetInfo() in the wrong order, which ends up swapping the person's first name with their last name. So then later, when you're searching for someone by their last name, you will never get a match!
The function signature looks like this (with lastName as the FIRST argument):
static void GetInfo(out string lastn, out string firstn, out string mjr)
But you are calling it like this (with lastName as the SECOND argument):
GetInfo(out firstName, out lastName, out major);
So to resolve this issue, you just need to swap the positions of firstName and lastName in the line above.
Also, I just noticed that you are trying to format the GPA as a date, which will not work. You might consider changing this line:
gpa.ToString("D2")
to this (if you want to show one decimal place):
gpa.ToString("0.0")
You could utilise LINQ to make this search nice and easy with something like this:
string searchValue = PutSearchValueInHere();
School[] selectedStudentArray = schoolArray.Where(school=>school.SearchField == searchValue).ToArray();
School selectedStudent = selectedStudentArray[0]; //Assuming you used a primary key as your search field
Essentially how this works is you pick a field (likely a unique student ID) and a property of your class (eg .StudentID) then pass it into the extention method .Where of your array as a lambda expression. It will then return any items where the lambda evaluates to true.
The expression school=>school.SearchField == searchValue essentially means "Does the search value equal the SearchField of this school object, yes/no?" and it repeats this operation for every item in your array.
Next, the .ToArray() simply tells it to store the results as a new array.
After you've done this, assuming only one student fits the criteria, you are free to select the first item in the array. However, it might be worth checking to see if this is empty or not.
As an after-thought, I really can't help but feel that you should be storing student information in a SQL database and accessing it through an ODBC link, but that's something different entirely.
Based on the concepts it looks like you've learned so far, you probably want to change your logic a little bit in your search algorithm.
What you can do is create a Boolean variable to track whether or not you found any students, and start it off with false
Then loop through your array, one student at a time, and compare the last name to the one we're searching for
If we find the student, output their details and set our Boolean variable to true.
Outside of the loop, we can now just check to see if our variable is false, and if it is we can write the message that no students were found:
The reason using IndexOf wasn't working like you wanted it to is that you have to pass an object of the type stored in the array, and it has to be an exact match to one in the array (the Compare method of the class would return true).
...
static void FindLastName(params School[] findLName)
{
Write("What is the last name? ");
string findL = ReadLine();
// Create a variable to track if we find a match
bool foundStudent = false;
// Search through each array item
for (int i = 0; i < findLName.Length; i++)
{
// See if this item's last name is a match
if (findLName[i].LName == findL)
{
// If it is, set our variable to this student and break out of the for loop
PrintStudent(findLName[i]);
foundStudent = true;
}
}
// If our variable is false (or "not true" in the syntax here), we tell the user
if (!foundStudent)
{
Write("No results found with that last name {0}.", findL);
}
}

How to delete a data from an array in a database (C#)?

I am currently working on a Employee Database using C#. I have 4 different classes which makes up my database; Salaried Employee, Hourly Employee, Commission Employee, and Base-Salaried Employee. I have a base class called "employee" which holds the first name, last name and SSN of each employee type.
At the moment, I am able to individually print each employee when I run the code. I use a test input file which test what type of employee is in the file. It outputs it in an output file with its corresponding type of employee.
Now that, I am able to create an employee record, I also want to be able to remove an employee record from the array.
The method I have for this is called
private void DeleteEmployeeRecord()
{
Console.WriteLine("***** DeleteEmployeeRecord");
}
I am having trouble with getting started with this method. Any tips or idea on how I could delete an employee from the array?
Below is the code for the Employee Database in which does all the operations for the system such as creating a record for employee, finding a record of employee, deleting a record of employee, etc. As I've mentioned, I only have the Create method working and not the rest. I would gladly appreciate any help I can get with understanding how to delete an employee from my temporary array.
**EmployeeDB:**
using System;
using System.IO;
namespace PayrollDB
{
internal class EmployeeDB
{
public const string SALARIED = "SALARIED";
public const string BASEPLUS = "BASEPLUS";
public const string COMMISSION = "COMMISSION";
public const string HOURLY = "HOURLY";
public const char CREATE_C = 'C';
public const char CREATE_c = 'c';
public const char SALARIED_S = 'S';
public const char SALARIED_s = 's';
public const char BASEPLUS_B = 'B';
public const char BASEPLUS_b = 'b';
public const char COMMISSION_M = 'M';
public const char COMMISSION_m = 'm';
public const char HOURLY_H = 'H';
public const char HOURLY_h = 'h';
// storage for all the students during the database operations
private Employee[] employees;
public EmployeeDB()
{
}
internal void ReadDataFromInputFile()
{
// create and intialize the file objects
FileStream fstream = new FileStream("INPUT.txt", FileMode.Open, FileAccess.Read);
StreamReader infile = new StreamReader(fstream); // FileStream
int numberOfRecords = int.Parse(infile.ReadLine());
employees = new Employee[numberOfRecords];
for (int i = 0; i < employees.Length; i++)
{
string employeeType = infile.ReadLine();
// read in data for an employee
string firstName = infile.ReadLine();
string lastName = infile.ReadLine();
string socialSecurityNumber = infile.ReadLine();
// how many more things are there to read?
if(employeeType == SALARIED)
{
decimal weeklySalary = decimal.Parse(infile.ReadLine());
// make a employee using the data you just read
// put the employee into the array
employees[i] = new Salaried(firstName, lastName, socialSecurityNumber, weeklySalary);
}
else if(employeeType == BASEPLUS)
{
decimal grossSales = decimal.Parse(infile.ReadLine());
decimal commissionRate = decimal.Parse(infile.ReadLine());
decimal baseSalary = decimal.Parse(infile.ReadLine());
// make an employee using the data you just read
// put the employee into the array
employees[i] = new BasePlus(firstName, lastName, socialSecurityNumber, grossSales, commissionRate, baseSalary);
}
else if (employeeType == COMMISSION)
{
decimal grossSales = decimal.Parse(infile.ReadLine());
decimal commissionRate = decimal.Parse(infile.ReadLine());
// make a student using the data you just read
// put the student into the array
employees[i] = new Commission(firstName, lastName, socialSecurityNumber, grossSales, commissionRate);
}
else if (employeeType == HOURLY)
{
decimal hourlyWage = decimal.Parse(infile.ReadLine());
decimal hoursWorked = decimal.Parse(infile.ReadLine());
// make a student using the data you just read
// put the student into the array
employees[i] = new Hourly(firstName, lastName, socialSecurityNumber, hourlyWage, hoursWorked);
}
else
{
Console.WriteLine("ERROR: That is not a valid employee type.");
}
}
// close the file or release the resource
infile.Close();
}
internal void WriteDataToOutputFile()
{
// create and open an output file
FileStream fstream = new FileStream("OUTPUT.txt", FileMode.Create, FileAccess.Write);
StreamWriter outfile = new StreamWriter(fstream);
// write the size of the array
outfile.WriteLine(employees.Length);
// write the data from the objects in the array to the output file
foreach (var employee in employees)
{
if (employee is Hourly)
{
var hourly = (Hourly)employee;
outfile.Write(hourly.ToDataFileString());
}
else if (employee is Salaried)
{
var salaried = (Salaried)employee;
outfile.Write(salaried.ToDataFileString());
}
else if (employee is Commission)
{
var commission = (Commission)employee;
outfile.Write(commission.ToDataFileString());
}
else if (employee is BasePlus)
{
var baseplus = (BasePlus)employee;
outfile.Write(baseplus.ToDataFileString());
}
}
// close the output file
outfile.Close();
}
public void PrintAllRecords()
{
Console.WriteLine("** Contents of db ***************");
foreach (var emp in employees)
{
Console.WriteLine(emp);
}
}
// main method that operates the application once we get
// all the data read into it
internal void OperateDatabase()
{
// explain the program to the user
DisplayProgramExplanation();
ConsoleKeyInfo choice;
do
{
// user interface
PresentUserInterface();
//string choice = Console.ReadLine();
//selection = choice[0];
choice = Console.ReadKey();
switch(choice.KeyChar)
{
case CREATE_C:
case CREATE_c:
CreateEmployeeRecord();
break;
case 'F':
case 'f':
FindAndPrintEmployeeRecord();
break;
case 'U':
case 'u':
UpdateEmployeeRecord();
break;
case 'D':
case 'd':
DeleteEmployeeRecord();
break;
case 'P':
case 'p':
PrintAllEmployeeRecords();
break;
default:
break;
}
} while ((choice.KeyChar != 'Q') && (choice.KeyChar != 'q'));
}
private void FindAndPrintEmployeeRecord()
{
throw new NotImplementedException();
}
private void PrintAllEmployeeRecords()
{
Console.WriteLine("***** PrintAllEmployeeRecords");
}
private void DeleteEmployeeRecord()
{
Console.WriteLine("***** DeleteEmployeeRecord");
}
private void UpdateEmployeeRecord()
{
Console.WriteLine("***** UpdateEmployeeRecord");
}
// Find a student object in the array.
// Inputs: email - a string containing the email address of
// the student that is being searched for
// Output: the student object with a matching email, otherwise null ref
private Employee FindEmployeeRecord(string socialSecurityNumber)
{
// look through the collection at each employee
foreach (var emp in employees)
{
// if we find a student with matching social security number
if(emp.SocialSecurityNumber == socialSecurityNumber)
{
// return the object
return emp;
}
}
// if we get through the entire collection with no student
// object find that matches the search email,
// so return a null reference
return null;
}
private void CreateEmployeeRecord()
{
Console.WriteLine(" :: CreateStudentRecord");
//display prompt that asks for employee's social security number
Console.Write("Enter the social security number for the record to add: ");
//user types in the student email
string socialSecurityNumber = Console.ReadLine();
// check to see if record already exists in the database
// if it does, return back to main menu, issue a message
Employee emp = FindEmployeeRecord(socialSecurityNumber);
if(emp != null)
{
Console.WriteLine("Error: " + socialSecurityNumber + " is already in the database.");
return;
}
//display prompt that asks for type of student
Console.Write("Enter the type of employee: ");
ConsoleKeyInfo employeeType = Console.ReadKey();
//display prompt that asks for first name
Console.Write("Enter the first name: ");
string firstName = Console.ReadLine();
//display prompt that asks for last name
Console.Write("Enter the last name: ");
string lastName = Console.ReadLine();
// if type of student was U
if(employeeType.KeyChar == SALARIED_S || employeeType.KeyChar == SALARIED_s)
{
//display prompts for the weekly salary
Console.Write("Enter the weekly salary: ");
decimal weeklySalary = decimal.Parse(Console.ReadLine());
// make an undergrad student
emp = new Salaried(firstName, lastName, socialSecurityNumber, weeklySalary);
}
else if (employeeType.KeyChar == BASEPLUS_B || employeeType.KeyChar == BASEPLUS_b)
{
//if student type is BasePlus Employee prompt for base salary
Console.Write("Enter the Base Salary: ");
decimal baseSalary = decimal.Parse(Console.ReadLine());
// prompt for the Gross Sales
Console.Write("Enter the Gross Sales: ");
decimal grossSales = decimal.Parse(Console.ReadLine());
//prompt for the Commission Rate
Console.Write("Enter the Commission Rate: ");
decimal commissionRate = decimal.Parse(Console.ReadLine());
// make a grad student
emp = new BasePlus(firstName, lastName, socialSecurityNumber, grossSales, commissionRate, baseSalary);
}
else if (employeeType.KeyChar == COMMISSION_M || employeeType.KeyChar == COMMISSION_m)
{
// prompt for the Gross Sales
Console.Write("Enter the Gross Sales: ");
decimal grossSales = decimal.Parse(Console.ReadLine());
//prompt for the Commission Rate
Console.Write("Enter the Commission Rate: ");
decimal commissionRate = decimal.Parse(Console.ReadLine());
// make a grad student
emp = new Commission(firstName, lastName, socialSecurityNumber, grossSales, commissionRate);
}
else if (employeeType.KeyChar == HOURLY_H || employeeType.KeyChar == HOURLY_h)
{
//if student type is BasePlus Employee prompt for base salary
Console.Write("Enter the Hourly Wage: ");
decimal hourlyWage = decimal.Parse(Console.ReadLine());
// prompt for the Gross Sales
Console.Write("Enter the Hours Worked: ");
decimal hoursWorked = decimal.Parse(Console.ReadLine());
// make a grad student
emp = new Hourly(firstName, lastName, socialSecurityNumber, hourlyWage, hoursWorked);
}
else
{
Console.WriteLine(employeeType.KeyChar + " is not a type of employee.");
return;
}
//display the current student data and ask for confirm
// ask user to confirm
// the db saves the record, and returns to main menu - steps:
// and insert the newly created student object into the array
// 1 - make an array that is 1 "bigger" than students
Employee[] biggerEmployeeArray = new Employee[employees.Length + 1];
// 2 - copy all objects from students to the bigger array
// (at the same index val)
for (int i = 0; i < employees.Length; i++)
{
biggerEmployeeArray[i] = employees[i];
}
// put stu in the last slot in the bigger array
biggerEmployeeArray[biggerEmployeeArray.Length - 1] = emp;
// make the students ref point to the bigger array
employees = biggerEmployeeArray;
}
private void PresentUserInterface()
{
Console.WriteLine(#"
Select from the following options:
[C]reate (a new employee)
[F]ind (search for a record)
[U]pdate
[D]elete
[P]rint all records in the database
[Q]uit
");
}
private void DisplayProgramExplanation()
{
Console.WriteLine(#"
********************************************
Welcome to the Employee Database application.
You can execute most typical db commnds,
including
[C]reate, [R]ead [U]pdate, and [D]elete
for the employee records that are present.
");
}
}
}
AS far as I can see, you are not using a real database, but rather an In-Memory-Collection. If you want to keep it like that, you should use another data-structure than an array to store your employees.
You should use something like a Dictionary<string, Employee> where the Key is the social security number, or a HashSet<Employee> and implement GetHashCode() and Equals() in your Employee class.
That way you have collections that will auto-size and from which you can easily remove items using their Remove(...) method.
I suggest you to use a generic List.
private List<Employee> employees = new List<Employee>();
For that you need:
using System.Collections.Generic;
Then you can easliy add employee like this:
employees.Add(emp);
And remove the like this:
employees.Remove(emp);
Your delete method should ask for some kind if identifier so you can search for the right employee and remove him/her afterwards.

C#: Searching through arrays

I have a dvd app that stores dvds and blu-rays, I want to search the arrays by director. Below is the code for the inventory class I have seen many different ways to do this. There seems to be some debate as the best/most efficient way to accomplish this, any suggestions?
Blockquote
namespace MovieInventoryApplication
{
class Inventory
{
public Bluray[] BlurayMovies;
public DVD[] DVDMovies;
private int blurayCount;
private int dvdCount;
public Inventory()
{
BlurayMovies = new Bluray[5];
DVDMovies = new DVD[5];
blurayCount = 0;
dvdCount = 0;
}
public void AddBluray()
{
String strTitle;
int intReleaseYear;
int intRunningTimeMinutes;
String strDirector;
int intPrice;
int intRegionCode;
try
{
Console.Write("Enter a title: ");
strTitle = Console.ReadLine();
Console.Write("Enter a release year: ");
intReleaseYear = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the running time in minutes: ");
intRunningTimeMinutes = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the directors name: ");
strDirector = Console.ReadLine();
Console.Write("Enter a rental price: ");
intPrice = Convert.ToInt32(Console.ReadLine());
BlurayMovies[blurayCount] = new Bluray(strTitle, intReleaseYear, intRunningTimeMinutes, strDirector, intPrice);
blurayCount++;
Console.Write("Enter the DVD region code: ");
intRegionCode = Convert.ToInt32(Console.ReadLine());
DVDMovies[dvdCount] = new DVD(strTitle, intReleaseYear, intRunningTimeMinutes, strDirector, intPrice, intRegionCode);
dvdCount++;
}
catch (FormatException FormatException)
{
Console.WriteLine(FormatException.Message);
Console.WriteLine("Please enter a number in this field.");
}
}
public void AddDVD()
{
String strTitle;
int intReleaseYear;
int intRunningTimeMinutes;
String strDirector;
int intPrice;
int intRegionCode;
try
{
Console.Write("Enter a title: ");
strTitle = Console.ReadLine();
Console.Write("Enter a release year: ");
intReleaseYear = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the running time in minutes: ");
intRunningTimeMinutes = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the directors name: ");
strDirector = Console.ReadLine();
Console.Write("Enter a rental price: ");
intPrice = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the region code: ");
intRegionCode = Convert.ToInt32(Console.ReadLine());
DVDMovies[dvdCount] = new DVD(strTitle, intReleaseYear, intRunningTimeMinutes, strDirector, intPrice, intRegionCode);
dvdCount++;
}
catch (FormatException FormatException)
{
Console.WriteLine(FormatException.Message);
Console.WriteLine("Please enter a number in this field.");
}
}
public void ListAllBluray()
{
int position = 0;
while (BlurayMovies[position] != null)
{
Console.WriteLine(position + " " + BlurayMovies[position].strTitle);
position++;
}
}
public void ListAllDVD()
{
int position = 0;
while (DVDMovies[position] != null)
{
//position + 1 + " " +
Console.WriteLine(position + " " + DVDMovies[position].strTitle);
position++;
}
}
public void BlurayInfo(int position)
{
Console.WriteLine("Title: {0}", DVDMovies[position].strTitle);
Console.WriteLine("Release Year: {0}", DVDMovies[position].intReleaseYear);
Console.WriteLine("Running Time (Minutes): {0}", DVDMovies[position].intRunningTimeMinutes);
Console.WriteLine("Director: {0}", DVDMovies[position].strDirector);
Console.WriteLine("Price: {0}", DVDMovies[position].intPrice);
}
public void DVDInfo(int position)
{
Console.WriteLine("Title: {0}", DVDMovies[position].strTitle);
Console.WriteLine("Release Year: {0}", DVDMovies[position].intReleaseYear);
Console.WriteLine("Running Time (Minutes): {0}", DVDMovies[position].intRunningTimeMinutes);
Console.WriteLine("Director: {0}", DVDMovies[position].strDirector);
Console.WriteLine("Price: {0}", DVDMovies[position].intPrice);
Console.WriteLine("Region Code: {0}", DVDMovies[position].intRegionCode);
}
}
}
I think you have a flaw in the design.
The DVD and BluRay classes really should be either:
A single class with a Type property, probably an enum that would contain DVD and BluRay. This way, in several years once you get a new media, you can just add a value to the Enum and your application will be up to date.
Two different classes that implement a custom interface that you could call, say, IMedia.
Also, I highly suggest you take advantage of the List object in C# instead of arrays. It's very fast and you can add/remove items easily without having to resize your array.
Here's a lesson on Linq: http://www.functionx.com/csharp/linq/Lesson09.htm
Here's how I would create the Media class:
public class Media
{
public enum MediaType
{
DVD,
Bluray
}
public MediaType TypeOfMedia { get; set; }
public string Director { get; set; }
public string Title { get; set; }
public Media(string Title, string Director, MediaType TypeOfMedia)
{
this.TypeOfMedia = TypeOfMedia;
this.Director = Director;
this.Title = Title;
}
}
And here's an example how to use it:
List<Media> data = new List<Media>();
results.Add(new Media("Movie 1", "John D", Media.MediaType.DVD));
results.Add(new Media("Movie 2", "John D", Media.MediaType.DVD));
results.Add(new Media("Movie 3", "SomeOtherDirector", Media.MediaType.Bluray));
results.Add(new Media("Movie 4", "John D", Media.MediaType.Bluray));
IEnumerable<Media> listDirectors = from media in data
where media.Director == "John D"
select media;
foreach (Media media in listDirectors)
Console.WriteLine(media.Title);
Another example, your "List DVD" and "List Bluray" functions could really be a single function:
private void ListMediaByType(List<Media> data, Media.MediaType type)
{
foreach (Media media in data.Where(media => media.TypeOfMedia == type))
Console.WriteLine(media.Title);
}
As you see, these techniques simplifies querying by a LOT. :)
The most easies (imho) is using Linq:
string director = "Alfred Hitchcock";
IEnumerable<DVD> dvds = DVDMovies.Where(dvd => dvd.Director == director);
IEnumerable<DVD> blueRays = BlurayMovies.Where(br => br.Director == director);
List<DVD> allMatches = new List<DVD>();
allMatches.AddRange(dvds.Concat(blueRays));

Categories