How to change some of my code to a Class? - c#

I wrote some code and it works, but now trying to take some of my code and change it to a Class. I already change part of the code to first a method and then turn it into a Class. But this last part of code having trouble figuring out how to change to a method so then I can make a Class.
else if (input == "3")
{
Console.WriteLine("Here are your Students: ");
Array.Sort(names);
Console.WriteLine(String.Join(", ", names));
Console.WriteLine("");
double average = gradesList.Average();
if (average >= 90)
{
Console.WriteLine($"There average is a {average.ToString("n2")} which is an A.");
}
else if (average >= 80)
{
Console.WriteLine($"There average is a {average.ToString("n2")} which is an B.");
}
else if (average >= 70)
{
Console.WriteLine($"There average is a {average.ToString("n2")} which is an C.");
}
else if (average >= 60)
{
Console.WriteLine($"There average is a {average.ToString("n2")} which is an D.");
}
else
{
Console.WriteLine($"There average is a {average.ToString("n2")} which is an E.");
}
}
The first part I was thinking of leaving that and just change the Grade part into a Class. I tried public static string GetLetterGrade(int average)
return ($"There average is a {average.ToString("n2")} which is an A.") but get all kinds or errors that I don't understand.

I would make the grade a non-mutable struct. It represents a value and should be a value type. A class is a reference type.
public readonly struct Grade
{
public Grade(double percentage)
{
Percentage = percentage;
}
public double Percentage { get; }
public char Letter
{
get {
if (Percentage >= 90) return 'A';
if (Percentage >= 80) return 'B';
if (Percentage >= 70) return 'C';
if (Percentage >= 60) return 'D';
return 'E';
}
}
public override string ToString() => $"{Percentage:n2} ({Letter})";
}
Since the if-statements return, it is not necessary to have an else-part.
Then you can easily print the message with
double average = gradesList.Average();
var grade = new Grade(average);
Console.WriteLine(
$"There average is a {grade.Percentage:n2} which is an {grade.Letter}.");
Note that because ToString is overridden, you can print the grade directly.
Console.WriteLine($"The average grade is {grade}");
It will print something like The average grade is 74.25 (C).

this should work
public static char GetLetterGrade(double average)
{
if (average >= 90)
{
return 'A';
}
else if (average >= 80)
{
return 'B';
}
else if (average >= 70)
{
return 'C';
}
else if (average >= 60)
{
return 'D';
}
return 'E';
}
but if you wish to use GetLetterGrade(int average) overload, use it like this
double average = gradesList.Average();
var grade = GetLetterGrade((int)average);

Related

How can I stop my average output from displaying the same letter grade as my original grade output? Also how to make sentinel values case insensitve?

I have a program that is supposed to return your grades and grade average to you using a sentinel value to end the program, while also using input validation. The issue that I am having at the moment is that it runs greatly and it stops when I use "Quit", but my ending prompt of:
Console.WriteLine("The average is {0} is a(n) {1}", average, grade);
is returning me the same letter grade as the prompt for my:
Console.WriteLine("A grade of {0} is a(n) {1}", anInt, grade);
I also need to make the quit be case insensitive so I tried to use the .ToLower() method, my program would not run properly and I would get an error that says "error CS0019: Operator ==' cannot be applied to operands of type method group' and `string'".
My code is listed below and I was wondering if the issue is that I am using the same string function to return both letters and that is why they are mimicking one another? For example, if I enter a grade that is returned as an F as the last letter in the program, the average grade will show as an F at the end of the program regardless of what the numerical grade value that represents the average is. I was also wondering if there was a proper way to implement the .ToLower() method, because I have tried it a few times and it kept giving me errors, so I just removed it as a whole.
using System;
class Program {
public static void Main (string[] args) {
int sum=0;
int count = 0;
string grade = "A";
bool KeepGoing = true;
while (KeepGoing){
string entry = GetEntry();
if (entry == "Quit") {
KeepGoing = false;
} else {
int anInt = Convert.ToInt32(entry);
grade = DetermineGrade(anInt);
sum += anInt;
count++;
Console.WriteLine("A grade of {0} is a(n) {1}", anInt, grade);
}
}
double average = sum/ (double)count;
Console.WriteLine("The average is {0} is a(n) {1}", average, grade);
}
public static string DetermineGrade(int anInt) {
if (anInt >= 90){
return "A";
}
if (anInt >= 80 & anInt <= 89){
return "B";
}
if (anInt >= 70 & anInt <= 79){
return "C";
}
if (anInt >= 60 & anInt <= 69){
return "D";
}
else{
return "F";
}
}
public static string GetEntry() {
while (true){
Console.WriteLine("Please enter your grade or enter Quit to end program.");
string entry = Console.ReadLine();
if (entry == "Quit"){
return entry;
}
int anInt;
if (Int32.TryParse (entry, out anInt)) {
if (anInt>= 0 && anInt <= 100) {
return entry;
} else {
Console.WriteLine("Error: Please enter a valid integer!");
}
}
}
}
}
"How can I stop my average output from displaying the same letter grade as my original grade output?"
You must call DetermineGrade again with the average. The variable grade will not change by itself.
The problem is that average is a double but DetermineGrade wants an int input. You could simply change the type of the input parameter to double. int arguments will automatically be converted to double.
The method can be simplified. Since the first case returns when the input is >= 90, you don't need to test whether it is <= 89 in the second case. The same is true for the following cases.
public static string DetermineGrade(double value) {
if (value >= 90.0) return "A";
if (value >= 80.0) return "B";
if (value >= 70.0) return "C";
if (value >= 60.0) return "D";
return "F";
}
And then
string averageGrade = DetermineGrade(average);
Console.WriteLine("The average is {0} is a(n) {1}", average, averageGrade );
You can also use a switch expression (since C# 8.0) and relational patterns (since C# 9.0) and a expression bodied method (since C# 6.0):
public static string DetermineGrade(double value) =>
value switch {
>= 90.0 => "A",
>= 80.0 => "B",
>= 70.0 => "C",
>= 60.0 => "D",
_ => "F"
};
"Also how to make sentinel values case insensitve?"
Using .ToLower() is an option. Another possibility is to use
while (true) { // Infinite loop.
string entry = GetEntry();
if (String.Equals(entry, "Quit", StringComparison.OrdinalIgnoreCase)) {
break; // Exit the while loop.
}
...
}
You also have the option to use CurrentCultureIgnoreCase or InvariantCultureIgnoreCase instead. This can make a difference for the Turkish culture, because they have two different "i"s (+ one without the dot) that may be handled differently.
In simple situations, where no accents or other special or foreign characters are used, OrdinalIgnoreCase will do it.

Attempting to call a class constructer in main method so I can create a report card

Im trying to create a report card class and return a letter grade to main. I used a class constructor for the report card as the actual report card must be a class. In the event an invalid value is entered it will return an argument exception an prompt the user to try again. Here is my code:
using System;
using static System.Console;
class StudentGradeDemo
{
static void Main()
{
char lettergrade = new ReportCard();
}
class StudentGrades
{
public string studentName;
public double midtermGrade;
public double finalExamGrade;
public char letterGrade;
public char ReportCard(string studentName, double midtermGrade, double finalExamGrade)
{
char[] letterGrade = { 'A', 'B', 'C', 'D', 'F' };
Console.WriteLine("Enter midterm grade");
midtermGrade = Convert.ToInt32(Console.ReadLine());
if(midtermGrade >= 0 && midtermGrade <= 100)
{
Console.WriteLine("Enter final exam grade");
finalExamGrade = Convert.ToInt32(Console.ReadLine());
if (finalExamGrade >= 0 && midtermGrade <= 100)
{
double gradeAverage = ((midtermGrade + finalExamGrade) / 2);
if(gradeAverage >= 90 && gradeAverage <= 100)
{
return letterGrade[0];
}
else if(gradeAverage >= 80 && gradeAverage <= 90)
{
return letterGrade[1];
}
else if(gradeAverage >= 70 && gradeAverage <= 80)
{
return letterGrade[2];
}
else if(gradeAverage >= 60 && gradeAverage <= 70)
{
return letterGrade[3];
}
else if(gradeAverage < 60)
{
return letterGrade[4];
}
}
else
{
try
{
throw new System.ArgumentException();
}
catch (ArgumentException)
{
Console.WriteLine("Grades must be between 0 - 100");
return letterGrade[0];
}
}
}
else
{
try
{
throw new System.ArgumentException();
}
catch (ArgumentException)
{
Console.WriteLine("Grades must be between 0 - 100");
return letterGrade[0];
}
}
return letterGrade[0];
}
}
}
The error that returns is: Error CS0246 The type or namespace name 'ReportCard' could not be found (are you missing a using directive or an assembly reference?)
This first thing you need to do is create an instance of the StudentGrades class. This will allow you to access the ReportCard method, as it's a method of the class. (see #1). https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/methods
Next, if you look at the ReportCard method it takes 3 parameters: studentName, midtermGrade, finalGrade. These values MUST be passed into the method when you call it (see #2). https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
static void Main()
{
var studentGrades = new StudentGrades(); // #1
Console.WriteLine("Enter student name");
var studentName = Console.ReadLine();
Console.WriteLine("Enter midterm grade");
var midtermGrade = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter final exam grade");
var finalExamGrade = Convert.ToDouble(Console.ReadLine());
var lettergrade = studentGrades.ReportCard(studentName, midtermGrade, finalExamGrade); // #2
Console.WriteLine($"{studentName}'s grade is an {lettergrade}");
}
Update: If you want to read input from the user, read in each line and assign to appropriate variable to pass in. I took this code from your ReportCard method, so you need to make sure to remove it from there. Also, you should be doing the appropriate type checking and handling for midterm and finalExamGrade. I'll leave that to you.
This is how to solve your problem:
class Program
{
static void Main(string[] args)
{
char lettergrade = StudentGrades.ReportCard();
}
}
public static class StudentGrades
{
public static char ReportCard()
{
char[] letterGrade = { 'A', 'B', 'C', 'D', 'F' };
Console.WriteLine("Enter midterm grade");
double midtermGrade = Convert.ToInt32(Console.ReadLine());
if (midtermGrade >= 0 && midtermGrade <= 100)
{
Console.WriteLine("Enter final exam grade");
double finalExamGrade = Convert.ToInt32(Console.ReadLine());
if (finalExamGrade >= 0 && midtermGrade <= 100)
{
double gradeAverage = ((midtermGrade + finalExamGrade) / 2);
if (gradeAverage >= 90 && gradeAverage <= 100)
{
return letterGrade[0];
}
else if (gradeAverage >= 80 && gradeAverage <= 90)
{
return letterGrade[1];
}
else if (gradeAverage >= 70 && gradeAverage <= 80)
{
return letterGrade[2];
}
else if (gradeAverage >= 60 && gradeAverage <= 70)
{
return letterGrade[3];
}
else if (gradeAverage < 60)
{
return letterGrade[4];
}
}
else
{
try
{
throw new System.ArgumentException();
}
catch (ArgumentException)
{
Console.WriteLine("Grades must be between 0 - 100");
return letterGrade[0];
}
}
}
else
{
try
{
throw new System.ArgumentException();
}
catch (ArgumentException)
{
Console.WriteLine("Grades must be between 0 - 100");
return letterGrade[0];
}
}
return letterGrade[0];
}
}

Why cant I later add a value to my string variable through if-statements and run the output code in C#?

I want to run the gradeStatus in the Console.WriteLine but I fail...
I've almost checked all posts to some extent relevant but none have resolved my problem, please guide?
Console.WriteLine("Type in grade to get stats!");
int gradeScore = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Grade Score: {0}", gradeScore);
bool isPassed;
if (gradeScore >= 50)
{
isPassed = true;
}
else
{
isPassed = false;
}
Console.WriteLine("Passed: {0}", isPassed);
string gradeStatus;
if(gradeScore == 50)
{
gradeStatus = "Okay";
}
else if (gradeScore == 60)
{
gradeStatus = "Good";
}
else if (gradeScore >= 70)
{
if (gradeScore == 70)
{
gradeStatus = "Great";
}
else if (gradeScore == 80)
{
gradeStatus = "Great";
}
}
else if (gradeScore == 90)
{
gradeStatus = "Excellent";
}
else if (gradeScore == 100)
{
gradeStatus = "Ace!";
}
Console.WriteLine("Grade Status: {0}", gradeStatus);
The problem is with your if statements. What you are probably wanting is the below portion of code for your set of if else statements.
if(gradeScore <= 50)
{
gradeStatus = "Okay";
}
else if (gradeScore <= 60)
{
gradeStatus = "Good";
}
else if (gradeScore <= 70)
{
gradeStatus = "Great";
}
else if (gradeScore <= 80)
{
gradeStatus = "Great";
}
else if (gradeScore <= 90)
{
gradeStatus = "Excellent";
}
else if (gradeScore <= 100)
{
gradeStatus = "Ace!";
}
For a problem like this one, it is often much easier to break the logic into a separate function. When you use a separate function, you can use early return to avoid else. That makes the logic much more plain and easy to read, and less prone to error.
For example, you could write a function like this one:
static string GetGradeStatus(int score)
{
if (score <= 50) return "Okay";
if (score <= 60) return "Good";
if (score <= 70) return "Great";
if (score <= 80) return "Great";
if (score <= 90) return "Excellent";
return "Ace";
}
And modify your code to use it:
Console.WriteLine("Type in grade to get stats!");
int gradeScore = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Grade Score: {0}", gradeScore);
var isPassed = gradeScore > 50;
Console.WriteLine("Passed: {0}", isPassed);
var gradeStatus = GetGradeStatus(gradeScore);
Console.WriteLine("Grade Status: {0}", gradeStatus);
This is easier to read and makes it very plain if you've got a logic error (e.g. it is obvious that "Great" is used twice, which is what your existing code does).
I also made two other changes:
I changed = to <= since there is nothing preventing the user from entering a number that is not a multiple of 10. That was just a guess. You might need to tweak the logic to meet your requirements correctly.
I changed the if/else assignment of isPassed to a simple Boolean assignment, which is idiomatic for c# and easier to read once you get used to it.

C# output letter grade from a range using doubles

It appears my teacher wants the class to use double to solve this problem. I am having difficulty getting it to take. I'm sure it's someting simple that I'm missing but I want to see what others think.
public char Test4(double grade)
{
// TODO: Write code here to compute an answer.
// Return the answer from this function.
// Read the lab document for detailed instructions.
}
I've tried using if else statements and to no luck. I'm not sure how to use a double for this. Please help.
Thanks.
Here's an example of what I've tried.
if (grade >= 90 && grade <= 100)
{
public char = 'A'
}
else if (grade >=80 && grade <90)
{
public char = 'B'
}
return public char;
{
The output:
I've cleaned this up. Hope this helps to clarify the question.
public char Test4(double grade)
{
// TODO: Write code here to compute an answer.
// Return the answer from this function.
// Read the lab document for detailed instructions.
if (grade >= 90.0)
{ return 'A'; }
else
if (grade >= 80.0)
{ return 'B'; }
else
if (grade >= 73.0)
{ return 'C'; }
else
if (grade >=70.0)
{ return 'D'; }
else
if (grade >= 0)
{ return 'F'; }
else
if (grade <0 )
{ return '?'; }
else
if (grade > 100)
{ return '?'; }
}
You are returning "public char", you need to either return it in place, or store the value in a variable.
example 1
if (grade >= 90)
{
return 'A';
}
else if ....
{
//copy for each letter grade above F
}
else
{
return 'F';
}
example 2
char gradeLetter = 'F';
if (grade >= 90)
{
gradeLetter = 'A';
}
else if ....
{
//copy for each letter grade above F
}
return gradeLetter;
I don't think that you compile with Test4 as written and are running and old, unimplemented version of Test4 (hence no results). You have an error, which I'm guessing is: "not all code paths return a value." To solve this, have a "catch all" at the end - you don't need to check if grade is <0 AND >100, just return ?.
...
else if(grade >= 0)
{
return 'F';
}
// if none of the if statements were hit, you have an incorrect grade value
return '?';
This is should properly compile Test4 (note, you have an error with Test5 that needs to be fixed as well) and give you the correct results.

Check the length of integer variable

Is there a way to check a lenth of integer variable, and if is to long just trim it.
I hava a field in database that accepts 3 character, lenth is 3.
So is it possible to do like it's done with string variable
example:
cust_ref = cust_ref.Length > 20 ? cust_ref.Substring(0, 19) : cust_ref;
Thanks!
The easiest answer would be:
//The length would be 3 chars.
public int myint = 111;
myint.ToString().Length;
The following worked a treat for me!
public static int IntLength(int i)
{
if (i < 0)
throw new ArgumentOutOfRangeException();
if (i == 0)
return 1;
return (int)Math.Floor(Math.Log10(i)) + 1;
}
Original Source: http://www.java2s.com/Code/CSharp/Data-Types/Getthedigitlengthofanintvalue.htm
You don't have to convert it to a string to make it shorter, that can be done numerically:
if (num > 999) {
num %= 1000;
}
This will cut of digits from the left, if you want to cut them off from the right:
while (num > 999) {
num /= 10;
}
If the value can be negative, also check:
if (num < -99) {
num = -(-num % 100);
}
or:
while (num < -99) {
num = -(-num / 10);
}
cust_ref = cust_ref.ToString().Length > 20 ? Convert.ToInt32(cust_ref.ToString().Substring(0, 19)) : cust_ref;
or simply use
cust_ref = Convert.ToInt32(Convert.ToString(cust_ref).Substring(0, 19));
Use like this
cust_ref= cust_ref.Tostring().Length > 20 ? Convert.ToInt32(cust_ref.ToString().Substring(0, 19)) : cust_ref;
Nont very clear what you're asking for, but as much as I unerstood you're asking for:
int a = 1234567890;
for some reason you want to make it shorter, like
int b = MakeShorter(a);
//b == 1234 (say)
If so, the easiest solution may be, convert it to string, made what you already implemented and reconvert it back to int.
If this is not what you're asking for, please clarify.
The conversion to the string is ugly way to implement it.
It's require a pure math solution
int CutTheNumber(int number, int maxLen)
{
var maxSize = (int)Math.Pow(10, maxlen);
if(maxSize <= Math.Abs(number))
{
number %= maxSize;
}
return number;
}
Checking length
length = cust_ref.ToString().Length;
Remove extra bits
if (length > need)
{
cust_ref =Convert.ToInt32( cust_ref.ToString().Remove(length -(length- need)));
}
for this u will have to do some simple stuffs.
like
cust_ref = Convert.ToInt32(Convert.ToString(cust_ref).Substring(0, 19));
or u can manually store it in any variable and the
You can try this code. use if else statement to check the validation ..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace avaragescore
{
class Program
{
static void Main(string[] args)
{
float quiz;
float midterm;
float final;
float avrg=0;
Start:
Console.WriteLine("Please enter the Quize Score here");
quiz = float.Parse(Console.ReadLine());
if(quiz > 100)
{
Console.WriteLine("You have entered wrong score please re-enter");
goto Start;
}
Start1:
Console.WriteLine("Please enter the Midterm Score here");
midterm = float.Parse(Console.ReadLine());
if(midterm > 100)
{
Console.WriteLine("You have entered wrong score please re- enter");
goto Start1;
}
Start3:
Console.WriteLine("Please enter the Final Score here");
final = float.Parse(Console.ReadLine());
if(final > 100)
{
Console.WriteLine("You have entered wrong Score Please re-enter");
goto Start3;
}
avrg = (quiz + midterm + final) / 3;
if(avrg >= 90)
{
Console.WriteLine("Your Score is {0} , You got A grade",avrg);
}
else if (avrg >= 70 && avrg < 90)
{
Console.WriteLine("Your Score is {0} , You got B grade", avrg);
}
else if (avrg >= 50 && avrg < 70)
{
Console.WriteLine("Your Score is {0} , You got C grade", avrg);
}
else if (avrg < 50)
{
Console.WriteLine("Yor Score is {0} , You are fail", avrg);
}
else
{
Console.WriteLine("You enter invalid Score");
}
Console.ReadLine();
}
}
}

Categories