first commit

This commit is contained in:
2025-08-01 14:10:44 -04:00
commit cf32cfcbcd
149 changed files with 80416 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
namespace Core.Entities;
public class AssignmentAssumption(CompetitiveEvent @event, Student student, Assumption assumption)
{
public CompetitiveEvent Event { get; } = @event;
public Student Student { get; } = student;
public Assumption Assumption { get; } = assumption;
public EventAssignment EventAssignment => new(@event, student);
}
+22
View File
@@ -0,0 +1,22 @@
namespace Core.Entities
{
public class AssignmentParameters(
int effortLowerBound = 6,
int effortUpperBound = 8,
int assignmentLowerBound = 2,
int assignmentUpperBound = 4,
int teamSizeLimit = 4,
bool limitTeamsToOne = true,
bool requireRegional = true,
bool requireOnSite = true)
{
public int EffortLowerBound { get; set; } = effortLowerBound;
public int EffortUpperBound { get; set; } = effortUpperBound;
public int AssignmentLowerBound { get; set; } = assignmentLowerBound;
public int AssignmentUpperBound { get; set; } = assignmentUpperBound;
public int TeamSizeLimit { get; set; } = teamSizeLimit;
public bool LimitTeamsToOne { get; set; } = limitTeamsToOne;
public bool RequireRegional { get; set; } = requireRegional;
public bool RequireOnSite { get; set; } = requireOnSite;
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Core.Entities;
public enum Assumption
{
Include,
Exclude
}
+71
View File
@@ -0,0 +1,71 @@
namespace Core.Entities;
public class CompetitiveEvent
{
public string Name { get; set; }
public string ShortName { get; set; }
public EventFormat Format { get; set; }
public int MinTeamSize { get; set; }
public int MaxTeamSize { get; set; }
public string TeamSize =>
MinTeamSize == MaxTeamSize
? MinTeamSize.ToString()
: $"{MinTeamSize.ToString()}-{MaxTeamSize.ToString()}";
public string SemifinalistActivity { get; set; }
public bool InterviewOrPresentation
=> SemifinalistActivity.Contains("Interview") || SemifinalistActivity.Contains("Presentation");
public bool OnSiteActivity
=> SemifinalistActivity.Contains("Challenge")
|| SemifinalistActivity.Contains("Race")
|| SemifinalistActivity.Contains("Speech")
|| SemifinalistActivity.Contains("Test")
|| SemifinalistActivity.Contains("Flight")
|| SemifinalistActivity.Contains("Debate")
|| SemifinalistActivity.Contains("Photography")
|| SemifinalistActivity.Contains("Build")
|| Name.Contains("Chapter")
|| Name.Contains("Essay")
|| SemifinalistActivity.Contains("Fly");
public string RegionalNotes { get; set; }
public int MaxTeamCountState { get; set; }
public bool RegionalEvent { get; set; }
public bool RegionalPresubmit { get; set; }
public bool StatePresubmission { get; set; }
public bool StatePretesting { get; set; }
public bool StatePreliminaryRound { get; set; }
public string Documentation { get; set; }
public string Eligibility { get; set; }
public string Theme { get; set; }
public string Description { get; set; }
public int? LevelOfEffort { get; set; }
public override string ToString()
{
return Name;
}
public static readonly CompetitiveEvent GeneralSchedule = new(){Name = "General Schedule"};
public static readonly CompetitiveEvent VotingDelegates = new(){Name = "Voting Delegates"};
public string EventAttributes ()
{
var st = new List<string>();
if (Format is EventFormat.Individual)
st.Add( "Ind.");
if (RegionalEvent)
st.Add( "Reg.");
return string.Join(", ", st);
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace Core.Entities;
public class EventAssignment
{
public CompetitiveEvent Event { get; }
public Student Student { get; }
public EventAssignment(CompetitiveEvent @event, Student student)
{
Event = @event;
Student = student;
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Core.Entities;
public enum EventFormat
{
Team,
Individual
}
+19
View File
@@ -0,0 +1,19 @@
namespace Core.Entities
{
public class EventOccurrence
{
public string Name { get; set; }
public string Time { get; set; }
public string Date { get; set; }
public DateTime StartTime { get; set; }
public DateTime? EndTime { get; set; }
public string Location { get; set; }
public bool SignupSubmitPickup =>
Name.Contains("Sign-up") ||
Name.Contains("Submit") ||
Name.Contains("Submission") ||
Name.Contains("Pick-up");
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace Core.Entities;
public class EventStudentPicks
{
public CompetitiveEvent Event { get; }
public IList<Tuple<Student,int>> StudentPicks { get; }
public EventStudentPicks(CompetitiveEvent @event, IList<Tuple<Student, int>> studentPicks)
{
Event = @event;
StudentPicks = studentPicks;
}
}
+18
View File
@@ -0,0 +1,18 @@
namespace Core.Entities;
public class PartialTeam : Team
{
public IList<Student> OmittedStudents { get; }
public PartialTeam(string name, CompetitiveEvent @event, IList<Student> students, IList<Student> omittedStudents) : base(name, @event, students)
{
OmittedStudents = omittedStudents;
}
public override Team CloneWithOmittedStudents(IEnumerable<Student> studentsToOmit)
{
var remainingStudents = Students.Where(s => !studentsToOmit.Contains(s)).ToList();
var omittedStudents = OmittedStudents.Union(Students.Where(studentsToOmit.Contains)).Distinct().ToList();
return new PartialTeam(Name, Event, remainingStudents, omittedStudents );
}
}
+74
View File
@@ -0,0 +1,74 @@
using System.Text.RegularExpressions;
namespace Core.Entities;
public class Student
{
public string Name { get; set; }
public string LastNameFirstName
{
get
{
if (Name.Contains(',')) return Name;
var match = Regex.Match(Name, @"(.*)\s(.*)");
if (match.Success)
return $"{match.Groups[2].Value}, {match.Groups[2].Value} ";
return Name;
}
}
public string FirstNameLastName
{
get
{
if (!Name.Contains(',')) return Name;
var match = Regex.Match(Name, @"(.*),\s*(.*)");
if (match.Success)
return $"{match.Groups[2].Value} {match.Groups[1].Value}";
return Name;
}
}
public string FirstName
{
get
{
var match = Regex.Match(LastNameFirstName, @"(.*),\s*(.*)");
if (match.Success)
return $"{match.Groups[2].Value}";
return Name;
}
}
public int Grade { get; }
public string StateID { get; }
public string RegionalID { get; }
public string NationalID { get; }
public int TsaYear { get; }
public string Officer { get; }
public IList<CompetitiveEvent> RankedEventPicks { get; }
public ICollection<Team> Teams { get; set; }
public Student(string name, int grade, int tsaYear, string officer, IList<CompetitiveEvent> rankedEventPicks,
string stateID, string regionalID, string nationalId)
{
Name = name;
Grade = grade;
TsaYear = tsaYear;
Officer = officer;
RankedEventPicks = rankedEventPicks;
StateID=stateID;
RegionalID = regionalID;
NationalID = nationalId;
}
public override string ToString()
{
return FirstName;
}
public bool VotingDelegate => Officer.Contains("Pres");
}
+102
View File
@@ -0,0 +1,102 @@
using System.Reflection;
using System.Text.RegularExpressions;
namespace Core.Entities;
public class Team
{
public string Name { get; }
public CompetitiveEvent Event { get; }
public IList<Student> Students { get; }
public Student? Captain { get; set; }
public string TeamNumber { get; set; }
public string RegionalTimeSlot { get; set; }
public Tuple<DateTime,DateTime?>? RegionalTimeSlotObj
{
get
{
if (string.IsNullOrEmpty(RegionalTimeSlot))
return null;
var times = Regex.Matches(RegionalTimeSlot, @"(.*)\s*-\s*(.*)");
if (times.Count == 0)
return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
var match = times[0];
if (!match.Success)
return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
return Tuple.Create(P(match.Groups[1].Value), (DateTime?)P(match.Groups[2].Value));
return null;
}
}
private DateTime P(string s)
{
var dt = DateTime.Parse(s);
if (dt.TimeOfDay < TimeSpan.FromHours(7))
return dt + TimeSpan.FromHours(12);
return dt;
}
public Team(string name, CompetitiveEvent @event, IList<Student> students, Student? captain = null, string teamNumber = null, string regionalTimeSlot = null)
{
Name = name;
Event = @event;
Students = students;
Captain = captain;
TeamNumber = teamNumber;
RegionalTimeSlot = regionalTimeSlot;
}
public virtual Team CloneWithOmittedStudents(IEnumerable<Student> studentsToOmit)
{
var studentsToOmitList = studentsToOmit.ToList();
var omittedStudents = Students.Where(studentsToOmitList.Contains).ToList();
if (!omittedStudents.Any())
return new Team(Name, Event, Students.ToList(), Captain);
var remainingStudents = Students.Where(s => !studentsToOmitList.Contains(s)).ToList();
return new PartialTeam(Name, Event, remainingStudents, omittedStudents);
}
public Team Clone() => CloneWithOmittedStudents(Array.Empty<Student>());
public static int GetStudentTeamOverlapCount(IList<Team>[] timeSlots)
{
return timeSlots.Sum(GetStudentTeamOverlapCount);
}
private static int GetStudentTeamOverlapCount(IList<Team> timeSlot)
{
return GetStudentTeamOverlaps(timeSlot).Count();
}
public static IEnumerable<Tuple<Student, IEnumerable<Team>>> GetStudentTeamOverlaps(IList<Team> timeSlot)
{
return
from s in timeSlot.SelectMany(ts => ts.Students).Distinct()
group s by timeSlot.Where(t => t.Students.Contains(s))
into gs
where gs.Key.Count() > 1
select Tuple.Create(gs.First(), gs.Key);
}
public override string ToString()
{
return Name;
}
public string ToStringWithIndividualAndRegional()
{
var ind = Event.Format is EventFormat.Individual ? " (Ind.)" : string.Empty;
var regional= Event.RegionalEvent ? " (Reg.)" : string.Empty;
//var regional= Event.RegionalEvent ? " (Reg.)" : string.Empty;
var eventAttributes = Event.EventAttributes();
return string.IsNullOrEmpty(eventAttributes) ? Name : Name + " (" + eventAttributes + ")";
}
}