Евгений Колесников 2 年之前
父節點
當前提交
08726d5ee3
共有 4 個文件被更改,包括 135 次插入198 次删除
  1. 4 0
      articles/api_asp_net_core.md
  2. 54 119
      articles/cs_http.md
  3. 8 11
      articles/kp2.md
  4. 69 68
      readme.md

+ 4 - 0
articles/api_asp_net_core.md

@@ -705,6 +705,10 @@ param1 = 1, param2 = 2, pageNum = 10, pageLen =
 
 ---
 
+**Задание:**
+
+В следующих лекциях нам понадобится список матералов продукта, реализуйте конечную точку `GET /material/{productId:int}`, возвращающую список материалов указанного продукта.
+
 Предыдущая лекция |  | Следующая лекция
 :----------------:|:----------:|:----------------:
 [Вывод списка материалов продукта. CRUD материалов продукта](./cs_product_material.md) | [Содержание](../readme.md#тема-515-разработка-своего-api) | [Авторизация и аутентификация. Методы авторизации. Basic-авторизация.](./api_auth.md)

+ 54 - 119
articles/cs_http.md

@@ -4,14 +4,9 @@
 
 Мы остановились на списке материалов.
 
-Реализуем получение списка материалов выбранного продукта с помощью HTTP-запроса к АПИ, которое мы реализовали в прошлой теме.
+Реализуем получение списка материалов выбранного продукта с помощью HTTP-запроса.
 
-Напоминаю, GET-запрос на локальный компьютер:
-
-```
-GET http://localhost:8080/Material?product_id=1
-Authorization: Basic esmirnov 111103
-```
+>Напоминаю, в лекции про АПИ было задание реализовать конечную точку `GET /material/{productId:int}`:
 
 На C# нам надо решить две задачи:
 
@@ -26,13 +21,13 @@ Authorization: Basic esmirnov 111103
 var client = new HttpClient();
 ```
 
-В АПИ мы использовали "базовую" авторизацию. В C# я не нашёл встроенных библиотек для облегчения формирования заголовка для "базовой" авторизации
+В АПИ мы использовали "базовую" авторизацию. В C# я не нашёл встроенных библиотек для облегчения формирования заголовка для "базовой" авторизации, но реализация не сложная - нпишем сами.
 
 Формируем base64-кодированную строку:
 
 ```cs
 var basic = Convert.ToBase64String(
-    ASCIIEncoding.ASCII.GetBytes("esmirnov:111103"));
+    ASCIIEncoding.ASCII.GetBytes("admin:password"));
 ```
 
 И добавляем заголовок нашему http-клиенту:
@@ -41,13 +36,19 @@ var basic = Convert.ToBase64String(
 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basic);
 ```
 
+## GET-запрос.
+
 Теперь можно запрашивать данные. 
 
-У **HttpClient** все методы асинхронные, нужно понимать как работают `async/await`. Я для облегчения вашей работы нарисовал синхронную реализацию:
+У класса **HttpClient** все методы *асинхронные*, нужно понимать как работают `async/await`.
+
+>[Асинхронность в C#](./cs_async_await.md)
+
+Я для облегчения вашей работы нарисовал синхронную реализацию:
 
 ```cs
 // в параметрах URL
-private string GetString(string url){
+private string GetBody(string url){
     var basic = Convert.ToBase64String(
         ASCIIEncoding.ASCII.GetBytes("esmirnov:111103"));
         
@@ -59,145 +60,79 @@ private string GetString(string url){
 }
 ```
 
-## Разбор JSON
-
-Сначала допишем интерфейс нашего поставщика данных:
-
-```cs
-interface IDataProvider
-{
-    ...
-    IEnumerable<MaterialTC> GetMaterials(int ProductId);
-}    
-```
-
-Здесь я класс назвал не **Material**, а **MaterialTC**, потому что АПИ возвращает не весь объект Material, а только название и количество (**T**itle**C**ount).
-
-### Классический вариант
+## GET-запрос. Разбор JSON ответа.
 
-И реализуем его:
+Для работы с JSON нужно установить **NuGet** пакет `Newtonsoft.Json` и использовать метод десериализации объекта:
 
 ```cs
-[DataContract]
-internal class MaterialTC
-{
-    [DataMember]
-    public string Title { get; set; }
-    [DataMember]
-    public int Count { get; set; }
-}
-
-// В ответе у нас не сразу массив материалов, а два вложенных объекта, поэтому надо их тоже описать
-
-[DataContract]
-internal class Notice
-{
-    [DataMember]
-    public Material[] data { get; set; }
-}
-
-[DataContract]
-internal class Answer
-{
-    [DataMember]
-    public Notice notice { get; set; }
-}
-
-public IEnumerable<MaterialTC> GetMaterials(int ProductId) {
-    var result = new List<MaterialTC>();
-
-    var resp = GetString($"http://localhost:8080/Material?product_id={ProductId}");
-
-    var Serializer = new DataContractJsonSerializer(typeof(Answer));
-
-    using (var sr = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(resp))))
-    {
-        var answer = (Answer)Serializer.ReadObject(sr.BaseStream);
-        foreach (MaterialTC material in answer.notice.data)
-        {
-            result.Add(material);
-        }
-    }
-    return result;
-}
+// в месте, где нам нужно распарсить ответ сервера
+materialList = JsonConvert.DeserializeObject<Material[]>("тут ответ вашего АПИ");
 ```
 
-### Вариант с JavaScriptSerializer
-
-Оказывается на **WorldSkills** можно использовать не только "голый" **.NET Framework**, но и библиотеки из других компонентов **Visual Studio**.
+В общем случае может быть десериализован любой валидный JSON, но мы явно в угловых скобках указываем, что ожидаем массив материалов.
 
-В пространстве имён **System.Web.Script.Serialization** есть класс **JavaScriptSerializer**, который выглядит попроще чем классическая реализация:
-
->В пакет разработки C# не входит библиотека **System.Web.Extensions** (в которой и находится **System.Web.Script.Serialization**). Нужно в "Обозревателе решений" добавить в "Ссылки" библиотеку *Сборки -> Платформа -> System.Web.Extensions*
+Весь метод получения списка материалов помещается в 3 строки:
 
 ```cs
-// целевые классы нам по прежнему нужны, но уже без всяких аннотаций
-internal class MaterialTC
+private void GetMaterials()
 {
-    public string Title { get; set; }
-    public int Count { get; set; }
+    var resp = GetBody($"http://localhost:8080/material/{currentProduct.Id}");
+    materialList = JsonConvert.DeserializeObject<Material[]>(resp);
+    Invalidate("materialList");
 }
-
-internal class Notice
-{
-    public Material[] data;
-}
-
-internal class Answer
-{
-    public Notice notice;
-}
-
-
-// в месте, где нам нужно распарсить JSON создаем сериализатор и разбираем строку
-var serializer = new JavaScriptSerializer();
-var answer = serializer.Deserialize<Answer>("тут ваша JSON-строка");
-
-// и ВСЁ
 ```
 
 ## Удаление записей
 
-Для удаления данных в REST API используется http-метод DELETE. (Но никто не запрещает использовать и другие методы)
-
-Запрос в REST клиенте выглядит примерно так, идентификатор удаляемой записи передаём параметрами:
-
-```
-DELETE {{url}}/Product?id=131
-                      ^^^^^^^  
-Authorization: Basic esmirnov 111103
-```
-
-Строку запроса, надеюсь, сформируете сами.
-
-Для вызова http-метода DELETE используется метод DeleteAsync:
+Для вызова http-метода `DELETE` используется метод *DeleteAsync*:
 
 ```cs
 var basic = Convert.ToBase64String(
             ASCIIEncoding.ASCII.GetBytes("esmirnov:111103"));
+
 var client = new HttpClient();
-client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basic);
-client.DeleteAsync($"http://localhost:8080/Product?id={id}").Result;
+
+client.DefaultRequestHeaders.Authorization = 
+    new AuthenticationHeaderValue("Basic", basic);
+
+client.DeleteAsync(
+    $"http://localhost:8080/material/{productId}/{materialId}")
+    .Result;
 ```
 
+При работе с таблицей **ProductMaterial** не забываем, что у нас составной первичный ключ и нужны идентификаторы и продукта и материала.
+
 ## POST запросы с JSON (Добавление записей в модель в терминологии REST API)
 
-1. В проекте C# нарисуйте форму добавления продажи (в окне продукции)
+1. В проекте нарисуйте форму добавления материала в текущий продукт (в окне продукции)
 
-1. В **DataProvider** добавьте метод *AddProductSale*, который на входе получает экземпляр класса **ProductSale** и реализуйте отправку POST-запроса в локальный PHP-сервер, который добавит эту продажу в соответствующую таблицу
+1. Реализуйте отправку POST-запроса, который добавит новый материал в таблицу **ProductMaterial**
 
     ```cs
+    // при добавлении материала 
+    // у вас должен быть выбран материал 
+    // и указано его количество
+
     // сначала запихиваем объект в JSON-строку. 
-    var jsonString = serializer.Serialize(NewProductSale);
+    var jsonString = JsonConvert.SerializeObject(new {
+        MaterialId = Id выбранного материала,
+        Count = количество});
 
-    // создаём контент для запроса
-    var json = new StringContent(jsonString, Encoding.UTF8, "application/json");
+    // создаём контент для http-запроса
+    var json = new StringContent(
+        jsonString, 
+        Encoding.UTF8, 
+        "application/json");
 
     // и вызываем POST-запрос
     var client = new HttpClient();
+
     // не забываем добавить авторизацию
-    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basic);
-    var result = client.PostAsync("http://localhost:8080/ProductSale", json).Result;
+    client.DefaultRequestHeaders.Authorization = 
+        new AuthenticationHeaderValue("Basic", basic);
 
-    // Console.WriteLine(result.Content.ReadAsStringAsync().Result);
+    var result = client.PostAsync(
+        $"http://localhost:8080/material/{currentProduct.Id}", 
+        json)
+        .Result;
     ```

+ 8 - 11
articles/kp2.md

@@ -29,7 +29,7 @@
 
 ### На "отлично"
 - АПИ-сервер
-- мобильное приложение (android) или веб-приложение (vue), получающее данные через АПИ-сервер (просмотр/заказ)
+- мобильное приложение (android) или веб-приложение (vue/react), получающее данные через АПИ-сервер (просмотр/заказ)
 
 <!-- - интеграция со сторонними сервисами (доставка) -->
 
@@ -139,20 +139,17 @@ USE-case и ER диаграммы рисуются для всей предме
     - разработать UseCase-диаграмму для основных пользователей системы. 
         - полную диаграмму в формате PDF положить в репозиторий
         - "свой" кусок картинкой прицепить к пояснительной записке (картинки в *MarkDown* внедряются разметкой: `![<alt>](<имя картинки с относительным путём в вашем репозитории>)`). Например, все свои ресурсы вы храните в подкаталоге `src`, тогда для картинки с названием `erd.png` команда будет выглядеть так: `![ER-диаграмма](./src/erd.png)`
-    - разработать спецификацию к UseCase (к 3 самым важным прецедентам). Формат **MarkDown**
+    - разработать спецификацию к UseCase (к 3 самым важным прецедентам). Формат **MarkDown**
     - разработать диаграмму последовательности (в формате PDF)
     - проектирование ERD. Необходимо спроектировать максимально полную ERD для предметной области. Обязательна 3 нормальная форма с обеспечением ссылочной целостности.
         - полную диаграмму в формате PDF положить в репозиторий
         - "свой" кусок картинкой прицепить к пояснительной записке
     - разработать словарь данных (MarkDown).
 * практическая часть, которая состоит из проектирования, описания его реализации
+
     - база данных (MYSQL):
-        * создание базы данных. На этом этапе реализовать только основной функционал подсистемы (подойти к преподавателю и утвердить набор обязательных таблиц)
-        * подготовить 3 файла с данными (в РАЗНЫХ форматах csv, txt, xls): 5 записей для справочников, 10 - для данных (список товаров/услуг/клиентов...). Для данных предусмотреть поле для изображения и, соответственно, каталог с изображениями.
-            + таблица с основными данными (продукты)
-            + таблица с составными данными (материалы для продуктов)
-            + таблица связей (продукты + материалы)
-        * импортировать данные в базу данных (в пояснительной записке привести SQL-команды, используемые при импорте)
+        * создание DDL-скрипта для базы данных.
+
     - разработка (C#)
         * отображение основного списка товаров/услуг с:
             - условной раскраской (по доступности/цене... уточнить у преподавателя);
@@ -169,14 +166,14 @@ USE-case и ER диаграммы рисуются для всей предме
             
         * добавление, удаление, редактирование записей списка товаров/услуг в отдельных модальных окнах, где это возможно. Если товар уже продавали (услугу оказывали), то выводить уведомление о невозможности удаления.
         * отображение дополнительного списка (продажи/оказанные услуги)
-    - разработка (PHP)
         * реализовать API для базы данных
-        * написать инструкцию по развертыванию сервера
+
     - разработка (мобильное или WEB приложение)
         * реализовать приложение для записи на услугу/заказ товара         
+
     - тестирование
         * разработать библиотеку классов (реализовать в ней метод для расчета вычисляемого поля в основной таблице)
         * разработать модульные тесты для метода из библиотеки классов (не менее 10)
         * разработка тестовых сценариев для удаления товара/услуги (не менее 5)
-    - XML-комментарии. Не очевидный код (разработка и тестирование) должен содержать комментарии
+    
 * заключение, в котором содержатся выводы и рекомендации относительно возможностей практического применения полученных результатов;

+ 69 - 68
readme.md

@@ -60,44 +60,7 @@ https://habr.com/ru/post/151185/
 
 http://sergeyteplyakov.blogspot.com/2014/01/microsoft-fakes-state-verification.html
 
- -->
-
-* [МДК. 05.01 Проектирование и дизайн информационных систем](#мдк-0501-проектирование-и-дизайн-информационных-систем)
-  - [Основы проектирования информационных систем](#тема-511-основы-проектирования-информационных-систем)
-    + [Основные понятия и определения ИС.](./articles/5_1_1_1_intro2.md)
-    + [Анализ предметной области. Основные понятия системного и структурного анализа.](./articles/5_1_1_4_analiz.md)
-    + [UML](./articles/uml.md)
-    + [Диаграмма вариантов использования (прецедентов, use case)](./articles/5_1_1_10_uml_use_case.md)
-    + [Спецификация вариантов использования (прецедентов)](./articles/5_1_1_10_uml_uc_spec.md)
-    + [Диаграмма состояний](./articles/uml_state.md)
-    + [Прототипы экранов и окон пользовательского интерфейса (wireframe)](./articles/wireframe.md)
-    + [Диаграммы взаимодействия (последовательности и коммуникации)](./articles/uml_sequence.md)
-    + [Диаграмма деятельности](./articles/uml_activity.md) недописана 
-    + [Диаграмма классов](./articles/uml_class_alt.md)
-  - [Проектирование баз данных](#тема-512-проектирование-баз-данных)
-    + [Основы проектирования баз данных.](./articles/5_1_1_1_erd2.md)
-    + [Словарь данных](./articles/5_1_1_1_data_dictionary.md)
-    + [Создание ER-диаграммы](./articles/5_1_1_1_erd_workbench.md)
-    + [Основы SQL](./articles/sql_for_beginner.md)
-    + [Создание базы данных. Импорт данных.](./articles/sql_import.md)
-    + [Импорт данных (вариант 22).](./articles/sql_import_22.md)
-    + [Представления (View)](./articles/sql_view.md)
-    + [Хранимые процедуры. Триггеры.](./articles/sql_trigger.md)
-  - [C# и MySQL](#тема-514-c-и-mysql)
-    + [Создание подключения к БД MySQL. Получение данных с сервера.](./articles/cs_mysql_connection3.md)
-    + [Вывод данных согласно макету (ListBox, Image). Вывод данных плиткой.](./articles/cs_layout2.md)
-    + [Пагинация, сортировка, фильтрация, поиск](./articles/cs_pagination2.md)<!-- datepicker -->
-    + [Подсветка элементов по условию. Массовая смена цены продукции.](./articles/cs_coloring2.md)
-    + [Создание, изменение, удаление продукции](./articles/cs_edit_product2.md)
-    + [Вывод списка материалов продукта. CRUD материалов продукта](./articles/cs_product_material.md)
-  - [Разработка API](#тема-515-разработка-своего-api)
-    + [API. REST API. Создание сервера ASP.NET Core. Swagger.](./articles/api_asp_net_core.md)
-    + [Авторизация и аутентификация. Методы авторизации. Basic-авторизация.](./articles/api_auth.md)
-    + [HTTP запросы в C#. Получение списка материалов выбранного продукта](./articles/cs_http.md)
-
-* [МДК. 05.02 Разработка кода ИС](#мдк-0502-разработка-кода-информационных-систем)
-
-<!-- ПООП
+ПООП
 
 Тема 5.2.1. (48 + 26) Основные инструменты для создания, исполнения и управления информационной системой
 
@@ -158,15 +121,54 @@ http://sergeyteplyakov.blogspot.com/2014/01/microsoft-fakes-state-verification.h
 
 -->
 
-* [МДК. 05.03 Тестирование информационных систем](#мдк-0503-тестирование-информационных-систем)
+* [МДК 05.02. Разработка кода ИС](#мдк-0502-разработка-кода-информационных-систем)
 
-# МДК. 05.01 Проектирование и дизайн информационных систем
+  - [Основы проектирования информационных систем](#основы-проектирования-информационных-систем)
+  
+    + [Основные понятия и определения ИС.](./articles/5_1_1_1_intro2.md)
+    + [Анализ предметной области. Основные понятия системного и структурного анализа.](./articles/5_1_1_4_analiz.md)
+    + [UML](./articles/uml.md)
+    + [Диаграмма вариантов использования (прецедентов, use case)](./articles/5_1_1_10_uml_use_case.md)
+    + [Спецификация вариантов использования (прецедентов)](./articles/5_1_1_10_uml_uc_spec.md)
+    + [Диаграмма состояний](./articles/uml_state.md)
+    + [Прототипы экранов и окон пользовательского интерфейса (wireframe)](./articles/wireframe.md)
+    + [Диаграммы взаимодействия (последовательности и коммуникации)](./articles/uml_sequence.md)
+    + [Диаграмма деятельности](./articles/uml_activity.md) недописана 
+    + [Диаграмма классов](./articles/uml_class_alt.md)
 
-## Тема 5.1.1. Основы проектирования информационных систем
+  - [Проектирование баз данных](#тема-512-проектирование-баз-данных)
 
-<!-- https://sites.google.com/site/anisimovkhv/learning/pris/lecture -->
+    + [Основы проектирования баз данных.](./articles/5_1_1_1_erd2.md)
+    + [Словарь данных](./articles/5_1_1_1_data_dictionary.md)
+    + [Создание ER-диаграммы](./articles/5_1_1_1_erd_workbench.md)
+    + [Основы SQL](./articles/sql_for_beginner.md)
+    + [Создание базы данных. Импорт данных.](./articles/sql_import.md)
+    + [Импорт данных (вариант 22).](./articles/sql_import_22.md)
+    + [Представления (View)](./articles/sql_view.md)
+    + [Хранимые процедуры. Триггеры.](./articles/sql_trigger.md)
+
+  - [C# и MySQL](#тема-514-c-и-mysql)
 
-### Лекции
+    + [Создание подключения к БД MySQL. Получение данных с сервера.](./articles/cs_mysql_connection3.md)
+    + [Вывод данных согласно макету (ListBox, Image). Вывод данных плиткой.](./articles/cs_layout2.md)
+    + [Пагинация, сортировка, фильтрация, поиск](./articles/cs_pagination2.md)<!-- datepicker -->
+    + [Подсветка элементов по условию. Массовая смена цены продукции.](./articles/cs_coloring2.md)
+    + [Создание, изменение, удаление продукции](./articles/cs_edit_product2.md)
+    + [Вывод списка материалов продукта. CRUD материалов продукта](./articles/cs_product_material.md)
+
+  - [Разработка API](#тема-515-разработка-своего-api)
+
+    + [API. REST API. Создание сервера ASP.NET Core. Swagger.](./articles/api_asp_net_core.md)
+    + [Авторизация и аутентификация. Методы авторизации. Basic-авторизация.](./articles/api_auth.md)
+    + [HTTP запросы в C#. Получение списка материалов выбранного продукта](./articles/cs_http.md)
+
+* [МДК 05.03. Тестирование информационных систем](#мдк-0503-тестирование-информационных-систем)
+
+## МДК. 05.02 Разработка кода информационных систем
+
+### Основы проектирования информационных систем
+
+<!-- https://sites.google.com/site/anisimovkhv/learning/pris/lecture -->
 
 <!-- TODO расковырять "практику и методику..." из доки -->
 
@@ -216,15 +218,15 @@ http://sergeyteplyakov.blogspot.com/2014/01/microsoft-fakes-state-verification.h
 
 1. [~~Основные процессы управления проектом. Средства управления проектами~~](articles/5_1_1_13.md)
 
-### Контрольные вопросы
+---
+
+**Контрольные вопросы**
 
 * назовите основные элементы диаграммы прецедентов
 * Что такое **данные**?
 * Что такое **информационная система**?
 
-## Тема 5.1.2. Проектирование баз данных
-
-### Лекции
+### Проектирование баз данных
 
 1. [Основы проектирования баз данных.](articles/5_1_1_1_erd2.md)
 
@@ -249,14 +251,18 @@ https://office-menu.ru/uroki-sql Уроки SQL
 - count и функции работы со временем (between)  
 -->
 
-### Контрольные вопросы
+---
+
+**Контрольные вопросы**
 
 * Что такое **домен**?
 * Что входит в классическую ER-диаграмму?
 * Какие виды **ключей** Вы знаете?
 * Назовите этапы проектирования БД.
 
-### Лабораторные
+---
+
+**Лабораторные**
 
 1. [Подключение к базе данных. Создание скрипта создания БД.](./articles/sql_create_db.md)
 
@@ -327,7 +333,7 @@ https://office-menu.ru/uroki-sql Уроки SQL
 
 </details>
 
-## Тема 5.1.4. C# и MySQL.
+### C# и MySQL.
 
 1. [Создание подключения к БД MySQL. Получение данных с сервера.](./articles/cs_mysql_connection3.md)
 
@@ -341,7 +347,7 @@ https://office-menu.ru/uroki-sql Уроки SQL
 
 1. [Вывод списка материалов продукта. CRUD материалов продукта](./articles/cs_product_material.md)
 
-## Тема 5.1.5. Разработка своего API.
+### Разработка своего API.
 
 1. [API. REST API. Создание сервера ASP.NET Core. Swagger.](./articles/api_asp_net_core.md)
 
@@ -350,17 +356,11 @@ https://office-menu.ru/uroki-sql Уроки SQL
 1. [HTTP запросы в C#. Получение списка материалов выбранного продукта](./articles/cs_http.md)
 
 <!-- TODO 
-  авторизация
-  
+  окно авторизации c#
 -->
 
 <!-- 1. [C# Параллельное программирование и асинхронность](./articles/cs_async_await.md) -->
 
-<!-- 1. [ASP NET Web API (Метанит)](https://metanit.com/sharp/aspnet_webapi/1.1.php)
-1. [ASP NET Core (Метанит)](https://metanit.com/sharp/aspnet6/2.11.php) -->
-
-
-
 <!-- ## Тема 6. Разбор заданий предыдущих лет.
 
 ### Задание регионального чемпионата 2021 года
@@ -425,13 +425,13 @@ https://office-menu.ru/uroki-sql Уроки SQL
 
 -->
 
-## Документация
+### Документирование ИС
 
 1. [Руководство пользователя](./articles/user_manual.md)
 
-# МДК. 05.02 Разработка кода информационных систем
+## Практика №1, разработка мобильных приложений
 
-## Тема 5.1.4. Разработка мобильных приложений. Android Studio. Kotlin.
+### Разработка мобильных приложений. Android Studio. Kotlin.
 
 1. [Основы языка Kotlin](./articles/kotlin.md)
 
@@ -483,11 +483,10 @@ tablayout
 
 -->
 
-# МДК. 05.03 Тестирование информационных систем
+## МДК 05.03. Тестирование информационных систем
 
-## Тема 5.3.1 Отладка и тестирование информационных систем
+### Отладка и тестирование информационных систем
 
-### Лекции
 
 1. [Тестирование и тестировщики](articles/5_3_1_1_intro.md)<!-- тут_ещё_вспомнаем_про_библиотеку_классов -->
 
@@ -501,7 +500,6 @@ tablayout
 
 1. [Обработка исключительных ситуаций. Методы и способы идентификации сбоев и ошибок.](articles/5_3_1_6_exceptions.md)
 
-
 1. Выявление ошибок системных компонентов (по ФГОС, но не представляю что давать)
 
 1. [Реинжиниринг бизнес-процессов в информационных системах.](articles/5_3_1_8_reengeniring.md)
@@ -512,7 +510,9 @@ tablayout
 
 1. [Fake data. Тестирование методов получающих внешние данные из удалённых источников](./articles/fake_unit_test.md)
 
-### Лабораторнo-практические работы
+---
+
+**Лабораторнo-практические работы**
 
 1. [Создание проекта по индивидуальному заданию. Разработка Unit-тестов для проекта](./articles/5_3_1_10_unit_test_lab.md)
 1. Лабораторная работа «Разработка тестового сценария проекта»
@@ -527,9 +527,10 @@ tablayout
 10. Лабораторная работа «Тестирование установки»
 
 
-# [Учебная практика](articles/praktika_I.md)
+## Практика №2, разработка web-приложений
+<!-- (articles/praktika_I.md) -->
 
-# [Курсовой проект](articles/kp2.md)
+## [Курсовой проект (ПМ 06)](articles/kp2.md)
 
 <!-- 
 -- разрешение пользователю создавать базы