如何将字母转换成数字并打印出BTEC最终成绩

本文关键字:打印 BTEC 数字 转换 | 更新日期: 2023-09-27 17:51:09

我正在设计一个BTEC等级计算器,对于那些不知道;BTEC是一种在英国完成的资格认证,它有一个"不同的"评分系统,主要基于课程作业。有很多单元(20个),每个单元你都可以通过,每个单元都有优点和区别。每一次及格,每一次优异和每一次优异加起来就是这么多的分数,这些分数加起来就是总分。

例如,120分将映射到PPP等级,240分将映射到MMM,以此类推。

我写了一个基于以下伪代码的程序:

Prompt for student name:
Operator enters student name
Operator enters their grade units one at a time (D, M, P, D etc):
Display Message about final grade:
    Your final Grade is:
    DMM

下面是我目前的代码,但它需要改变和固定。目前,我需要输入单位成绩为数字(20,40)。我希望能够输入成绩字母(D,M,P)。我如何改变我的程序,使它能够解释字母并将它们映射到单元分数?

我也有一个问题,从最终分数到最终成绩的转换。目前,如果我输入两个单元成绩为80,总分为160,那么显示的成绩应该是MPP,但是打印的是120。我做错了什么?

class Program
{
    static void Main(string[] args)
    {
        int counter;
        double score;
        while (true)
        {
            counter = 1;
            score = 0.0;
            Console.WriteLine("Enter Your Name or type 'exit' to quit): ");
            // Naming for exiting 
            string name = Console.ReadLine();
            if (name == "exit")
            {
                Environment.Exit(0);
            }
            else
            {
                int numberOfUnits = 20;
                Console.WriteLine("Number of Units:  ");
                numberOfUnits = int.Parse(Console.ReadLine());
                while (counter <= numberOfUnits)
                {
                    Console.WriteLine("Final Grade Score {0}", counter);
                    score += double.Parse(Console.ReadLine());
                    counter++;
                }
                // Add up and print letter grade. 
                score = (score / (counter - 1));
                if (score < 120)
                {
                    Console.WriteLine("Letter Grade: PPP");
                }
                else if (score < 160)
                {
                    Console.WriteLine("Letter Grade: MPP");
                }
                else if (score < 200)
                {
                    Console.WriteLine("Letter Grade: MMP");
                }
                else if (score < 240)
                {
                    Console.WriteLine("Letter Grade: MMM");
                }
                else if (score < 280)
                {
                    Console.WriteLine("Letter Grade: DMM");
                }
                else if (score < 320)
                {
                    Console.WriteLine("Letter Grade: DDM");
                }
                else if (score < 360)
                {
                    Console.WriteLine("Letter Grade: DDD");
                }
                    // After DDD it goes up by 20's ..... D* = 20 not 40...
                else if (score < 380)
                {
                    Console.WriteLine("Letter Grade: D*DD");
                }
                else if (score < 400)
                {
                    Console.WriteLine("Letter Grade: D*D*D");
                }
                else if (score < 420)
                {
                    Console.WriteLine("Letter Grade: D*D*D*");
                }
                Console.WriteLine("Grade: {0}", (score).ToString("P"));
            }
        }
    }
}

如何将字母转换成数字并打印出BTEC最终成绩

下面是经过一些小编辑的代码,以及将字母转换为数字的switch语句。

public class Program
{
    static void Main(string[] args)
    {
        int counter;
        double score;
        while (true)
        {
            counter = 1;
            score = 0.0;
            Console.WriteLine("Enter Your Name or type 'exit' to quit): ");
            // Naming for exiting 
            string name = Console.ReadLine();
            if (name == "exit")
            {
                return;
            }
            else
            {
                int numberOfUnits = 20;
                Console.WriteLine("Number of Units:  ");
                numberOfUnits = int.Parse(Console.ReadLine());
                while (counter <= numberOfUnits)
                {
                    Console.WriteLine("Final Grade Score {0}", counter);
                    string s = Console.ReadLine().ToUpper();
                    double d;
                    if (double.TryParse(s, out d)) //parsing as a number was successfull, and the result is in d.
                        score += d;
                    else //parsing failed.
                    {
                        switch (s)
                        {
                            case "D":
                                score += 20;
                                break;
                            case "M":
                                score += 50;
                                break;
                            case "P":
                                score += 70;
                                break;
                            default:
                                counter--; //parsing of a letter failed. reducing counter that will be later incremented, to offset the effect.
                                Console.WriteLine("Could not parse your grade. Enter a number or a letter");
                                break;
                        }
                    }
                    counter++;
                }
                // Add up and print letter grade. 
                score = (score / (counter - 1));
                if (score < 120) Console.WriteLine("Letter Grade: PPP");
                else if (score < 160) Console.WriteLine("Letter Grade: MPP");
                else if (score < 200) Console.WriteLine("Letter Grade: MMP");
                else if (score < 240) Console.WriteLine("Letter Grade: MMM");
                else if (score < 280) Console.WriteLine("Letter Grade: DMM");
                else if (score < 320) Console.WriteLine("Letter Grade: DDM");
                else if (score < 360) Console.WriteLine("Letter Grade: DDD");
                // After DDD it goes up by 20's ..... D* = 20 not 40...
                else if (score < 380) Console.WriteLine("Letter Grade: D*DD");
                else if (score < 400) Console.WriteLine("Letter Grade: D*D*D");
                else if (score < 420) Console.WriteLine("Letter Grade: D*D*D*");
                Console.WriteLine("Grade: {0}", (score).ToString("P"));
            }
        }
    }
}

你的代码有相当多的问题,太多的问题真的。正如我在评论中所说的,如果你需要将任意字符串转换为数字,你可以使用一系列if语句,或者一个开关,或者你可以使用某种映射。至于你把分数转换回等级的问题,我的印象仍然是问题出在这一行:

score = (score / (counter - 1));

用分数除以单元数是没有意义的。如果你每个单元得20分,除以单元数,你的最终得分是20分……这似乎很不对。

你遇到的部分问题是你已经在一个函数中编码了整个东西。您确实需要考虑将代码分解为逻辑单元。单元将更小,更容易理解,更容易测试。我强烈建议不要在主方法中写太多东西。成立另一个相关的班级,把工作交给它。下面是一些建议的替代方法来分解你的程序。这还远远不够完善,但比较一下两者,看看哪个更容易理解。

// Main class.  This doesn't do anything but spin up a new class
// and tell it to get all student grades.
class Program
{
    static void Main(string[] args)
    {
        var calculator = new BTECGradeCalculator();
        calculator.GetAllStudentGrades();
    }
}

新的BTECGradeCalculator由几个函数组成。我做的第一件事是输入对上面的伪代码的解释和一个新函数:

public void GetAllStudentGrades() {
    while (true) {
        string studentName = PromptStudentAndGetName();
        if (studentName.ToUpper() == "EXIT") {
            return;
        }
        List<string> studentGrades = GetStudentGrades();
        int score = CalculateScoreFromGrades(studentGrades);
        string finalGrade = CalculateGradeFromScore(score);
        PrintFinalStatement(studentName, finalGrade);
    }
}

可以看到函数本身几乎完全由函数调用组成。每个方法都有一个合理的描述性名称(非常主观),因此该方法读起来几乎像是伪代码。

然后,我实现了这些方法中的每一个。每一个都有一个特定的任务,与它的名字相匹配。这使您有更好的机会尝试识别错误。你也可以将这些方法设为公共的,或者将其中的一些方法移到其他类中,然后使用nunit这样的测试框架对它们单独进行单元测试。
private string PromptStudentAndGetName() {
    Console.WriteLine("Enter Your Name or type 'exit' to quit): ");
    return Console.ReadLine();
}

private List<string> GetStudentGrades() {
    List<string> grades = new List<string>();
    Console.WriteLine("Number of Units:  ");
    int numberOfUnits = GetNumberOfUnits();
    for (int counter = 1; counter <= numberOfUnits; ) {
        Console.WriteLine("What was your grade for unit {0}", counter);
        var grade = Console.ReadLine();
        if (IsValidGrade(grade)) {
            grades.Add(grade);
            counter++;
        }
        else {
            Console.WriteLine("That's not a valid grade!");
        }
    }
    return grades;
}
private int CalculateScoreFromGrades(List<string> studentGrades) {
    int score = 0;
    foreach (var grade in studentGrades) {
        score += GetScoreFromGrade(grade);
    }
    return score;
}
private string CalculateGradeFromScore(int score) {
    if (score < 120) return "PPP";
    if (score < 160) return "MPP";
    if (score < 200) return "MMP";
    if (score < 240) return "MMM";
    if (score < 280) return "DMM";
    if (score < 320) return "DDM";
    if (score < 360) return "DDD";
    if (score < 380) return "D*DD";
    if (score < 400) return "D*D*D";
    if (score < 420) return "D*D*D*";
    throw new InvalidOperationException(string.Format("Unexpected score {0}", score));
}
private void PrintFinalStatement(string studentName, string finalGrade) {
    // Add up and print letter grade. 
    Console.WriteLine("Student: {0}", studentName);
    Console.WriteLine("Grade: {0}", finalGrade);
}

注意,一些方法再次被分解,以调用其他较小的方法,以保持代码大小可管理。这些方法如下:

private int GetNumberOfUnits() {
    int numberOfUnits;
    if (!int.TryParse(Console.ReadLine(), out numberOfUnits)) {
        Console.WriteLine("Sorry... I didn't understand that.  I'm going to assume you have the expected 20 units.");
        numberOfUnits = 20;
    }
    return numberOfUnits;
}
bool IsValidGrade(string grade) {
    string [] validGrades = {"D","M","P"};
    return validGrades.Contains(grade.ToUpper());
}
private int GetScoreFromGrade(string grade) {
    switch (grade.ToUpper()) {
        case "P":
            return 20;
        case "M":
            return 40;
        case "D":
            return 80;
    }
    throw new InvalidOperationException(string.Format("Tried to get a score from an invalid grade {0}", grade));
}

还要注意,上面的一些方法在遇到包含有关错误信息的意外情况时抛出异常,例如意外的分数/等级,以帮助确定问题的原因。正如我所说的,这不是一个理想的程序,但它确实有希望为您提供一个方向,以帮助您诊断自己的问题。