How to make a counter based on user response? - c#

I'm trying to make a counter that will increment based on the response of the user. Here's the code I got so far:
string ok = "";
int z = 0;
test(ok, z);
test1(ok, z);
Console.WriteLine(z);
}
static void test(string ok, int z)
{
bool estok = false;
while (!estok)
{
ConsoleKeyInfo saisie = Console.ReadKey(true);
if (saisie.Key == ConsoleKey.A || saisie.Key == ConsoleKey.B)
{
estok = true;
if (saisie.Key == ConsoleKey.A)
{
z++;
}
if (saisie.Key == ConsoleKey.B)
{
z--;
}
}
else
{
estok = false;
Console.WriteLine("Error");
}
}
}
static void test1(string ok, int z)
{
bool estok = false;
while (!estok)
{
ConsoleKeyInfo saisie = Console.ReadKey(true);
if (saisie.Key == ConsoleKey.A || saisie.Key == ConsoleKey.B)
{
estok = true;
if (saisie.Key == ConsoleKey.A)
{
z++;
}
if (saisie.Key == ConsoleKey.B)
{
z--;
}
}
else
{
estok = false;
Console.WriteLine("Error");
}
}
}
I got 2 functions (test and test1) that both increment the int z. The Console.WriteLine(z) will return me 0, in place of the 2 i'm waiting for (when the user has 2 correct answers).
I figured that the increment won't happen since it's in the function and that the Console.WriteLine(z) can't reach the z++. How can I change that ?
How can I get the result from these?

int and other primitive types are passed by value by default where as reference types (think instances of a class) are passed by reference; this is what allows changes to the parameter to be persisted after the method returns. The way you are updating the value of the parameter, you'll need to pass z by reference.
static void test(string ok, int z)
becomes
static void test(string ok, ref int z)
and the call test(ok, z); becomes test(ok, ref z);
You can learn more about passing values by reference from the C# Language Reference

method parameters for int are of value types and not reference type, as far as I understood from your question, you may need to use out keyword in the method call or return from the method you have.
int z1= z;
test(ok, out z1);
int z2=z;
test1(ok, out z2);
and the method declaration also will have to be changed to
static void test(string ok, out int z)
static void test1(string ok, out int z)
OR you can simply put a Console.WriteLine(z) in the method test and test1 directly.

Related

Beginner question about a task in a course in C#

The code
class Program
{
static int Add(int x, int y)
{
x = 4;
y = 3;
int f = x + y;
return f;
}
static void Main(string[] args)
{
int x = 4;
int y = 3;
Console.WriteLine("Answer: ");
Add(x, y);
}
}
Doing a beginner course in C# and I have been stuck at this question for two days now.
I know its probably really simple, but I have tried so many different things that I think I have made it harder for me than it really.
I fixed to call strings in methods, but numbers seems hard.
The task is about to take two numbers in and that return the answer.
Tried searching around all the different errors I got with all the different tries, but didn't find the help, or the answers I understand.
You almost did all of it, just with 2 issues.
You should relay on the numbers you pass from Main to Add and not reassign the values inside Add otherwise passing them is useless and unusable for other numbers.
Add returns a value but you never save it + print it.
Example for #1
static int Add(int x, int y)
{
int f = x + y;
return f;
}
Example of #2
var result = Add(x, y);
Console.WriteLine(result);
Corrected Example:
class Program
{
static int Add(int x, int y)
{
// You don't need to redefine the variables x and y,
// because you get them when you call the method
// You can shorten the last part
// and just return the Addition
return x + y;
}
static void Main(string[] args)
{
int x = 4;
int y = 3;
// Prints the Word Answer
// as well as the Addition result into the Console now
Console.WriteLine("Answer: " + Add(x, y));
}
}
Your Errors:
You never printed the Result into the Console!
You shouldn't redefine the variables in the Function, because if you do that you don't need to use a function in the first place
You can shorten the return statement (you don't have to)
You can add Add(x,y) into the Console.WriteLine because it returns a Integer, therefore it is basically like writting Console.WriteLine("Answer: " + 7);
Here is an working version with explaination:
class Program
{
static int Add(int x, int y)
{
//x = 4; these are passed in as parameter, no need to set it
//y = 3;
int f = x + y;
return f;
}
static void Main(string[] args)
{
int someX = 4; //these are only known inside the scope of "Main"
int someY = 3;
int result = Add(someX, someY); //these are passed inside the function,
//the value is copied
Console.WriteLine("Answer: " + result.ToString());
}
}
You can do it even easier and simple In addition , this answer is more dynamic as you can choose the two numbers every time you run the program:
class Program
{
static int Add(int x, int y)
{
return x + y;
}
static void Main(string[] args)
{
Console.WriteLine("Answer: " + Add(Convert.ToInt32(Console.ReadLine()),
Convert.ToInt32(Console.ReadLine())).ToString());
Console.ReadLine(); //In order to be able to see the result in the screen
}
}

Not all code paths return a value with a while loop [duplicate]

This question already has answers here:
.NET compiler and "Not all code paths return a value"
(5 answers)
Closed 4 years ago.
The compiler is complaining that the following code snippet won't always return. I have inspected it and don't see an issue.
private int MyFunction(int b)
{
int result = -1;
while (result != 1)
{
result = MySmallFunction(out var x);
if (result == 1)
{
return x;
}
}
}
private int MySmallFunction(out int x)
{
x = 1;
return 1;
}
MySmallFunction does stuff and returns a code, 1 meaning success, and the rest is an error code.
If it returns 1, that means that the out int x has a value.
If the return value is not 1 (error code), then I want to retry.
If MySmallFunction never returns 1, the application should just be stuck in a loop forever. That shouldn't be a problem for the compiler.
I rewrote the function to this:
private int MyFunction()
{
int result = -1;
int x = int.MinValue;
while (result != 1)
{
result = MySmallFunction(out x);
}
return x;
}
private int MySmallFunction(out int x)
{
x = 1;
return 1;
}
Now x will only be returned if MySmallFunction returns a status code of 1.
In the case that your while loop doesn't trigger, there is not return instruction, you need a return at the bottom of your function outside the while loop.
As per the signature of the method MyFunction() it should return a value to the calling method in all conditions. but in your case, you are returning a value only if (result == 1) in all other case it is invalid, so you have to add a return at the end, which will return an integer. So you have to change something like this:
private int MyFunction(int b)
{
int result = -1;
while (result != 1)
{
result = MySmallFunction(out var x);
if (result == 1)
{
return x;
}
}
return 0;
}

C# - Passing functions (with arguments) as arguments of a function

I need to create a function, that will take another functions (always different quantity of them). Can someone help me please?
Function DoThisFunction will have different types and quantity of parameters.
there can be different number of condition functions.
I'll try to show it here:
bool MyFunction(condition1(args), condition2(args), condition3(args), ... , DoThisFunction(args))
{
...
if (condition1(int x) == true && condition2(int x, string C) == 5)
{
DoThisFunction(par1, par2, par3 ...);
return true;
}
}
bool condition1(int x)
{
if (x>5)
return true;
else
return false;
}
int condition2(int x, string C)
{
....
return par1;
}
etc...
Then I need to call:
bool z = MyFunction(condition1(int x)==true, condition2(int x, string C)==5, DoThisFunction(par1, anotherArguments ...))
I would like to suggest another approach for your code.
Maybe, you can keep a separated list with all the functions you need to verify, and run each method inside a very simple loop (foreach), in this case:
the code will be very friendly (easy to understand)
better maintainability
you can review less code and add more functionality (for instance, you may inject some code and just add another Func<> into your List<>)
Please, take a look at the following example:
static class Program
{
private static void Main(string[] args)
{
var assertions = new List<Func<object[], bool>>
{
Assertion1,
Assertion2,
Assertion3
};
var yourResult = Assert(assertions, 1, "1", true);
Console.WriteLine(yourResult); // returns "True" in this case
Console.ReadLine();
}
private static bool Assert(IEnumerable<Func<object[], bool>> assertions, params object[] args)
{
// the same as
// return assertions.Aggregate(true, (current, assertion) => current & assertion(args));
var result = true;
foreach (var assertion in assertions)
result = result & assertion(args);
return result;
}
private static bool Assertion1(params object[] args)
{
return Convert.ToInt32(args[0]) == 1;
}
private static bool Assertion2(params object[] args)
{
return Convert.ToInt32(args[0]) == Convert.ToInt32(args[1]);
}
private static bool Assertion3(params object[] args)
{
return Convert.ToBoolean(args[2]);
}
}
This solution seems to generic for your problem.
For checking preconditions before executing methods have a look at Code Contracts
You can use functor like the following:
private bool MyFunction(Func<int, bool> condition1, Func<int,string,int> condition2, Func<int,string,int, int> doThisFunction, int x, string str)
{
if (condition1(x) && condition2(x, str) == 5)
return doThisFunction(x, str, x) == 10;
return false;
}
Then call this function in your code like the below:
MyFunction(x => x > 5 ? true : false, (x, C) => C.Length == x * 5 ? 5 : C.Length,
(x, str, y) =>
{
if (x + y > str.Length)
return 5;
else if (x * y > 5)
return 10;
else
return 15;
}, 10, "Csharp");

C# Recursive Increment Decrement not working as parameters

I am using recursion to add two numbers together, By adding 1 to the first input one at a time until I have reached the value of the second.
Why does this work...
private static int AddMethod(int input1, int input2)
{
if (input2 == 0)
{
Console.WriteLine(input1);
return (input1);
}
else
{
input1++;
input2--;
return AddMethod(input1, input2);
}
}
But not this..
private static int AddMethod(int input1, int input2)
{
if (input2 == 0)
{
Console.WriteLine(input1);
return (input1);
}
else
{
return AddMethod(input1++, input2--);
}
}
I am using Visual Studio 2010 and .Net 4.0
Because return AddMethod(input1++, input2--); first passes your inputs, and THEN increments and decrements.
Try
return AddMethod(++input1, --input2);
Post fix increment works by first "assigning" the value, then incrementing the value.
Compare:
int a = 1;
int b = 1;
int x = a++;
int y = ++b;
So in your case, the value you pass to AddMethod is the unchanged value, it modifies the value of input1 and input2 after they are passed.
Because the ++ and -- operators are executed after passing the values as parameters to the function.
Your code:
return AddMethod(input1++, input2--);
Is equal to:
int result AddMethod(input1, input2);
input1++;
input2--;
return result;
Instead of all this, you could use:
return AddMethod(++input1, --input2);

How to return multiple variables across different classes

I am currently taking a C# class and in the class we are looking to take our error handling out of our primary code and build all the error handling and data parsing for all integers in another class, however the problem is you can only return one variable.
How can i return both a "true/false" (bool) and the parsed data from one class to another.
Class1.cs (primary code)
int num1;
Class2 class2Object = new Class2();
public Class1()
{
//constructor
}
public void Num1Method()
{
string tempVal = "";
bool errorFlag; //bool = true/false
do
{
errorFlag = false; //no error & initialize
Console.Write("Enter Num1: ");
tempVal = Console.ReadLine();
class2Object.IntErrorCheckMethod(tempVal);
}//close do
while (errorFlag == true);
}//close Num1Method
Class2.cs (error and parse handling)
public bool IntErrorCheckMethod(string xTempVal)
{
int tempNum = 0;
bool errorFlag = false;
try
{
tempNum = int.Parse(xTempVal);
}
catch(FormatException)
{
errorFlag = true;
tempNum = 999;
}
return errorFlag;
}//close int error check
So Class2 will only return the true/false (if there is an error or not), how can I also return the good parsed data back to Class1 to be put into the "int num1" variable?
Our professor can only think to remove the bool and use a dummy value (like if the data has an error, set the value to 999 and return it, then do an if elseif to check if the value is 999 then return an error message, otherwise submit the data to the variable.
I think its better code to be able to use a bool for the error as 999 could POSSIBLY be good data that is entered by the user.
Any ideas are appreciated,
Thanks!
You can use out parameter just like TryParse methods in .NET. BTW
instead of your method you can use
int tempNum;
errorFlag = Int32.TryParse(string, out tempNum);
Or if you really want to use your own method for parsing:
public bool IntErrorCheckMethod(string xTempVal, out int tempNum)
{
tempNum = 0;
bool errorFlag = false;
try
{
tempNum = int.Parse(xTempVal);
}
catch(FormatException)
{
errorFlag = true;
tempNum = 999;
}
return errorFlag;
}
Usage:
int num1;
public void Num1Method()
{
string tempVal;
do
{
Console.Write("Enter Num1: ");
tempVal = Console.ReadLine();
}
while(class2Object.IntErrorCheckMethod(tempVal, out num1));
}
Also consider to do some refactoring to your method:
public bool TryParse(string s, out int result)
{
result = 0;
try
{
result = Int32.Parse(s);
return true; // parsing succeed
}
catch(FormatException)
{
return false; // parsing failed, you don't care of result value
}
}

Categories

Resources