I have a question, I want to know how i can show on CONSOLE the 2 highest of N entered numbers? Im doing something like this:
Console.WriteLine("Enter the weight of the fish:");
if(decimal.TryParse(Console.ReadLine(), out _fishWeight))
{
if (_fishWeight > _highest2)
{
_highest = _fishWeight;
if (_fishWeight < _highest1)
{
_highest = _fishWeight;
}
}
}
but it doesn't work. It only shows me the _highest1 but not the other _highest...
If someone can help me, I would be really glad!
you want something more like
if (_fishweight > _highest)
{
_highest2 = _highest;
_highest = _fishweight;
}
else if(_fishweight > _highest2)
{
_highest2 = _fishweight;
}
Alternatively If you want a more flexible leaderboard
// declare something like...
private List<int> _leaderboard = new List<int>();
private readonly int _leaderboardCount = 2;
// then update it like...
_leaderboard.Add(_fishweight);
_leaderboard = _leaderboard.OrderByDescending(v => v).Take(_leaderboardCount).ToList();
Now you have the top 2, but you can easily change it to a top 10 later on if you want.
Math.Max() is your friend here. No need to do manual comparison, just feed in two values, it'll output the highest of them and just set that to your _heighestWeight.
while (true)
{
Console.Write("Enter the weight of the fish: ");
var input = Console.ReadLine();
if (decimal.TryParse(input, out _fishWeight))
{
break;
}
Console.WriteLine("Please only enter a decimal number");
Console.Clear();
}
_heighestWeight = Math.Max(_fishWeight, _heighestWeight);
I also added a while loop in case they input something other than a decimal.
Related
I'm writing a program that displays a fast food menu and it allows the user to select an item. Then, the user enters the quantity of that item, and can continue selecting items with specific quantities until done. What I'm having trouble with is finding out how to calculate a running total. I am new to c# so I only know the basics. What is the best way to keep track of the running total while using multiple methods? In addition, I'm open to any criticism in my code. Thank you in advance.
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
bool ordering = true;
string userInput;
double itemPrice;
double itemQuantity;
double subTol;
string response;
void pricing()
{
Console.Write("Enter option 1, 2, 3: ");
userInput = Console.ReadLine();
switch (userInput)
{
case "1":
itemPrice = 3.00;
Console.WriteLine("You have picked a burger.");
break;
case "2":
itemPrice = 1.50;
Console.WriteLine("You have picked fries.");
break;
case "3":
itemPrice = 1.00;
Console.WriteLine("You have picked a soda.");
break;
default:
Console.WriteLine("That is not on our menu.");
pricing();
break;
}
}
void quantity()
{
Console.Write("Enter quantity: ");
itemQuantity = Convert.ToDouble(Console.ReadLine());
}
void subTotal()
{
subTol = itemQuantity * itemPrice;
Console.WriteLine();
Console.WriteLine("Your Subtotal: " + subTol);
}
while (ordering)
{
Console.WriteLine("What would you like from our menu?");
Console.WriteLine("\n1. Burger ($3.00) \n2. Fries ($1.50) \n3. Soda ($1.00)");
Console.WriteLine();
pricing();
quantity();
subTotal();
Console.Write("Would you like anything else? Y/N: ");
response = Console.ReadLine();
response = response.ToUpper();
if (response == "Y")
{
ordering = true;
}
else
{
ordering = false;
Console.WriteLine("Enjoy your meal!");
}
}
}
}
}
First of all, for the
If(response==“Y”)
Part you can actually just say
ordering = response == “Y”;
Also, this would only accept uppercase y. String.EqualsIgnoreCase() or something similar would probably do a better job
ordering = response.equalsIgnoreCase(“Y”);
You could keep a list of how many of each item the person has ordered, like
Int burgers = 0; and so on.
Then for the total, you could get 3*burgers + 1.5*fries and so on. However, if you want custom orders, using a struct might be better. For example, a struct could contain a type(burger or fries) and a price, depending on how many additions they have. You could also just add the price of each item to a total every time you order. This seems like a fun project, and I hope I could help!
For keeping track of total, the best approach would be to have a list of ordered items with their quantities, where you go and put each order from the user.
When you want to calculate the subtotal or total, you just go and compute from the list.
Here are some insights on how you can accomplish that, with some changes to the code you shared. Check the comments for details and reasoning.
namespace ConsoleApp1{
// creating record classes to store structured data
record MenuItem(string Product, decimal Price);
record Order(MenuItem Item, int Quantity);
class Program {
static void Main(string[] args) {
// better to keep your menu options & prices in a central place,
// instead of hardcoding them everywhere
List<MenuItem> menu = new() {
new ("Burger", 3.00M),
new ("Fries", 1.50M),
new ("Soda", 1.00M),
};
// this is a list to store the ordered items so far
List<Order> orders = new();
// moved most of the procedures to separate functions
do {
PrintMenu(menu);
var item = InputItem(menu);
var quantity = InputQuantity();
orders.Add(new Order(item, quantity));
PrintSubTotal(orders);
} while (CheckIfContinue());
PrintTotal(orders);
ByeBye();
}
static void PrintMenu(List<MenuItem> menu) {
// print each menu entry in a loop
Console.WriteLine("What would you like from our menu?");
for (int i = 0; i < menu.Count; i++) {
// adding 1 to the index for printing, because in c# indexes start at 0
Console.WriteLine($"{i + 1}: {menu[i].Product} (${menu[i].Price})");
}
Console.WriteLine();
}
static MenuItem InputItem(List<MenuItem> menu) {
// enter a loop, will be broken only if the input is correct
while (true) {
Console.Write($"Enter option: 1 to {menu.Count}: ");
if (int.TryParse(Console.ReadLine(), out int i) && i > 0 && i <= menu.Count) {
// must subtract 1 from the index, because indexes start from 0 in c#
Console.WriteLine($"You have picked {i}: {menu[i - 1].Product}.\n");
// if the input is a valid int
return menu[i - 1];
}
Console.WriteLine("That is not in our menu.\n");
}
}
static int InputQuantity() {
// same thing here, will repeat the loop unless the input is valid
while (true) {
Console.Write("Enter quantity: ");
if (int.TryParse(Console.ReadLine(), out int i) && i > 0) {
return i;
}
Console.WriteLine("Invalid quantity.\n");
}
}
static void PrintSubTotal(List<Order> orders) {
// using LINQ to iterate the list of orders sum up the prices x quantities
Console.WriteLine($"Your Subtotal: ${orders.Sum(o => o.Item.Price * o.Quantity)}\n");
}
static bool CheckIfContinue() {
Console.Write("Would you like anything else? Y/N: ");
// will return True if the input is y
return Console.ReadLine()?.Trim().ToUpper() == "Y";
}
static void PrintTotal(List<Order> orders) {
Console.WriteLine($"Your Order:");
foreach (var order in orders) {
// subtotal for each order item
Console.WriteLine($"{order.Item.Product, -10} x{order.Quantity, -4}: ${order.Item.Price * order.Quantity}");
}
// total for the whole order
Console.WriteLine($"---------- Total: ${orders.Sum(o => o.Item.Price * o.Quantity)}\n");
}
static void ByeBye() {
Console.WriteLine("Enjoy your meal!");
}
}
}
I completed an exercise and wrote this code:
var random = new Random();
var number = random.Next(1, 10);
Console.WriteLine(number);
var control = 0;
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Enter a number: ");
var guessedNumber = Convert.ToInt32(Console.ReadLine());
if (guessedNumber == number)
{
Console.WriteLine("You won");
control = 1;
break;
}
}
if (control == 0)
{
Console.WriteLine("You lost");
}
And the answer is this:
var number = new Random().Next(1, 10);
Console.WriteLine("Secret is " + number);
for (var i = 0; i < 4; i++)
{
Console.Write("Guess the secret number: ");
var guess = Convert.ToInt32(Console.ReadLine());
if (guess == number)
{
Console.WriteLine("You won!");
return;
}
}
Console.WriteLine("You lost!");
I have added the control variable because if I didn't even if the user guessed the number it would still display "You lost".
Can someone explain what does "return" do in the other code and why if the user guesses the correct number it doesn't display "You lost"?
The Code is as I suppose packed in a function or main.
This function has a return type.
The function here maybe looks like this:
public void NumberGuessing()
{
.... code here ....
}
With the return statement you jump directly out of this block.
As the return type of the function is void, there is no value and a simple return will jump out of the function and everything after the return statement is not executed.
The break just exits the loop, but not the function.
your function is supposed to stop when you find the correct answer so return seems more logical, it eliminates the need for your extra control variable making the code simpler to read and less error prone (e.g. for changes in the future like find two correct answers).
I have 2 arrays one of the types of numbers that will be used and the 2nd array is how many times that number can be used. I have a letter that determines what kind of method will be used I need to figure out how many times I can use a certain number from an array to determine a letter+number The ‘number’ is what I have to make with all the available numbers I can use. If the number cannot be made I would like to just say number cant be made or anything but allow the program to move on.
Here is what I have
int[] picksToUse = { 100, 50, 20, 10, 5, 1 };
int[] timesToUse = { 10, 10, 10, 10, 10, 10 };
string choice = Console.ReadLine();
string input = "";
if(choice.Length > 2)
{
input = choice.Substring(choice.IndexOf("$") + 1);
}
if(...){
}
else if (choice.Equals("D"))
{
int amt = Convert.ToInt32(input);
// code here to determine if number can be made with above choices
Dispense(amt, timesToUse);
}
Assuming picksToUse and timesToUse are exactly the same as you declared them, here's a way to know if you have enough of everything in stock to "pay up". It's a boolean function, which uses recursion. You would call it with the amount needed as parameter, and it would tell you right there if you have enough of everything.
Private Function HasCashInStock(amount As Integer, Optional index As Integer = 0) As Boolean
Dim billsNeeded As Integer = amount \ picksToUse(index)
If billsNeeded > timesToUse(index) Then
Return False
End If
amount -= picksToUse(index) * billsNeeded
If amount = 0 Then
Return True
End If
Return HasCashInStock(amount, index + 1)
End Function
The \ is an integer division operator (in VB.NET, at least - I'm shamelessly letting you translate this code). If you're not familiar with the integer division operator, well, when you use it with integer it gets rid of the floating numbers.
3 / 2 is not valid on integers, because it would yield 1.5.
3 \ 2 is valid on integers, and will yield 1.
That's all there is to it, really. Oh yeah, and recursion. I like recursion, but others will tell you to avoid it as much as you can. What can I say, I think that a nice recursive function has elegance.
You can also totally copy this function another time, modify it and use it to subtracts from your timesToUse() array once you know for sure that there's enough of everything to pay up.
If HasCashInStock(HereIsTheAmountAsInteger) Then
GivesTheMoney(HereIsTheAmountAsInteger)
End If
Having two functions is not the leanest code but it would be more readable. Have fun!
This is what I used to finish my project.
public static bool Validate(int amount, int[] total, int[] needed)
{
int[] billCount = total;
int[] cash = { 100, 50, 20, 10, 5, 1 };
int total = amount;
bool isValid = true;
for (int i = 0; i < total.Length; i++)
{
if(total >= cash[i])
{
billCount[i] = billCount[i] - needed[i];
}
if(billCount[i] < 0)
{
isValid = false;
break;
}
}
return isValid;
}
I got some working code. I did it with a class. I remember when I couldn't see what good classes were. Now I can't brush my teeth without a class. :-)
I force myself to do these problems to gain a little experience in C#. Now I have 3 things I like about C#.
class ATM
{
public int Denomination { get; set; }
public int Inventory { get; set; }
public ATM(int denom, int inven)
{
Denomination = denom;
Inventory = inven;
}
}
List<int> Bills = new List<int>();
List<ATM> ATMs = new List<ATM>();
private void OP2()
{
int[] picksToUse = { 100, 50, 20, 10, 5, 1 };
foreach (int d in picksToUse )
{
ATM atm = new ATM(d, 10);
ATMs.Add(atm);
}
//string sAmtRequested = Console.ReadLine();
string sAmtRequested = textBox1.Text;
if (int.TryParse(sAmtRequested, out int AmtRequested))
{
int RunningBalance = AmtRequested;
do
{
ATM BillReturn = GetBill(RunningBalance);
if (BillReturn is null)
{
MessageBox.Show("Cannot complete transaction");
return;
}
RunningBalance -= BillReturn.Denomination;
} while (RunningBalance > 0);
}
else
{
MessageBox.Show("Non-numeric request.");
return;
}
foreach (int bill in Bills)
Debug.Print(bill.ToString());
Debug.Print("Remaining Inventory");
foreach (ATM atm in ATMs)
Debug.Print($"For Denomination {atm.Denomination} there are {atm.Inventory} bills remaining");
}
private ATM GetBill(int RequestBalance)
{
var FilteredATMs = from atm in ATMs
where atm.Inventory > 0
orderby atm.Denomination descending
select atm;
foreach (ATM bill in FilteredATMs)
{
if (RequestBalance >= bill.Denomination )
{
bill.Inventory -= 1;
Bills.Add(bill.Denomination);
return bill;
}
}
return null;
}
This question already has answers here:
Return multiple values to a method caller
(28 answers)
Closed 7 years ago.
Apologies on the duplicate question, I viewed similar Qs and just got confused. I have a method that is prompting a user to enter 5 different attribute values and would like to return the values chosen to be used for later decisions in the program.
while (true)
{
Console.Write("Please enter a value between 0-10 for ingenuity: ");
inputIngenuity = Console.ReadLine();
if (!UInt32.TryParse(inputIngenuity, out validIngenuity))
{
Console.WriteLine();
Console.WriteLine("Input was not a valid value for ingenuity.");
}
else if (validIngenuity < 0 || validIngenuity > 10)
{
Console.WriteLine();
Console.WriteLine("Input was not a valid value for ingenuity.");
}
else if (validIngenuity > (attributePoints - validStrength - validIntelligence - validPersonality - validSpeed))
{
Console.WriteLine();
Console.WriteLine("You do not have enough attribute points remaining.");
}
else break;
}
Console.WriteLine();
Console.WriteLine("You have " + (attributePoints - validStrength - validSpeed - validPersonality - validIntelligence - validIngenuity) + " attribute points remaining");
Console.WriteLine();
Console.WriteLine(String.Format("Strength Value = {0}", validStrength));
Console.WriteLine(String.Format("Speed Value = {0}", validSpeed));
Console.WriteLine(String.Format("Intelligence Value = {0}", validIntelligence));
Console.WriteLine(String.Format("Personaility Value = {0}", validPersonality));
Console.WriteLine(String.Format("Ingenuity Value = {0}", validIngenuity));
Console.WriteLine();
Console.WriteLine("These are your attributes!");
while (true)
{
Console.Write("Do you accept these? Type 1 for Yes, Type 2 for No. If No then choose again: ");
areYouHappyWithChoices = Console.ReadLine();
if (!UInt32.TryParse(areYouHappyWithChoices, out validChoices))
Console.WriteLine("Please try again. Enter 1 for Yes and 2 for No");
else if (validChoices > 2 || validChoices < 1)
Console.WriteLine("Please try again. Enter 1 for Yes and 2 for No");
else if (areYouHappyWithChoices == "2")
chooseAttributePoints(); //this method contains the whole routine
else
Console.WriteLine("We may now begin the game!");
break;
}
UInt32[] attributePointArray = new UInt32[5] { validStrength, validSpeed, validIntelligence, validPersonality, validIngenuity };
return attributePointArray;
The while statement for ingenuity is repeated in the method for the other 4 attributes and works without issues. I'm envisioning later code that would have different results based on how strong the user is for example. Am I going in the right direction by trying to put the values into an array? Thank you.
That would be one way to do it, however I think you'd be better off having a class or struct created to represent the data. This way you'll keep the "strong typey ness" and context of what your data is, rather than simply an array index.
example:
public class Person
{
public int Strength { get; private set; }
public int Speed { get; private set; }
public int Intel { get; private set; }
public int Personality { get; private set; }
public int Ingenuity { get; private set; }
public Person (int strength, int speed, int intel, int personality, int ingenuity)
{
this.Strength = strength;
this.Speed = speed;
this.Intel = intel;
this.Personality = personality;
this.Ingenuity = ingenuity;
}
}
Then your assignment to array:
UInt32[] attributePointArray = new UInt32[5] { validStrength, validSpeed, validIntelligence, validPersonality, validIngenuity };
return attributePointArray;
Gets updated to:
return new Person(validStrength, validSpeed, validIntelligence, validPersonality, validIngenuity);
and your return type needs to be changed from uint[] to Person
This way, rather than having to remember that returnedArray[1] is Speed (or whatever) - you would simply use returnedPerson.Speed.
You should create an object type that wraps the attributes you want to return. The return type of your method will be your newly-created object type.
Ai'm new here and new in programming as well. I'm sorry if this question is really childish but i'm having some trouble using return type in a simple c# program.
Here is my code file, at d == 2 in AccountTest class, I want the withdrawal process to start over again but this time not asking the user to enter the account balance. A friend advice to use while loop but I have no idea how to use while loop over here. Thanks in advance. :)
using System;
public class Account
{
public static void Main(string[] args)
{
Console.Write("Enter your account balance: ");
int AccountBalance = Convert.ToInt32(Console.ReadLine());
Account.Debit(AccountBalance);
}
public static void Debit(int AccountBalance)
{
Console.Write("\n\nEnter the amount you want to withdraw in Rs: ");
int WithdrawalAmount = Convert.ToInt32(Console.ReadLine());
AccountTest.DebitTest(AccountBalance, WithdrawalAmount);
}
}
And my Account class
public class AccountTest
{
public static int DebitTest(int AccountBalance, int WithdrawalAmount)
{
if (WithdrawalAmount > AccountBalance)
{
Console.WriteLine("\n\nDebit amount exceeded account balance.");
Console.ReadLine();
return 0;
}
else if (WithdrawalAmount <= 0)
{
Console.WriteLine("\n\nError. Incorrect amount.");
Console.ReadLine();
return 0;
}
else
{
int newBalance = AccountBalance - WithdrawalAmount;
Console.WriteLine("\n\nWithdrawal was successful. Thankyou for using our services.\n\nPress 1 to exit, 2 to withdraw again, 3 to check your account balance.\n");
int InputNumber = Convert.ToInt32(Console.ReadLine());
if (InputNumber == 1)
{
Console.ReadLine();
return 0;
}
else if (InputNumber == 2)
{
return WithdrawalAmount;
}
else if (InputNumber == 3)
{
Console.WriteLine("\n\nYour remaining account balance is: {0}", newBalance);
Console.ReadLine();
return 0;
}
}
return 0;
}
}
Really the code should be refactored. Treating an Account like a thing makes more sense, in that it should be it's own object, and you should tell it what to do:
public class Account
{
public int Balance { get; set; }
public Account(int startBalance)
{
Balance = startBalance;
}
public void Debit(int amount) { Balance -= amount; }
public void Credit(int amount) { Balance += amount; }
}
Now, you can ask the user what they want to do with their Account, and you have room to add multiple accounts. So the program may look like:
int startingAmount = int.Parse(Console.ReadLine());
var account = new Account(startingAmount);
Console.WriteLine("1 to credit, 2 to debit, 0 to exit");
var input = int.Parse(Console.ReadLine());
while (input != 0)
{
//manipulate account
}
I'd start by reading up about static vs instance objects
first of, welcome to the coding community there is no childish question feel free to ask when ever you need, there some who will answer you with "google has the answer" but no worries a lot of other will help you, i saw you already selected an answer but ill add my point of view for you and the rest of new programmers.
a. if your new to codding never start with code it will only complicate things, instead start with a flow chart that illustrates what you to achieve from the program and from each component ( classes,functions etc. ) after you got that, its a lot easier to transform it to code, you can try using this site
it seems to be very user friendly and will draw you flow charts with the correct format.
b. like people here said before me never use variable like a,b,c because the next day youll try to continue where you left off and you will forget what you meant.
c. try to think of ways to use code to prevent repeating yourself.
d. using hard coded values is bad practice (hard coded means this:
return "this value to return is hard coded and will never change";
)
by the time i got to answer your question i already saw #Jonesy answer which is right and like what
i wanted to suggest so ill leave you with his answer.
hope this helps someone :)
The loop can be implemented in the Debit method:
public static void Debit(int AccountBalance)
{
int result = 0;
do
{
Console.Write("\n\nEnter the amount you want to withdraw in Rs: ");
var WithdrawalAmount = Convert.ToInt32(Console.ReadLine());
result = AccountTest.DebitTest(AccountBalance, WithdrawalAmount);
} while (result != 0);
}
You should read up on while loops. Basically what you'd want is the method to return a number that decides what the program is supposed to do next, or when it should end. Think of the loop as your engine that states "As long as [chosen key] is not pressed, keep doing something".
A small example, with [chosen key] being 1, would be:
int choice = 0;
int balance = 100;
while (choice != 1) {
Console.WriteLine("Enter withdraw amount");
string userInput = Console.ReadLine();
// This will crash the program if the user enters text.
// Used for demonstration only. int.TryParse is preferred.
int value = int.Parse(userInput);
choice = AccountTest.DebitTest(balance, value);
}
class AccountTest {
public static int DebitTest(int AccountBalance, int WithdrawalAmount)
{
// do the test if the debit is OK
//..........
// At the end, you can do this. This till return the value entered and
// choice will be given a new value. If it was 1, the program will end.
// NOTE: It's not safe to use convert as
// it will crash the program if the user enters text.
return Convert.ToInt32(Console.ReadLine());
}
}
Note that this is not a functional ATM-program, as the balance never gets updated. I leave that for you to solve since I'm guessing this is for a class in programming =)
Well, this is my version of your program. I changed the behavior a bit (like asking again when the value is invalid). It's not perfect; for example, the messages and the RequestDebit method should be handled outside the Account class, perhaps in an AccountHandler class, but all this might be overkill for this simple exercise. Anyway I hope you find it useful:
public class Account
{
public int Balance { get; set; }
public Account(int startingBalance)
{
this.Balance = startingBalance;
}
private bool Debit(int amount)
{
if (amount <= 0)
{
Console.WriteLine("\n\nError. Incorrect amount.");
return false;
}
if (amount > this.Balance)
{
Console.WriteLine("\n\nDebit amount exceeded account balance.");
return false;
}
this.Balance -= amount;
Console.WriteLine("\n\nWithdrawal was successful. Thankyou for using our services.");
return true;
}
public void RequestDebit()
{
bool success;
do
{
Console.Write("\n\nEnter the amount you want to withdraw in Rs: ");
int withdrawalAmount = Convert.ToInt32(Console.ReadLine());
success = this.Debit(withdrawalAmount);
} while (!success);
}
}
class Program
{
static void Main(string[] args)
{
int accountBalance;
do
{
Console.Write("Enter your account balance: ");
accountBalance = Convert.ToInt32(Console.ReadLine());
} while (accountBalance <= 0);
var myAccount = new Account(accountBalance);
myAccount.RequestDebit();
int inputNumber;
do
{
Console.WriteLine("\n\nPress 1 to exit, 2 to withdraw again, 3 to check your account balance.\n");
inputNumber = Convert.ToInt32(Console.ReadLine());
switch (inputNumber)
{
case 2: myAccount.RequestDebit();
break;
case 3:
Console.WriteLine("\n\nYour remaining account balance is: {0}", myAccount.Balance);
break;
}
} while (inputNumber != 1);
}
}