2016-12-23 7 views
2

私は、各科目で得られたマークの数を取って試験の結果を計算するプログラムを作成しようとしています。ほとんど完了していますが、エラーが発生しました。ユーザーが値を入力する代わりにEnterキーを押すだけで、アプリケーションは進行しません。また、このコードを短縮する方法はありますか?C#で空白を受け入れるにはどうすればよいですか?

Console.WriteLine("Danyal's result calculator for students of class IX. Enter the marks requested, if not applicable leave blank and press enter :)"); 
Console.Write("Enter your Urdu marks: "); 
int urdu = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Maths marks: "); 
int maths = int.Parse(Console.ReadLine()); 
Console.Write("Enter your English Literature marks: "); 
int lit = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Biology marks: "); 
int bio = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Chemistry marks: "); 
int chem = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Islamiat marks: "); 
int isl = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Physics marks: "); 
int physics = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Computer marks: "); 
int comp = int.Parse(Console.ReadLine()); 
Console.Write("Enter your English Language marks: "); 
int lang = int.Parse(Console.ReadLine()); 
Console.Write("Enter your Pakistan Studies marks: "); 
int pst = int.Parse(Console.ReadLine()); 


int total = urdu + maths + lit + lang + bio + chem + physics + isl + comp + pst; 
Console.WriteLine("Your total marks are {0} out of 1000", total); 
float percentage = total * 100/1000; 
Console.WriteLine("Your percentage is: {0}%",percentage); 
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs."); 
Console.ReadLine(); 
+2

数字以外のものを入力した場合と同じですか?ループ内でint.TryParse()を呼び出す&呼び出すメソッドを作成します。 –

答えて

4

は、私は、ユーザーが空白のままに、または無効な値を入力する場合にはしたいと思うかわからないんだけど、あなたはこのような何かを行うことができます。この例では

 Dictionary<string,int> grades = new Dictionary<string, int> 
     { 
      { "Urdu", 0 }, 
      { "Maths", 0 }, 
      { "English", 0 }, 
      { "Biology", 0 }, 
      { "Chemistry", 0 }, 
      { "Islamiat", 0 }, 
      { "Physics", 0 }, 
      { "Computer", 0 }, 
      { "English Language", 0 }, 
      { "Pakistan Studies", 0 }, 
     }; 

     foreach (string grade in grades.Keys.ToArray()) 
     { 
      Console.WriteLine(string.Format("Enter your {0} marks: ", grade)); 
      int mark; 
      if (int.TryParse(Console.ReadLine(), out mark)) 
       grades[grade] = mark; 
     } 
     int total = grades.Sum((g) => g.Value); 

不正な入力が使用されている場合は、あなたに望んでいた場合、等級は0にデフォルト設定されますループに解析しようとすると1が同様に入力されるまでは良い値を要求した場合を変更することができます。

1

これは、DRYの原則に従わない明確なケースです。あなたは基本的に同じ操作を繰り返していますが、そうしないでください。一般的なパターンや動作が1つの場所で解決されるように、コードをリファクタリングします。

どうすればいいですか?

  1. 特定の情報を入力するように求める方法を作成します。ユーザーは何が必要ですか?彼が何をしなければならないかについての説明的なメッセージ。ユーザーは何をする必要がありますか?有効な入力を入力してください。 [OK]を、このことを念頭に置いて、この方法の次のプロトタイプは良い出発点のように思える:

    private static int GetUserInput(string message) { ... } 
    
  2. うーん...有効な入力を入力してください。これは何らかのバリデーションが必要なことを意味しますので、これをどのように解決できるか考えてみましょう。

    private static int ValidateUserInput(string input) { ... } 
    

    これで十分ですか?まあ...いいえ。ユーザーが間違った番号を入力した場合はどうなりますか?入力が発信者に有効でないことを伝える便利な方法はありません。 -1を返すことも、例外をスローすることもできますが、どちらも偽であるようです。

    最高の解決策は、2つの値を返すことです。 1つは入力が有効かどうかを示すもので、もう1つは入力が何であるかを示すものです。 C#では、これはあまり魅力的ではありません(少なくともC#7が登場するまで)。これを行う方法は、out引数を使用しています:

    private static bool ValidateUserInput(string message, out int input) { ... } 
    

    このメソッドは、私たちの目的を完全に果たします。戻り値は、入力が有効で、out引数inputが検証済みの値を返しているかどうかを示します(検証が失敗した場合は無視します)。

  3. 基本的に合計と平均が必要な場合は、それぞれのマークに変数intを作成するのはなぜですか?すべてのマークを保存するList<int>を作成します。

    また、どのようなマークがどの被写体に対応しているかを把握したい場合は、Dictionary<string, key>を使用します。ここで、キーはサブジェクト名で、値は対応するマークになります。しかし今はList<int>を使用してください。私たちは私たちのソリューションを構築することができます心の中ですべてのことで

public static void ComputeMarksSummary() 
{ 
    var marks = new List<int>(); 

    marks.Add(GetUserInput("Enter your Urdu marks: ")); 
    marks.Add(GetUserInput("Enter your Maths marks: : ")); 
    marks.Add(GetUserInput("Enter your English Literature marks: ")); 
    marks.Add(GetUserInput("Enter your Biology marks: ")); 
    marks.Add(GetUserInput("Enter your Chemistry marks: ")); 
    marks.Add(GetUserInput("Enter your Islamiat marks: ")); 
    marks.Add(GetUserInput("Enter your Computer marks: ")); 
    marks.Add(GetUserInput("Enter your English language marks: ")); 
    marks.Add(GetUserInput("Enter your Pakistan studies marks: ")); 

    var total = marks.Sum(); 
    Console.WriteLine("Your total marks are {0} out of 1000", total); 
    Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4 
    Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs."); 
    //WRONG! Percentage is not rounded off, its truncated: 9/10 is 0 in integer division. 
    Console.ReadLine(); 
} 

private static int GetUserInput(string message) 
{ 
    int mark; 

    while (true) 
    { 
      Console.WriteLine(message); 
      var input = Console.ReadLine(); 

      if (!ValidateUserInput(input, out mark)) 
      { 
       Console.WriteLine("Invalid input, please try again."); 
      } 
      else 
      { 
       return mark; 
      } 
    } 
} 

private static bool ValidateUserInput(string message, out int input) 
{ 
    //left as an excerice. Hint: look into int.TryParse(...); 
    //here you could decide if a blank input should be valid and parsed as zero. 
} 

うわーは、今では多くのクリーナーを思わ....ちょっと、我々はまだ少し良く行うことができます。これらすべてのものは何ですか?marks.Add(....)?コードをもう一度リファクタリングできないのですか?まあ、私たちは基本的に同じことを本質的に求めています、主語の名前だけが変わります。私たちはこのような何かについてどのように:

public static void ComputeMarksSummary(IEnumerable<string> subjectNames) 
{ 
    var marks = new List<int>(); 

    foreach (var subject in sujectNames) 
    { 
     marks.Add(GetUserInput(string.Format("Enter your {0} marks: ", subject))); 
    } 

    var total = marks.Sum(); 
    Console.WriteLine("Your total marks are {0} out of 1000", total); 
    Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4 
    Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs."); 
    Console.ReadLine(); 
} 

をそして、あなたはこのようにそれを呼び出すことができます。

ComputeMarksSummary(new string[] { "Urdu", "Maths", ...); 

はそんなにきれいに見えることはありませんか?

+0

Woah!それは吸収することがたくさんある。私は、初心者の初心者を見て、私は私の想像力を使用しています。私はMS Virtual Academyから学びます。まあありがとう!すべてを書き留めて説明するためのものです。これは、サムスンのようなさまざまなヘルパーメソッドを知るために役立ちました。そして、事を四捨五入した間違った用語を使用して申し訳ありません。 –

+0

@DanyalAhmedKhanは絶望しない!私は初心者のためにそれは少し難しいように思えるかもしれませんが、終わりには論理を適用し、より明確で維持可能な方法でコードする方法を考えています...プロのコーダーのほとんどの時間がコードを書くのに費やし、他の人のレビューに費やしました。明日、2つの新しい科目を追加し、廃止予定の1つを削除するコードを改善しなければならないと想像してください。どのようにコードを変更する必要があり、答えの最終版を変更する必要があるかを考えてください。あなたの将来の人生、そして他のものをもっと楽にしてください! – InBetween

+0

こんにちは、チップのおかげで! –

関連する問題