/// <summary> /// This method saved the specified scoreboard to the appropriate user's scoreboard file. it writes the data of the scoreboard /// using a similar notation to html, where the different tags refer to different fields of the scoreboard hierarchy. Items /// are nested inside sessions, which are in turn nested inside a scoreboard. /// </summary> /// <param name="scoreboard"></param> public static void SaveScoreboard(MPAiSoundScoreBoard scoreboard) { if (scoreboard.IsEmpty()) { return; } if (File.Exists(SoundScoreboardFileAddress(scoreboard.User))) { File.Delete(SoundScoreboardFileAddress(scoreboard.User)); } using (FileStream fs = new FileStream(SoundScoreboardFileAddress(scoreboard.User), FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.WriteLine("<Scoreboard>"); foreach (MPAiSoundScoreBoardSession session in scoreboard.Sessions) { if (session.IsEmpty()) { continue; } sw.WriteLine("<Session>"); sw.WriteLine("<Date>"); sw.WriteLine(session.DateAndTime); sw.WriteLine("</Date>"); sw.WriteLine("<OverallCorrectnessPercentage>"); sw.WriteLine(session.OverallCorrectnessPercentage); sw.WriteLine("</OverallCorrectnessPercentage>"); sw.WriteLine("<Content>"); foreach (MPAiSoundScoreBoardItem item in session.Content) { sw.WriteLine("<Vowel>"); sw.WriteLine(item.Vowel); sw.WriteLine("</Vowel>"); sw.WriteLine("<CorrectnessPercentage>"); sw.WriteLine(item.CorrectnessPercentage); sw.WriteLine("</CorrectnessPercentage>"); } sw.WriteLine("</Content>"); sw.WriteLine("</Session>"); } sw.WriteLine("</Scoreboard>"); } } File.SetAttributes(SoundScoreboardFileAddress(scoreboard.User), File.GetAttributes(SoundScoreboardFileAddress(scoreboard.User)) | FileAttributes.Hidden); }
/// <summary> /// Generates an HTML score report based on an input MPAiSound scoreboard. /// </summary> /// <param name="scoreboard">The scoreboard to generate an HTML report of.</param> public static void GenerateMPAiSoundScoreHTML(MPAiSoundScoreBoard scoreboard) { if (scoreboard.IsEmpty()) { return; } scoreboard.SaveScoreBoardToFile(); if (!File.Exists(ScoreboardReportCSSAddress)) { generateScoreboardCSS(); } using (FileStream fs = new FileStream(MPAiSoundScoreReportHTMLAddress, FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { using (HtmlTextWriter htw = new HtmlTextWriter(sw)) { htw.RenderBeginTag(HtmlTextWriterTag.Html); // Table settings htw.RenderBeginTag(HtmlTextWriterTag.Head); htw.AddAttribute("charset", "UTF-8"); htw.RenderBeginTag(HtmlTextWriterTag.Meta); htw.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet"); htw.AddAttribute(HtmlTextWriterAttribute.Type, "text/css"); htw.AddAttribute(HtmlTextWriterAttribute.Href, "Scoreboard.css"); htw.RenderBeginTag(HtmlTextWriterTag.Link); htw.RenderEndTag(); htw.RenderEndTag(); htw.RenderEndTag(); //Scoreboard Title htw.RenderBeginTag(HtmlTextWriterTag.Body); htw.AddAttribute(HtmlTextWriterAttribute.Class, "title"); htw.RenderBeginTag(HtmlTextWriterTag.Div); htw.RenderBeginTag(HtmlTextWriterTag.H3); htw.Write(scoreboard.User.GetCorrectlyCapitalisedName() + "'s MPAi Sound Pronunciation Scoreboard"); htw.RenderEndTag(); htw.RenderEndTag(); foreach (MPAiSoundScoreBoardSession session in scoreboard.Sessions) { if (session.IsEmpty()) { continue; } //Table Title htw.AddAttribute(HtmlTextWriterAttribute.Class, "table-title"); htw.RenderBeginTag(HtmlTextWriterTag.Div); htw.RenderBeginTag(HtmlTextWriterTag.H3); htw.Write(session.DateAndTime.ToString("dd MMMM yyyy, h:mm tt")); htw.RenderEndTag(); htw.RenderEndTag(); // Header row of the table htw.AddAttribute(HtmlTextWriterAttribute.Class, "table-fill"); htw.RenderBeginTag(HtmlTextWriterTag.Table); htw.RenderBeginTag(HtmlTextWriterTag.Tr); htw.RenderBeginTag(HtmlTextWriterTag.Th); htw.Write("Vowel"); htw.RenderEndTag(); htw.RenderBeginTag(HtmlTextWriterTag.Th); htw.Write("Correctness Percentage"); htw.RenderEndTag(); htw.RenderEndTag(); // Table rows foreach (MPAiSoundScoreBoardItem item in session.Content) { htw.RenderBeginTag(HtmlTextWriterTag.Tr); htw.RenderBeginTag(HtmlTextWriterTag.Td); htw.Write(item.Vowel); htw.RenderEndTag(); htw.RenderBeginTag(HtmlTextWriterTag.Td); htw.Write(item.CorrectnessPercentage); htw.RenderEndTag(); htw.RenderEndTag(); } // Correctness score float correctness = session.OverallCorrectnessPercentage / 100; if (correctness >= 0.8) { htw.AddAttribute(HtmlTextWriterAttribute.Class, "good-colour"); } else if (correctness >= 0.5) { htw.AddAttribute(HtmlTextWriterAttribute.Class, "medium-colour"); } else { htw.AddAttribute(HtmlTextWriterAttribute.Class, "bad-colour"); } htw.RenderBeginTag(HtmlTextWriterTag.Tr); htw.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); htw.RenderBeginTag(HtmlTextWriterTag.Td); htw.Write("Pronunciation is " + correctness.ToString("0.0%") + " Correct"); htw.RenderEndTag(); htw.RenderEndTag(); htw.RenderEndTag(); } htw.RenderEndTag(); htw.RenderEndTag(); } } } }
/// <summary> /// This method loads the scoreboard for the specified user. It does this by reading the html-style file created by SaveScoreboard. /// The nested nature of the file is why this method is also deeply nested. /// </summary> /// <param name="user"></param> /// <returns></returns> public static MPAiSoundScoreBoard LoadScoreboard(MPAiUser user) { MPAiSoundScoreBoard scoreboard = new MPAiSoundScoreBoard(user); if (File.Exists(SoundScoreboardFileAddress(scoreboard.User))) { using (FileStream fs = new FileStream(SoundScoreboardFileAddress(scoreboard.User), FileMode.Open)) { using (StreamReader sr = new StreamReader(fs)) { string line; line = sr.ReadLine(); //MPAiMessageBoxFactory.Show(line + ": <Scoreboard> expected"); if (line.Equals("<Scoreboard>")) { //MPAiMessageBoxFactory.Show("Success, entered <Scoreboard>"); while (!line.Equals("</Scoreboard>")) { line = sr.ReadLine(); while (line.Equals("<Session>")) { line = sr.ReadLine(); while (!line.Equals("</Session>")) { DateTime dateAndTime = new DateTime();; if (line.Equals("<Date>")) { line = sr.ReadLine(); while (!line.Equals("</Date>")) { dateAndTime = new DateTime(); if (!DateTime.TryParse(line, out dateAndTime)) { throw new FileLoadException("Date could not be read"); } line = sr.ReadLine(); } line = sr.ReadLine(); } float overallCorrectnessPercentage = -1; if (line.Equals("<OverallCorrectnessPercentage>")) { line = sr.ReadLine(); while (!line.Equals("</OverallCorrectnessPercentage>")) { if (!float.TryParse(line, out overallCorrectnessPercentage)) { throw new FileLoadException("Overall Correctness Percentage could not be read"); } line = sr.ReadLine(); } line = sr.ReadLine(); } List <MPAiSoundScoreBoardItem> content = new List <MPAiSoundScoreBoardItem>(); if (line.Equals("<Content>")) { line = sr.ReadLine(); while (!line.Equals("</Content>")) { string vowel = ""; float correctnessPercentage = -1; if (line.Equals("<Vowel>")) { bool firstline = true; line = sr.ReadLine(); while (!line.Equals("</Vowel>")) { if (firstline) { firstline = false; vowel += line; } else { vowel += String.Format(@"{0}", Environment.NewLine) + line; } line = sr.ReadLine(); } line = sr.ReadLine(); } if (line.Equals("<CorrectnessPercentage>")) { line = sr.ReadLine(); while (!line.Equals("</CorrectnessPercentage>")) { if (!float.TryParse(line, out correctnessPercentage)) { throw new FileLoadException("Correctness Percentage could not be read"); } line = sr.ReadLine(); } line = sr.ReadLine(); } content.Add(new MPAiSoundScoreBoardItem(vowel, correctnessPercentage)); } line = sr.ReadLine(); } MPAiSoundScoreBoardSession session = scoreboard.NewScoreBoardSession(dateAndTime, content); session.OverallCorrectnessPercentage = overallCorrectnessPercentage; } line = sr.ReadLine(); } } } } } } return(scoreboard); }