Method being run through twice when it should only run once - c#

class Myclass
{
public string Driver1()
{
string a = "";
Console.Write("Please enter drivers name: ");
a = Console.ReadLine();
return a;
}
public int numberOfTrips()
{
int a = 0;
{
Console.Write("Enter the number of trips: ");
a = Convert.ToInt32(Console.ReadLine());
}
return a;
}
public List<float> Payments()
{
List<float> a = new List<float>();
float input;
for (int i = 0; i<numberOfTrips(); i++)
{
Console.Write("Enter payment {0}: ", (1 + i));
input = float.Parse(Console.ReadLine());
Console.WriteLine("Payment added");
a.Add(input);
}
return a;
}
}
class Program
{
static void Main(string[] args)
{
Myclass a = new Myclass();
string name = a.Driver1();
int trip = a.numberOfTrips();
float total = a.Payments().Sum();
Console.WriteLine("\nDriver: {0}\n" + "Number of trips: {1}\n" + "Total payment: {2}\n", name, trip, total);
}
}
The issue i am having is that the "public int numberOfTrips()" method is running twice before it gets to the method containing the for loop. I think this is to do with the fact i am using it within the for loop to specify when the loop should stop. I am guessing i have done this wrong so how would i correct this? I need the user to be able to set the how many times it will ask for payment.
Any help is appreciated.

Just pass the number from numberOfTrips as a parameter to Payments:
public List<float> Payments(int tripCount)
{
List<float> a = new List<float>();
float input;
for (int i = 0; i < tripCount; i++)
{
Console.Write("Enter payment {0}: ", (1 + i));
input = float.Parse(Console.ReadLine());
Console.WriteLine("Payment added");
a.Add(input);
}
return a;
}
In your Main method:
Myclass a = new Myclass();
string name = a.Driver1();
int trip = a.numberOfTrips();
float total = a.Payments(trip).Sum();

Instead of calling numberOfTrips() in Main() as well as in Payments() you might try creating an instance variable or static variable in MyClass. Then you can fetch the number of trips from that variable after all payments are calculated.

That is correct. The first time it runs is in Main to set the 'trip' variable. The second time it runs is in Payments, inside the for loop declaration.

Related

Function that writes out the sum only writes out 0

Problem: The sum writes out as 0. How do i make it so that the function Summa() writes out the actual sum out of the 10 numbers that user writes in?
This is probably extremely simple but im new to this :P
All of the things in the code weren't separate before but i wanted if i could move the sum part to it's own function
using System;
namespace Array
{
class Program
{
static void Main(string[] args)
{
int number;
int[] vektor = new int[10];
for (int i = 0; i < vektor.Length; i++)
{
Console.WriteLine("Enter a number");
number = Convert.ToInt32(Console.ReadLine());
vektor[i] = number;
}
Summa();
}
static void Summa()
{
int sum = 0;
int[] vektor = new int[10];
int i = 0;
sum = sum + vektor[i];
Console.WriteLine("The amount is " + sum);
}
}
}
You are creating a new array called vektor in the Summa() function, instead of using the one created in the main() function. Also you've to iterate through the array to find the sum
Change Summa to :
static void Summa(int[] vektor)
{
int sum = 0;
for(int i=0; i < vektor.Length; i++)
{
sum = sum + vektor[i];
}
Console.WriteLine("The amount is " + sum);
}
And change the function call in the main() to:
Summa(vektor);
You are summing a different array; you'd need to pass the array in:
static void Summa(int[] vektor)
{
int sum = 0;
foreach (var val in vektor)
sum += val;
// ^^^ or just use: var sum = vektor.Sum();
Console.WriteLine("The amount is " + sum);
}
/// ...
Summa(vektor);
So, you're not passing any information to your method "Summa", but you're instead creating a new Array.
So you need to pass the Array from your main method to you "summa" method.
namespace Array
{
class Program
{
static void Main(string[] args)
{
int number;
int[] vektor = new int[3];
for (int i = 0; i < vektor.Length; i++)
{
Console.WriteLine("Enter a number");
number = Convert.ToInt32(Console.ReadLine());
vektor[i] = number;
}
Summa(vektor);
}
static void Summa(int[] vektor)
{
int sum = 0;
foreach (var item in vektor)
{
sum += vektor[item];
}
Console.WriteLine("The amount is " + sum);
}
}
}
Also, using foreach loops will make your life much easier in the future.
https://www.w3schools.com/cs/cs_for_loop.asp
When you're unsure what your program is doing and don't know why it isn't working like it should. Try using the debug feature.
If you're using Visual Studio you can access it by pressing F11.
Lycka till med studierna!

Passing a value to a class keeps returning 0

this might be a simple/dumb question but I'm trying to figure out why my code keeps returning 0. I don't think my syntax for passing the value is correct but I cant figure out the proper way of doing it.
class ICESMARK
{
static int ICECount = 0;
public double average = 0;
public double[] ICES = new double[8];
public ICESMARK(double Mark)
{
Mark = ICES[ICECount];
if (ICECount == (ICES.Length - 1))
{
for (int x = 0; x < ICES.Length; x++)
{
average += ICES[x];
}
average /= ICES.Length;
}
ICECount++;
}
}
class Program
{
static void Main(string[] args)
{
ICESMARK[] ICE = new ICESMARK[8];
//LABSMARK[] LAB = new LABSMARK[6];
double userInput;
for (int counter = 0; counter < ICE.Length ; counter++)
{
Console.Write("Please enter your mark for ICE{0}: ", counter + 1 );
bool ifInt = double.TryParse(Console.ReadLine(), out userInput);
ICE[counter] = new ICESMARK(userInput);
}
Console.WriteLine(ICE[1].average);
Console.ReadLine();
}
}
ICE[1].average - Displays 0
Also if anyone has a more efficient way of doing this, feel free to let me know. Except for the average, is gotta be a calculation, cant use the built in method.
Simplest code to get your work done:
void Main()
{
double[] ICE = new double[8];
double userInput = 0.0;
for (int counter = 0; counter < ICE.Length; counter++)
{
Console.WriteLine($"Please enter your mark for ICE {counter}: ");
bool isNumerical = false;
while(!isNumerical)
isNumerical = double.TryParse(Console.ReadLine(), out userInput);
ICE[counter] = userInput;
}
Console.WriteLine("Average : " + ICE.Average());
Console.ReadLine();
}
How it works:
Removed all the frills, you don't need an extra class just for this purpose
Made it mandatory for code to enter valid double value to fill all the slots
Finally used Linq Average to calculate Average value
I want to clarify that yes there are easier ways to solve this, but the entire point of the project was to use a class and it specifically says I cant use built in methods such as "array.average".
Sorry that my code was super messy, I was honestly all over the place and very confused. Having that said I finally arrived to this solution. Thanks to everyone who tried to help! really appreciate it, some tips here were very helpful in solving and cleaning up my code.
class ICESMARK
{
public static int ICECount = 0;
public static double average = 0;
public ICESMARK(double Mark)
{
average += Mark;
if (ICECount < 8) { ICECount++; }
if (ICECount == 8) { average /= ICECount;}
}
}
class Program
{
static void Main(string[] args)
{
ICESMARK[] ICE = new ICESMARK[8];
double userInput;
for (int counter = 0; counter < ICE.Length ; counter++)
{
Console.Write("Please enter your mark for ICE{0}: ", counter + 1 );
bool ifInt = double.TryParse(Console.ReadLine(), out userInput);
ICE[counter] = new ICESMARK(userInput);
Console.WriteLine(ICESMARK.ICECount);
}
Console.WriteLine(ICESMARK.average);
Console.WriteLine(ICESMARK.ICECount);
Console.ReadLine();
}
}

Finding highest number of votes and matching to array of string

I'm trying to figure out how to match a candidate name with candidate votes and display the highest vote along with the candidate name.
As in how to match the two arrays I have.
I know I'm missing something but what? I've only started learing C# at home.
namespace NumberOfVotes
{
class Program
{
static void Main(string[] args)
{
int size, minVotes;
int[] numOfCandidates;
int[] numOfVotes;
double avgMarks;
string[] candidateName;
Console.WriteLine("Enter number of candidates");
size = int.Parse(Console.ReadLine());
numOfCandidates = new int[size];
candidateName = new string[size];
numOfVotes = new int[size];
for (int i = 0; i < numOfCandidates.Length; i++)
{
Console.WriteLine("Enter a Candidate Name");
candidateName[i] = Console.ReadLine();
Console.WriteLine("Enter number of votes thus far");
numOfVotes[i] = int.Parse(Console.ReadLine());
}
int max = numOfVotes.Max();
avgMarks = numOfVotes.Average();
minVotes = numOfVotes.Min();
Console.WriteLine("Average votes: {0}", avgMarks);
Console.WriteLine("Min number of votes is: {0}", minVotes);
}
}
}
See these kind of things you can do with thinking about it with your head. StackOverflow isn't a website to post your problem if you're stuck, only if the problem you have needs a solution which can help other people.
This would work(most straightfoward approach to me):
int maxIndex = -1;
int max = -1;
for (int i = 0; i < numOfCandidates.Length; i++)
{
Console.WriteLine("Enter a Candidate Name");
candidateName[i] = Console.ReadLine();
Console.WriteLine("Enter number of votes thus far");
int num = int.Parse(Console.ReadLine()); // <-- unsafe
// just check it every time, if the number is greater than the previous maximum, update it.
if (num > max)
{
max = num;
maxIndex = i;
}
numOfVotes[i] = num;
}
Console.WriteLine("Candidate {0}, with {1} votes, has the most votes", candidateName[maxIndex], max);
However, if you want more things to calculate (like who has the least votes) without doing these kind of things, you should use a Dictionary<string, int>. That's a string associated with a number, a name associated with votes.
(More info about that here: http://www.dotnetperls.com/dictionary)
You should use a Dictionary for this:
static void Main(string[] args)
{
var candidates = new Dictionary<string, int>();
Console.WriteLine("Enter number of candidates");
var size = int.Parse(Console.ReadLine());
for (int i = 0; i < size; i++)
{
Console.WriteLine("Enter a Candidate Name");
var name = Console.ReadLine();
Console.WriteLine("Enter number of votes thus far");
var votes = int.Parse(Console.ReadLine());
candidates.Add(name, votes);
}
Console.WriteLine("Average votes: {0}", candidates.Average(entry => entry.Value));
Console.WriteLine("Min number of votes is: {0}", candidates.Min(entry => entry.Value));
}
You should probably use dictionary instead, but if you want to use array, here's how to do it :
avgMarks = numOfVotes.Average();
int avgIndex = numOfVotes.ToList().IndexOf(avgMarks);
Console.WriteLine("Average votes: {0} Candidate Names: {1}", avgMarks, candidateName[avgIndex]);
Your code just works fine. What you are looking for is the index of the array having highest number of votes. This index will be also useful to get the candidateName having highest number of vote. So, to get that index simply use the maximum value you got from this line :
int max = numOfVotes.Max();
and then use IndexOf static method to find the index of max in your array. For that try this line of code :
int index = Array.IndexOf<int>(numOfVotes, max);
Now simply print out the candidateName and highest number of votes as below :
Console.WriteLine(candidateName[index] + " has highest number of vote : " + numOfVotes[index] );
You can have a clean conception about Array.IndexOf() from DotNetPerls and MSDN
The solution to the problem, as it is, is to do something like this:
int indexOfWinner = Array.IndexOf(numOfVotes, numOfVotes.Max());
string winner = candidateName[indexOfWinner];
I don't know how far along in your C# and programming education you are (OOP and suchlike), so a couple of points you may find obvious or not:
you should use generic collections and not primitive arrays (List<> in this case).
you should encapsulate all this into a class.
This is how I would do it:
class Program
{
static void Main(string[] args) {
Candidates c = new Candidates("foo", "bar", "baz");
Random rand = new Random();
c.addVote(0, rand.Next(100));
c.addVote(1, rand.Next(100));
c.addVote(2, rand.Next(100));
Console.WriteLine(c.getWinner());
Console.WriteLine("number of votes:");
Console.WriteLine(c[0] + ": " + c[0].numberOfVotes);
Console.WriteLine(c[1] + ": " + c[1].numberOfVotes);
Console.WriteLine(c[2] + ": " + c[2].numberOfVotes);
}
}
class Candidates
{
private List<Candidate> candidates;
public Candidate this[string name] {
get {
return candidates.First(v => v.name == name);
}
}
public Candidate this[int index] {
get {
return candidates[index];
}
}
public Candidates(string firstCandidate, params string[] candidates) { //this is done to disable an empty constructor call
//and also allow multiple candidates
this.candidates = new List<Candidate>(candidates.Length);
this.candidates.Add(new Candidate(firstCandidate));
foreach(var c in candidates) {
this.candidates.Add(new Candidate(c));
}
}
public void addVote(int candidateNumber, int numberOfVotes = 1) {
candidates[candidateNumber].numberOfVotes += numberOfVotes;
}
public Candidate getWinner() {
candidates.Sort((candidate1, candidate2) => candidate2.numberOfVotes.CompareTo(candidate1.numberOfVotes));
return candidates[0];
}
}
class Candidate
{
public string name { get; private set; }
public int numberOfVotes { get; set; }
public Candidate(string name) {
this.name = name;
this.numberOfVotes = 0;
}
public override string ToString() {
return name;
}
}

The array dont save my numbers

I am trying to learn C# and doing some questions i googeld. This is the task to do:
*"Beginner level:
The task is to make
a dice game where the user throws 3
Each 12-sided dice (numbers
shall be randomly selected and stored in an array / field or list).
Add up the total of the dice and show on the screen.
Create a function / method that accepts a figure
(the total sum of the dice). Function / method
should return the text "Good throw" if the figure
is higher or equal to 20.
In all other cases, the text
"Sorry" is returned.
Call the function / method in the main method
and prints the total and the text.
Advanced level:
This is an extension of the task where you must use a class to simulate a dice. The user shall have the option of writing a x y-sided dice himself.
If the total sum of a roll of the dice generates a score that is> 50% of the maximum score, the words "good throw" is displayed.
This logic can be in your main method.
Create the class described in the class diagram and use appropriate
way in your code."*
The thing is that i cant get it to work, the array in my class do not save my numbers im typing in... I only get the reslut 0. I think i have just done some big misstake i cant see...
This is the Main code:
static void Main(string[] args)
{
List<Dice> _Dice = new List<Dice>();
int a = 0;
int times = int.Parse(Interaction.InputBox("Write how many times you want to repeat the game:"));
while (a != times)
{
int antThrow = int.Parse(Interaction.InputBox("Write how many times you want each dice to get thrown:"));
int xChoice = int.Parse(Interaction.InputBox("Write how many dice you want to throw:"));
int yChoice = int.Parse(Interaction.InputBox("Write how many sides you want each dice should have:"));
_Dice.Add(new Dice(xChoice,yChoice, antThrow));
a++;
}
int e = 1;
foreach (var item in _Dice)
{
Interaction.MsgBox(string.Format("Result of game {0}: {1}", e++, item.Tostring()));
}
}
This is the Dice class:
class Dice
{
static int _xChoice, _yChoice, _throw;
static List<int> sum = new List<int>();
static int w = 0;
static int _sum;
static int[,] dice = new int[_xChoice, _yChoice];
public string Tostring()
{
int half = _sum / 2;
if (half <= _sum/2)
{
return "Good throw!" + _sum;
}
else
{
return "Bad throw!";
}
}
void random()
{
Random rnd = new Random();
while (w != _throw)
{
for (int i = 0; i < dice.GetLength(0); i++)
{
for (int j = 0; j < dice.GetLength(1); j++)
{
dice[i, j] = rnd.Next(1, _yChoice);
_sum += dice[j, i];
sum.Add(_sum);
}
}
w++;
}
}
public Tarning(int Xchoice, int Ychoice, int throw)
{
_throw = thorw;
_xChoice = Xchoice;
_yChoice = Ychoice;
}
}
Your main problem is in the static keyword. Static field means that there's only
one field for all the instances, which is not your case: you need each instance of Dice has its own fields' values.
class Dice {
// no static here
private int _xChoice, _yChoice, _throw;
// no static here
private List<int> sum = new List<int>();
// no static here
private int w = 0;
// no static here
private int _sum;
// no static here
private int[,] dice = new int[_xChoice, _yChoice];
// BUT, you want a random generator for all the instances, that's why "static"
private static Random rnd = new Random();
// When overriding method mark it with "override"
// And Be Careful with CAPitalization:
// the method's name "ToString" not Tostring
public override string ToString() {
...
}
void random() {
// Do not create Random generator each time you call it:
// It makes the random sequences skewed badly!
// Istead use one generator for all the calls, see the code above
// private static Random rnd = new Random();
// Random rnd = new Random();
...
}
...
class Program
{
static void Main(string[] args)
{
var dice = new List<DiceLogic>();
int a = 0;
int times = GetTimes();
while (a != times)
{
int antThrow = GetAntThrow();
int xChoice = GetXChoice();
int yChoice = GetYChoice();
dice.Add(new DiceLogic(xChoice, yChoice, antThrow));
a++;
}
int e = 1;
foreach (var item in dice)
{
Console.WriteLine("Result of game {0}: {1}", e++, item.Tostring());
}
Console.ReadLine();
}
private static int GetTimes()
{
while (true)
{
Console.WriteLine("Write how many times you want to repeat the game:");
int times;
var result = int.TryParse(Console.ReadLine(), out times);
if (result) return times;
Console.WriteLine("Value must be a number.");
}
}
private static int GetAntThrow()
{
while (true)
{
Console.WriteLine("Write how many times you want each dice to get thrown:");
int antThrow;
var result = int.TryParse(Console.ReadLine(), out antThrow);
if (result) return antThrow;
Console.WriteLine("Value must be a number.");
}
}
private static int GetXChoice()
{
while (true)
{
Console.WriteLine("Write how many dice you want to throw:");
int getXChoice;
var result = int.TryParse(Console.ReadLine(), out getXChoice);
if (result) return getXChoice;
Console.WriteLine("Value must be a number.");
}
}
private static int GetYChoice()
{
while (true)
{
Console.WriteLine("Write how many sides you want each dice should have:");
int getXChoice;
var result = int.TryParse(Console.ReadLine(), out getXChoice);
if (result) return getXChoice;
Console.WriteLine("Value must be a number.");
}
}
}
public class DiceLogic
{
public string Tostring()
{
int maxScore = _diceSides*_dices;
if (_result >= maxScore / 2)
{
return "Good throw! " + _result;
}
return "Bad throw! " + _result;
}
private readonly int _dices;
private readonly int _diceSides;
private readonly int _throwDice;
private int _result;
private void CalculateResult()
{
var rnd = new Random();
for (int i = 0; i < _dices; i++)
{
int currentResult = 0;
for (int j = 0; j < _throwDice; j++)
{
currentResult = rnd.Next(0, _diceSides);
}
_result += currentResult;
}
}
public DiceLogic(int dices, int diceSides, int throwEachDice)
{
_dices = dices;
_diceSides = diceSides;
_throwDice = throwEachDice;
CalculateResult();
}
}
This is an example of how you could implement what they are asking, go through te code line by line with the debugger so you understand what is going on.
You never call the method random(). Therefore, the value of your member variable _sum is never changed and remains 0. You need to call the method random() somewhere. You should probably make it public and call it from your main method after you have set up all your dice.
Furthermore, your member variables in the Dice class are all static! That means that the different Dice instances will all share the same values. I think this is not intended. You should make the variables instance variables by removing the static modifier.
Your method Tarning is not called and it takes a reserved word “throw” [I believe it was supposed to be thorw]. The method is not void so it must return a type.
Random() is not invoked and does display anything.
Dice has not constructor that has 3 arguments within its braces but it’s declared as _Dice.Add(new Dice(xChoice,yChoice, antThrow));

C# launch a program with mandatory parameters and optional parameters from cmd

I need to call a program from cmd using an array of numbers(mandatory) and an int time(optional). I have never done this so i'm a bit shaky on the details.
The path is D:\Robert\FactorialConsoleApplication\FactorialConsoleApplication\bin\Debug\FactorialConsoleApplication.exe
As you can tell, the program calculates the factorial of the numbers in the array. The int time is used as a delay in order to display the progress of the stack.
How do I call the program with parameters?
Thanks in advance!
P.S. Here is some of the code
class Program
{
public static void Progress(ProgressEventArgs e)
{
int result = e.getPartialResult;
int stack_value = e.getValue ;
double max = System.Convert.ToDouble(numbers[j]);
System.Convert.ToDouble(stack_value);
double percent = (stack_value / max) * 100;
Console.CursorLeft = 18;
Console.Write(result + " ");
Console.CursorLeft = 46;
Console.Write(System.Convert.ToInt32(percent) + "% ");
}
public static void Calculate(int number, int time=0)
{
Factorial Fact = new Factorial();
Fact.Progression += new Factorial.ProgressEventHandler(Progress);
Console.Write("\n" + "Partial results : ");
Console.CursorLeft = 35;
Console.Write("Progress : ");
int Result = Fact.CalculateFactorial(number, time);
Console.WriteLine(" ");
Console.WriteLine("The factorial of " + number + " is : " + Result);
Console.ReadLine();
}
static int j;
static int[] numbers;
public static void Main(string[] args)
{
int i=0;
bool ok = false;
string line = string.Empty;
numbers = new int[10];
Console.Write("Please insert wait time (0,1 or 2) : ");
int time = int.Parse(Console.ReadLine()) * 1000;
Console.Write("Please insert a number : ");
do
{
line = Console.ReadLine();
if (line != "")
{
i++;
numbers[i] = int.Parse(line);
}
else
{
ok = true;
}
}
while (ok == false);
for (j = 1; j <= i; j++)
{
Calculate(numbers[j],time);
}
}
}
In .net you can use Process.Start from System.Diagnostics to launch an application, you can pass parameters too
For example Process.Start("IExplore.exe", "C:\\myPath\\myFile.htm"); will open Internet Explorer and pass the value "C:\\myPath\\myFile.htm" as parameter to it.For more examplles check the MSDN article on Process.Start method
Update
If in case you are looking to take parameters to your application, when launching itself you don't have to do anything, you are already doing that, the parameter args in your Main method will hold the arguments passed to your application, just try and parse those values in the args array to int array and you are good to go.
Ok, so here is the solution.
I used an args parser like this :
static int extra;
public static void Main(string[] args)
{
foreach (string s in args)
{
extra = int.Parse(s);
Calculate(extra);
}
}
And I changed :double max = System.Convert.ToDouble(numbers[j]);
to :double max = System.Convert.ToDouble(extra);
To call it I open cmd in the directory where the exe is and I type :
Program.exe 3 4 5
It will calculate the factorials of 3, 4 and 5 respectively

Categories