Reputation: 75
I have a program that grades multiple choice answers from a text file against the correct answers defined in another array. It is all working properly but I want to add the ability to show which question numbers are incorrect so the user knows where they went wrong. Below is the code I have minus any attempts to create this functionality.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Assignment1_Part_2b
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void exitBtn_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnCalculate_Click(object sender, EventArgs e)
{
string[] answers = { "B", "D", "A", "A", "C", "A", "B", "A", "C", "D",
"B", "C", "D", "A", "D", "C", "C", "B", "D", "A" };
string[] studentAnswers = new string[20];
studentAnswers = File.ReadAllLines("StudentAnswers.txt");
int correct = 0;
int incorrect = 0;
int totalMark;
for (int i = 0; i < answers.Length; i++)
{
if (answers[i] == studentAnswers[i])
{
correct = (correct + 1);
}
else
{
incorrect = (incorrect++);
}
totalMark = (correct - incorrect);
wrongAnswerLabel.Text = incorrect.ToString();
correctLabel.Text = correct.ToString();
if (totalMark > 14)
{
resultTextBox.Text = "Pass";
}
else
{
resultTextBox.Text = "Fail";
}
}
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearAll();
}
private void ClearAll()
{
resultTextBox.Text = "";
incorrectLabel.Text = "";
}
}
}
I am stuck for ideas on how I would approach this so any help would be appreciated.
Thanks guys.
Upvotes: 1
Views: 89
Reputation: 74307
You can use a Linq one-liner:
public int[] WrongAnswers( char[] reference , char[] answer )
{
if ( reference.Length != answer.Length ) throw new ArgumentOutOfRangeException();
int[] wrongAnswers = Enumerable
.Range(0,reference.Length)
.Select( i => new Tuple<int,bool>( i , reference[i]==answer[i] ) )
.Where( x => !x.Item2)
.Select( x => x.Item1 )
.ToArray()
;
return wrongAnswers ;
}
You can do something like this:
public int[] WrongAnswers( char[] reference , char[] answer )
{
if ( reference.Length != answer.Length ) throw new ArgumentOutOfRangeException();
List<int> wrongAnswers = new List<int>() ;
for ( int i = 0 ; i < reference.Length ; +=i )
{
if ( reference[i] != answer[i] ) wrongAnswers.Add(i) ;
}
return wrongAnswers.ToArray() ;
}
Upvotes: 2
Reputation: 101701
Declare another list to store indices of wrong answers:
var wrongAnswers = new List<int>();
Then if answer is incorrect add it's index to the list:
else
{
incorrect = (incorrect++);
wrongAnswers.Add(i + 1);
}
Btw instead of this incorrect = (incorrect++);
you could just use incorrect++;
Also I think you might want to move these lines outside of your loop:
totalMark = (correct - incorrect);
wrongAnswerLabel.Text = incorrect.ToString();
correctLabel.Text = correct.ToString();
if (totalMark > 14)
{
resultTextBox.Text = "Pass";
}
else
{
resultTextBox.Text = "Fail";
}
In order to display wrong answer numbers you could use String.Join
and concatenate numbers into single string
and display it like this:
string text = string.Join(" ", wrongAnswers);
wrongAnswersLabel.Text = "Wrong answers: " + text;
Upvotes: 3
Reputation: 11187
You can define an array or a list outside of your loop and add the question number to it when incorrect. You'll end up with the list of incorrect questions.
Upvotes: 0