Files
chapter-organizer/Core/Parsers/TeamParser.cs
T

166 lines
3.8 KiB
C#

using System.Globalization;
using Core.Entities;
using CsvHelper;
using CsvHelper.Configuration;
using FuzzySharp;
namespace Core.Parsers
{
public class TeamWriter
{
private readonly ICollection<Team> _teams;
public string Filename { get; }
public TeamWriter(ICollection<Team> teams, string filename)
{
_teams = teams;
Filename = filename;
}
public void Write()
{
var csvConfiguration = new CsvConfiguration(CultureInfo.CurrentCulture)
{
HasHeaderRecord = true,
};
using var writer = new StreamWriter(Filename);
using var csv = new CsvWriter(writer, csvConfiguration);
// header
csv.WriteField("Team Name");
csv.WriteField("Event Name");
var max = _teams.Max(t => t.Students.Count);
for (var i = 1; i < max + 1; i++)
{
csv.WriteField($"Student {i}");
}
foreach (var team in _teams)
{
csv.WriteField(team.Name);
csv.WriteField(team.Event.Name);
foreach (var teamStudent in team.Students)
{
csv.WriteField(teamStudent.Name);
}
csv.NextRecord();
}
}
}
public class TeamParser : CsvParserBase
{
public TeamParser(FileSystemInfo csvFile, bool ignoreBlankLines = true) : base(csvFile, ignoreBlankLines)
{
}
public Team[] Parse(ICollection<EventDefinition> events, ICollection<Student> students)
{
var teams = new List<Team>();
CsvReader.Read();
CsvReader.ReadHeader();
while (CsvReader.Read())
{
var eventName
= CsvReader.GetField("Event Name");
if (string.IsNullOrEmpty(eventName))
continue;
if (eventName.StartsWith("Team Size"))
continue;
eventName = eventName.Replace("ᵃ", string.Empty);
eventName = eventName.Replace("ⁱ", string.Empty);
eventName = eventName.TrimEnd();
var teamName = CsvReader.GetField("Team Name");
if (string.IsNullOrEmpty(teamName))
teamName = eventName;
eventName = eventName.Trim();
var @event =
(from e in events
let rat = Fuzz.Ratio(e.Name, eventName)
where rat > 50
orderby rat descending
select e).FirstOrDefault();
if (@event == null)
continue;
var regionalTimeSlot = CsvReader.GetField("Regional Time Slot");
if (!string.IsNullOrEmpty(regionalTimeSlot))
regionalTimeSlot.Trim();
var teamStudents = new List<Student>();
Student? captain = null;
for (var i = 1; i <= 9; i++)
{
var studentName = CsvReader.GetField($"Student {i}");
if (string.IsNullOrEmpty(studentName)) continue;
studentName = studentName.Trim();
if (studentName == "?")
continue;
var studentMatches =
from s in students
let rat = new[]
{
Fuzz.Ratio(s.Name, studentName),
Fuzz.Ratio(s.FirstNameLastName, studentName),
Fuzz.Ratio(s.FirstName, studentName)
}.Max()
where rat > 90
orderby rat descending
select s;
var student = studentMatches.FirstOrDefault();
if (student == null)
{
//continue;
throw new ArgumentException($"Student named '{studentName}' not found");
}
teamStudents.Add(student);
if (i == 1)
captain = student;
}
var teamNumber = string.Empty;
if (teamName.EndsWith("Team 2"))
teamNumber = "12227-2";
else if (@event.EventFormat == EventFormat.Team)
teamNumber = "2227";
if (teamStudents.Count > 0)
{
if (@event.EventFormat is EventFormat.Team)
{
teams.Add(new Team { Event = @event, Students = teamStudents, Captain = captain, Name = teamName, TeamId = teamNumber});
}
else if (@event.EventFormat is EventFormat.Individual)
{
foreach (var student in teamStudents)
{
teams.Add(new Team{Name = $"{teamName} - {student.FirstName}", Event = @event,
Students = new List<Student> { student }, Captain = student, TeamId = teamNumber});
}
}
}
}
return teams.ToArray();
}
}
}