УДК 004.415.2
Разработка программного обеспечения для мониторинга популяции попугаев
Чижов Александр Дмитриевич – студент кафедры вычислительной техники Новосибирского государственного технического университета
Аннотация: В статье рассматривается проектирование и разработка программного обеспечения для мониторинга популяции попугаев. Представлены введение в предметную область, сравнительный анализ существующих решений, бизнес-анализ проекта, системная аналитика (в т.ч. требования к проекту), проектирование и реализация приложения.
Ключевые слова: клуб, заводчик, приложение, пользователь, кольцевание.
Сегодня в России существует проблема дефицита решений для контроля за популяцией птиц, находящихся в негосударственном владении. В Европе имеется множество клубов, позволяющих решать данную проблему.
Клуб позволяет решать биологическую проблему сохранения разнообразия редких видов птиц, в том числе: защитить животное от потери или кражи (кольцевание), предостеречь близкородственное скрещивание (генеалогическое дерево), исключить частые ошибки в содержании животных (просвещение – блог). Участниками подобных клубов могут быть не только хозяева птиц, но и заводчики, а также ученые и ветеринарные врачи, занимающиеся исследованием попугаев.
Согласно опросу Всероссийского центра изучения общественного мнения от 2020 года 3% населения России содержит декоративных птиц. То есть, около 4,5 млн человек являются обладателями попугаев. Каждый человек из указанных может стать потенциальным участником клуба.
На текущий момент в России нет продукта для мониторинга популяции попугаев, который мог бы конкурировать с европейскими аналогами по своим функциональным возможностям. Подобное решение станет новым витком развития программного обеспечения в этой сфере.
Сравнительный анализ существующих средств мониторинга популяции попугаев
Сравнение интернет-ресурсов производится по ряду показателей, каждый из которых оценивается от 0 до 2 баллов, где 0 – неудовлетворительный уровень показателя, 1 – удовлетворительный и 2 – высокий уровень.
Было выбрано по три отечественных (1 – Российское общество любителей волнистых попугаев [1], 2 – Московский клуб любителей певчих и экзотических птиц [2], 3 – Московский клуб «Русская канарейка» [3]) и зарубежных (4 – British Bird Council [4], 5 – International Ornithological Association [5], 6 – Federación Ornitológica Argentina [6]) ресурса. В таблицу 1 сведены результаты сравнения.
Таблица 1. Результаты сравнительного анализа.
Показатель сравнения |
Номер интернет-ресурса |
|||||
1 |
2 |
3 |
4 |
5 |
6 |
|
Информативность |
1 |
2 |
2 |
2 |
2 |
2 |
Визуальная составляющая |
0 |
1 |
0 |
2 |
2 |
2 |
Обратная связь |
0 |
2 |
1 |
1 |
1 |
2 |
Дополнительный функционал |
0 |
2 |
1 |
1 |
2 |
2 |
Общий балл |
1 |
7 |
4 |
6 |
7 |
8 |
Можем заметить, что функционал только одного российского ресурса схож с зарубежными аналогами, однако уступает им в некотором областях (нет реализации интернет-магазина сопутствующей продукции для разведения птиц). Главной задачей подобных сервисов является кольцевание птиц, однако отечественные клубы не предоставляют такой возможности. Зарубежные аналоги имеют хороший уровень развития ПО, вследствие чего и пользуются большой популярностью.
Несмотря на наличие положительных черт, российские средства контроля за популяцией попугаев сильно уступают в функционале. Что говорит о необходимости подобного продукта соответствующего уровня развития.
На рисунке 1 представлена диаграмма прецедентов веб-приложения.
Рисунок 1. Диаграмма прецедентов.
Иерархический список требований к проекту
Система должна содержать следующую информацию: новостную ленту; интернет-магазин с продажей сертифицированных колец; блог – небольшие статьи о птицах; страницу с автоматической расшифровкой кольца; страницу для поиска информации о птице.
Система должна предоставлять следующие возможности:
- регистрация новых пользователей – заводчика (член клуба) и владельца. Для аккаунта с правами доступа «заводчик» доступен следующий функционал: заполнение личной информации о заводчике, регистрация новой птицы в единой базе клуба, форма, позволяющая получить правильную маркировку птицы и другое;
- при продаже попугая заводчик или прежний владелец передает «права на владение» в анкете на птицу новому владельцу;
- зарегистрированные пользователи получают возможность просмотра генеалогического древа птицы;
- владелец просматривает список птиц, принадлежащих ему;
- админ-панель необходимая для управления сайтом (интернет-магазин, блог, новости, поддержка актуальной информации и др.). Аккаунт менеджера связан только с деятельностью интернет-магазина.
Требования к графическому интерфейсу: необходимо обеспечить пользователю графический интерфейс для взаимодействия с объектами системы; реализовать систему в виде одностраничного веб-приложения; оформить блоки страницы веб-сайта в едином стиле.
Требования к базе данных: при проектировании реляционной базы данных необходимо помнить об эффективности структуры БД.
Стек технологий и инструментов
Для разработки WEB-приложения по мониторингу популяции попугаев был определен стек технологий и используемых инструментов. Среда разработки: WebStorm; язык программирования серверной части: Python; серверный фреймворк: Django; язык программирования клиентской части: JavaScript; клиентский фреймворк: Vue.js; СУБД: PostgreSQL; графический редактор: Figma.
Проектирование
На рисунке 2 приведена диаграмма состояний WEB-приложения.
Рисунок 2. Диаграмма состояний.
Выделяются 12 сущностей: заказ, товары в заказе, корзина, пользователь, товар, адреса, птицы, статьи, новости, оценка статьи/новости/продукта. В каждой из таблиц будут храниться все данные о сущностях (описание таблиц сведено в таблицу 2).
Таблица 2. Таблицы базы данных.
Название таблиц |
Описание |
OrderProduct |
Таблица содержит информацию о товарах в заказе |
OnlineOrder |
Таблица содержит информацию о деталях заказа |
Cart |
Таблица содержит данные о корзине пользователя |
Account |
Таблица содержит данные пользователя |
Address |
Таблица содержит адреса пользователей |
Bird |
Таблица содержит информацию о животном |
Product |
Таблица содержит информацию о товарах магазина |
Article |
Таблица содержит статьи |
News |
Таблица содержит новости |
StarProduct, StarNews, StarArticle |
Таблицы содержат оценки пользователей |
На рисунке 3 приведена схема БД, содержащая информацию о связях таблиц, атрибутах таблиц и их типах, первичных ключах.
Рисунок 3. Схема базы данных.
Серверная часть приложения
Описание ORM. В качестве примера приведем фрагмент кода модели Bird. Модель Bird хранит в себе информацию о птице.
1: class Bird(models.Model): 2: id = models.AutoField(primary_key=True) 3: user = models.ForeignKey(Account, on_delete=models.CASCADE) 4: number = models.CharField(max_length=64, null=True) 5: name = models.CharField(max_length=256, null=True) 6: date_of_birth = models.DateField(null=True) 7: parent1 = models.CharField(max_length=64, null=True) 8: parent2 = models.CharField(max_length=64, null=True) 9: GENDER_BIRD = ( 10: ('Male', 'Male'), 11: ('Female', 'Female'), 12: ('None', 'None'), 13: ) 14: gender = models.CharField(max_length=6, choices=GENDER_BIRD) |
Сериализация данных. Сериалайзеры данных позволяют адаптировать модель данных для отображения клиенту и наоборот. В приведенном фрагменте демонстрируется типовая схема сериализатора данных.
1: class BirdSerializer(serializers.ModelSerializer):2: class Meta:3: model = Bird4: fields = ('id', 'user', 'number', 'name', 'date_of_birth', 'parent1', 'parent2', 'gender') |
Типовая схема HTTP запросов. Для работы с данными используется четыре типа HTTP запроса: get, post, put, delete. Все обработчики запросов для работы с данными действуют по одному сценарию.
Диспетчер URL. В корневой папке проекта находится файл urls.py, он ссылается на файлы urls.py, хранящиеся в каждом из четырех модулей. Ниже приведены фрагменты кода корневого файла urls и одного из urls модулей.
1: urlpatterns = [2: path('admin/', admin.site.urls),3: path('', include('Core.urls')),4: path('', include('Shop.urls')),5: path('', include('News.urls')),6: path('', include('Article.urls')),7: ] |
1: urlpatterns = [2: path('news', views.newsApi),3: path('news/<int:section>', views.newsApi),4: 5: path('news/savefile', views.SaveFile),6: 7: path('news/<slug:section>', views.newsApi),8: 9: path('starnews', views.starnewsApi), 10: path('starnews/<int:section>', views.starnewsApi),11: ]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) |
Клиентская часть приложения
Компоненты. Компонентами являются отдельные фрагменты приложения, которые могут быть использованы на любой из страниц приложения. В данном случае таких компонента только два: my_nav и my_footer.
Маршрутизация (router). В приложении используется два типа маршрутизации статическая и динамическая. Статической являются страницы с постоянными данными, к примеру домашняя страница, страница пользователя и тд. В то время как динамические страницы необходимы для страниц с постоянно меняющимися данными, например страница открытого товара интернет-магазина или же страница статьи, новости. Ниже приведен фрагмент маршрутизации для каждого из видов.
1: const routes = [2: 3: {4: path: '/',5: name: 'home',6: component: () => import('../views/Home.vue')7: },8: 9: {10: path: '/open_news/:id',11: name: 'open_news',12: component: () => import('../views/Open_news.vue')13: },14: ]15: const router = createRouter({16: history: createWebHistory(process.env.BASE_URL),17: Routes18: })19: export default router |
Хранилище состояний (VUEX). Для каждой сущности, хранимой в БД, был создан отдельный модуль в хранилище состояний VUEX. Хранилище состоит из: state – непосредственно данных, getters – функций для получения данных из state вне хранилища, mutations – изменения данных хранилища и actions – получения данных из БД. Ниже приведен пример хранилища для сущности Bird и код для подключения этого модуля к VUEX
1: import axios from "axios";2: import {variables_url} from '@/URLs'3: 4: export default {5: state: {6: bird: []7: },8: getters: {9: ALL_BIRD: state => state.bird10: },11: mutations: {12: SET_BIRD: (state, bird) => state.bird = bird,13: NEW_BIRD: (state, bird) => state.bird.unshift(bird),14: UPD_BIRD: (state, new_bird) => {15: const index = state.bird.findIndex(t => {return t.id === Number(new_bird.id)})16: if (index !== -1){17: state.bird.splice(index, 1, new_bird);18: }19: },20: REMOVE_BIRD: (state, id) => {21: state.bird = state.bird.filter(t => {return t.id !== id} ) }22: },23: actions: {24: async GET_BIRD_ID({ commit }, bird_id) {25: commit('SET_BIRD', (await axios.get(`${variables_url.API_URL}bird/${bird_id}`)).data);26: },27: async GET_BIRD({ commit, getters }, tree) {28: if (getters.GET_AUTH === 4 || tree === true){29: commit('SET_BIRD', (await axios.get(`${variables_url.API_URL}bird/tree`)).data);30: }else{31: commit('SET_BIRD', (await axios.get(`${variables_url.API_URL}bird/user/${getters.GET_ID}`)).data); }32: },33: async POST_BIRD({ commit }, bird) {34: commit('NEW_BIRD', (await axios.post(`${variables_url.API_URL}bird`, bird)).data);35: },36: async PUT_BIRD({ commit }, bird) {37: commit('UPD_BIRD', (await axios.put(`${variables_url.API_URL}bird`, bird)).data);38: },39: async DEL_BIRD({ commit }, bird) {40: commit('REMOVE_BIRD', (await axios.delete(`${variables_url.API_URL}bird/${bird.id}`)).data);41: }42: },43: } |
1: import { createStore } from 'vuex'2: import bird from "@/store/modules/bird";3: 4: export default createStore({5: modules: {6: bird,7: }8: }) |
Дополнительный функционал. Важной особенностью приложения является построение генеалогического древа. Специальная функция (приведена ниже) на основе введённого номера птицы выдает обычный html список и с помощью css список приобретает вид дерева.
1: function toHTML(bird_list, number) {2: const result = bird_list.find(e => e.number == number);3: if (result) {4: let out = "<li>" + result.number, get_res;5: if (result.parent1 || result.parent2) {6: out += "<ul>";7: if (result.parent1) {8: get_res = toHTML(bird_list, result.parent1);9: if (typeof get_res != 'undefined')10: out += get_res;11: Else12: out += "<li>" + result.parent1 + "</li>";13: }14: if (result.parent2) {15: get_res = toHTML(bird_list, result.parent2);16: if (typeof get_res != 'undefined')17: out += get_res;18: Else19: out += "<li>" + result.parent2 + "</li>";20: }21: out += "</ul>";22: }23: out += "</li>";24: return out;25: }26: } |
Для работы с оценками по пятизвездочной шкале использовался шаблон vue-star-rating. В фрагменте кода изображено подключение модуля непосредственно в html код.
1: <star-rating v-if="GET_AUTH === 0" :read-only="true" class="prod_text" :rating="star1" @update:rating="setRating" :star-size="20"></star-rating>2: <star-rating v-else class="prod_text" :rating="star1" @update:rating="setRating" :star-size="20"></star-rating> |
Для оценки предусмотрены следующие свойства: если пользователь не авторизован, то он видит среднюю оценку и не может на нее влиять; если пользователь авторизован, но не ставил ранее оценку, то он может ее поставить (изначально отображается средняя величина); для авторизованного и поставившего оценку пользователя в следующий раз будет отображаться поставленная им оценка.
При загрузке страницы срабатывает следующий фрагмент для определения текущего рейтинга
1: star: function (){2: const tmp = this.ALL_STARPRODUCT.filter(t => t.user === this.GET_ID)3: if (tmp[0]?.user > -1)4: return tmp[0]?.evaluation5: else {6: let sum = 0;7: for(const item in this.ALL_STARPRODUCT)8: sum += this.ALL_STARPRODUCT[item].evaluation;9: if (Object.keys(this.ALL_STARPRODUCT).length === 0)10: return 011: Else12: return sum / Object.keys(this.ALL_STARPRODUCT).length;13: }14: }, |
При нажатии на шкалу оценивания срабатывает следующий фрагмент кода.
1: setRating(star){2: const tmp = this.ALL_STARPRODUCT.filter(t => t.user === this.GET_ID)3: if (tmp[0]?.user > -1)4: this.PUT_STARPRODUCT({5: id: tmp[0]?.id,6: user: this.GET_ID,7: product: this.$route.params.id,8: evaluation: star,9: })10: else{11: this.POST_STARPRODUCT({12: user: this.GET_ID,13: product: this.$route.params.id,14: evaluation: star,15: })16: }17: }, |
Для страницы смены пользователя птицы существует ряд условий. Передаваемый пользователь нажимает на кнопку сгенерировать и получает специальный код. Фрагмент кода для генерации ключа приведен ниже.
1: generate_code(){2: const bird = this.ALL_BIRD.filter(t => t.number === this.number);3: const exch = this.ALL_EXCHANGE.filter(t => t.bird === bird[0]?.id);4: if(bird[0]?.user > -1) {5: for(const item in exch)6: if (exch[item].status === 'Active') {7: this.get_code = exch[item].code;8: Return }9: this.get_code = uniqid()10: this.POST_EXCHANGE({11: user_former: this.GET_ID,12: bird: bird[0]?.id,13: code: this.get_code,14: status: "Active",15: })16: }17: }, |
Отправитель может отменить передачу прав, нажав на специальную кнопку. Нижеприведенный фрагмент кода демонстрирует функцию, отрабатываемую при нажатии на кнопку отмены.
1: cancellation(){2: const bird = this.ALL_BIRD.filter(t => t.number === this.number);3: const exch = this.ALL_EXCHANGE.filter(t => t.bird === bird[0]?.id);4: if(bird[0]?.user > -1)5: for(const item in exch)6: if (exch[item].status === 'Active')7: this.PUT_EXCHANGE({8: id: Number(exch[item].id),9: user_former: this.GET_ID,10: bird: bird[0]?.id,11: code: this.get_code,12: status: "Canceled",13: })14: this.get_code = "";15: this.number = "";16: }, |
Получатель же, вставляя этот код в специальное поле, принимает права на птицу.
1: add() {2: const exch = this.ALL_EXCHANGE.filter(t => t.code === this.set_code);3: console.log(exch)4: if (exch.length === 0 || this.set_code === "")5: Return6: const bird = this.ALL_BIRD.filter(t => t.id === exch[0]?.bird);7: this.POST_BIRD({8: user: this.GET_ID,9: number: bird[0]?.number,10: name: bird[0]?.name,11: date_of_birth: bird[0]?.date_of_birth,12: parent1: bird[0]?.parent1,13: parent2: bird[0]?.parent2,14: gender: bird[0]?.gender,15: })16: this.DEL_BIRD({17: id: Number(bird[0]?.id),18: })19: this.set_code = "";20: } |
Список литературы
- Российское общество любителей волнистых попугаев [Электронный ресурс] – 2023. Режим доступа: http://rbs.parrots.ru/ (дата обращения: 10.03.2023).
- Московский клуб любителей певчих и экзотических птиц [Электронный ресурс] – 2023. Режим доступа: http://mosbirdclub.ru/ (дата обращения: 10.03.2023).
- Московский клуб «Русская канарейка» [Электронный ресурс] – 2023. Режим доступа: http://canaria.msk.ru/kluby/moskovskij-klub-russkaya-kanarejka.html (дата обращения: 10.03.2023).
- British Bird Council [Электронный ресурс]– 2023. Режим доступа: https://www.britishbirdcouncil.com/ (дата обращения: 10.03.2023).
- International Ornithological Association [Электронный ресурс] – 2023. Режим доступа: https://www.ioa-com-uk.org/ (дата обращения: 10.03.2023).
- Federación Ornitológica Argentina [Электронный ресурс] – 2023. Режим доступа: http://ornitofoa.com.ar/ (дата обращения: 10.03.2023).