I am working on a school project and I am trying to write a C# program that will allow the user to input total sales. I need to take the total sales and calculate it by the profitRatio as follows:
totalSales profitRatio
0-$1,000: 3%
$1,000.01-%5,000 3.5%
$5,000.01-$10,000 4%
Over 10,000 4.5%
The next step would be to calculate the total sales by the % category that it matches and store that data. I will also want to display the profit ratio % used to the user along with the new profit. Will “if then” statements work to do this if written like this?
private decimal ReturnRatio()
{
if (totalSales > 0 && totalSales < 1000)
{
profitRatio = .03M;
}
else if (totalSales >= 1000.01 && totalSales < 5000)
{
profitRatio = .035M;
}
else if (totalSales >= 5000.01 && totalSales <= 10000)
{
profitRatio = .40M;
}
else if (totalSales < 10000)
{
profitRatio = .045M;
}
}
In your last branch, else if (totalSales < 10000) you would allow in numbers that are <= 0>. I think that last branch should be else if (totalSales > 10000).
Well, the last branch should probably really be an else statement that handles other amounts since the user is allowed to enter amounts. For example:
else if (totalSales > 10000)
{
profitRatio = .045M;
}
else
{
Console.WriteLine("You entered an invalid amount.");
}
If then statements will work, but if I were your teacher I would be hoping for more. You should consider creating a Range class with a field for Min and a field for Max, then create objects to represent each category.
Place these Range objects in a collection like a List, then do a foreach loop to go through each Range object individually.
If this were code in an enterprise system, I would hunt you down unless this was the hot loop in some extreme performance stuff.
Related
I'm trying to create a method that takes a user's height, weight, and age, and returns their BMI and BMR.
I think I've done this fine.
However, the last thing I need to do is add some validation to make sure the user has put in some sensible numbers. The constraints being applied to the input are:
50 [cm] ≤ height ≤ 220 [cm]
10 [kg] ≤ weight ≤ 250 [kg]
18 [years] ≤ age ≤ 70 [years]
To do this, I've tried using if statements
if (getHight >= 220 && getHight <= 50)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getAge >= 70 && getAge <= 18)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getWeight >= 250 && getWeight <= 10)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
However, regardless of what I ender, nothing shows up in the console by way of validation errors. It just outputs my BMI and BMR.
What am I missing here?
Your mistake is that you are using AND instead of OR.
You cannot both be taller than 220cm and shorter than 50cm.
Use OR operators instead of AND:
if (getHight > 220 || getHight < 50)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getAge > 70 || getAge < 18)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getWeight > 250 || getWeight < 10)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
Also as #PaulF mentioned, you should not be using <= and >= since the valid range of values is inclusive. Since your logic is the inverse (invalid values), you should drop the = and just use < and >.
As already mentioned, you should be using || instead of && when doing the comparisons and you should be using < and > since the boundary values are acceptable. You might spend some time reading up on the Boolean logical operators - AND, OR, NOT, XOR so they all make sense, because they're very common and used in just about every program you'll write.
I just wanted to add another possible solution in case you're doing a lot of these types of comparisons, which is to write an extension method for them. This way you only have to write it once, which reduces the chance of error.
Below I have an extension method that tests if a number is between a minimum and maximum value (along with an option to specify if those boundary values as valid). Note that I assumed you're testing with an int type, but you can change the type easily by changing the this int value to this double value or this float value, or whatever numeric type you're using:
public static class Extensions
{
public static bool IsBetween(this int value, int min, int max,
bool inclusive = true)
{
return inclusive ?
min <= value && value <= max:
min < value && value < max;
}
}
Now if you include that class in your project, we can use this method to test if the value is not between our accepted values by using the ! not operator. Also note that I changed the else if to separate if statements. This way, if there's more than one error, they all get reported at the same time and the user can correct them all at once. I also changed the error message so the user actually knows what's wrong and how to fix it:
// In your program class, not in the Extensions class above
if (!getHeight.IsBetween(50, 220))
{
Console.WriteLine("ERROR: Height must be an integer between 50 and 220");
}
if (!getAge.IsBetween(18, 70))
{
Console.WriteLine("ERROR: Age must be an integer between 18 and 70");
}
if (!getWeight.IsBetween(10, 250))
{
Console.WriteLine("ERROR: Weight must be an integer between 10 and 250");
}
This question already has answers here:
Or in IF statement not working properly
(4 answers)
Closed 9 months ago.
I'm a beginner in c#, and I am currently practicing conditional statements and others. I wanted to create a simple movie rating code, where the user would enter a value and show the movie's rating.
I'm having a little trouble because I get the wrong rating when I type in a specific number.
A NY help with this code would be appreciated. Thank you.
static void Main(string[] args)
{
int rating;
string movie;
Console.Write("Enter the name of the movie: ");
movie = Console.ReadLine();
Console.Write("What is your rating: ");
rating = Convert.ToInt32(Console.ReadLine());
if (rating == 10 || rating >= 8)
Console.WriteLine("Great movie");
else if(rating <= 7 || rating >= 5)
Console.WriteLine("Good movie");
else if (rating <= 4 || rating >= 1)
Console.WriteLine("Poor movie");
else
Console.WriteLine("Very Very Poor");
Console.WriteLine("The movie {0} is of {1} rating", movie, rating);
Console.ReadKey();
}
Looking at the conditional statements, let's think about what would happen if I were to enter, say, 4 for the rating:
if (rating == 10 || rating >= 8)
4 is not 10, and it's not >= 8. Moving on...
else if(rating <= 7 || rating >= 5)
4 is not >= 5, but it IS <= 7. Since this is an || condition, the result is true if either side is true, and that is the case here. I don't think that's what you intended.
You probably want && for these, instead of ||. Additionally, since we go in order from large to small, using else if blocks, you only need to check the lower bound of each rating.
As this is beginning work, I'll leave incorporating these suggestions into the original code for the OP.
The first conditions in all ifs are useless: rating == 10 || rating >= 8 - when rating >= 8 we have no need to check rating == 10; rating <= 7 || rating >= 5 meets every rating - all integer numbers either less than 7 or greater than 5 etc.
Film is
Great if its rating is at least 8.
Good if its rating is at least 5 (and it's not Great).
Poor if its rating is at least 1 (and it's not Good).
Very Very Poor in other cases.
if (rating >= 8)
Console.WriteLine("Great movie");
else if (rating >= 5)
Console.WriteLine("Good movie");
else if (rating >= 1)
Console.WriteLine("Poor movie");
else
Console.WriteLine("Very Very Poor");
I am trying to price group. For example: a tutor costs 100 euro per 5 people; 6 people needs 2 tutors so it comes to 200 euro.
Basically I don't know how to go about this, this is what I tried. What I did works perfectly but let's say the user enters a bigger number and I didn't put an if statement how can I fix it? Thanks
int tutorprice;
int students;
Console.WriteLine("How many students");
students = Convert.ToInt32(Console.ReadLine());
if (students <= 1 && students <= 5)
{
tutorprice = 100;
}
else if (students > 5 && students <=10 )
{
tutorprice = 200;
}
You have 2 problems here.
First of all you need to learn basic implementation. For that you can search help other places.
To implement the best calculating function you should look at this topic :
Math Round to always upper integer
I have been creating a simple chess engine in c# over the last month and made some nice progress on it. It is using a simple Alpha-Beta algorithm.
In order to correct the Horizon-Effect, I tried to implement the Quiescence Search (and failed several times before it worked). The strength of the engine seems to have improved quiet a bit from that, but it is terribly slow!
Before, I could search to a 6 ply depth in about 160 secs (somewhere in a midgame state), with the quiescent search, it takes the computer about 80secs to get a move on search depth 3!
The brute-force node counter is at about 20000 Nodes at depth 3, while the quiescent node counter is up to 20 millions!
Since this is my first chess engine, I don't really know if those numbers are normal or if I might have made a mistake in my Quiescence-Algorithm. I would appreciate if someone more experienced could tell me what the usual ratio of BF Nodes/Quiescent nodes is.
Btw, just to have a look at:
(this Method is called by the BF tree whenever the searchdepth is 0)
public static int QuiescentValue(chessBoard Board, int Alpha, int Beta)
{
QuiescentNodes++;
int MinMax = Board.WhoseMove; // 1 = maximierend, -1 = minimierend
int Counter = 0;
int maxCount;
int tempValue = 0;
int currentAlpha = Alpha;
int currentBeta = Beta;
int QuietWorth = chEvaluation.Evaluate(Board);
if(MinMax == 1) //Max
{
if (QuietWorth >= currentBeta)
return currentBeta;
if (QuietWorth > currentAlpha)
currentAlpha = QuietWorth;
}
else //Min
{
if (QuietWorth <= currentAlpha)
return currentAlpha;
if (QuietWorth < currentBeta)
currentBeta = QuietWorth;
}
List<chMove> HitMoves = GetAllHitMoves(Board);
maxCount = HitMoves.Count;
if(maxCount == 0)
return chEvaluation.Evaluate(Board);
chessBoard tempBoard;
while (Counter < maxCount)
{
tempBoard = new chessBoard(Board);
tempBoard.Move(HitMoves[Counter]);
tempValue = QuiescentValue(tempBoard, currentAlpha, currentBeta);
if (MinMax == 1) //maximierend
{
if (tempValue >= currentBeta)
{
return currentBeta;
}
if (tempValue > currentAlpha)
{
currentAlpha = tempValue;
}
}
else //minimierend
{
if (tempValue <= currentAlpha)
{
return currentAlpha;
}
if (tempValue < currentBeta)
{
currentBeta = tempValue;
}
}
Counter++;
}
if (MinMax == 1)
return currentAlpha;
else
return currentBeta;
}
I am not familliar with the english terminology - is a HitMove a move where you remove a piece from the board?
In that case it seems to me that you use GetAllHitMoves to get a list of the "noisy" moves for the quiescence search which are then evaluated further than the usual 3 or 6 plies. This is called recursively though, so you evaluate this over and over as long as there are possible HitMoves leftover. Giving a limit to your quiescence search should fix your performance issues.
As for choosing the limit for the quiescence search - wiki states:
Modern chess engines may search certain moves up to 2 or 3 times deeper than the minimum.
I can think of some very convoluted methods with loops and nested loops to solve this problem but I'm trying to be more professional than that.
My scenario is that I need to enter a section of code every ten percent but it isn't quite working as expected. It is entering the code about every percent which is due to my code but I lack the knowledge to know how to change it.
int currentPercent = Math.Truncate((current * 100M) / total);
//avoid divide by zero error
if (currentPercent > 0)
{
if (IsDivisible(100, currentPercent))
{
....my code that works fine other than coming in too many times
}
}
Helper referenced above where the trouble is:
private bool IsDivisible(int x, int y)
{
return (x % y) == 0;
}
So obviously it works as it should. Mod eliminates currentPercent of 3 but 1 & 2 pass when really I don't want a true value until currentPercent = 10 and then not again till 20...etc.
Thank you and my apologies for the elementary question
Mod will only catch exact occurrences of your interval. Try keeping track of your next milestone, you'll be less likely to miss them.
const int cycles = 100;
const int interval = 10;
int nextPercent = interval;
for (int index = 0; index <= cycles; index++)
{
int currentPercent = (index * 100) / cycles;
if (currentPercent >= nextPercent)
{
nextPercent = currentPercent - (currentPercent % interval) + interval;
}
}
I might misunderstand you, but it seems like you're trying to do something extremely simple more complex than it needs to be. What about this?
for (int i = 1; i <= 100; i++)
{
if (i % 10 == 0)
{
// Here, you can do what you want - this will happen
// every ten iterations ("percent")
}
}
Or, if your entire code enters from somewhere else (so no loop in this scope), the important part is the i % 10 == 0.
if (IsDivisible(100, currentPercent))
{
....my code that works fine other than coming in too many times
}
try changing that 100 to a 10. And I think your x and y are also backwards.
You can try a few sample operations using google calculator.
(20 mod 10) = 0
Not sure if I fully understand, but I think this is what you want? You also reversed the order of modulo in your code (100 mod percent, rather than the other way around):
int currentPercent = current * 100 / total;
if (currentPercent % 10 == 0)
{
// your code here, every 10%, starting at 0%
}
Note that code this way only works properly if you are guaranteed to hit every percentage-mark. If you could, say, skip from 19% to 21% then you'll need to keep track of which percentage the previous time was to see if you went over a 10% mark.
try this:
for (int percent = 1; percent <= 100; percent++)
{
if (percent % 10 == 0)
{
//code goes here
}
}
Depending on how you increment your % value, this may or may not work % 10 == 0. For example jumping from 89 to 91 % would effectively skip the code execution. You should store last executed value, 80 in this case. Then check if interval is >= 10, so 90 would work, as well as 91.