So I am currently trying to finish this program that when you input a number correlating to the days of the week, it reflects the text connected to the numeric variable. (IE : Sunday - 1, Monday - 2, etc etc.)
I have found a functioning code that makes the program work, but it outputs incorrect information. No matter what number I put in, it always displays Sunday. And it doesn't stop me from inputting bad variables. Which I want it to. I'm frustrated at this point and I am very new to all of this. Can someone check over my code and tell me what I'm doing incorrectly? Thank you.
private void OkButton_Click(object sender, EventArgs e)
{
string day ="1";
int number;
if (int.TryParse(day, out number))
{
if (number >= 7 && number <= 1)
{
switch (day)
{
case "1":
dayOutputLabel.Text = "Sunday";
break;
case "2":
dayOutputLabel.Text = "Monday";
break;
case "3":
dayOutputLabel.Text = "Tuesday";
break;
case "4":
dayOutputLabel.Text = "Wednesday";
break;
case "5":
dayOutputLabel.Text = "Thursday";
break;
case "6":
dayOutputLabel.Text = "Friday";
break;
case "7":
dayOutputLabel.Text = "Saturday";
break;
}
}
else
{
MessageBox.Show("Invalid number input. Please use a number between 1 and 7.");
}
}
else
{
MessageBox.Show("Please put in a valid number.");
}
}
private void ExitButton_Click(object sender, EventArgs e)
{
this.Close();
}
Looks like you've hard coded day = "1" (i.e. Sunday).
Also this is a mistake:
if (number >= 7 && number <= 1)
Surely you meant...
if (number >= 1 && number <= 7)
I can't tell precisely what sort of project you're working on, but the following slight modification works in wpf and should be all you need to solve this:
private void OKButton_Click(object sender, RoutedEventArgs e)
{
string day = myTextBox.Text.Trim();
int number = 0;
if (int.TryParse(day, out number))
{
if (number >= 1 && number <= 7)
{
switch (day)
{
case "1":
dayOutputLabel.Content = "Sunday";
break;
case "2":
dayOutputLabel.Content = "Monday";
break;
case "3":
dayOutputLabel.Content = "Tuesday";
break;
case "4":
dayOutputLabel.Content = "Wednesday";
break;
case "5":
dayOutputLabel.Content = "Thursday";
break;
case "6":
dayOutputLabel.Content = "Friday";
break;
case "7":
dayOutputLabel.Content = "Saturday";
break;
}
}
else
{
MessageBox.Show("Invalid number input. Please use a number between 1 and 7.");
}
As mentioned in the comment above... here is a possible solution using the System.DayOfWeek enumeration:
private void OKButton_Click(object sender, RoutedEventArgs e)
{
// this TryParse makes use of pattern matching
if(int.TryParse(myTextBox.Text.Trim(), out var input) && input >= 0 && input <= 6)
{
// this should automatically convert to the name of the day of week
// if not, add .ToString() at the end
dayOutputLabel.Content = (DayOfWeek)input;
}
else
{
MessageBox.Show(
text: "Please use a number between 0 and 6",
caption: "Invalid Input",
buttons: MessageBoxButtons.OK,
icon: MessageBoxIcon.Error);
}
}
And here is an another option using Enum.TryParse() instead:
private void OKButton_Click(object sender, RoutedEventArgs e)
{
// this TryParse makes use of pattern matching
if(Enum.TryParse(myTextBox.Text.Trim(), out DayOfWeek input) &&
input >= DayOfWeek.Sunday && input <= DayOfWeek.Saturday)
{
// this should automatically convert to the name of the day of week
// if not, add .ToString() at the end
dayOutputLabel.Content = input;
}
else
{
MessageBox.Show(
text: "Please use a number between 0 and 6",
caption: "Invalid Input",
buttons: MessageBoxButtons.OK,
icon: MessageBoxIcon.Error);
}
}
Related
I'm trying to make a question repeat if the input isn't right. Here's the code:
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
Boolean input = true;
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
break;
case "bob":
Console.WriteLine("you chose a bob");
break;
}
How do I make it if it isn't one of the two answers it reasks the question?
Use the default case.
If none of the cases in a switch statement match, the default case runs.
Here's an example.
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
switch (userInput)
{
case "joe":
// ...
break;
case "bob":
// ...
break;
default:
// This runs if userInput is neither "joe" nor "bob"
}
Then you can make a method that writes choose a name to the console, takes the user's input, and runs the switch statement - and the default case would call the same method.
void GetName()
{
// Write "choose a name" to the console
// Take the user's input
switch (userInput)
{
case "joe":
// ...
break;
case "bob":
// ...
break;
default:
GetName();
return;
}
}
You need a loop (either while or do-while) to repeat the iteration but not a switch-case.
While switch-case is used to control the flag (isCorrectInput) that stops the loop.
bool isCorrectInput = false;
do
{
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
isCorrectInput = true;
break;
case "bob":
Console.WriteLine("you chose a bob");
isCorrectInput = true;
break;
}
} while (!isCorrectInput);
Reference
Iteration statement
You should use a bool variable, that will determine whether you need to repeat the logic or not. Combine it with a loop and you get this:
bool keepAsking = true;
while (keepAsking)
{
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
Boolean input = true;
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
keepAsking = false;
break;
case "bob":
Console.WriteLine("you chose a bob");
keepAsking= false;
break;
}
}
You can try something like this. BUt you need to slightly change your code.
class XYZ
{
static void Main(string[] args)
{
GetData()
}
}
static void GetData()
{
string userInput = Console.ReadLine();
checkcondition(userInput);
}
static void checkcondition(userInput)
{
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
break;
case "bob":
Console.WriteLine("you chose a bob");
break;
default:
GetData();
break;
}
}
You can also achieve the same results using a smaller code but with a while loop instead of switch statement
while(true){
Console.Write("Choose a Name: ");
var name = Console.ReadLine().ToLower();
if(name == "joe" || name == "bob"){
Console.WriteLine("You chose a " + name + "!");
break;
}else{
Console.WriteLine("Invalid Selection, Try Again");
}
}
when i tried to use the Switch case function, it goes always to the default message besides case 5:
private void btnCandlesLight_Click(object sender, EventArgs e)
{
int result;
result = Convert.ToInt32(textBox1.Text);
switch(result)
{
case 1:
day1.Start();
candlesOne();
break;
case 2:
day2.Start();
candlesTwo();
break;
case 3:
day3.Start();
candlesThree();
break;
case 4:
day4.Start();
candlesFour();
break;
case 5:
day5.Start();
candlesFive();
break;
case 6:
day6.Start();
candlesSix();
break;
case 7:
day7.Start();
candlesSeven();
break;
case 8:
day8.Start();
candlesEight();
break;
default:
MessageBox.Show("Enter new day");
break;
}
}
When I Enter the value 1 for example to the text box, the default case works, but only when I enter the value 5 it works perfectly.
If you want to see the difference between the function "candlesOne" to "candlesFive":
The "c" variable is a variable of the seconds. i tried to use a timer in a way of lighting up the candles every 2-3 seconds.
public void candlesOne()
{
firedmatch.Left = firedmatch.Left + 100;
if (c == 1)
{
candle1.Visible = true;
}
if (c == 3)
{
candle2.Visible = true;
}
}
and:
public void candlesFive()
{
firedmatch.Left = firedmatch.Left + 100;
if(c == 1)
{
candle1.Visible = true;
}
if(c == 3)
{
candle2.Visible = true;
}
if(c == 5)
{
candle3.Visible = true;
}
if(c == 7)
{
candle4.Visible = true;
}
if(c == 11)
{
candle5.Visible = true;
}
}
I haven't found a mistake,
can you guys help me?
Thanks
Have you checked if you really get for example (int)1 as a result of the "1" input from your conversion?
On a broader scale, there is a lot of repetition in your code, you should consider refactoring it a little.
In your CandlesOne and CandlesFive methods, you use a c variable, no idea what that is or where it comes from. Those two methods (and probably the other CandlesXXX() do the same kind of things. Can't you remove complexity by generalizing the logic? Can the result used in your switch-case be passed as a parameter and used to trigger the numbers of c == X calls in the CandleXXX() methods?
This way you could remove the switch and lose a lot of complexity!
Edit
If you have further problems, consider creating a .NET Fiddle, I miss a lot of context in your code so I cannot efficiently help you here.
Some refactoring ideas for you:
// Somewhere else in your code, create a dictionary with your day1-day8 objects
var days = new Dictionary<int, Day>()
days[1] = day1;
...
days[8] = day8;
//Simplfiy your method
private void btnCandlesLight_Click(object sender, EventArgs e)
{
try
{
var dayIndex = Convert.ToInt32(textBox1.Text);
if(dayIndex > 0 && dayIndex <= 8)
{
days[dayIndex].Start(); //Get the corresponding day via its Key
LightUpCandles(dayIndex); //pass the key as a parameter
}
else
{
MessageBox.Show("Enter new day");
}
}
catch(InvalidCastException exception)
{
//Whatever you do when the textbox cannot be parsed
}
}
I still don't get what your candlesOne to five methods are really doing or why the method "candlesOne" lights up two candles (pay attention to the variable naming). I also don't get how this makes up some kind of timer... but here's a first potential refactoring for it anyway:
public void LightUpCandles(int dayIndex)
{
firedmatch.Left = firedmatch.Left + 100;
if(c == 1)
{
candle1.Visible = true;
}
if(c == 3 && dayIndex > 1)
{
candle2.Visible = true;
}
if(c == 5 && dayIndex > 2)
{
candle3.Visible = true;
}
if(c == 7 && dayIndex > 3)
{
candle4.Visible = true;
}
if(c == 11 && dayIndex > 4)
{
candle5.Visible = true;
}
}
Your switch logic is correct which I tested with the following;
int result;
result = Convert.ToInt32(textBox1.Text);
switch (result)
{
case 1:
MessageBox.Show("1");
break;
case 2:
MessageBox.Show("2");
break;
case 3:
MessageBox.Show("3");
break;
case 4:
MessageBox.Show("4");
break;
case 5:
MessageBox.Show("5");
break;
case 6:
MessageBox.Show("6");
break;
case 7:
MessageBox.Show("7");
break;
case 8:
MessageBox.Show("8");
break;
default:
MessageBox.Show("Enter new day");
break;
}
If you don't get the same results I would perhaps look at making the message boxes above display the data type of the variable.
MessageBox.Show(result.GetType().ToString());
So, I have made a calculator in C# but it cannot calculate decimal numbers.
It works perfectly fine when clicking on for example the buttons: 6 then . (this is a dot) then 5. But as soon as I click on the "+"-button (or any other operator) afterwards in the form, the program stops and I get a message saying that
"An unhandled exception of type 'System.FormatException' occured in
mscorlib.dll. The input string was not in a correct format".
I don't know exactly how to solve this. Is there anyone that knows how to solve this problem?
Here is my code:
namespace Kalkylator{
public partial class Form1 : Form{
String operation = ""; //the operation we will use
Double resultat = 0; //the result we will get
bool finished = false; //if false, we have not pressed the "=" button yet
public Form1(){
InitializeComponent();
}
//
private void button_click(object sender, EventArgs e){
if (finished == true){ //if we press any operator, clear the textbox-window so new numbers can be entered
textBoxFonster.Clear();
}
finished = false; //we are not done with the calculation
Button b = (Button)sender;
if (b.Text == "."){
if (!textBoxFonster.Text.Contains(".")){
textBoxFonster.Text = textBoxFonster.Text + b.Text;
}
}
else{
textBoxFonster.Text = textBoxFonster.Text + b.Text; //writes the number in the textBox
}
}
private void operator_click(object sender, EventArgs e)
{
Button b = (Button)sender;
operation = b.Text; //the operation we will perform is the operatorButton we will press
resultat = Double.Parse(textBoxFonster.Text); //HERE IS WHERE THE PROGRAM GIVES ME THE ERROR.
finished = true; //we are done with the calculation
}
private void clear_click(object sender, EventArgs e)
{
textBoxFonster.Text = ""; //clear the window from all text
resultat = 0; //clear the value of resultat and set it to 0
}
private void LikaMed_click(object sender, EventArgs e)
{
switch(operation){
case "+": //add the result with the text in the textBox
textBoxFonster.Text = (resultat + Double.Parse(textBoxFonster.Text)).ToString();
break;
case "-":
textBoxFonster.Text = (resultat - Double.Parse(textBoxFonster.Text)).ToString();
break;
case "*":
textBoxFonster.Text = (resultat * Double.Parse(textBoxFonster.Text)).ToString();
break;
case "%":
textBoxFonster.Text = (resultat / Double.Parse(textBoxFonster.Text) * (resultat/100)).ToString();
break;
case "^":
textBoxFonster.Text = (Math.Pow(resultat, Double.Parse(textBoxFonster.Text))).ToString();
break;
case "Log": //takes the 10th log of resultat
textBoxFonster.Text = (Math.Log10(resultat)).ToString();
break;
case "Sqrt":
textBoxFonster.Text = (Math.Sqrt(resultat)).ToString();
break;
case "/": //divide the result with the text in the textBox if that text is not 0. If so, show an error message
if ((Double.Parse(textBoxFonster.Text)) != 0){
textBoxFonster.Text = (resultat / Double.Parse(textBoxFonster.Text)).ToString();
}
else{ //show error in MessageBox
MessageBox.Show("Cannot divide by 0!");
}
break;
default:
break;
}
finished = true; //this will clear the result textbox when clicking another number after the equal sign has been clicked
}
}
}
Don't use Double.Parse without specifying the Culture.
Change:
switch(operation){
case "+": //add the result with the text in the textBox
textBoxFonster.Text = (resultat + Double.Parse(textBoxFonster.Text)).ToString();
break;
case "-":
textBoxFonster.Text = (resultat - Double.Parse(textBoxFonster.Text)).ToString();
break;
to:
Double operand1=resultat;
Double operand2=0;
Double.TryParse(textBoxFonster.Text,NumberStyles.Float,CultureInfo.InvariantCulture,out operand2);
switch(operation){
case "+": //add the result with the text in the textBox
textBoxFonster.Text = (operand1 + operand2).ToString();
break;
case "-":
textBoxFonster.Text = (operand1 - operand2).ToString();
break;
Alternatively, you could actually support multiple cultures, and change this code:
if (b.Text == "."){
if (!textBoxFonster.Text.Contains(".")){
textBoxFonster.Text = textBoxFonster.Text + b.Text;
}
}
to this:
if (b.Text == System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator){
if (!textBoxFonster.Text.Contains(System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)){
textBoxFonster.Text = textBoxFonster.Text + b.Text;
}
}
private void btnCalculate_Click(object sender, RoutedEventArgs e)
{
double pay;
pay = 0.00;
double add;
add = 0.00;
int age;
age = int.Parse(txtAge.Text);
string month;
month = txtMonth.Text;
if (age >= 18 && age <= 55)
{
pay = 350;
}
else if (age <= 18)
{
pay = 150; //if-else-if statements depending on age
}
else if (age > 55)
{
pay = 35;
}
switch (month)
{
case "January":
case "january":
case "July":
case "july": //switch statement, how much you pay depending on month
add = 100;
break;
case "February":
case "february":
case "August":
case "august":
add = 120;
break;
case "March":
case "march":
case "September":
case "september":
add = 140;
break;
case "April":
case "april":
case "October":
case "october":
add = 160;
break;
case "May":
case "may":
case "November":
case "november":
add = 180;
break;
case "June":
case "june":
case "December":
case "december":
add = 120;
break;
}
lblTotal.Content = (pay + add) * 1.13; //calculation that prints to the label
}
So when I run the code it just outputs 0 in the label
If I put the Calculation at the bottom (seen here) it will say something about the label not being reachable. Any help would be great. Code has been solved
You can directly assign variables. Declaration and assignment need not be different statements.
18 has two different checks: >= 18 in the if, and <= 18 in the first else if. Not a code error but a semantics error.
The final assignment is inside the switch block and unreachable. Put it outside the switch.
It looks like you're using WPF? If so, you should have a look at the MVVM pattern, as well as data binding. It's a good bit to learn and not easy but very important in WPF. It will eliminate the need for querying and writing properties of elements in most cases, though – because that will be handled by the runtime.
Also consider using a ComboBox for the month. Way easier to validate the data.
As suggested your label assignment was inside the switch statement causing it not to execute unless the month was June or December.
In any case, I'd suggest though that you simplify.
Try this:
private void btnCalculate_Click(object sender, RoutedEventArgs e)
{
int age = int.Parse(txtAge.Text);
double pay = age <= 18 ? 150.0 : (age > 55 ? 35.0 : 350.0);
int index = (DateTime.Parse("1 " + txtMonth.Text).Month - 1) % 6;
double[] choices = new [] { 100.0, 120.0, 140.0, 160.0, 180.0, 120.0 };
double add = choices[index];
lblTotal.Content = (pay + add) * 1.13;
}
The label assignment was inside the switch statement. There's a lot of other improvements you can make to code as well.
For starters, you can also join assignment and declaration of variables and use .ToLower() in switch to save yourself the extra cases:
private void btnCalculate_Click(object sender, RoutedEventArgs e)
{
var pay = 0.00;
var add = 0.00;
var age = int.Parse(txtAge.Text);
var month = txtMonth.Text;
if (age >= 18 && age <= 55)
{
pay = 350;
}
else if (age <= 18)
{
pay = 150;
}
else if (age > 55)
{
pay = 35;
}
switch (month.ToLower())
{
case "january":
case "july":
add = 100;
break;
case "february":
case "august":
case "june":
case "december":
add = 120;
break;
case "march":
case "september":
add = 140;
break;
case "april":
case "october":
add = 160;
break;
case "may":
case "november":
add = 180;
break;
}
lblTotal.Text = Convert.ToString((pay + add) * 1.13); //calculation that prints to the label
}
Full disclosure here, I am a student doing homework. I have 2 listboxes with items that can be selected. What is said in them is not needed to be extracted. I wrote the code out and everything works except I get an error saying "use of unassigned variable" on 3 variables at the end of the code. They are locFees, days, and registration. Can anyone tell me what I am doing wrong that is causing the variables to not have a value?
private void btnCalc_Click(object sender, EventArgs e)
{
double registration, lodging, total, days, locFees;
int workshopIndex, locationIndex;
if (lbWorkshop.SelectedIndex != -1)
{
workshopIndex = lbWorkshop.SelectedIndex;
switch (workshopIndex)
{
case 0:
days = 3;
registration = 1000;
break;
case 1:
days = 3;
registration = 800;
break;
case 2:
days = 3;
registration = 1500;
break;
case 3:
days = 5;
registration = 1300;
break;
case 4:
days = 1;
registration = 500;
break;
}
}
else
{
MessageBox.Show("You didn't select a workshop.");
}
if (lbLocation.SelectedIndex != -1)
{
locationIndex = lbLocation.SelectedIndex;
switch (locationIndex)
{
case 0:
locFees = 150;
break;
case 1:
locFees = 225;
break;
case 2:
locFees = 175;
break;
case 3:
locFees = 300;
break;
case 4:
locFees = 175;
break;
case 5:
locFees = 150;
break;
}
}
else
{
MessageBox.Show("You didn't select a city.");
}
lodging = locFees * days;
total = registration + lodging;
}
Can anyone tell me what I am doing wrong that is causing the variables to not have a value?
Sure - you're ignoring the possibility that workshopIndex isn't 0, 1, 2, 3 or 4.
If you believe that should never happen, just add:
default:
throw new InvalidOperationException("Invalid selected index " + workshopIndex);
Or if you just want to use some defaults, do something like:
default:
days = 1;
registration = 100;
break;
That's the first way you can end up with days and registration unassigned.
Next, there's the fact that you only go into the switch block at all if lbWorkshop.SelectedIndex != -1. Your else block is just:
else
{
MessageBox.Show("You didn't select a workshop.");
}
... so after that else block, you're going to continue. You probably want:
else
{
MessageBox.Show("You didn't select a workshop.");
return;
}
You've then got the same problem for locFees, in terms of both the switch statement and the else block.
One thing to learn from this: be grateful that the compiler spotted these for you. It's stopped you from running code which definitely had bugs in. That's always a good thing.