public async Task RefreshCaches() { _logger.Info("Refreshing caches"); LocalDate today = _clock.GetToday(); LocalDate tomorrow = today.PlusDays(1); await UpdateCodeBasedTags(today); await _masterGameRepo.UpdateReleaseDateEstimates(tomorrow); await UpdateSystemWideValues(); HypeConstants hypeConstants; if (_configuration.DefaultHypeConstants) { _logger.Info("Using default hype constants"); hypeConstants = HypeConstants.GetReasonableDefaults(); } else { hypeConstants = await GetHypeConstants(); } await UpdateGameStats(hypeConstants); _logger.Info("Done refreshing caches"); }
private async Task <HypeConstants> GetHypeConstants() { _logger.LogInformation("Getting Hype Constants"); var supportedYears = await _interLeagueService.GetSupportedYears(); List <MasterGameYear> allMasterGameYears = new List <MasterGameYear>(); foreach (var supportedYear in supportedYears) { if (supportedYear.Year < 2019) { continue; } var masterGamesForYear = await _masterGameRepo.GetMasterGameYears(supportedYear.Year, true); var relevantGames = masterGamesForYear.Where(x => x.IsRelevantInYear(supportedYear)); allMasterGameYears.AddRange(relevantGames); } var outputModels = allMasterGameYears.Select(x => new MasterGameYearScriptInput(x)); string scriptsFolder = "C:\\FantasyCritic\\Scripts\\"; string scriptFileName = "regression_model.py"; string scriptPath = Path.Combine(scriptsFolder, scriptFileName); string dataFileName = Guid.NewGuid() + ".csv"; string dataPath = Path.Combine(scriptsFolder, dataFileName); using (var writer = new StreamWriter(dataPath)) using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)) { csv.WriteRecords(outputModels); } var result = _pythonRunner.RunPython(scriptPath, dataPath); var splitString = result.Split(' '); File.Delete(dataPath); double baseScore = double.Parse(splitString[2]); double standardGameConstant = double.Parse(splitString[4]); double counterPickConstant = double.Parse(splitString[8]); double hypeFactorConstant = double.Parse(splitString[12]); double averageDraftPositionConstant = double.Parse(splitString[16]); double totalBidAmountConstant = double.Parse(splitString[20]); double bidPercentileConstant = double.Parse(splitString[24]); HypeConstants hypeConstants = new HypeConstants(baseScore, standardGameConstant, counterPickConstant, hypeFactorConstant, averageDraftPositionConstant, totalBidAmountConstant, bidPercentileConstant); _logger.LogInformation($"Hype Constants: {hypeConstants}"); return(hypeConstants); }
private async Task UpdateHypeFactor(HypeConstants hypeConstants) { var supportedYears = await _interLeagueService.GetSupportedYears(); foreach (var supportedYear in supportedYears) { if (supportedYear.Finished) { continue; } List <MasterGameHypeScores> hypeScores = new List <MasterGameHypeScores>(); var cleanMasterGames = await _masterGameRepo.GetMasterGameYears(supportedYear.Year, false); var cachedMasterGames = await _masterGameRepo.GetMasterGameYears(supportedYear.Year, true); var masterGameCacheLookup = cachedMasterGames.ToDictionary(x => x.MasterGame.MasterGameID, y => y); foreach (var masterGame in cleanMasterGames) { var gameIsCached = masterGameCacheLookup.TryGetValue(masterGame.MasterGame.MasterGameID, out var cachedMasterGame); if (masterGame.MasterGame.CriticScore.HasValue && gameIsCached) { hypeScores.Add(new MasterGameHypeScores(masterGame, cachedMasterGame.HypeFactor, cachedMasterGame.DateAdjustedHypeFactor, cachedMasterGame.LinearRegressionHypeFactor)); continue; } double notNullAverageDraftPosition = masterGame.AverageDraftPosition ?? 0; double hypeFactor = (101 - notNullAverageDraftPosition) * masterGame.PercentStandardGame; double dateAdjustedHypeFactor = (101 - notNullAverageDraftPosition) * masterGame.EligiblePercentStandardGame; double standardGameCalculation = masterGame.EligiblePercentStandardGame * hypeConstants.StandardGameConstant; double counterPickCalculation = masterGame.EligiblePercentCounterPick * hypeConstants.CounterPickConstant; double hypeFactorCalculation = dateAdjustedHypeFactor * hypeConstants.HypeFactorConstant; double averageDraftPositionCalculation = notNullAverageDraftPosition * hypeConstants.AverageDraftPositionConstant; double totalBidCalculation = masterGame.TotalBidAmount * hypeConstants.TotalBidAmountConstant; double bidPercentileCalculation = masterGame.BidPercentile * hypeConstants.BidPercentileConstant; double linearRegressionHypeFactor = hypeConstants.BaseScore + standardGameCalculation + counterPickCalculation + hypeFactorCalculation + averageDraftPositionCalculation + totalBidCalculation + bidPercentileCalculation; hypeScores.Add(new MasterGameHypeScores(masterGame, hypeFactor, dateAdjustedHypeFactor, linearRegressionHypeFactor)); } await _masterGameRepo.UpdateHypeFactors(hypeScores, supportedYear.Year); } }
private async Task <HypeConstants> GetHypeConstants() { _logger.LogInformation("Getting Hype Constants"); REngine.SetEnvironmentVariables(); var engine = REngine.GetInstance(); string rscript = Resource.MasterGameStatisticsScript; var supportedYears = await _interLeagueService.GetSupportedYears(); List <MasterGameYear> allMasterGameYears = new List <MasterGameYear>(); foreach (var supportedYear in supportedYears) { if (supportedYear.Year < 2019) { continue; } var masterGamesForYear = await _masterGameRepo.GetMasterGameYears(2019, true); var relevantGames = masterGamesForYear.Where(x => x.IsRelevantInYear(supportedYear)); if (!supportedYear.Finished) { relevantGames = relevantGames.Where(x => !x.WillRelease() || x.MasterGame.CriticScore.HasValue); } allMasterGameYears.AddRange(relevantGames); } var outputModels = allMasterGameYears.Select(x => new MasterGameYearRInput(x)); string fileName = Guid.NewGuid() + ".csv"; using (var writer = new StreamWriter(fileName)) using (var csv = new CsvWriter(writer)) { csv.WriteRecords(outputModels); } var args_r = new string[1] { fileName }; engine.SetCommandLineArguments(args_r); CharacterVector vector = engine.Evaluate(rscript).AsCharacter(); string result = vector[0]; var splitString = result.Split(' '); File.Delete(fileName); double baseScore = double.Parse(splitString[2]); double standardGameConstant = double.Parse(splitString[4]); double counterPickConstant = double.Parse(splitString[8]); double hypeFactorConstant = double.Parse(splitString[12]); double averageDraftPositionConstant = double.Parse(splitString[16]); double totalBidAmountConstant = double.Parse(splitString[20]); double bidPercentileConstant = double.Parse(splitString[24]); HypeConstants hypeConstants = new HypeConstants(baseScore, standardGameConstant, counterPickConstant, hypeFactorConstant, averageDraftPositionConstant, totalBidAmountConstant, bidPercentileConstant); _logger.LogInformation($"Hype Constants: {hypeConstants}"); return(hypeConstants); }
private async Task UpdateGameStats(HypeConstants hypeConstants) { var supportedYears = await _interLeagueService.GetSupportedYears(); foreach (var supportedYear in supportedYears) { if (supportedYear.Finished) { continue; } List <MasterGameCalculatedStats> calculatedStats = new List <MasterGameCalculatedStats>(); IReadOnlyList <MasterGame> cleanMasterGames = await _masterGameRepo.GetMasterGames(); IReadOnlyList <MasterGameYear> cachedMasterGames = await _masterGameRepo.GetMasterGameYears(supportedYear.Year); IReadOnlyList <Publisher> allPublishers = await _fantasyCriticRepo.GetAllPublishersForYear(supportedYear.Year); IReadOnlyList <Publisher> publishersInRealLeagues = allPublishers.Where(x => !x.LeagueYear.League.TestLeague).ToList(); IReadOnlyList <Publisher> publishersInCompleteLeagues = publishersInRealLeagues.Where(x => x.LeagueYear.PlayStatus.DraftFinished).ToList(); IReadOnlyList <PublisherGame> publisherGames = publishersInCompleteLeagues.SelectMany(x => x.PublisherGames).Where(x => x.MasterGame.HasValue).ToList(); IReadOnlyList <PickupBid> processedBids = await _fantasyCriticRepo.GetProcessedPickupBids(supportedYear.Year); ILookup <MasterGame, PickupBid> bidsByGame = processedBids.ToLookup(x => x.MasterGame); IReadOnlyDictionary <MasterGame, long> totalBidAmounts = bidsByGame.ToDictionary(x => x.Key, y => y.Sum(x => x.BidAmount)); IReadOnlyList <MasterGame> allGamesWithBids = bidsByGame.Select(x => x.Key).ToList(); var publisherGamesByMasterGame = publisherGames.ToLookup(x => x.MasterGame.Value.MasterGame.MasterGameID); Dictionary <LeagueYear, HashSet <MasterGame> > standardGamesByLeague = new Dictionary <LeagueYear, HashSet <MasterGame> >(); Dictionary <LeagueYear, HashSet <MasterGame> > counterPicksByLeague = new Dictionary <LeagueYear, HashSet <MasterGame> >(); foreach (var publisher in publishersInCompleteLeagues) { if (!standardGamesByLeague.ContainsKey(publisher.LeagueYear)) { standardGamesByLeague[publisher.LeagueYear] = new HashSet <MasterGame>(); } if (!counterPicksByLeague.ContainsKey(publisher.LeagueYear)) { counterPicksByLeague[publisher.LeagueYear] = new HashSet <MasterGame>(); } foreach (var game in publisher.PublisherGames) { if (game.MasterGame.HasNoValue) { continue; } if (game.CounterPick) { counterPicksByLeague[publisher.LeagueYear].Add(game.MasterGame.Value.MasterGame); } else { standardGamesByLeague[publisher.LeagueYear].Add(game.MasterGame.Value.MasterGame); } } } var masterGameCacheLookup = cachedMasterGames.ToDictionary(x => x.MasterGame.MasterGameID, y => y); var allLeagueYears = publishersInCompleteLeagues.Select(x => x.LeagueYear).Distinct().ToList(); double totalLeagueCount = allLeagueYears.Count(); foreach (var masterGame in cleanMasterGames) { var gameIsCached = masterGameCacheLookup.TryGetValue(masterGame.MasterGameID, out var cachedMasterGame); if (masterGame.ReleaseDate.HasValue && masterGame.ReleaseDate < new LocalDate(supportedYear.Year, 1, 1) && gameIsCached) { calculatedStats.Add(new MasterGameCalculatedStats(masterGame, cachedMasterGame)); continue; } //Basic Stats var publisherGamesForMasterGame = publisherGamesByMasterGame[masterGame.MasterGameID]; var leaguesWithGame = standardGamesByLeague.Count(x => x.Value.Contains(masterGame)); var leaguesWithCounterPickGame = counterPicksByLeague.Count(x => x.Value.Contains(masterGame)); List <LeagueYear> leaguesWhereEligible = allLeagueYears.Where(x => x.GameIsEligible(masterGame)).ToList(); List <LeagueYear> timeAdjustedLeagues; if (masterGame.FirstCriticScoreTimestamp.HasValue) { timeAdjustedLeagues = leaguesWhereEligible.Where(x => x.DraftStartedTimestamp.HasValue && x.DraftStartedTimestamp <= masterGame.FirstCriticScoreTimestamp.Value) .ToList(); } else { timeAdjustedLeagues = leaguesWhereEligible; } double leaguesWhereEligibleCount = timeAdjustedLeagues.Count; double percentStandardGame = leaguesWithGame / totalLeagueCount; double percentCounterPick = leaguesWithCounterPickGame / totalLeagueCount; double eligiblePercentStandardGame = leaguesWithGame / leaguesWhereEligibleCount; double eligiblePercentCounterPick = leaguesWithCounterPickGame / leaguesWhereEligibleCount; var bidsForGame = bidsByGame[masterGame]; int numberOfBids = bidsForGame.Count(); bool hasBids = totalBidAmounts.TryGetValue(masterGame, out long totalBidAmount); if (!hasBids) { totalBidAmount = 0; } var gamesWithMoreBidTotal = totalBidAmounts.Where(x => x.Value > totalBidAmount); double percentageGamesWithHigherBidTotal = gamesWithMoreBidTotal.Count() / (double)cleanMasterGames.Count; double bidPercentile = 100 - (percentageGamesWithHigherBidTotal * 100); double?averageDraftPosition = publisherGamesForMasterGame.Average(x => x.OverallDraftPosition); double?averageWinningBid = bidsByGame[masterGame].Where(x => x.Successful.HasValue && x.Successful.Value).Select(x => (double)x.BidAmount).DefaultIfEmpty(0.0).Average(); double notNullAverageDraftPosition = averageDraftPosition ?? 0; double percentStandardGameToUse = eligiblePercentStandardGame; double percentCounterPickToUse = eligiblePercentCounterPick; if (masterGame.EligibilityChanged || eligiblePercentStandardGame > 1) { percentStandardGameToUse = percentStandardGame; percentCounterPickToUse = percentCounterPick; } //Derived Stats double hypeFactor = (101 - notNullAverageDraftPosition) * percentStandardGame; double dateAdjustedHypeFactor = (101 - notNullAverageDraftPosition) * percentStandardGameToUse; percentStandardGame = FixDouble(percentStandardGame); percentCounterPick = FixDouble(percentCounterPick); eligiblePercentStandardGame = FixDouble(eligiblePercentStandardGame); eligiblePercentCounterPick = FixDouble(eligiblePercentCounterPick); bidPercentile = FixDouble(bidPercentile); hypeFactor = FixDouble(hypeFactor); dateAdjustedHypeFactor = FixDouble(dateAdjustedHypeFactor); if (masterGame.CriticScore.HasValue && gameIsCached) { calculatedStats.Add(new MasterGameCalculatedStats(masterGame, supportedYear.Year, percentStandardGame, percentCounterPick, eligiblePercentStandardGame, eligiblePercentCounterPick, numberOfBids, (int)totalBidAmount, bidPercentile, averageDraftPosition, averageWinningBid, hypeFactor, dateAdjustedHypeFactor, cachedMasterGame.LinearRegressionHypeFactor)); continue; } //Linear Regression double standardGameCalculation = percentStandardGameToUse * hypeConstants.StandardGameConstant; double counterPickCalculation = percentCounterPickToUse * hypeConstants.CounterPickConstant; double hypeFactorCalculation = dateAdjustedHypeFactor * hypeConstants.HypeFactorConstant; double averageDraftPositionCalculation = notNullAverageDraftPosition * hypeConstants.AverageDraftPositionConstant; double totalBidCalculation = totalBidAmount * hypeConstants.TotalBidAmountConstant; double bidPercentileCalculation = bidPercentile * hypeConstants.BidPercentileConstant; double linearRegressionHypeFactor = hypeConstants.BaseScore + standardGameCalculation + counterPickCalculation + hypeFactorCalculation + averageDraftPositionCalculation + totalBidCalculation + bidPercentileCalculation; linearRegressionHypeFactor = FixDouble(linearRegressionHypeFactor); calculatedStats.Add(new MasterGameCalculatedStats(masterGame, supportedYear.Year, percentStandardGame, percentCounterPick, eligiblePercentStandardGame, eligiblePercentCounterPick, numberOfBids, (int)totalBidAmount, bidPercentile, averageDraftPosition, averageWinningBid, hypeFactor, dateAdjustedHypeFactor, linearRegressionHypeFactor)); } await _masterGameRepo.UpdateCalculatedStats(calculatedStats, supportedYear.Year); } }
private async Task UpdateGameStats(HypeConstants hypeConstants) { _logger.Info("Updating game stats."); var supportedYears = await _interLeagueService.GetSupportedYears(); var currentDate = _clock.GetToday(); foreach (var supportedYear in supportedYears) { if (supportedYear.Finished) { continue; } List <MasterGameCalculatedStats> calculatedStats = new List <MasterGameCalculatedStats>(); IReadOnlyList <MasterGame> cleanMasterGames = await _masterGameRepo.GetMasterGames(); IReadOnlyList <MasterGameYear> cachedMasterGames = await _masterGameRepo.GetMasterGameYears(supportedYear.Year); IReadOnlyList <LeagueYear> leagueYears = await _fantasyCriticRepo.GetLeagueYears(supportedYear.Year); var leagueYearDictionary = leagueYears.ToDictionary(x => x.Key); IReadOnlyList <Publisher> allPublishers = leagueYears.SelectMany(x => x.Publishers).ToList(); List <Publisher> publishersInCompleteLeagues = new List <Publisher>(); foreach (var publisher in allPublishers) { var leagueYear = leagueYearDictionary[publisher.LeagueYearKey]; if (leagueYear.League.TestLeague || !leagueYear.PlayStatus.DraftFinished) { continue; } publishersInCompleteLeagues.Add(publisher); } var leagueYearsToCount = publishersInCompleteLeagues.Select(x => x.LeagueYearKey).ToHashSet(); IReadOnlyList <PublisherGame> publisherGames = publishersInCompleteLeagues.SelectMany(x => x.PublisherGames).Where(x => x.MasterGame is not null).ToList(); IReadOnlyList <PickupBid> processedBids = await _fantasyCriticRepo.GetProcessedPickupBids(supportedYear.Year, leagueYears); var bidsToCount = processedBids.Where(x => leagueYearsToCount.Contains(x.LeagueYear.Key)).ToList(); ILookup <MasterGame, PickupBid> bidsByGame = bidsToCount.ToLookup(x => x.MasterGame); IReadOnlyDictionary <MasterGame, long> totalBidAmounts = bidsByGame.ToDictionary(x => x.Key, y => y.Sum(x => x.BidAmount)); var publisherGamesByMasterGame = publisherGames.ToLookup(x => x.MasterGame !.MasterGame.MasterGameID); Dictionary <LeagueYearKey, HashSet <MasterGame> > standardGamesByLeague = new Dictionary <LeagueYearKey, HashSet <MasterGame> >(); Dictionary <LeagueYearKey, HashSet <MasterGame> > counterPicksByLeague = new Dictionary <LeagueYearKey, HashSet <MasterGame> >(); foreach (var publisher in publishersInCompleteLeagues) { if (!standardGamesByLeague.ContainsKey(publisher.LeagueYearKey)) { standardGamesByLeague[publisher.LeagueYearKey] = new HashSet <MasterGame>(); } if (!counterPicksByLeague.ContainsKey(publisher.LeagueYearKey)) { counterPicksByLeague[publisher.LeagueYearKey] = new HashSet <MasterGame>(); } foreach (var game in publisher.PublisherGames) { if (game.MasterGame is null) { continue; } if (game.CounterPick) { counterPicksByLeague[publisher.LeagueYearKey].Add(game.MasterGame.MasterGame); } else { standardGamesByLeague[publisher.LeagueYearKey].Add(game.MasterGame.MasterGame); } } } var masterGameCacheLookup = cachedMasterGames.ToDictionary(x => x.MasterGame.MasterGameID, y => y); var completeLeagueYearKeys = publishersInCompleteLeagues.Select(x => x.LeagueYearKey).ToHashSet(); var allLeagueYears = leagueYears.Where(x => completeLeagueYearKeys.Contains(x.Key)).ToList(); double totalLeagueCount = allLeagueYears.Count; foreach (var masterGame in cleanMasterGames) { if (masterGame.ReleaseDate.HasValue && masterGame.ReleaseDate.Value.Year < supportedYear.Year) { continue; } //Basic Stats var publisherGamesForMasterGame = publisherGamesByMasterGame[masterGame.MasterGameID]; var leaguesWithGame = standardGamesByLeague.Count(x => x.Value.Contains(masterGame)); var leaguesWithCounterPickGame = counterPicksByLeague.Count(x => x.Value.Contains(masterGame)); List <LeagueYear> leaguesWhereEligible = allLeagueYears.Where(x => x.GameIsEligibleInAnySlot(masterGame, currentDate)).ToList(); List <LeagueYear> timeAdjustedLeagues; var scoreOrReleaseTime = masterGame.FirstCriticScoreTimestamp ?? masterGame.ReleaseDate?.AtStartOfDayInZone(TimeExtensions.EasternTimeZone).ToInstant(); if (scoreOrReleaseTime.HasValue) { timeAdjustedLeagues = leaguesWhereEligible.Where(x => x.DraftStartedTimestamp.HasValue && x.DraftStartedTimestamp <= scoreOrReleaseTime) .ToList(); } else { timeAdjustedLeagues = leaguesWhereEligible; } double leaguesWhereEligibleCount = timeAdjustedLeagues.Count; double percentStandardGame = leaguesWithGame / totalLeagueCount; double eligiblePercentStandardGame = leaguesWithGame / leaguesWhereEligibleCount; double percentCounterPick = leaguesWithCounterPickGame / totalLeagueCount; double?adjustedPercentCounterPick = null; if (leaguesWithGame >= 3) { adjustedPercentCounterPick = (double)leaguesWithCounterPickGame / (double)leaguesWithGame; } var bidsForGame = bidsByGame[masterGame]; int numberOfBids = bidsForGame.Count(); bool hasBids = totalBidAmounts.TryGetValue(masterGame, out long totalBidAmount); if (!hasBids) { totalBidAmount = 0; } var gamesWithMoreBidTotal = totalBidAmounts.Where(x => x.Value > totalBidAmount); double percentageGamesWithHigherBidTotal = gamesWithMoreBidTotal.Count() / (double)cleanMasterGames.Count; double bidPercentile = 100 - (percentageGamesWithHigherBidTotal * 100); double?averageDraftPosition = publisherGamesForMasterGame.Average(x => x.OverallDraftPosition); double?averageWinningBid = bidsByGame[masterGame].Where(x => x.Successful.HasValue && x.Successful.Value).Select(x => (double)x.BidAmount).DefaultIfEmpty(0.0).Average(); double notNullAverageDraftPosition = averageDraftPosition ?? 0; double percentStandardGameToUse = eligiblePercentStandardGame; double percentCounterPickToUse = adjustedPercentCounterPick ?? percentCounterPick; if (masterGame.EligibilityChanged || eligiblePercentStandardGame > 1) { percentStandardGameToUse = percentStandardGame; percentCounterPickToUse = percentCounterPick; } //Derived Stats double hypeFactor = (101 - notNullAverageDraftPosition) * percentStandardGame; double dateAdjustedHypeFactor = (101 - notNullAverageDraftPosition) * percentStandardGameToUse; percentStandardGame = FixDouble(percentStandardGame); percentCounterPick = FixDouble(percentCounterPick); eligiblePercentStandardGame = FixDouble(eligiblePercentStandardGame); adjustedPercentCounterPick = FixDouble(adjustedPercentCounterPick); bidPercentile = FixDouble(bidPercentile); hypeFactor = FixDouble(hypeFactor); dateAdjustedHypeFactor = FixDouble(dateAdjustedHypeFactor); double peakHypeFactor = hypeFactor; if (masterGameCacheLookup.TryGetValue(masterGame.MasterGameID, out var cachedMasterGame)) { if (cachedMasterGame.PeakHypeFactor > peakHypeFactor) { peakHypeFactor = cachedMasterGame.PeakHypeFactor; } if (masterGame.CriticScore.HasValue) { calculatedStats.Add(new MasterGameCalculatedStats(masterGame, supportedYear.Year, percentStandardGame, percentCounterPick, eligiblePercentStandardGame, adjustedPercentCounterPick, numberOfBids, (int)totalBidAmount, bidPercentile, averageDraftPosition, averageWinningBid, hypeFactor, dateAdjustedHypeFactor, peakHypeFactor, cachedMasterGame.LinearRegressionHypeFactor)); continue; } } //Linear Regression double standardGameCalculation = percentStandardGameToUse * hypeConstants.StandardGameConstant; double counterPickCalculation = percentCounterPickToUse * hypeConstants.CounterPickConstant; double hypeFactorCalculation = dateAdjustedHypeFactor * hypeConstants.HypeFactorConstant; double linearRegressionHypeFactor = hypeConstants.BaseScore + standardGameCalculation + counterPickCalculation + hypeFactorCalculation; linearRegressionHypeFactor = FixDouble(linearRegressionHypeFactor); calculatedStats.Add(new MasterGameCalculatedStats(masterGame, supportedYear.Year, percentStandardGame, percentCounterPick, eligiblePercentStandardGame, adjustedPercentCounterPick, numberOfBids, (int)totalBidAmount, bidPercentile, averageDraftPosition, averageWinningBid, hypeFactor, dateAdjustedHypeFactor, peakHypeFactor, linearRegressionHypeFactor)); } await _masterGameRepo.UpdateCalculatedStats(calculatedStats, supportedYear.Year); } }
public Task UpdateHypeConstants(HypeConstants hypeConstants) { throw new NotImplementedException(); }