diff --git a/Lab1/App.config b/Lab1/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/Lab1/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Lab1/Controller.cs b/Lab1/Controller.cs new file mode 100644 index 0000000..d5eb6fe --- /dev/null +++ b/Lab1/Controller.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lab1 +{ + class Controller + { + private View view; + + // Геттеры и сеттеры для view + public View View + { + get { return view; } + set { view = value; } + } + + public Controller() + { + View = new View(); + View.Show(); + } + + public Controller(View view) + { + View = view; + View.Show(); + } + + static Controller() + { + Console.WriteLine("Вызыван статический конструктор Controller"); + } + } +} diff --git a/Lab1/ISubjectIndex.cs b/Lab1/ISubjectIndex.cs new file mode 100644 index 0000000..fd45398 --- /dev/null +++ b/Lab1/ISubjectIndex.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lab1 +{ + interface ISubjectIndex + { + // Загрузка из клавиатуры + void LoadFromKeyboard(); + + // Загрузка из файла + void LoadFromFile(string filename); + + // Вывод указателя + void Print(); + + // Вывод номеров страниц для заданного слова + void PrintPages(string word); + + // Удаление элемента из указателя + void Delete(string word); + } +} diff --git a/Lab1/Lab1.csproj b/Lab1/Lab1.csproj new file mode 100644 index 0000000..4ed1c4c --- /dev/null +++ b/Lab1/Lab1.csproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + {4FF3599C-D978-4EE7-993D-BAAE95E08F8E} + Exe + Lab1 + Lab1 + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lab1/Lab1.sln b/Lab1/Lab1.sln new file mode 100644 index 0000000..1fff7e4 --- /dev/null +++ b/Lab1/Lab1.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32126.315 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab1", "Lab1.csproj", "{4FF3599C-D978-4EE7-993D-BAAE95E08F8E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4FF3599C-D978-4EE7-993D-BAAE95E08F8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FF3599C-D978-4EE7-993D-BAAE95E08F8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FF3599C-D978-4EE7-993D-BAAE95E08F8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FF3599C-D978-4EE7-993D-BAAE95E08F8E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F0FC7884-21F6-4AD7-851D-C028F7E64151} + EndGlobalSection +EndGlobal diff --git a/Lab1/MockedSubjectIndex.cs b/Lab1/MockedSubjectIndex.cs new file mode 100644 index 0000000..bf2a298 --- /dev/null +++ b/Lab1/MockedSubjectIndex.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lab1 +{ + /* + * Класс MockedSubjectIndex наследует от SubjectIndex и переопределяет методы. + * Методы заглушки печают свое название и вызывают метод базового класса. + */ + class MockedSubjectIndex: SubjectIndex + { + + public override void LoadFromKeyboard() + { + Console.WriteLine("Вызов метода LoadFromKeyboard"); + base.LoadFromKeyboard(); + } + + public override void LoadFromFile(string filename) + { + Console.WriteLine("Вызов метода LoadFromFile"); + base.LoadFromFile(filename); + } + + public override void Print() + { + Console.WriteLine("Вызов метода Print"); + base.Print(); + } + + public override void PrintPages(string word) + { + Console.WriteLine("Вызов метода PrintPages"); + base.PrintPages(word); + } + + public override void Delete(string word) + { + Console.WriteLine("Вызов метода Delete"); + base.Delete(word); + } + } +} diff --git a/Lab1/Program.cs b/Lab1/Program.cs new file mode 100644 index 0000000..98a0d47 --- /dev/null +++ b/Lab1/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lab1 +{ + class Program + { + static void Main(string[] args) + { + Controller controller = new Controller(); + } + } +} diff --git a/Lab1/Properties/AssemblyInfo.cs b/Lab1/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f2dace6 --- /dev/null +++ b/Lab1/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные с этой сборкой. +[assembly: AssemblyTitle("Lab1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Lab1")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// из модели COM задайте для атрибута ComVisible этого типа значение true. +[assembly: ComVisible(false)] + +// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM +[assembly: Guid("4ff3599c-d978-4ee7-993d-baae95e08f8e")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Номер редакции +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Lab1/SubjectIndex.cs b/Lab1/SubjectIndex.cs new file mode 100644 index 0000000..313c9f8 --- /dev/null +++ b/Lab1/SubjectIndex.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lab1 +{ + public class SubjectIndex : ISubjectIndex + { + Dictionary> _data; + + public SubjectIndex() + { + _data = new Dictionary>(); + } + + public SubjectIndex(Dictionary> data) + { + _data = data; + } + + // Геттеры и сеттеры для поля _data + public Dictionary> Data + { + get { return _data; } + set { _data = value; } + } + + static SubjectIndex() + { + Console.WriteLine("Вызыван статический конструктор SubjectIndex"); + } + + // Загрузка из клавиатуры + public virtual void LoadFromKeyboard() + { + while (true) + { + Console.WriteLine("Введите слово:"); + Console.WriteLine(".q - выйти"); + Console.WriteLine(""); + Console.Write("> "); + string input = Console.ReadLine(); + + // Если input == ".q", то выходим из цикла + if (input == ".q") + break; + + if (input == "") + { + Console.WriteLine("Введена пустая строка!"); + continue; + } + + string key = input; + + // Проверяем, что _data содержит слово + if (_data.ContainsKey(key)) + { + Console.WriteLine("Предметный указатель содержит данное слово!"); + continue; + } + + _data[key] = new List(); + + // Вводим номера страниц (максимум 10) + while (_data[key].Count < 10) + { + Console.WriteLine("Введите номер страницы ({0}/10):", _data[key].Count + 1); + Console.WriteLine(".q - выйти"); + Console.WriteLine(""); + Console.Write("> "); + input = Console.ReadLine(); + + + // Если input == ".q" выходим из цикла (выход из ввода страниц) + if (input == ".q") + break; + + int page; + + // Проверка на корректность ввода + if (!int.TryParse(input, out page) || page <= 0) + { + Console.WriteLine("Некорректный ввод. Попробуйте еще раз."); + continue; + } + + // Добавляем номер страницы в список + _data[key].Add(page); + } + } + } + + // Загрузка из файла + public virtual void LoadFromFile(string filename) + { + // Открываем файл + System.IO.StreamReader file = new System.IO.StreamReader(filename); + + int lineNumber = 0; + /* + * Читаем построчно из файла и добавляем в словарь + * Формат файла: слово и номера страниц, разделенные пробелом + */ + while (!file.EndOfStream) + { + lineNumber++; + string line = file.ReadLine(); + string[] parts = line.Split(' '); + + // Если массив parts пуст - выкидываем исключение + if (parts.Length == 0) + { + throw new Exception("Строка пустая!"); + } + + string key = parts[0]; + + // Если слово это пустая строка - выкидываем исключение + if (key == "") + { + throw new Exception("Слово пустое!"); + } + + // Если слово уже есть в словаре - выкидываем исключение + if (_data.ContainsKey(key)) + { + throw new Exception("Предметный указатель содержит данное слово!"); + } + + List value = new List(); + + int page; + for (int i = 1; i < parts.Length; i++) + { + // Если parts[i] не является натуральным числом, то вызываем исключение + if (!int.TryParse(parts[i], out page) || page <= 0) + throw new Exception(String.Format("Некорректный формат файла! {0} - не является натуральным числом", parts[i])); + + // Добавляем страницу в список + value.Add(page); + } + + _data[key] = value; + } + + } + + // Вывод указателя + public virtual void Print() + { + string result = ""; + foreach (KeyValuePair> kvp in _data) + { + result += String.Format("\"{0}\": [", kvp.Key, kvp.Value); + result += (String.Join(", ", kvp.Value.ToArray())) + "]\n"; + } + + Console.WriteLine(result); + } + + // Вывод номеров страниц для заданного слова + public virtual void PrintPages(string word) + { + Console.WriteLine(string.Join(", ", _data[word])); + } + + // Удаление элемента из указателя + public virtual void Delete(string word) + { + _data.Remove(word); + } + + // Индексатор + public List this[string word] + { + get + { + return _data[word]; + } + set + { + _data[word] = value; + } + } + + // Перечислитель + public IEnumerator>> GetEnumerator() + { + // Итератор + foreach (KeyValuePair> kvp in _data) + { + yield return kvp; + } + } + + // Переопределение метода ToString + public override string ToString() + { + string result = "SubjectIndex: \n"; + foreach (KeyValuePair> kvp in _data) + { + result += String.Format("\"{0}\": [", kvp.Key, kvp.Value); + result += (String.Join(", ", kvp.Value.ToArray())) + "]\n"; + } + return result; + } + } +} diff --git a/Lab1/View.cs b/Lab1/View.cs new file mode 100644 index 0000000..10a00b6 --- /dev/null +++ b/Lab1/View.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lab1 +{ + class View + { + private ISubjectIndex index; + + public View() + { + index = null; + } + + public View(ISubjectIndex index) + { + this.index = index; + } + + static View() + { + Console.WriteLine("Вызыван статический конструктор View"); + } + + public ISubjectIndex Index + { + get { return index; } + set { index = value; } + } + + public Tuple ReadMenuKey(int maxValue = 1) + { + int value = -1; + string input = ""; + + do + { + Console.Write("> "); + input = Console.ReadLine(); + + // Если input == ".q", то выходим + if (input == ".q") + break; + + // Проверяем на корректность ввода + if (!int.TryParse(input, out value) || value < 0 || value > maxValue) + { + Console.WriteLine("Некорректный ввод. Попробуйте еще раз."); + continue; + } + + break; + + } while (true); + + return new Tuple(value, input); + } + + public void Show() + { + do + { + Console.Clear(); + + Console.WriteLine("[Главное меню]"); + Console.WriteLine("1. Создать предметный указатель"); + Console.WriteLine("2. Вывод указателя"); + Console.WriteLine("3. Вывод номеров страниц для заданного слова"); + Console.WriteLine("4. Удаление элемента из указателя"); + Console.WriteLine(".q - выйти"); + Console.WriteLine(""); + var (value, input) = ReadMenuKey(4); + + if (input == ".q") + break; + + switch (value) + { + case 1: + CreateSubjectIndexMenu(); + break; + + case 2: + PrintSubjectIndex(); + break; + + case 3: + PrintPagesForWord(); + break; + + case 4: + DeleteSubjectIndex(); + break; + } + + } while (true); + + } + + public void CreateSubjectIndexMenu() + { + while (true) + { + + Console.Clear(); + Console.WriteLine("[Создать предметный указатель]"); + Console.WriteLine("1. C клавиатуры"); + Console.WriteLine("2. Из файла"); + Console.WriteLine(".q - выйти"); + Console.WriteLine(""); + + var (value, input) = ReadMenuKey(2); + + if (input == ".q") + break; + + switch (value) + { + case 1: + CreateSubjectIndexFromKeyboardMenu(); + break; + case 2: + CreateSubjectIndexFromFileMenu(); + break; + } + + }; + } + + public void CreateSubjectIndexFromKeyboardMenu() + { + Console.Clear(); + Index = new MockedSubjectIndex(); + Index.LoadFromKeyboard(); + } + + public void CreateSubjectIndexFromFileMenu() + { + Console.Clear(); + Console.Write("Введите путь к файлу: "); + string path = Console.ReadLine(); + Index = new MockedSubjectIndex(); + try + { + Index.LoadFromFile(path); + } + catch (Exception e) + { + Console.WriteLine(string.Format("Ошибка: {0}", e.Message)); + Index = null; + Console.WriteLine("Нажмите любую клавишу для продолжения..."); + Console.ReadKey(); + } + } + + public void PrintSubjectIndex() + { + Console.Clear(); + + if (Index != null) + { + Console.WriteLine("Предметный указатель:"); + Index.Print(); + } else + { + Console.WriteLine("Предметный указатель не создан."); + } + + Console.WriteLine("Нажмите любую клавишу..."); + Console.ReadKey(); + } + + public void PrintPagesForWord() + { + Console.Clear(); + + if (Index != null) + { + Console.WriteLine("Введите слово:"); + var word = Console.ReadLine(); + try + { + Index.PrintPages(word); + } + catch (Exception e) + { + Console.WriteLine(string.Format("Ошибка: {0}", e.Message)); + } + } else + { + Console.WriteLine("Предметный указатель не создан."); + } + + Console.WriteLine("Нажмите любую клавишу..."); + Console.ReadKey(); + } + + public void DeleteSubjectIndex() + { + Console.Clear(); + + if (Index != null) + { + Console.WriteLine("Введите элемент, который нужно удалить"); + Console.WriteLine(".q - выйти"); + Console.WriteLine(""); + Console.Write("> "); + string input = Console.ReadLine(); + if (input == ".q") + return; + + Index.Delete(input); + Console.WriteLine("OK"); + } + else + { + Console.WriteLine("Предметный указатель не создан."); + } + + Console.WriteLine("Нажмите любую клавишу..."); + Console.ReadKey(); + } + } +}