Finding min and max of user input data C# (without Linq) [duplicate] - c#

This question already has answers here:
How to find the highest and the lowest number C#
(10 answers)
Closed 8 years ago.
I have a program that I am working on to practice for a midterm, it is a simple Gradebook program that allows the user to input as many grades from 0-100 as they want. I have various things that calculate at the end that work fine but I need the program to also display the lowest and the highest grades. I saw another post where someone talks about linq (?) I have not worked with this and haven't researched it yet. I figure if it isn't in the book I shouldn't need it yet. the code is long so I will try to only include what I think is necessary...
using System;
public class GradeBook
{
private int total;
private int gradeCounter;
private int aCount;
private int bCount;
private int cCount;
private int dCount;
private int fCount;
// automatic popert CourseName
public string CourseName { get; set; }
then in order to get the user input
public void InputGrades()
{
int grade; //grade made by user
string input; //text entered by user
Console.WriteLine("{0}\n{1}",
"enter integer in the range of 0-100.",
"Type <ctrl> Z and press endter to terminate input:");
input = Console.ReadLine(); //user input
//loop until user enters the end of file indicator
while (input != null)
{
grade = Convert.ToInt32(input);
total += grade; //create total to form sum
++gradeCounter;//increment the number of grades for average
// call method to increment appropriate counter
IncrementLetterGradeCounter(grade);
input = Console.ReadLine();
}//end while(input != null)
This is my first post to SO so if there is something I have done wrong please let me know. If more code is necessary let me know.

Add these two under int grade
int high = 0;
int low = 100;
And then in your while loop
if(input > high) high = input;
if(input < low) low = input;
And then after your while loop.
Console.WriteLine("The highest grade was: " + high);
Console.WriteLine("The lowest grade was: " + low);

Related

How to do while loop/Do while loop with sentinel value with switch

Hello I am trying to figure out why my program is not working, it's supposed to output a program in which department codes would be entered and followed by a prompt to enter a mark and so on until Q is entered. I can't seem to get that part working at all. If anyone could help please I will appreciate it.
// declare variables
char deptCode = ' ';
int count = 0;
double markVal, sum = 0, average = 0.0;
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
while (char.ToUpper(deptCode) != 'Q')
do
{
Console.Write("Enter a mark between 0 and 100 => ");
markVal = Convert.ToDouble(Console.ReadLine());
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
} while (markVal >= 0 && markVal <= 100);
count++;
average = (double)sum / count;
Console.WriteLine("***Error, Please Enter Valid Mark");
Console.WriteLine("The Average mark for Computer Science Students is {0}", average);
Console.WriteLine("The Average mark for Biology Students is {0}", average);
Console.WriteLine("The Average mark for Physics Students is {0}", average);
Console.ReadLine();
{
I am sympathetic to your dilemma and know it can be challenging to learn coding when you are not familiar with it. So hopefully the suggestions below may help to get you started at least down the right path. At the bottom of this is a basic “shell” but parts are missing and hopefully you will be able to fill in the missing parts.
One idea that you will find very helpful is if you break things down into pieces (methods) that will make things easier to follow and manage. In this particular case, you need to get a handle on the endless loops that you will be creating. From what I can see there would be three (3) possible endless loops that you will need to manage.
An endless loop that lets the user enter any number of discipline marks.
An endless loop when we ask the user which discipline to use
And an endless loop when we ask the user for a Mark between 0 and 100
When I say endless loop I mean that when we ask the user for a Discipline or a Mark… then, the user MUST press the “c”, “b” “p” or “q” character to exit the discipline loop. In addition the user MUST enter a valid double value between 0 and 100 to exit the Mark loop. The first endless loop will run allowing the user to enter multiple disciplines and marks and will not exit until the user presses the q character when selecting a discipline.
And finally when the user presses the ‘q’ character, then we can output the averages.
So to help… I will create two methods for you. One that will represent the endless loop for getting the Mark from the user… i.e.…. a number between 0 and 100. Then a second endless loop method that will get the Discipline from the user… i.e. … ‘c’, ‘b’, ‘p’ or ‘q’… and it may look something like…
private static char GetDisciplineFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a department code: ‘C’ for Computer Science,‘B’ for Biology, ‘P’ for Physics, or enter ‘Q’ to quit:");
userInput = Console.ReadLine().ToLower();
if (userInput.Length > 0) {
if (userInput[0] == 'c' || userInput[0] == 'b' ||
userInput[0] == 'p' || userInput[0] == 'q') {
return userInput[0];
}
}
Console.WriteLine("Invalid discipline => " + userInput + " try again.");
}
}
Note… the loop will never end until the user selects the characters ‘c’, ‘b’, ‘p’ or ‘q’. We can guarantee that when we call the method above, ONLY those characters are returned.
Next is the endless loop to get the Mark from the user and may look something like…
private static double GetMarkFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a mark between 0 and 100 => ");
userInput = Console.ReadLine().Trim();
if (double.TryParse(userInput, out double mark)) {
if (mark >= 0 && mark <= 100) {
return mark;
}
}
Console.WriteLine("Invalid Mark => " + userInput + " try again.");
}
}
Similar to the previous method, and one difference is we want to make sure that the user enters a valid number between 0 and 100. This is done using a TryParse method and most numeric types have a TryParse method and I highly recommend you get familiar with it when checking for valid numeric input.
These two methods should come in handy and simplify the main code. So your next issue which I will leave to you, is how are you going to store these values? When the user enters a CS 89 mark… how are you going to store this info? In this simple case… six variables may work like…
int totalsCSMarks = 0;
int totalsBiologyMarks = 0;
int totalsPhysicsMarks = 0;
double totalOfAllCSMarks = 0;
double totalOfAllBiologyMarks = 0;
double totalOfAllPhysicsMarks = 0;
Now you have something to store the users input in.
And finally the shell that would work using the methods above and you should see this uncomplicates things a bit in comparison to your current code. Hopefully you should be able to fill in the missing parts. Good Luck.
static void Main(string[] args) {
// you will need some kind of storage for each discipline.. see above...
char currentDiscipline = 'x';
double currentMark;
while (currentDiscipline != 'q') {
currentDiscipline = GetDisciplineFromUser();
if (currentDiscipline != 'q') {
currentMark = GetMarkFromUser();
switch (currentDiscipline) {
case 'c':
// add 1 to total number of CS marks
// add currentMarkValue to the total of CS marks
break;
case 'b':
// add 1 to total number of Biology marks
// add currentMarkValue to the total of Biology marks
break;
default: // <- we know for sure that only p could be left
// add 1 to total number of Physics marks
// add currentMarkValue to the total of Physics marks
break;
}
}
}
Console.WriteLine("Averages ------");
//Console.WriteLine("The Average mark for Computer Science Students is {0}", totalOfAllCSMarks / totalCSMarks);
//Console.WriteLine("The Average mark for Biology Students is {0}", ...);
//Console.WriteLine("The Average mark for Physics Students is {0}", ...);
Console.ReadLine();
}

How to fix this "Input string was not in a correct format" problem in the following code? [duplicate]

This question already has answers here:
int.Parse, Input string was not in a correct format
(7 answers)
Closed 2 years ago.
Here is my code :
using System;
namespace CappedSum
{
class Program
{
static void Main(string[] args)
{
int sumLimit = Convert.ToInt32(Console.ReadLine());
int sum = 0;
int count = 0;
while (sum<sumLimit)
{
int number = Convert.ToInt32(Console.ReadLine());
if (sum + number < sumLimit)
{
sum += number;
count++;
}
else if (sum + number > sumLimit)
{
Console.WriteLine(sum + " " + count);
}
}
}
}
}
I had to write a console application that reads from the keyboard a list of numbers until their sum reaches a certain limit also entered by the user.
The limit is given on the first line, and on the next lines will be the list of numbers which has to be added. The program will stop reading when the sum of the numbers entered so far exceeds the limit and will display the last amount that did not exceed the limit, as well as how many numbers were needed to calculate it.
for example : if I enter 10 (which is the limit) then I enter 2,3,2,6. The result will be 7 (which is the last amount that did not exceed the limit) and 3 (which represents how many numbers needed to calculate it).
Try out Int32.Parse instead of Convert.ToInt32. Also, a really basic I use sometimes to debug my same mistakes, is to write MessageBoxes after specific instructions, so if they do not work I never get to the message, viceversa if the message shows I know that works. I'd put two Messageboxes after the Int32.Parse(Console.Readline()) being like MessageBox.Show(sumlimit/number.ToString());. This way you know how far the code works.

While loop breaks unintentionally

I am in my second week of C# training, so I am pretty new to programming. I have to make a program that returns the smallest integer out of a series of random integer inputs. Once the input = 0, the program should break out of the loop. I am only allowed to use while and for loops. For some reason my program breaks out of loop after the second input and it looks like it doesn't even care if there is a "0" or not. Could you please see where I went wrong? I have been busting my head off with this. Sorry if this question has already been posted by somebody else but I did not find an answer to it anywhere.
PS: The zero input should be taken into account for the comparison.
So this is what I've got so far:
class Program
{
static void Main()
{
int i = 0;
int input = Int32.Parse(Console.ReadLine());
int min = default;
while (input != 0)
{
Console.ReadLine();
if (i == 0)
{
min = input;
break;
}
if (input < min && i !=0)
{
input = Convert.ToInt32(Console.ReadLine());
min = input;
}
i++;
}
Console.WriteLine(min);
}
First of all you will want to re-read the documentation for for- and while-loops. There are several useful pages out there.. e.g. for / while.
Problem
The reason why your loop breaks is that you initialize i with 0.
int i = 0;
Inside your loop you are using the if-statment to break the loop if the condition "i is 0" is met.
if (i == 0)
{
min = input;
break;
}
The input that the user has to provide each iteration of the loop is ignored by your program as you are never storing this kind of information to any variable.
while (input != 0)
{
Console.ReadLine();
// ...
}
Possible Solution
As a beginner it is helpful to tackle tasks step by step. Try to write down each of this steps to define a simple algorithm. As there are many solutions to this problem one possible way could be:
Declare minimum value + assign max value to it
Use a while loop and loop till a specific condition is matched
Read user-input and try converting it to an integer
Check whether the value is 0 or not
4.1. If the value is 0, go to step 8
4.2. If the value is not 0, go to step 5
Check whether the value is smaller than the current minimum value
5.1. If the value is smaller, go to step 6
5.2. If the value is not smaller, go back to step 3
Set the new minimum
Go back to step 3
Break the loop
End program
A program that handles the above steps could look like:
using System;
namespace FindMinimum
{
public class Program
{
static void Main(string[] args)
{
// Declare minimum value + assign initial value
int minValue = int.MaxValue;
// Loop until something else breaks out
while (true)
{
Console.WriteLine("Please insert any number...");
// Read io and try to parse it to int
bool parseOk = int.TryParse(Console.ReadLine(), out int num);
// If the user did not provide any number, let him retry
if (!parseOk)
{
Console.WriteLine("Incorrect input. Please insert numbers only.");
continue;
}
// If the user typed in a valid number and that number is zero, break out of the loop
if (parseOk && num == 0)
{
break;
}
// If the user typed in a valid number and that number is smaller than the minimum-value, set the new minimum
if (parseOk && num < minValue)
{
minValue = num;
}
}
// Print the result to the console
Console.WriteLine($"Minimum value: {minValue}.");
// Keep console open
Console.ReadLine();
}
}
}
Try This:
int input;
Console.Write("Enter number:");
input = Int32.Parse(Console.ReadLine());
int min = input;
while(true)
{
if (input == 0)
break;
if (min > input)
min = input;
Console.Write("Enter number:");
input = Int32.Parse(Console.ReadLine());
}
Console.WriteLine(min);
Console.ReadKey();
I hope it helps.

storing user input into an array and referring to the array c#

This code works properly well but it doesn't have a memory for storing user input.
I also need to categorize the grades into its respective columns in array format, having "S/N, Category and Count" and I dont know how to go about it. Any help would be appreciated.
namespace ExamScore
{
class YourExamScore
{
private static string GetGrade(int examScore)
{
if (examScore >= 90 && examScore <= 100)
return "Excellent";
if (examScore >= 70 && examScore <= 89)
return "Good";
if (examScore >= 50 && examScore <= 69)
return "Satisfactory";
if (examScore >= 0 && examScore <= 49)
return "Unsatisfactory";
return "Invalid";
}
static void Main(string[] args)
{
// Print a greeting message. After all, why not?
Console.WriteLine("Welcome to ExamScore Calculator!");
Console.WriteLine("Input Your Exam Score...");
Console.WriteLine("Press -2 when you have inputed all scores");
while (true)
{
var examScore = Convert.ToInt32(Console.ReadLine());
if (examScore == -2)
{
break;
}
var grade = GetGrade(examScore);
Console.WriteLine(grade);
}
Console.WriteLine("\n\nProccessing Scores... Please Wait...");
Console.ReadLine();
}
}
}
Well it seems like a homework, so i am not going to help with codes directly,
for the storage of marks, you can follow either of one way
if you know how many input you are going to use, then use a fixed size array
var marks = new int[10];
if the no. of input is not fixed then you can use List<int>
var marks = new List();
I am not sure if I understood you correctly, but I think you are asking to keep track of the amount of grades that fall in a certain category. In that case, I would do it as follows.
You will need to keep track of an array of ints (int[]) with an entry for each category that keeps track of the amount of grades in that category so far. So you will first have to make a static array of size 4, which will automatically initialize with zeroes everywhere. Semantically, each index stands for a category (say 0 for excellent, 1 for good, etc.). Then, in the GetGrade method you should for each category also increase the right category before returning.
To store user input in memory you can use array or list (List<MyData> is better if you have to insert often, Hashtable if you want to search fast, MyData[] - least memory and fastest access by index, etc.)
After entering -2 you may want to store (serialize) your data somehow, so data will persists between runs. It can be xml-file (XmlSerializer), own format text-/binary- file, database, etc.
You also need to define how you will work with data: are they saved immediately after entering (then database itself is a memory storage) or upon exit, delete/correct possibility and such.
Finally, you can add statistic and reporting, which query your data and produce results.
It is a bit unclear what
"S/N, Category and Count"
stands for. Could you elaborate? Your code is asking for score and producing grade. You could count how many users have which grade, how many total users, how many grades (all those are "Counts"), but "S/N" and "Category" are confusing.
To example, you only want to print how many users belongs different grades.
1) Very manual approach, count occurrences (statistic) upon entering (use)
int grade90plus; // fields
int grade70plus;
...
// inside GetGrade
if(examScore > 90)
{
grade90plus++;
return "Excellent";
}
else
if(examScore > 70)
{
grade70plus++;
return "Good";
}
...
// report
Console.WriteLine("Excellent: " + grade90plus);
Console.WriteLine("Good: " + grade90plus);
2) High tec (serialization unfriendly)
public class Grade
{
public string Name;
public int Count;
public int ScoreMin;
public int ScoreMax;
public bool Test(int score) { return score >= ScoreMin && score <= ScoreMax; }
public static readonly Grade Excellent = new Grade() {Name = "Excellent", ScoreMin = 90, ScoreMax = 100};
public static readonly Grade Good = new Grade() {Name = "Good", ScoreMin = 70, ScoreMax = 89};
public static readonly Grade[] GetAll = new Grade[] { Excellent, Good };
}
private static string GetGrade(int examScore)
{
foreach(var grade in Grade.GetAll)
if(grade.Test)
{
grade.Count++;
return grade.Name;
}
return "Invalid";
}
// report
foreach(var grade in Grade.GetAll)
Console.WriteLine(grade.Name + "," + grade.Count);
You can surely improve those or make own solution (serialization friendly, utilizing database, one what uses expressions for Test, etc).

Console.Read() and Console.ReadLine() problems [duplicate]

This question already has answers here:
Console.Read not returning my int32 [duplicate]
(7 answers)
Closed 1 year ago.
I have been trying to use Console.Read() and Console.ReadLine() in C# but have been getting weird results. for example this code
Console.WriteLine("How many students would you like to enter?");
int amount = Console.Read();
Console.WriteLine("{0} {1}", "amount equals", amount);
for (int i=0; i < amount; i++)
{
Console.WriteLine("Input the name of a student");
String StudentName = Console.ReadLine();
Console.WriteLine("the Students name is " + StudentName);
}
has been giving me that amount = 49 when I input 1 for the number of students, and Im not even getting a chance to input a student name.
This because you read a char.
Use appropriate methods like ReadInt32() that takes care of a correct conversion from the read symbol to the type you wish.
The reason why you get 49 is because it's a char code of the '1' symbol, and not it's integer representation.
char code
0 : 48
1 : 49
2: 50
...
9: 57
for example: ReadInt32() can look like this:
public static int ReadInt32(string value){
int val = -1;
if(!int.TryParse(value, out val))
return -1;
return val;
}
and use this like:
int val = ReadInt32(Console.ReadLine());
It Would be really nice to have a possibility to create an extension method, but unfortunately it's not possible to create extension method on static type and Console is a static type.
Try to change your code in this way
int amount;
while(true)
{
Console.WriteLine("How many students would you like to enter?");
string number = Console.ReadLine();
if(Int32.TryParse(number, out amount))
break;
}
Console.WriteLine("{0} {1}", "amount equals", amount);
for (int i=0; i < amount; i++)
{
Console.WriteLine("Input the name of a student");
String StudentName = Console.ReadLine();
Console.WriteLine("the Students name is " + StudentName);
}
Instead to use Read use ReadLine and then check if the user input is really an integer number using Int32.TryParse. If the user doesn't input a valid number repeat the question.
Using Console.Read will limit your input to a single char that need to be converted and checked to be a valid number.
Of course this is a brutal example without any error checking or any kind of safe abort from the loops.
For someone who might still need this:
static void Main(string[] args)
{
Console.WriteLine("How many students would you like to enter?");
var amount = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("{0} {1}", "amount equals", amount);
for (int i = 0; i < amt; i++)
{
Console.WriteLine("Input the name of a student");
String StudentName = Console.ReadLine();
Console.WriteLine("the Students name is " + StudentName);
}
}
you get a character char from read not an int. you will need to make it a string first and parse that as a string. THe implementation could look like the below
Console.WriteLine("How many students would you like to enter?");
var read = Console.ReadLine();
int amount;
if(int.TryParse(read,out amount)) {
Console.WriteLine("{0} {1}", "amount equals", amount);
for (int i=0; i < amount; i++)
{
Console.WriteLine("Input the name of a student");
String StudentName = Console.ReadLine();
Console.WriteLine("the Students name is " + StudentName);
}
}
I've changed it to use readline because readline returns a string an doesn't arbitrarily limits the number of students to 9 (the max number with one digit)
Console.Read() is returning the char code of the character that you enter. You need to use Convert.ToChar(amount); to get the character as a string, and then you will need to do int.Parse() to get the value you're looking for.
Console.Read returns the asci value of the key character that was pressed.
If you use Console.ReadKey().KeyChar you'll get a char that represents the actual character that was pressed.
You can then turn that character to a one character string by using .ToString().
Now that you have a string you can use int.Parse or int.TryParse to turn a string containing entirely numeric characters into an integer.
So putting it all together:
int value;
if (int.TryParse(Console.ReadKey().KeyChar.ToString(), out value))
{
//use `value` here
}
else
{
//they entered a non-numeric key
}
Instead of:
int amount = Console.Read();
try:
int amount = 0;
int.TryParse(Console.ReadLine(), out amount);
Its because You read just character code, so for example typing 11 You will still get 49. You need to read string value and the parse it to int value. With code above in case of bad input You will get 0.
Try this:
int amount = ReadInt32();
or if it doesn't work try this:
int amount = Console.ReadInt32();
or this:
int amount = Convert.ToInt32(Console.Readline());
In this, it will read string then it will convert it into Int32 value.
You can also go here: http://www.java2s.com/Tutorials/CSharp/System.IO/BinaryReader/C_BinaryReader_ReadInt32.htm
If nothing works, please let me know.
Console.WriteLine("How many students would you like to enter?");
string amount = Console.ReadLine();
int amt = Convert.ToInt32(amount);
Console.WriteLine("{0} {1}", "amount equals", amount);
for (int i = 0; i < amt; i++)
{
Console.WriteLine("Input the name of a student");
String StudentName = Console.ReadLine();
Console.WriteLine("the Students name is " + StudentName);
}
//thats it
TL;DR; Enter key in Windows isn't a single character. This fact is at the root of many issues related to Console.Read() method.
Complete Details:
If you run below piece of code on your computer then you can solve lot of mysteries behind Console.Read():
static void Main(string[] args)
{
var c = Console.Read();
Console.WriteLine(c);
c = Console.Read();
Console.WriteLine(c);
}
While running the program, hit the Enter key just once on your keyboard and check the output on console. Below is how it looks:
Interestingly you pressed Enter key just once but it was able to cater to two Read() calls in my code snippet. Enter key in windows emits two characters for a new line character namely carriage return (\r - ASCII code 13) and line feed (\n - ASCII code 10). You can read about it more here in this post - Does Windows carriage return \r\n consist of two characters or one character?

Categories

Resources