I am trying to do something like a if else condition in C#.
My below code is to check that all the text in text block is correct and show a display message.
if ((correctAns.Contains(textBlock1.Text)) &&
(correctAns.Contains(textBlock2.Text)) &&
(correctAns.Contains(textBlock3.Text)) &&
(correctAns.Contains(textBlock4.Text)) &&
(correctAns.Contains(textBlock5.Text)))
{
//If it contains the correct answer
MessageBox.Show("All correct");
}
What i want for now is to check if any 3 of the text in the text block is correct will show a message box.
How should i go about doing it?
It might be easier to put all the textboxes in an array and use Linq to count:
if (textboxes.Where(tb => correctAns.Contains(tb.Text)).Count() >= 3)
{
// show message
}
This way it is much easier to add or remove textboxes to this check.
Count them.
If your code matches the entire problem, this is probably the most straight-forward - but if the number of text blocks grow, you might want to re-think the solution:
int count = 0;
if (correctAns.Contains(textBlock1.Text)) count++;
if (correctAns.Contains(textBlock2.Text)) count++;
if (correctAns.Contains(textBlock3.Text)) count++;
if (correctAns.Contains(textBlock4.Text)) count++;
if (correctAns.Contains(textBlock5.Text)) count++;
if (count >= 3)
{
MessageBox.Show("At least 3 correct");
}
If you want any three in any combination, writing out a single conditional block to cover everything will be pretty rigid and non-flexible. It will be better to count them, then check the count.
int count = 0;
if (correctAns.Contains(textBlock1.Text))
++count;
if (correctAns.Contains(textBlock2.Text))
++count;
if (correctAns.Contains(textBlock3.Text))
++count;
if (correctAns.Contains(textBlock4.Text))
++count;
if (correctAns.Contains(textBlock5.Text))
++count;
if (count >= 3) {
// Show message.
}
Related
I'm working through a practice problem for one of my classes and I'm having a bit of trouble with part of the prompt.
We need to:
Write code to go through number -20 - 20 (but skip 5-15 inclusively)
If the number is negative, the line should start with an "*"
If the number is divisible by 2, add "#" to the end of the current line
If the number is divisible by 3, add "!" to the front of the line
If the previous line has both "!" and "#", then add "wow" to the end of the current line (Hint: use bool)
With the code I've written so far, I've managed to complete the first two tasks on the list, but I run into trouble starting with the third task. In my code I'm using
if (num%2==0)
{
Console.WriteLine(num+"#");
}
but all it's doing is outputting another number with "#" instead of putting "#" on the current line. How do I make it so "#" is appended to the end of the current line?
Here's my code for reference:
static void Main(string[] args)
{
int num = -20;
while (num <= 20)
{
if (num < 5 || num > 15)
{
if (num < 0)
{
Console.WriteLine("*" + num);
}
if (num%2==0)
{
Console.WriteLine(num+"#");
}
else
{
Console.WriteLine(num);
}
}
num++;
}
}
Since we are only working with the first 3 points in this question (try the other 2 yourself), I will only address those.
The main problem with the code is that it will always write the number more than once if more than one rule applies to it. There's 2 ways to tackle this. Also note I cleaned up the code a bit and I'll explain why later since it's secondary.
Fix
Method 1 : Incremental Writing
This method uses incremental writing to apply rules and then write a new line at the end before going to the next iteration.
// More succinct than a while loop for this particular scenario
for (int num = -20; num <=20; num++)
{
//Skip while avoiding nested if
if (num >= 5 && num <= 15)
continue;
//Since it needs to start with * in this case we prioritize it
if (num < 0)
Console.Write("*");
Console.Write(num);
// Since this would need to be appended at the end if it's true
if (num % 2 == 0)
Console.Write("#");
Console.Write(Environment.NewLine);
}
Method 2: Store the line then print before next iteration
In this case you would build the line that you want to print and then use one Console.WriteLine statement to write it while avoiding duplication. The writing would need to be done before moving to the next iteration.
You can use string concatenation instead of StringBuilder which would generally be more costly but in this case performance doesn't really matter (string are really small and amount of concatenation is minimal). However this would be a typical use case for a StringBuilder.
Also, since we know we know that we will always print out num when we aren't skipping then we can start off with num. But we could also do it like Method 1 where we add it in the middle. I'll illustrate both ways.
StringBuilder constructor with number
// More succinct than a while loop for this particular scenario
for (int num = -20; num <= 20; num++)
{
//Skip while avoiding nested if
if (num >= 5 && num <= 15)
continue;
// Create and update your string in a string builder, apply rules thereafter
// (this constructor usage means we don't need to add the number later)
var line = new StringBuilder(num.ToString());
//Since it needs to start with * in this case we prioritize it
if (num < 0)
line.Insert(0, "*");
// No need to add the number, already present
// Since this would need to be appended at the end if it's true
if (num % 2 == 0)
line.Append("#");
Console.WriteLine(line.ToString());
}
StringBuilder constructor without number
// More succinct than a while loop for this particular scenario
for (int num = -20; num <= 20; num++)
{
//Skip while avoiding nested if
if (num >= 5 && num <= 15)
continue;
// Create and update your string in a string builder, apply rules thereafter
// (this constructor usage means we must add the number later)
var line = new StringBuilder();
//Since it needs to start with * in this case we prioritize it
if (num < 0)
line.Append("*"); // NOTICE: This is now Append instead of Insert since line is empty
// Since we didn't add the number before
line.Append(num);
// Since this would need to be appended at the end if it's true
if (num % 2 == 0)
line.Append("#");
Console.WriteLine(line.ToString());
}
Additional Changes
for loop is better suited for this situation since you have an int with a clear start, end and an incrementor supported by the structure.
Avoid unnecessary nesting of conditions, common newbie mistake. If you have a condition to skip in certain cases, simply check and skip and otherwise the rest of the code will apply. This could otherwise lead to really annoying duplication and condition checks that are unnecessary (most of the time).
use string.concat but first save the string into variable and reach the end and finally do the concatenation
I am aware that questions like these have been asked before here, however I could not find one which explains how to do this LIVE while the user is inputting a string in a textbox. This is regarding a windows form app in C#.
Here is my current code:
for (int i = 4; i <= input.Length; i += 4)
{
input = input.Insert(i, " ");
i++;
}
This does not work, as it continues to add spaces after every keypress. I have this for-loop run on a non-return keypress.
Ok I figured it out. For anyone browsing this thread years in the future, here is what I did:
if (input.Replace(" ", String.Empty).Length % 4 == 0 && input[input.Length - 1] != ' ')
{
input += ' ';
}
This adds spaces where they are needed and makes sure to not cause an infinite loop of adding spaces and triggering the TextChanged event.
This is the solution I came to, I think that if you adapt the "Console." stuff to window forms, it will work.
string text = string.Empty;
for (int i = 0; i < 50; i++) //Change 50 for whatever size you want
{
switch (i % 5) //every time 'i' is a multiple of 5 it will write a blank space
{
default:
text += Console.ReadKey().KeyChar;
break;
case 0:
Console.Write(" ");
break;
}
}
I am trying to create an Add method that allows the user to enter a team which will then be added to list<string> teams, it will then display the lists contents. It need to have the following clauses, if Colchester is enter it puts out No and if the contents of the list reach 10 then nothing else is added and an error is returned.
public FootballTeams(){ }
List<string> teams;
public void ListInit()
{
teams = new List<string>(10);
teams.Add("Everton");
teams.Add("Liverpool");
teams.Add("Arsenal");
teams.Add("Manchester United");
teams.Add("West Ham United");
}
public void AddTeams()
{
Console.WriteLine("Enter a team to be added: ");
string userinput = Console.ReadLine();
if (userinput == "Colchester")
{
Console.Write("NOT ALLOWED");
}
else if (teams.Count < 10)
{
teams.Add(userinput);
foreach (var item in teams)
Console.Write(item.ToString() + " ");
}
else
Console.Write("You entered something else....");
}
In the code I have the list is set to a max of 10.
In the method add teams an error springs up at (teams.Add(userinput)) saying cannot implicitly convert type void to bool and I have zero idea of how to get the error to crop up when the contents of the list reach 10. I am also assuming that the Colchester bit is correct.
UPDATE
It now looks like this:
public void AddTeams()
{
Console.WriteLine("Enter a team to be added: ");
string userinput = Console.ReadLine();
if (teams.Count < 10)
{
if (userinput != "Colchester")
{
teams.Add(userinput);
foreach (var item in teams)
Console.Write(item.ToString() + " ");
}
else
Console.Write("NOT ALLOWED");
}
else
Console.Write("MAXIMUM LIMIT REACHED");
}
However I have discovered that Colchester is still added to the list, any ideas on how to stop this? Also when more than 10 teams are entered the message “MAXIMUM NUMBER REACHED” should display?
Note-I am a new to C#, I know my code sucks :)
The reason you are getting the void to bool conversion error is that the "Add" method of System.Collections.Generic.List does not return anything, thus it can not be used as the conditional expression of an if statement.
Also, lists do not have fixed size like arrays, so you wouldn't even get an exception if your "limit" of 10 was reached. (You would get an IndexOutOfRange exception if you did use a size 10 array).
King King's answer provides the code that will do what you asked for in the other part of your question. The error message at the end could definitely be more descriptive.
Side note, since you know the list is of type "string", why bother calling ToString, it would have been called by the runtime if it wasn't a string anyways.
To answer your edit, the check for "Colchester" should come first, the code is entering the first if (because the count is less than 10) and doesn't even check the name. You could also nest the check for "Colchester" inside the count check. The nesting approach is probably "technically" better, but both will work.
To answer the second edit, replace "You entered something else" with "MAXIMUM NUMBER REACHED", to ensure that this message is displayed even if the item that would exceed the limit is "Colchester", make the check for "Colchester" nested in the count check (otherwise the "Colchester" check will take precedence).
Approach 1 (not nested):
if (input == "Colchester)
... (display error)
else if (list.Count < 10)
... (add and print)
else
... (display different error)
Approach 2 (nested):
if (list.Count < 10)
{
if (input != "Colchester")
{
... (add and print)
}
else
... (display error)
}
else
... (display other error)
Try this:
if (teams.Count < 10){
teams.Add(userinput);
foreach (var item in teams)
Console.Write(item.ToString() + " ");
} else if (userinput == "Colchester") Console.Write("NOT ALLOWED");
else Console.Write("You enter something else....");
Note that the logic of your code is not good (the message printed does not make much sense).
I have a simple message box pop up when a variable is achieved. It spirals into infinity since I have no stopper. Perhaps it's just my inability to figure out where the stopper is to be placed, but it doesn't seem to halt no matter my solution.
if (number == 10)
{
MessageBox.Show("Woot!");
}
Without more code, you can either use a break (as it sounds like you are using a loop), or set your number to something other than 10
while(switchstatement)
{
...logic...
if(number == 10)
{
MessageBox.Show("woot");
break;
}
...more logic...
}
Or, you can set the switch that kills your loop
while(switchstatement)
{
...logic...
if(number == 10)
{
MessageBox.Show("woot");
switchstatement = false;
}
...more logic...
}
That is based off of limited code...so you may have to provide more code if this is not correct.
You are using a variable but i don't see where you set the value so i assume that you never change it in the loop. Hence you are in an infinite loop.
You could use a for-loop instead
for(int number = 0; number < 10; number++)
{
MessageBox.Show("Woot!");
}
or in a while
int number = 0;
while(number++ < 10)
{
MessageBox.Show("Woot!");
}
C# Increment Int
++ Operator (C# Reference)
I have a 2D array which some of it's members are numbers (playerID -1,2,3,4 etc.)and the rest are zeros.
I want to make a for loop containing all kinds of check methods that goes through the the loop and returns an answer. the checks are ranked, so that when one of the higher checks is returned TRUE, the loop for that playerID can terminate. Later on I want to use the check results to compare between the players, but first thing's first - I can't get the big FOR loop running.
I had in mind something like this:
for (int playerID = 1; playerID <= participants; playerID++)
{
checkA = Check4forsequenceof4(matrix); //method A
if (checkA == 0)
continue;
else
Console.WriteLine(p + "completed check A");
break;
if (checkB == 0)
continue;
else
Console.WriteLine(p + "completed check B");
break;
if (checkC == 0)
continue;
else
Console.WriteLine(p + "completed check C");
break;
}
Problems are: the break breaks out of the FOR loop instead of only from the if, and I can't think of how to check for the next playerID, and also can't figure out how best to store the results for every player for later display.
First off, if you want to make this work, you can't rely on indentation - you need braces:
if (checkA == 0)
continue;
else
{
Console.WriteLine(p + "completed check A");
break;
}
This will solve your immediate problem of the loop immediately breaking out.
That being said, given the above check, you'll NEVER check for B. I suspect you want to invert your logic, as such:
if (checkA != 0)
{
Console.WriteLine(p + "completed check A");
break;
}
This will cause checkA to run, then checkB, etc.
You have a much bigger problem. Your code reads:
checkA = Check4forsequenceof4(matrix); //method A
if (checkA == 0)
continue;
else
Console.WriteLine(p + "completed check A");
break;
That will always break out of the loop the first time checkA is not 0. So checkB will never be executed.
I'm not sure what you're trying to do. The indentation of your code indicates that the break isn't necessary anywhere, since the default is tao fall through (which I think is what you want to do).
var allPlayers = new List<Player>();
// Fill the list allPlayers here.
var validPlayers = new List<Player>();
foreach (Player p in allPlayers) {
if(CheckA(p) || CheckB(p) || CheckC(p)) {
validPlayers.Add(p);
}
}
Note: c# performs a so called shortcircuit evaluation. I.e. if CheckA returns true the others will not be evaluated any more. If CheckB returns true, then CheckC will not be evaluated. By the way "||" is a logical OR. If all checks have to be OK then use the logical AND "&&" instead. Here c# will stop checking as soon as a check fails.
If you are only interested in which check has returned true first, then only use "continue" when the check is OK, but no "break" otherwise.
My answer might not be very appropriate, but I am not really sure what you are trying to do.
I think this is what you're looking for. Though I don't know when checkB or C is supposed to be set. After the checkA check?
for (int playerID = 1; playerID <= participants; playerID++)
{
checkA = Check4forsequenceof4(matrix); //method A
if (checkA == 0)
continue;
Console.WriteLine(p + "completed check A");
if (checkB == 0)
continue;
Console.WriteLine(p + "completed check B");
if (checkC == 0)
continue;
Console.WriteLine(p + "completed check C");
}
unless I misunderstand your question:
for (int playerID = 1; playerID <= participants; playerID++)
{
checkA = Check4forsequenceof4(matrix); //method A
if (checkA != 0)
Console.WriteLine(p + "completed check A");
else
continue;
if (checkB != 0)
Console.WriteLine(p + "completed check B");
else
continue;
if (checkC != 0)
Console.WriteLine(p + "completed check C");
else
continue;
}
Restructure your if statements...
if (0 != checkValue) {
Console.WriteLine(p + " completed check X");
Continue;
}
So this will cause the loop to go into the next iteration when a check value is non-zero.
There is no such thing as breaking out of an if statement.
I came up with the following code.
// This store all of the checks formed as Fun<Player, bool> delegates.
var checks = new List<Func<Player, bool>>();
checks.Add(x => DoesPlayerSatisfyCheck1(x));
checks.Add(x => DoesPlayerSatisfyCheck2(x));
checks.Add(x => DoesPlayerSatisfyCheck3(x));
// Add more checks here if necessary.
// This stores all players who have passed a check.
// The first check that passed will be associated with that player.
var results = new Dictionary<Player, int>();
// Loop through all players.
foreach (Player p in participants)
{
// Now perform each test in order.
for (int i = 0; i < checks.Count; i++)
{
Func<Player, bool> checker = checks[i];
if (checker(p))
{
results.Add(p, i);
break;
}
}
}
After this code executes the results data structure will contain an entry for each Player that passed one of the checks. That entry will also contain the check number. If you want to add more checks later you can simply add it to the checks data structure.
This code does not behave the same as what you posted. But, it does behave per the requirement you gave; as best I can tell anyway.