Here is my code, for my if statements I want to have it between two values for example:
if(rating < 5 > 2);
So I'm saying i want it to only print the command if that value is below 5 but higher than 2.
Is there a way to do this? Thank you for your time.
Here is my code.
public static void Main(string[] args)
{
Console.WriteLine("What would you rate starcraft out of 10?");
int rating = Console.Read();
if (rating < 5) ;
{
Console.WriteLine("Not good enough!");
Console.ReadLine();
}
if (rating > 5) ;
{
Console.WriteLine("OOOOOOOOO yeeeeeeee");
Console.ReadLine();
}
if (rating > 8) ;
{
Console.WriteLine("We are bestfriends now ;)");
Console.ReadLine();
Use conditional logical AND operator &&:
if (rating < 5 && rating > 2)
{
}
Or pattern matching (read more #1, read more #2):
if (rating is < 5 and > 2)
{
}
P.S.
You can refactor a bit with switch expression and ordering the checks to remove some code repetition and improve readability (note that original code does not cover rating == 5 case compared to the following):
var rating = ...;
var message = rating switch
{
< 2 => "Terrible",
< 5 => "Not good enough!",
< 8 => "OOOOOOOOO yeeeeeeee",
_ => "We are bestfriends now ;)"
};
Console.WriteLine(message);
Console.ReadLine();
To avoid complications, you can sort ratings' thresholds and then check them in order with a help of if ... else if pattern, e.g. having
2 - Nightmare
5 - Not good enough!
8 - OOOOOOOOO yeeeeeeee
more - We are bestfriends now
We can put it as
if (rating <= 2) // 2 or less
Console.WriteLine("Nightmare");
else if (rating <= 5) // (2..5]
Console.WriteLine("Not good enough!");
else if (rating <= 8) // (5..8]
Console.WriteLine("OOOOOOOOO yeeeeeeee");
else // more than 8
Console.WriteLine("We are bestfriends now");
Console.ReadLine();
Related
Noob here. I have written a program that allows a user to enter how many grades they would like to input into an array, and then lets them enter the grades for the number of indexes they chose. I am trying to output the total percentage grade based on the inputted grades, and also output the actual letter grade, but I am having trouble figuring out what I would code to convert to letter grades. Any help is appreciated.
Code:
public static void Main(string[] args)
{
int ARRAYLENGTH = 0;
int i = 0;
double sum = 0;
Console.WriteLine("How many scores would you like to enter? ");
ARRAYLENGTH = Convert.ToInt32(Console.ReadLine());
string[] test = new string[ARRAYLENGTH];
for (i = 0; i < test.Length; i++)
{
Console.Write("Enter your test score " + (i + 1) + ": ");
test[i] =
Console.ReadLine();
}
for (i = 0; i < test.Length; i++)
{
sum = sum +
Convert.ToDouble(test[i].Trim());
}
Console.WriteLine("\nThis is your average = " + (sum / test.Length));
Console.WriteLine("\nYour grade is: ");//Not sure how this would work
Console.Write("\nPress the [Enter] key to exit.");
Console.ReadLine();
}
For one, you're better of doing some more assignment (rather than calculating the grade in the print statement) so I've included that below. Once you have the percentage in a var you just use an if/else or a switch to derive the letter grade.
double gradePer = sum / test.Length
string gradeLetter = "F";
if (gradePer >= 60 && gradePer < 70) {
gradeLetter = "D";
} else if (gradePer >= 70 && gradePer < 80) {
gradeLetter = "C";
} // you fill in the rest
Console.WriteLine("\nThis is your average = " + gradePer);
Console.WriteLine("\nYour grade is: " + gradeLetter);
I would use a switch, specificing a range of values for each letter
You can make a function to get your letter grade from the average you computed:
static char GetLetterGrade(double score)
{
if (score >= 90.0)
{
return 'A';
}
if (score >= 80.0)
{
return 'B';
}
if (score >= 70.0)
{
return 'C';
}
if (score >= 60.0)
{
return 'D';
}
return 'F';
}
In the simplest possible way... I would create a dictionary:
Key - Value
10 - A
9 - A
8 - B
7 - C
6 - D
5 - F
4 - F
3 - F
2 - F
1 - F
0 - F
Now that you have this dictionary set up, you can take the grade into your method, divide by 10, take the floor and find the entry associated with that value.
public class Grades
{
Dictionary<int, char> GradeValues { get; set; }
public Grades()
{
GradeValues.Add(10, 'A');
GradeValues.Add(9, 'A');
GradeValues.Add(8, 'B');
...
GradeValues.Add(0, 'F');
}
public char GetGrade(int grade)
{
char value = GradeValues[int.Floor(grade/10)];
if (value == null)
return 'F';
return value;
}
}
That being said, there are probably better ways to handle this.
Edit: This assumes that you don't have B- or other grades that happen when a grade of 88 is passed into the method.
If statements or cases would work great too, but I prefer this method of development. It is easier to extend when you want to change a grade. You don't have to update the method. You only need to update the dictionary in the constructor.
Edit 2: I have seen that someone downvoted every answer. I upvoted the other answers as they are all valid...
You could just fill out the entire dictionary from 0 to 100 with the grade for that score.
Note: This is my first time using "Stack Overflow" and I am relatively new to C#
(please excuse my poor programming skills at the moment)
My Code:
static void Main(string[] args)
{
Challenge(5, 12);
}
static void Challenge(int num1, int num2)
{
//finds the sum of the two variables
int sum = num1 + num2;
Console.WriteLine("The sum of {0} and {1} is...\n{2}", num1, num2, sum);
bool isDivisible = true;
//checks if divisible by 5 and sets a value for 'isDivisible'
if ((sum % 10 == 5) || (sum % 10 == 0))
{
Console.WriteLine("\nThe sum is divisible by 5!");
isDivisible = true;
}
else if ((sum % 10 != 5) || (sum % 10 != 0))
{
Console.WriteLine("\nThe sum is not divisible by 5!");
isDivisible = false;
}
//depending on value of 'isDivisible', returns certain functions
if (isDivisible == true)
{
Console.WriteLine("This value is usable.");
Console.WriteLine("\n\nThe remaining usable values are: ");
for (int newVal = sum + 1; newVal <= 55; newVal++) // '+ 1' added to make sure 'sum' is not printed again
{
if ((newVal % 10 == 5) || (newVal % 10 == 0))
{
Console.WriteLine(newVal);
}
}
}
else if (isDivisible == false)
{
Console.WriteLine("This value is not usable.");
Console.WriteLine("\n\nThese values are considered usable: ");
for (int newVal = 0; newVal <= 55; newVal++)
{
if ((newVal % 10 == 5) || (newVal % 10 == 0))
{
Console.WriteLine(newVal);
}
}
}
Console.ReadLine();
}
I viewed some articles online, as well as the "Stack Overflow" post: Why compile error "Use of unassigned local variable"? . After learning that local variables are not initialized (and must be given a value), I set my bool value for "isDivisible" equal to true by default.
Question:
Is there a better way to define a local variable that is of Boolean value (at least in the case of the program I am trying to run here)?
Thanks!
Your condition in the else if is wrong, it's not the complement of the first condition, so it doesn't make sense. The correct complement would be:
else if ((sum % 10 != 5) && (sum % 10 != 0))
However, you don't need to use an else if at all, you can just use an else as you want to catch every case that is not caught by the first condition. That also means that you don't have to initialise the boolean variable, as the compiler can see that it always will be set by one of the code blocks:
bool isDivisible;
//checks if divisible by 5 and sets a value for 'isDivisible'
if ((sum % 10 == 5) || (sum % 10 == 0))
{
Console.WriteLine("\nThe sum is divisible by 5!");
isDivisible = true;
}
else
{
Console.WriteLine("\nThe sum is not divisible by 5!");
isDivisible = false;
}
Side note: Instead of (sum % 10 == 5) || (sum % 10 == 0) you could just use sum % 5 == 0.
Side note 2: You don't need to compare a boolean variable to true, you can just use it as a condition. Also, you don't need the else if there either. Instead of this:
if (isDivisible == true)
{
...
}
else if (isDivisible == false)
{
...
}
you can use:
if (isDivisible)
{
...
}
else
{
...
}
Comparison expressions in C# will return a boolean value indicating whether or not they are true. So you could simplify your initial assignment to:
bool isDivisible = ((sum % 10 == 5) || (sum % 10 == 0));
Instead of explicitly setting it to true or false. Then your variable would always be set.
This doesn't work for all cases. Sometimes, it is difficult to reduce the comparison operation to a simple expression. But, it is often a handy way to initialize bools.
for (int k = 0; k < proc.Count; k++){
for (int i = k + 1; i < proc.Count; i++){
if (proc[k].arrivalTime >= proc[i].arrivalTime && proc[k].priority >= proc[i].priority && proc[k].brust > proc[i].brust){
temp = proc[i];
proc[i] = proc[k];
proc[k] = temp;
}
}
}
Input
Process Arrival Brust Priority
P0 0 10 5
P1 1 3 1
P2 1 2 1
P3 5 1 5
P4 5 8 2
I want to sort these processes following these rules
1) If the process arrived alone it'll work no matter what.
2) If 2 processes arrived in the same time, we gonna check the priority if the first one has higher priority(lower number) it'll work first, and if they have the same priority we gonna let the one who has lower Brust work first.
There's problem with last 2 processes where's the problem?
P3 5 1 5
P4 5 8 2
process 4 should work because it has higher priority
Rather than bubble sorting (which is the one of the least efficient ways to sort collections), why not just sort the collection using LINQ's OrderBy(), e.g.
var sorted = proc.OrderBy(x => x.arrivalTime)
.ThenBy(x => x.priority)
.ThenBy(x => x.brust)
.ToList(); // or .ToArray() or whatever collection you need
You provided very clear explanation of the rules.
Now check this line
if (proc[k].arrivalTime >= proc[i].arrivalTime && proc[k].priority >= proc[i].priority && proc[k].brust > proc[i].brust)
Is it doing what the rules say? Definitely no. The direct translation of the rules would be something like this
if (proc[k].arrivalTime > proc[i].arrivalTime ||
(proc[k].arrivalTime == proc[i].arrivalTime &&
(proc[k].priority > proc[i].priority ||
(proc[k].priority == proc[i].priority && proc[k].brust > proc[i].brust))))
Better and more readable would be
int compare = proc[k].arrivalTime.CompareTo(proc[i].arrivalTime);
if (compare == 0)
compare = proc[k].priority.CompareTo(proc[i].priority);
if (compare == 0)
compare = proc[k].brust.CompareTo(proc[i].brust);
if (compare > 0)
{
// ...
}
which is the standard way of doing multi key comparison.
Mahmoud, your if-statment is incorrect because it will evaluate to true if ALL conditions are met, your statement should cascade the conditions.
for (int k = 0; k < proc.Count; k++){
for (int i = k + 1; i < proc.Count; i++){
bool doSwap = false;
if (proc[k].arrivalTime > proc[i].arrivalTime)
{
doSwap = true;
}
else if (proc[k].arrivalTime == proc[i].arrivalTime)
{
if(proc[k].priority > proc[i].priority)
{
doSwap = true;
}
else if (proc[k].priority == proc[i].priority )
{
if(proc[k].brust > proc[i].brust)
{
doSwap = true;
}
}
}
if(doSwap)
{
temp = proc[i];
proc[i] = proc[k];
proc[k] = temp;
}
}
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
When solving "fizz-buzz" in C# using a "while" loop, I found out that first I should find the multiples of both 3 and 5 (multiples of 15) and then go to the multiples of 3 and 5 like below.
int myval = 0;
while (myval < 100)
{
myval = myval + 1;
if (myval % 15 == 0)
{
listBox1.Items.Add("fizzbuzz");
}
else if (myval % 3 == 0)
{
listBox1.Items.Add("fizz");
}
else if (myval % 5 == 0)
{
listBox1.Items.Add("buzz");
}
else
{
listBox1.Items.Add(myval);
}
}
But if I write the code to filter multiples of 3 and 5 first and then go to the multiples of both 3 and 5 (multiples of 15) like below the end result only shows the fizz (multiples of 3) and buzz (multiples of 5) without fizz-buzz (multiples of both 3 and 5). Does anyone know what's the reason for this even IDE doesn't show me any errors.
myval = 0;
while (myval < 100)
{
myval = myval + 1;
if (myval % 3 == 0)
{
listBox1.Items.Add("fizz");
}
else if (myval % 5 == 0)
{
listBox1.Items.Add("buzz");
}
else if (myval % 15 == 0)
{
listBox1.Items.Add("fizzbuzz"); // for multiples of both 3 and 5
}
else
{
listBox1.Items.Add(myval);
}
}
Because it satisfies the first two conditions. So it will never hit your third else statement.
This boils down to the fact that if-else statements are processed sequentially. As soon as a condition that evaluates to true is encountered, the other else if clauses are skipped.
Suppose that a and b are both true. When you write
if (a) {
Foo1();
}
else if (b) {
Foo2();
}
you do not execute both Foo1 and Foo2. Since a is true, Foo1 executes and b is not even evaluated.
Now consider your problem. Consider the number 15. All three candidate divisors, 3, 5 and 15, divide into that number.
if (myval % 3 == 0)
{
listBox1.Items.Add("fizz");
}
else if (myval % 5 == 0)
{
listBox1.Items.Add("buzz");
}
else if (myval % 15 == 0)
{
listBox1.Items.Add("fizzbuzz"); // for multiples of both 3 and 5
}
else
{
listBox1.Items.Add(myval);
}
Since the multiples of 15 are also multiples of 3 (and 5), you will never even reach the myval % 15 == 0 test for multiples of 15.
It's because something divisible by 3 and 5 is also divisible by 3 and by 5. If you catch either of those conditions first, the later condition is never checked.
You could also write it like so:
var resultString = "";
if(myval % 3 == 0) resultString += "fizz";
if(myval % 5 == 0) resultString += "buzz";
if(myval % 5 != 0 && myval % 3 != 0) resultString += myval;
listBox1.Items.Add(resultString);
This will print all conditions without needing a separate check for % 15.
Also, I know this wasn't the original question, but typically someone wouldn't use a while loop to cycle through a range of numbers. Use a for loop for that:
for( int myval = 0; myval <= 100; myval++)
{
// code goes here
}
I always solved this a slightly different way: by constructing the string to add.
for (int myVal = 0; myVal < 100; myVal++)
{
string fb = "";
if ((myVal % 3) == 0) { fb = "fizz"; }
if ((myVal % 5) == 0) { fb += "buzz"; }
// Handle the case where it isn't divisible by 3 or 5:
if (fb == "") { fb = myVal.ToString(); }
// "output" the string.
listBox1.Items.Add(fb);
}
You can use this method to fill your Listbox:
foreach (int i in Enumerable.Range(1,100)){
string str = null;
listBox1.Items.Add((str = (i % 3 == 0 ? "fizz" : "")
+ (i % 5 == 0 ? "buzz" : "")) == ""
? i.ToString() : str );
}
I am trying to improve a list collection that i have to replace values that are divisible by two and 10 and replace everything that is divisible by two with dTwo and ten with dTen?
My code works with one divisible statment but not two.
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
num.Add(n % 10 == 0 ? "dTen" : n.ToString());
}
Since any number that is divisible by 10 is also divisible by 2 you have to switch your addition statements, and continue with the next number if you have a number divisible by 10:
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
if( n % 10 == 0)
{
num.Add("dTen");
}
else num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
}
If I can I try avoid using loop controls out side of the defined construct of the actual loop, ie. I prefer to avoid using continue if I can, it sort of feels like using goto statements. For this case, I would go for the plain and simple approach which I believe is readable, maintainable and simple albeit a little more verbose.
You can switch the order of the if/else if statements to change the priority if required, in this case the n % 10 has priority
var num = new List<string>();
for (int n = 0; n < 101; ++n)
{
if (n % 10 == 0)
{
num.Add("dTen");
}
else if (n % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(n.ToString());
}
}
There are two approaches I would take here, the first is verbose, but conveys what you're trying to do in a very readable manner:
var num = new List<string>(101);
for (int i = 0; i < 101 ; i++)
{
if (i == 0)
{
num.Add(i.ToString());
}
else if (i % 10 == 0)
{
num.Add("dTen");
}
else if (i % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(i.ToString());
}
}
The second uses a more concise LINQ-y type approach, like this.
var num = Enumerable.Range(0, 101)
.Select(
n => n == 0 ? n.ToString() :
n % 10 == 0 ? "dTen" :
n % 2 == 0 ? "dTwo" :
n.ToString())
.ToList();
Note that I've also taken into account the 0 edge case, where 0 would otherwise get reported as being divisible by 10.
Which one you go for is largely up to your taste. Personally I'd go for the latter implementation, as it's concise but still conveys the intent of the code. Some very rudimentary tests I've just done shows that it'll execute faster as well.