Why doesn't my code increase a variable everytime? [closed] - c#

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am trying to make a code that loops through random numbers until it gets a six(this part is working) and then if you rolled a six in less than 6 tries but my code won't up my "amountOfMoney" variable if you get it in less than six. All it outputs is one even if you get under 6 two times in row. Here is the code:
class Program
{
static void Main(string[] args)
{
Start:
int attempt = 0;
int numberOfAttempts = 0;
int amountOfMoney = 0;
Random numberGen = new Random();
while (attempt != 6)
{
attempt = numberGen.Next(1, 7);
Console.WriteLine("Tom rolled: " + attempt + ".");
numberOfAttempts++;
}
Console.WriteLine("It took tom " + numberOfAttempts + " attempts to roll a six");
if(numberOfAttempts <= 6)
{
amountOfMoney++;
Console.WriteLine("You now have " + amountOfMoney + " dollars");
}
if(numberOfAttempts > 6)
{
amountOfMoney--;
Console.WriteLine("You now have " + amountOfMoney + " dollars");
}
Console.ReadKey();
goto Start;
}
}

You should be using the tools available to you to solve this (i.e the debugger), but it seems like you are new so I will risk the downvotes in an attempt to help you...
The code you have is pretty close to what you need. However the problem you have is a combination of using goto, and not understanding variable scope.
Let me be very clear: goto is very bad practice
When this line is hit:
goto Start;
It goes to the very top of your Main() method, the next 3 lines declare your variables and set them to 0. Thats why you are never able to persist the values.
You need to remove the goto and utilize a loop like you are already doing. Then put the variables you want to persist across loop iterations outside the scope of your new loop:
int amountOfMoney = 0;
while(someCondition)
{
//game logic here
amountOfMoney++;
}
//amountOfMoney has not reset every loop and now has all the changes you made to it
Console.WriteLine(amountOfMoney);
With your new loops you need to come up with an exit condition though. Is it a user's input that exits the loop (and the game), is it a fixed number of loops (use a for loop). That is up to you...
I made a simple "coin-flip" game here so you can see an example of what I am talking about. Doing the work for you wont help you learn but this should be more than enough to contextualize things for you.

I'm answering because this is actually an awesome teachable moment. What you have provided is one of the simplest examples of a very common design issue, an uncontextualized neologism. This label:
Start:
...seems innocent enough. But in the programming world, things are actually very, very, specific, and this label is nowhere near specific enough. What exactly is starting?
Whoever wrote this code...
int attempt = 0;
int numberOfAttempts = 0;
int amountOfMoney = 0;
...thought it was the start of the game.
Whoever wrote this code...
goto Start;
...thought it was the start of the round.
To fix this, make the label more specific, and put it in the right place.
P.S. Also, don't use goto and come up with an exit condition. But I think those lessons are less valuable.

Related

C# variable used but never assigned

So I have been working on a program that calculates nearest and larger 3rd power to a number which is entered (if entered number is 20 then result is 27 because 3^3=27). However due to my lack of skills I have stumbled upon a problem. It seems that variable result is used but never assigned (even if its value is asigned to it in a for cycle) Here is the code:
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
Console.Write("Enter a number: ");
int num = Convert.ToInt32(Console.ReadLine());
int result;
for(int i = num; (i * i * i) >= 0; i--)
{
result = i * i * i;
}
Console.WriteLine("Nest 3rd pow. is: " + result);
Console.WriteLine("Press any key to contiunue...");
Console.ReadLine();
}
}
}
Thank you for your answers.
The comments have probably dealt with your issue (you didn't set a value for result when you created it, the compiler can foresee a scenario where no loop runs and there is never any assignment, but you always use it. A "use of unassigned local variable" error arises), but I wanted to point out that your program is some way off solving the advertised problem of finding the next larger int cube than the entered number
To solve this, cube root the entered number, round it up to the next integer and cube it
Math.Pow(Math.Ceiling(Math.Pow(num, 1.0/3.0)), 3.0);
As things stand, I'm not really sure what you're aiming to achieve with the loop, and it looks like it will run however many times needed to set the result to 0 (it loops until i is zero, result is 0). Perhaps you intended to start i from 2 and increment i until result was larger than num, but that seems less efficient than doing the calc directly
One overall rule of good programming praxis is to initialize a variable on the declaration.
The compiler error says that you are using result when it has not been assigned. That's because in your for loop you can't predict that it will iterate at least one time (therefore there are scenarios where the variable is used without ever being assigned).
As have been mentioned before, this can be fixed by initializing the variable (0 is the standard)
int result = 0;

C# program using Random executes differently when running and interactively debugging [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm trying to make a Computer Vs. Computer guessing game. I've done it on python and matlab, but im having trouble doing it with c#.
I dont think that the application is executing the loop, but when using the debugger to step through the application it appears to work as intended.
using System;
using static System.Console;
namespace ComVsCom
{
class ComVsCom
{
static void Main(string[] args)
{
int rand, comp, pick = 0;
bool tri = false;
Random number = new Random();
rand = number.Next(1, 10);
Random computer = new Random();
comp = computer.Next(1, 10);
while (comp != rand && tri == false)
{
if (comp > rand)
WriteLine("Guess again you are too high!");
if (comp < rand)
WriteLine("Guess again you are too low!");
pick++;
WriteLine("{0} attempt", pick);
comp = computer.Next(1, 10);
if (comp == rand)
{
WriteLine("You got it! it took you {0} times the number was {1}", pick, rand);
tri = true;
}
}
}
}
}
Running the program normally, it terminates gives no output. However, when debugging the output given is what was expected and is something like:
Guess again you are too high!
3 attempt
Guess again you are too low
6 attempt
You got it! it took you 3 times the number was 6
Why does this work when using the debugger and not when running the program normally?
The problem is almost certainly that you are never entering the loop:
See https://msdn.microsoft.com/en-us/library/h343ddh9(v=vs.110).aspx
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers.
You create two Randoms at the start, then call exactly the same method on each of them. As expected based on the documentation, they produce exactly the same result. In the loop condition you check that these are different - they aren't, so the loop is never entered. Because all of your program logic is in that loop, none of it ever happens.
Note that your different behavior when debugging is probably due to stepping through the constructing of Randoms, making them occur at different times, so they will have different seed values and produce different sequences.

how GOTO works in c# [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a for loop in c# winform and I want to start for loop again if i=7
The code looks like this :
for (int i = 0; i < 10; i++)
{
if (i==7)
{
MessageBox.Show("you must start for loop again ");
//here I want to go back to for loop again
}
}
any ideas ?
also,I know this code makes no sense, I just wrote it for example — I have similar situation in my c# code.
In this case, just mutate i back to 0, like so:
for (int i = 0; i < 10; i++)
{
if (i==7)
{
MessageBox.Show("you must start for loop again ");
i = 0;
}
}
If you really want to use goto, then here is an example for that:
BackToTheStart:
for (int i = 0; i < 10; i++)
{
if (i==7)
{
MessageBox.Show("you must start for loop again ");
goto BackToTheStart;
}
}
It's worth keeping in mind if you didn't already know, goto is generally considered bad practice and an unwelcome legacy baggage C# brought from C style languages of yesteryear. In most cases you do not need it, like in this example, it's easier not to use it. And, most importantly, no one will ever thank you for adding a goto.
It's worth noting that this would be an infinite loop. Think about it: if you go back to 0 every time i reaches 7, how would it ever bet the case that i == 10? How would you break out of the loop? This may be a case of the XY problem - i.e. you probably don't actually want to do what you say you want to do here.
If you really want this to occur in an infinite loop, just do this:
while (true) {
for (int i = 0; i <= 7; i++) {
if (i == 7) {
// ..
}
}
}
Actually, I'm slightly baffled as to why you bother with the "for" loop at all in this case if you're only doing something in the case where i = 7; why bother with the for loop at all and just put the action in an infinite loop?
Also, if you're doing this on the UI thread, it'll appear to "hang" the UI because the UI thread won't ever be able to do anything other than service your for loop. Users won't even be able to close it normally.
Finally, as other people have pointed out, never use goto, it's a bad practice - Microsoft shouldn't have even included it in the language.

if statement performance in c# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm just trying to determine the impact of each "if" statement on the performance of my C# application when it is used in cycles with large number of iterations. I have not found the topic about this so I have created this one.
For the test I made 2 cycles: one without "if" and one with a single "if" statement. The code is the following.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace IfPerformance
{
class Program
{
static void Main(string[] args)
{
int N = 500000000;
Stopwatch sw = new Stopwatch();
double a = 0, b = 0;
bool f;
sw.Restart();
for (int i = 0; i < N; i++)
{
a += 1.1;
f = a < N;
}
sw.Stop();
Console.WriteLine("Without if: " + sw.ElapsedMilliseconds + " ms");
a = 0;
sw.Restart();
for (int i = 0; i < N; i++)
{
if (a < N)
a += 1.1;
else
b += 1.1;
}
sw.Stop();
Console.WriteLine("With if: " + sw.ElapsedMilliseconds + " ms");
Console.ReadKey();
}
}
}
I ran the test with "Optimize code" build option and "Start without debugging". The result is the following:
Without if: 154 ms
With if: 742 ms
This means that a single "if" statement brings almost 5 times slowdown to the performance. I think regarding this will be helpful.
Also, I have noticed that the presence of several extra "if"s in a large loop may slow down my final application by 25%, which on my opinion is significant.
To be specific, I'm running Monte-Carlo optimization on a set of data, which require many loops through the whole data set. The loop contains branching which depends on the user settings. From this point "if"s arise.
My questions to the professionals in performance aspects are:
What is the impact of extra "if"s in a loop on the time of running many iterations?
How to avoid the slowdown?
Please post your opinion if I'm going in the wrong direction.
It doesn't matter ...
You're testing 500 MILLION iterations ... and it takes less than a second ... IN THE WORST case ...
As comments said, you'll be in a hell of a trouble to begin with, since you won't be running in debug for testing performance, and even then, you'll have heaps of other things to take into consideration (it's a whole big world about performance testing, and it's not as simple as it seems usually).
Now, do notice that you're doing two different things in the two places. If you would like to see the performance of the if, you should have them do basically the same. I'm sure the branching changes the IL code to begin with ...
Last, but not least, as I said again ... it DOESTN'T MATTER ... unless you really need to run 500 MILLION times, and have this in so many places that your program starts to slow down because of that.
Go for readability over obsessing if you can save some micro seconds on an if statement
Feel free to read these articles by Eric Lippert (who has "only" 250K rep and i̶s̶ was a principal developer on the C# compiler team :) who'll get you on the right direction:
c# performance benchmarks mistakes part 1
c# performance benchmarks mistakes part 2
c# performance benchmarks mistakes part 3
c# performance benchmarks mistakes part 4
(Talking about this, I would guess that garbage collection (article 4) might have been something to consider ...)
Then look at: this elaborate answer about the topic
And last, but not least, have a look at Writing Faster Managed Code: Know What Things Cost. This is by Jan Gray, from the Microsoft CLR Performance Team. I'll be honest and say I didn't read this one yet :). I Will though, later on...
It goes on an on ... :)
These code sample are two different codes one is a boolean assignment and the other one is condition statement so this is not suitable method to evaluate performance
Those benchmarks tell you essentially nothing at all.
There are much more things at play than just an additional if.
You also have to take branch-prediction and caching into account.
Such micro optimizations will only hinder you writing good code.
You will spend more time optimizing useless stuff than you spend time implementing good features in your software...
Think of it this way, no kind of optimization will help you if you have even a single design mistake in your code.
For example using a unfitting datastructure (for example a list for 'fast' lookup instead of a dictionary).

Changing variables outside of Scope C#

I'm a beginner C# programmer, and to improve my skills I decided to give Project Euler a try. The first problem on the site asks you to find the sum of all the multiples of 3 and 5 under 1000. Since I'm essentially doing the same thing twice, I made a method to multiply a base number incrementally, and add the sum of all the answers togethor.
public static int SumOfMultiplication(int Base, int limit)
{
bool Escape = false;
for (int mult = 1; Escape == true; mult++)
{
int Number = 0;
int iSum = 0;
Number = Base * mult;
if (Number > limit)
return iSum;
else
iSum = iSum + Number;
}
regardless of what I put in for both parameters, it ALWAYS returns zero. I'm 99% sure it has something to do with the scope of the variables, but I have no clue how to fix it. All help is appreciated.
Thanks in advance,
Sam
Your loop never actually executes:
bool Escape = false;
for (int mult = 1; Escape == true; mult++)
Escape is set to false initially, so the first test fails (Escape == true returns false) and the body of the loop is skipped.
The compiler would have told you if you were trying to access variables outside of their defined scope, so that's not the problem. You are also missing a return statement, but that is probably a typo.
I would also note that your code never checks if the number to be added to the sum is actually a multiple of 3 or 5. There are other issues as well (for example, iSum is declared inside of the loop and initialized to 0 after each iteration), but I'll let you work that one out since this is practice. The debugger is your friend in cases like these :)
EDIT: If you need help with the actual logic I'll be happy to help, but I figure you want to work it out on your own if possible.
As others have pointed out, the problem is that the control flow does not do what you think it does. This is a common beginner problem.
My suggestion to you is learn how to use your debugger. Beginners often have this strange idea that they're not allowed to use tools to solve their coding problems; that rather, they have to reason out the defect in the program by simply reading it. Once the programs become more than a page long, that becomes impossible for humans. The debugger is your best friend, so get to know its features really well.
In this case if you'd stepped through the code in the debugger you'd see that the loop condition was being evaluated and then the loop was being skipped. At that point you wouldn't be asking "why does this return zero?", you'd be asking "why is the loop body always skipped?" Clearly that is a much more productive question to ask since that is actually the problem here.
Don't write any code without stepping through it in the debugger. Watch every variable, watch how it changes value (the debugger highlights variables in the watch windows right after they change value, by the way) and make sure that the control flow and the variable changes are exactly as you'd expect. Pay attention to quiet doubts; if anything seems out of the ordinary, track it down, and either learn why it is correct, or fix it until it is.
Regarding the actual problem: remember that 15, 30, 45, 60... are all multiples of both three and five, but you only want to add them to the sum once. My advice when solving Project Euler problems is to write code that is as like what you are trying to solve as is possible. Try writing the problem out in "pseudocode" first. I'd pseudocode this as:
sum = 0
for each positive number under 1000:
if number is multiple of three or five then:
add number to sum
Once you have that pseudocode you can notice its subtleties. Like, is 1000 included? Does the problem say "under 1000" or "up to 1000"? Make sure your loop condition considers that. And so on.
The closer the program reads like the problem actually being solved, the more likely it is to be correct.
It does not enter for loop because for condition is false.
Escape == true
returns false
Advice:
Using for loop is much simpler if you use condition as limit for breaking loop
for (int mult = 1; something < limit; mult++)
This way in most cases you do not need to check condition in loop
Most programming languages have have operator modulo division.
http://en.wikipedia.org/wiki/Modulo_operation
It might come handy whit this problem.
There are several problems with this code. The first, and most important, is that you are using the Escape variable only once. It is never set to false within your for loop, so it serves no purpose whatsoever. It should be removed. Second, isum is declared within your for loop, which means it will keep being re-initialized to 0 every time the loop executes. This means you will only get the last multiple, not the addition of all multiples. Here is a corrected code sample:
int iSum = 0;
for(int mult = 1; true; mult++)
{
int Number = Base * mult;
if(Number > limit)
return iSum;
else
iSum += Number;
}

Categories

Resources