Passing Variable through function to main() - c#

I'm very new to C# but am learning more and more every day. Today, I'm trying to build a simple console calculator and need help passing a variable from the function to Main() so I can use it in an if-else to determine what function should execute.
public static void Main(string[] args)
{
int decision = Introduction();
Console.Clear();
Console.WriteLine(decision);
Console.ReadLine();
}
public static int Introduction()
{
int decision = 0;
while (decision < 1 || decision > 7)
{
Console.Clear();
Console.WriteLine("Advanced Math Calculations 1.0");
Console.WriteLine("==========================");
Console.WriteLine("What function would you like to perform?");
Console.WriteLine("Press 1 for Addition ++++");
Console.WriteLine("Press 2 for Subtraction -----");
Console.WriteLine("Press 3 for Multiplication ****");
Console.WriteLine("Press 4 for Division ////");
Console.WriteLine("Press 5 for calculating the Perimeter of a rectangle (x/y)");
Console.WriteLine("Press 6 for calculating the Volume of an object (x/y/z)");
Console.WriteLine("Press 7 for calculating the standard deviation of a set of 10 numbers");
decision = int.Parse(Console.ReadLine());
if (decision < 1 || decision > 7)
{
decision = 0;
Console.WriteLine("Please select a function from the list. Press Enter to reselect.");
Console.ReadLine();
}
else
{
break;
}
}
return decision;
}
When I try to use decision up in Main() it says "The name decision does not exist in the current context".
I'm stumped and tried googling it to no avail.
Cheers
SUCCESS!

Return the value from Introduction. The value is local to the method and to use it elsewhere you need to return it and assign to a local variable. Alternatively, you could make decision a static class variable, but that's not a particularly good practice, at least in this case. The Introduction method (not a particularly good name, IMO, it should probably be GetCalculationType() since that is what it is doing) typically shouldn't have any side-effects.
public static void Main( string[] args )
{
int decision = Introduction();
...
}
public static int Introduction()
{
int decision = 0;
...
return decision;
}

Main() is the entry point for your app. It then calls your method Introduction() which adds a new stack frame on the stack. Because you declare the decision variable inside your Introduction method, the Main method has no knowledge of it.
If you instead declare your decision variable outside both methods, you should be able to reference it from either:
int decision;
static void Main(string[] args)
{
// code here
}
static void Introduction()
{
// code here
}

You can't use the decision variable in main since it is local to the function Introduction.
You could make decision a static class variable but better would be to return the value from Introduction and assign it to a local variable in main.

Related

How to get a time span between two methods in c#?

I am trying to make a stopwatch with C# as an exercise for myself. my plan was to make two methods " start()" and " stop()" then call these from my stopwatch class in my main. the problem I have is that I do not know how to get the time span between these two.
for your information, this is how I want the program to work: if they typed s the timer starts and when press enter or type f the time will be shown to them.
this is the code I have written so far, but got stuck when getting the time span.
class StopWatch
{
DateTime starting = DateTime.Now;
DateTime finishing = DateTime.Now;
public void start()
{
Console.WriteLine(starting);
}
public void stop()
{
Console.WriteLine(finishing);
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("type s to start and f to stop");
var input = Console.ReadLine();
var stopwatch = new StopWatch();
if (input.ToLower() == "s") { stopwatch.start(); }
var Input2 = Console.ReadLine();
if (Input2.ToLower() == "f") { stopwatch.stop(); }
Console.ReadKey();
}
}
I agree with the comment to use what already exists in the library, but since you said you are doing this as an exercise, here is some feedback:
To answer you direct question how to get a TimeSpan:
var duration = finishing - starting;
The current implementation will not do what you intend to do, since you set both starting and finishing at object creation time: field initializers are executed before any constructor code. So you should set starting in the start() method and finishing in the stop() method. Then you can calculate the duration as shown above in the stop() method, too.
And allow me a little side note on naming: "starting" and "finishing" are progressive forms in English, but here you want to name specific values. Therefore I'd recommend "startTime" and "endTime"/"stopTime".

It is more efficient to call object outside methods in c#?

Which is better to achieve efficiency if i need to use this object in many methods in my class?
Doing this:
Create object above of class so i can accecc c in multiple methods.
using System;
class Program
{
static Customers c = new Customers("text1", "text2");
public static void Main()
{
}
}
Or doing this:
Create object inside methods so every time i need to use c object i
must create it.
using System;
class Program
{
public static void Main()
{
Customers c = new Customers("text1", "text2");
}
}
Generally it is a best practice to restrict variables' scope(s) as much as possible (great explaination why). This means that if you need a variable to be accessible by multiple methods, then great, make a global variable. If not, then make it local because that's all it needs to be. Neither of these are "more efficient" than the other per-say, they are just used in different scenarios.
For example, let's say you're writing a simple calculator-like program to add/subtract 2
random numbers.
static int num1;
static int num2;
static void Main(string[] args){
var rand = new Random();
num1 = rand.Next(10); // Generate random number between 0 and 10
num2 = rand.Next(10);
Add();
Subtract();
Console.ReadLine();
}
static void Add(){
Console.WriteLine($"{num1} + {num2} = {num1+num2}");
}
static void Subtract(){
Console.WriteLine($"{num1} - {num2} = {num1-num2}");
}
In this example, num1 and num2 need to be processed by the Add() and Subtract() methods, so we make them global variables. The rand variable on the other hand is only needed in the Main() method, so we keep it local.
Global variables can also be accessed from within other classes (depending on their scope), whereas local variables cannot.

How to return a user input value to another class? c#

I'm new to c# and object orientated programming so please excuse me if it's a nooby question but i'm not too familiar with everything yet.
I want to ask the user for input in a method in the first class, and then return this value to a method in the second class, to work out the final cost. I understand how to pass a set value via constructors but thats as far as i know, this would be fine however i need an input value to be passed not a set value. (this code is just a bit from my main program)
class TableOrder
{
string inputtablenumber;
int tablenumber;
public int TableNumber()
{
Console.Write("please enter the table number:");
inputtablenumber = Console.ReadLine();
tablenumber = int.Parse(inputtablenumber);
return tablenumber;
}
}
class TableBill
{
public void CalculateBill()
{
TableOrder TO = new TableOrder();
TO.AddDrink();
if (tablenumber >= 6 & tablenumber < 10)
{
Console.Write("You are due a 10% discount");
}
if (tablenumber > 10)
{
Console.Write("you are due a 15% discount");
}
}
}
class Program
{
static void Main(string[] args)
{
TableBill TB = new TableBill();
TB.CalculateBill();
}
}
so i want to use the number that comes from the TableNumber method in my CalculateBill class, instead of passing over an already set value. I tried with the TO.AddDrink(); but i didn't get anywhere. This is only a small snippet of my overall code so whats happening may not make too much sence but i just want to access this tablenumber value in another class.
Thank You in advance!
Change int tablenumber; to public int tablenumber;, then in CalculateBill call TO.TableNumber and replace tablenumber with TO.tablenumber.
Alternatively:
public void CalculateBill()
{
TableOrder TO = new TableOrder();
var tablenumber = TO.TableNumber();
TO.AddDrink();
if (tablenumber >= 6 & tablenumber < 10)
{
Console.Write("You are due a 10% discount");
}
if (tablenumber > 10)
{
Console.Write("you are due a 15% discount");
}
}
}

How to stop a running method with keyboard input in a Console Application on C#?

In short, I'm utilizing C# to scientific computation and I've written a method that has a while loop that may run to a user-specified quantity of steps... Actually, this method may take too long to execute (like more than 5 hours). When it takes this long, I may want to stop the method pressing Esc key, for example.
As I read something about breaking while, it is as simple as a Boolean flag or something like this. So I thought in something like this:
public Double? Run(int n)
{
int i = 0;
while ((i < n) && (/* inputkey != ConsoleKey.Escape */))
{
// here goes the heavy computation thing
// and I need to read some "inputkey" as well to break this loop
i++;
}
// I'm not worried about the return statement, as it is easy to do...
// returns null if the user skipped the method by pressing Escape
// returns null if the method didn't converged
// returns the double value that the method calculated otherwise
}
Well, this is what I wondered until now... So please, could you give useful ideas to this extent? How can I wait for a user input (I thought about Events, but I'm not sure how to implement it here and I think that it will make the code even slower, if I have to listen to a key at every while step the code goes into...
Well, any ideas or comments?
Update: I think I should have had described better the problem. All the solutions you gave me may solve this problem I proposed, but I think I was not completely reliable to my real problem. I don't know if I should ask another question or keep with this one...
You could run this method from a separate thread and set a stop variable when a key is pressed:
object myLock = new object();
bool stopProcessing = false;
public Double? Run(int n)
{
int i = 0;
while (i < n)
{
lock(myLock)
{
if(stopProcessing)
break;
}
// here goes the heavy computation thing
// and I need to read some "inputkey" as well to break this loop
i++;
}
}
and when a key is pressed, update stopProcessing accordingly:
Console.ReadKey();
lock(myLock)
{
stopProcessing = true;
}
If you're just wanting to stop the application, Ctrl-C from the command line will do it. If you really need to intercept input during a long running process, you might want to spawn a worker thread to do the long running process and then just use the main thread to interact with the console (i.e. Console.ReadLine()).
You will need to do this using threading. When you start the task, spawn a new thread and execute the task on that thread. Then in your Program.cs, wait for user input. If the user enters something meaningful - in your case, the Esc key - alert the background thread of the action. The simplest way to do this is by setting a static variable. The background thread will be checking this static variable and when it has been changed, the background thread will clean itself up and abort.
See the MSDN article on Threading.
A code sample will be a little more in depth, but it would look something like this:
public class Program.cs
{
public static myFlag = false;
public void Main()
{
thread = new Thread(new ThreadStart(DoWork));
thread.Start();
Console.ReadLine();
myFlag = true;
}
public static DoWork()
{
while(myFlag == false)
{
DoMoreWork();
}
CleanUp()
}
public static DoMoreWork() { }
public static CleanUp() { }
}
pool on Console.KeyAvailable in timely manner and take the action accordingly.
using System;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static bool _cancelled = false;
static void Main( string[] args )
{
var computationTask = Task.Factory.StartNew(PerformIncredibleComputation);
var acceptCancelKey = Task.Factory.StartNew(AcceptCancel);
while (!acceptCancelKey.IsCompleted && ! computationTask.IsCompleted)
{
computationTask.Wait (100);
}
if( acceptCancelKey.IsCompleted && !computationTask.IsCompleted )
{
computationTask.Wait (new System.Threading.CancellationToken ());
}
else if(!acceptCancelKey.IsCompleted)
{
acceptCancelKey.Wait(new System.Threading.CancellationToken());
}
}
private static void PerformIncredibleComputation()
{
Console.WriteLine("Performing computation.");
int ticks = Environment.TickCount;
int diff = Environment.TickCount - ticks;
while (!_cancelled && diff < 10000)
{
//computing
}
Console.WriteLine("Computation finished");
}
private static void AcceptCancel()
{
var key = Console.ReadKey(true);
Console.WriteLine("Press Esc to cancel");
while(key.Key != ConsoleKey.Escape)
{
key = Console.ReadKey(true);
}
_cancelled = true;
Console.Write("Computation was cancelled");
}
}
}

Threading: Variable Access and Termination of a Thread

Let me start by showing you my code so far:
using System;
using System.Threading;
class MathQuiz
{
static void Main()
{
int score = 0;
string preanswer;
decimal answer = 0;
Console.WriteLine("Welcome to Project5, a MathQuiz project.");
Console.WriteLine("You will be asked 10 questions, and will have 30 seconds to read and answer each one.");
Console.WriteLine("Press any key to begin.");
Console.ReadKey(true);
Console.WriteLine("What is 2 + 2?");
Thread ask = new Thread (new ThreadStart (MathQuiz.prompt));
ask.Start();
Thread.Sleep(3000);
//This is where I want to end the thread if it isn't already done.
if (answer == 4)
{
score = score+1; //Here's where I don't know if my adding is correct.
}
Console.WriteLine("Press any key to move on to the next question!");
Console.ReadKey(true);
}
static void prompt()
{
preanswer = (Console.ReadLine());
if (!decimal.TryParse(preanswer, out answer))
{
Console.WriteLine("That wasn't even a number or decimal!");
}
else
{
answer = decimal.Parse(preanswer);
}
}
}
So, when I try and compile this code, I get CS0103 errors for preanswer and answer in the "prompt" method.
This leads to 3 questions:
What EXACTLY do I have to do to make preanswer and answer accessible to the "prompt" method?
Did I add 1 onto the score variable correctly?
How can I terminate a thread if it is running? (In this case, the "ask" thread wouldn't end until they typed an answer.)
Please just tell me what to change. I don't know coding words and terminology because I just started a few weeks ago. Please try to be as clear as possible.
static string preanswer;
static decimal answer = 0;
static void Main()
{
int score = 0;
//string preanswer;
//decimal answer = 0;
...
etc.
To wait for the thread, use Join()... This will tell the thread which the function is called on to wait for the thread until it joins back:
ask.Join(int);

Categories