public static TariffMetroCommandCalculateInterval First(this TariffMetro tariff) { TariffMetroCommand cmd = tariff.Commands.FirstOrDefault(); if (cmd == null) { return(null); } while (cmd.Type == TariffMetroCommandType.Goto) { cmd = tariff.Goto(cmd); } return((TariffMetroCommandCalculateInterval)cmd); }
private DateTime GetNextEndTime(TariffMetro tariff, TariffMetroCommandCalculateInterval currentCommand, ref DateTime dtEstimatedDate) { //TimeSpan t1 = currentCommand.StartTime; //t1 = t_интN TariffMetroCommandCalculateInterval nextCommand = tariff.Next(currentCommand); //U_к = U_к + 1 //TimeSpan t2 = nextCommand.StartTime; //t2 = t_интN+1 var endTime = dtEstimatedDate.Add(nextCommand.StartTime); //t_интNкон = t_опл/дата + t_интN+1 if (nextCommand.StartTime > currentCommand.StartTime) { return(endTime); } endTime += TimeSpan.FromDays(1); //t_интNкон = t_интNкон + 24ч dtEstimatedDate += TimeSpan.FromDays(1); //t_опл/дата = t_опл/дата + 24ч return(endTime); }
public TariffMetro(TariffMetro tariffMetro) : base(tariffMetro) { commands = new List <TariffMetroCommand>(tariffMetro.Commands); }
/// <summary> /// Создаёт тариф метро из указанного файла /// </summary> public static Tariff LoadFromFile(string fileName) { //check file exists if (!File.Exists(fileName)) { throw new FileNotFoundException("Файл не найден", fileName); } //read valid entries IEnumerable <string> entries = File.ReadAllLines(fileName, Encoding.Default) .Where(s => ((s.Length > 3) && (s[0] == CommandStartSign))); //create commands and properties Dictionary <int, TariffMetroCommand> commands = new Dictionary <int, TariffMetroCommand>(); Dictionary <char, int> properties = PropertyNames.ToDictionary(p => p, p => (int)PropertyDefaultValue); //parse entries foreach (string e in entries) { //split entry string[] sa = SplitEntry(e); //get entry name char name = sa[0].ToUpper()[1]; //entry is command? if (Char.IsDigit(name)) { var n = (int)Char.GetNumericValue(name); TariffMetroCommand cmd = ParseCommand(sa); //stop parsing at end command if (cmd.Type == TariffMetroCommandType.End) { break; } cmd.ID = n; commands.Add(n, cmd); continue; } //entry is property? if (!properties.ContainsKey(name)) { continue; } properties[name] = ParseProperty(name, sa); } //check command sequence int[] ids = commands.Keys.OrderBy(k => k).ToArray(); if (commands.Count > 1) { int firstId = ids[0]; for (int i = 1; i < ids.Length; i++) { if ((ids[i] - ids[i - 1]) > 1) { throw new InvalidDataException("Неверная последовательность команд"); } } } //check goto command destinations if (commands.Values .Where(c => c.Type == TariffMetroCommandType.Goto) .Cast <TariffMetroCommandGoto>() .Any(g => !ids.Contains(g.Destination))) { throw new InvalidDataException("Не найдено назначение команды перехода"); } //check cyclic goto (1 level) if (commands.Values .Where(c => c.Type == TariffMetroCommandType.Goto) .Cast <TariffMetroCommandGoto>() .Any(g => { TariffMetroCommand g2 = commands[g.Destination]; if (g2.Type != TariffMetroCommandType.Goto) { return(false); } return(((TariffMetroCommandGoto)g2).Destination == g.ID); })) { throw new InvalidDataException("Обнаружен циклический переход"); } //check properties if (properties.Values.Any(v => v == PropertyDefaultValue)) { throw new InvalidDataException("Не найдены все свойства"); } //create tariff var tariff = new TariffMetro(); int id = properties['C']; id += (properties['B'] << 8); id += (properties['A'] << 16); tariff.ID = id; tariff.PaymentDiscrete = ConvertMoney(properties['D']); tariff.FreeTimeAtStart = TimeSpan.FromSeconds(properties['E']); tariff.FreeTimeAfterPayment = TimeSpan.FromSeconds(properties['F']); for (int i = 0; i < ids.Length; i++) { tariff.AddCommand(commands[i]); } return(tariff); }
private static TariffMetroCommand Goto(this TariffMetro tariff, TariffMetroCommand command) { var g = command as TariffMetroCommandGoto; return(g == null ? command : tariff.Commands.FirstOrDefault(c => c.ID == g.Destination)); }