I'm an extreme beginner, only a few days into learning, so sorry if this is an obvious question.
I'm trying to use ReadLine() to get the user to enter a string (Rock, Paper or Scissors), then use an if statement to assign a variable of the same names a number 1-3 and then return to break out of the statement and then write the value in Main(). I've done the first one here b/c no point doing the rest (again) if it doesn't work for one.
The error messages from VS Code are
There is no argument given that corresponds to the required formal parameter 'choice' of 'RockPaperScissors.Method()'
and
Not all code paths return a value
What am I forgetting/misunderstanding?
using System;
class RockPaperScissors
{
static int Method()
{
string playerString = Console.ReadLine();
int rock = 1;
if (playerString == "Rock")
{
int choice = rock;
return choice;
}
}
static void Main()
{
int Move = Method();
Console.WriteLine(Move);
}
}
As it is mentioned in the error, your code handle only one use case, and it didn't return an integer for the rest of cases.
This may help:
static int Method()
{
var playerString = Console.ReadLine();
switch (playerString)
{
case "Rock":
return 1;
case "Paper":
return 2;
case "Scissors":
return 3;
default:
// when the input data is not one of the previous strings
// it throws an exception so it should be catched and handled
throw new Exception("Not valid input");
}
}
Or, making the code easier to read by using an enum:
public enum HandSign
{
Rock, // rock beats scissors
Paper, // paper beats rock
Scissors, // scissors beats paper
}
Which allows this:
public static HandSign GetUserChoice()
{
HandSign result = default;
bool isCorrectEntry = false;
while (!isCorrectEntry)
{
Console.Write(#"Enter choice (Rock/Paper/Scissors): ");
var enteredText = Console.ReadLine();
isCorrectEntry = Enum.TryParse<HandSign>(enteredText, ignoreCase:true, out result);
}
return result;
}
Notice that it will prompt you over and over again until you spell scissors correctly. It also ignores the case of the entered text.
static int Method()
{
string playerString = Console.ReadLine();
int rock = 1;
if (playerString == "Rock")
{
int choice = rock;
return choice;
}
return rock;
}
Related
I am writing a program that will ask the user to enter a number. I have coded that, but what I am struggling to add is a part where it will ask the user again if they entered a character or never answered the question in the first place. I want this done to all my questions that I ask them since they are all asking for an Integer.
using System;
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("---welcome to split my bill---");
Console.Write("What is the total bill?: £");
float bill_total = Convert.ToSingle(Console.ReadLine());
Console.Write("How many people are sharing?:");
int people = Convert.ToInt32(Console.ReadLine());
Console.Write("What percentage tip would you like to leave?:");
float tip_percentage = Convert.ToSingle(Console.ReadLine());
float percentage_decimal = tip_percentage/100;
float tip_total = bill_total * percentage_decimal;
bill_total = bill_total + tip_total;
float CostPerPerson = bill_total/people;
Console.WriteLine("Total Bill including tip is: £"+bill_total);
Console.WriteLine("Total cost per person is: £"+CostPerPerson);
}
}
any help?
Since you are learning C#, think a bit more general and write a function to handle user inputs with repeats if they type something wrong.
class Program
{
static void Main(string[] args)
{
float totalBill = AskForNumber("What is the total bill?");
}
static float AskForNumber(string prompt)
{
while (true)
{
Console.WriteLine(prompt);
var input = Console.ReadLine();
if (float.TryParse(input, out float value))
{
return value;
}
Console.WriteLine("Invalid Input. Try again.");
}
}
}
The problem with the above method is that the user has no way of exiting the program unless they press Ctrl-C which is not very graceful.
You need to learn of about out parameters for functions, and then you can write the function to input a value and return true if the program should proceed, or false if it needs to exit. The value itself is assigned to the variable designated with the out keyword.
Below is an example of the whole process. Each step proceeds only if the previous function returned true. If a user enters a blank line, then the program will exit as the return value is going to be 'false' and the program is not going to continue inside the if() statement.
class Program
{
static void Main(string[] args)
{
if (AskForNumber("What is the total bill?", out float totalBill))
{
if (AskForInteger("How many people are sharing?", out int people))
{
if (AskForNumber("What percentage tip would you like to leave?", out float tipPercent))
{
float tip_total = totalBill * (tipPercent/100);
totalBill += tip_total;
float costPerPerson = totalBill/people;
Console.WriteLine("Total Bill including tip is: £"+totalBill);
Console.WriteLine("Total cost per person is: £"+costPerPerson);
}
}
}
}
static bool AskForNumber(string prompt, out float value)
{
while (true)
{
Console.WriteLine(prompt);
var input = Console.ReadLine();
if (float.TryParse(input, out value))
{
return true;
}
if (input.Length == 0)
{
return false;
}
Console.WriteLine("Invalid Input. Try again.");
}
}
static bool AskForInteger(string prompt, out int value)
{
while (true)
{
Console.WriteLine(prompt);
var input = Console.ReadLine();
if (int.TryParse(input, out value) && value>0)
{
return true;
}
if (input.Length == 0)
{
return false;
}
Console.WriteLine("Invalid Input. Try again.");
}
}
}
I have typed up some code to try and practice what I have learned in my programming course. Something is wrong with my logic as I am not getting the answer I am supposed to get.
I have searched and google and rewatched the training videos but nothing seems to help.
namespace TenPinBowling
{
class Program
{
static void Main(string[] args)
{
while (true)
{
Console.Write("Would you like to bowl, Y or N: ");
var answer = Console.ReadLine();
if (answer == "n")
{
Console.WriteLine("Thanks for playing, press any to exit :)");
Console.ReadKey();
break;
}
Score();
}
}
static void Score()
{
{
Random pins = new Random();
var pinsKnockedDown = pins.Next(0, 10);
//var totalScore = 0;
Console.WriteLine("You bowled a: " + pinsKnockedDown);
//var result = totalScore + pinsKnockedDown;
Console.WriteLine("You're total score is: " + Tally(pinsKnockedDown));
}
}
static int Tally(int score)
{
{
int result = 0;
result = result + score;
return result;
}
}
}
}
I was hoping my second method would keep a running total of my score but it resets to the individual score every time.
In
static int Tally(int score)
{
{
int result = 0;
result = result + score;
return result;
}
}
you create a new local variable result each time you invoke the method, so the record of past scores is lost. Making result a field of the class would allow it to persist for the duration of the game. A minimal code change might be:
private static int result = 0;
static int Tally(int score)
{
result = result + score;
return result;
}
I would guess you always need to keep track of your total score, if it should not reset. Right now you always add the current score to zero (in Tally). If you put int result outside of tally it should keep track accordingly.
I'm trying to get a user to input 1 value into the array, and then exit to main menu, then the next person to enter a value gets his put into the next bracket, not replace slot 0, currently it just loops the first array bracket and replaces the number. Help would be much appreciated
static void Main(string[] args)
{
int[] myArray = new int[10];
while (true)
{
int enteredNumber;
Startmenu();
enteredNumber = Convert.ToInt32(Console.ReadLine());
if (enteredNumber == 1)
{
for (int i = 0; i < myArray.Length; i++)
{
Console.WriteLine("Insert Number:");
myArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.Clear();
Console.WriteLine("blabla");
Thread.Sleep(2000);
Console.Clear();
}
if (enteredNumber == 9)
{
if (Login(1234, 3) == true)
{
foreach (int number in myArray)
{
Console.WriteLine(number);
}
}
}
}
}
One problem I think you have in that code is that you're trying to do too much in one method. You might want to break out discreet operations into separate methods, which will both enable code reuse and also serve to make your code more readable.
First, you need a method that will get an int from the user. Let's write a helper method that does that, which takes in a string that will be displayed as a prompt to the user, and which will continue to prompt them until they enter a valid int. We can use int.TryParse to determine if they enter a valie int. It takes a string argument to parse, and an out int that will contain the parsed value if it succeeds. The method itself returns true if it was successful:
private static int GetIntFromUser(string prompt)
{
int result;
do
{
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out result));
return result;
}
You don't show the code for ShowMenu, but it probably gives the user some menu choices, and I've added the functionality where it returns the menu choice entered by the user:
private static int ShowMenu()
{
int menuChoice;
do
{
Console.Clear();
Console.WriteLine("Main Menu:");
Console.WriteLine("1. Input an array item");
Console.WriteLine("9. Print the numbers\n");
menuChoice = GetIntFromUser("Enter your choice (1 or 9): ");
} while (menuChoice != 1 && menuChoice != 9);
return menuChoice;
}
Now, another thing you seem to be missing that might help here, is to add a "pause" to the program after printing out the array items, so the user has a chance to see them. I think this is probably the main problem. Currently you write them all out to the screen, then the while loop runs again and you don't get a chance to see it. Here's a helper method that asks the user to press a key when they're ready, and then waits for the user to press a key:
private static void WaitForUserInput()
{
Console.Write("\nPress any key to continue...");
Console.ReadKey();
}
We can also put the code to populate the array in a separate method. Since you want to enable the user to populate only one item at a time, we will need to keep track of which item is the next one to populate, so we'll set a class-level variable for that, and make use of it in the method. We'll populate that item, then increment the variable. Of course we have to first make sure the next item is not greater than the number of items available:
private static int NextIndexToPopulate = 0;
private static void PopulateNextArrayItem(int[] array)
{
if (array == null) return;
if (NextIndexToPopulate >= array.Length)
{
Console.WriteLine("The array is full; no items left to enter.");
WaitForUserInput();
}
else
{
array[NextIndexToPopulate] = GetIntFromUser("Enter number to insert: ");
NextIndexToPopulate++;
}
}
And another method can be used to print out the array:
private static void PrintArray(int[] array)
{
if (array == null)
{
Console.WriteLine("The array is null - nothing to print.");
}
else
{
Console.WriteLine("Here are the array items entered:");
for (int i = 0; i < NextIndexToPopulate; i++)
{
Console.WriteLine(array[i]);
}
}
}
You also didn't show the Login code, so here's a dummy method I'll use that always returns true:
private static bool Login(int first, int second)
{
return true;
}
Now, with all that extra stuff encapsulated in methods, our main code becomes a little more readable, there's less chance for errors, and when there are errors, it's more clear what they are:
private static void Main()
{
int[] myArray = new int[10];
while (true)
{
int enteredNumber = ShowMenu();
if (enteredNumber == 1)
{
PopulateNextArrayItem(myArray);
}
else if (enteredNumber == 9)
{
if (Login(1234, 3))
{
PrintArray(myArray);
WaitForUserInput();
}
}
}
}
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
Console.WriteLine("Welcome to our Multiplex");
Console.WriteLine("We are presently Showing:");
Console.WriteLine("1.Legend");
Console.WriteLine("2.Macbeth");
Console.WriteLine("3.Everest");
Console.WriteLine("4.A Walk In the Woods");
Console.WriteLine("5.Hotel Transylvania");
Console.WriteLine("Enter the number of the film you wish to see?");
{
string moviestring = Console.ReadLine();
int movie = int.Parse(moviestring);
Here is solution I could suggest for your case:
static void Main(){
bool flag0 = true; //initialize tracking bool value to exit loop when needed
int result;
Console.WriteLine("Welcome to our Multiplex");
Console.WriteLine("We are presently Showing:");
Console.WriteLine("1.Legend");
Console.WriteLine("2.Macbeth");
Console.WriteLine("3.Everest");
Console.WriteLine("4.A Walk In the Woods");
Console.WriteLine("5.Hotel Transylvania");
do //do while loop suits this case best as it does check the value on the end
{
Console.WriteLine("Enter the number of the film you wish to see?");
string moviestring = Console.ReadLine();
int.TryParse(moviestring, out result); //does try-catch check so it wont crash on the run-time
if (result <= 5 && result >= 1) //logical check if value is correct
flag0 = false; //exits the loop
//do true logic....
else
Console.WriteLine("Incorrect value. Try again.");
//do false logic
} while (flag0);
}
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);
}
}