Logistics_Analyzer новая функция и изменения
Продолжаем серию публикаций о разработке программы. Предыдущие статьи можно найти здесь. Разработка логистической программы
На прошлой неделе я не внес значительных изменений. Однако я всё же успел реализовать несколько важных задач.
Типы транспорта
Ранее я уже говорил о необходимости добавить типы транспорта для более точного расчёта закрытия объекта. Это также пригодится в будущих анализах.
К сожалению, в тулбаре теперь отображается на один объект больше. Но, к счастью, тулбар анимирован, поэтому место для новых элементов ещё есть.
Нажимая на "Транспорт" открывается диалоговое окно, которое показывает полный список созданных типов транспорта и их вместимость.
Пользователь может:
Создать новый тип
Редактировать
Удалить
Окна создания и редактирования между собой похожи
При создании записи с данными в SQLite каждый пользователь, работающий с исходным файлом, видит изменения в своём интерфейсе.
Пользователь также может привязать типы транспорта к региону с уникальной ценой за трак. Важно понимать, что цена за трак не всегда отражает реальную стоимость перевозки. Существует KPI по проценту утилизации трака, который показывает, насколько эффективно используется транспорт.
В транспортной и складской логистике успешная транспортировка считается, когда процент утилизации трак стремится к 100%. Однако это редкое явление, так как часто перевозят воздух в коробках, а упаковка, например, стрейч, также влияет на утилизацию. Если же транспортировка осуществляется паллетами, то процент утилизации обычно ниже 85%.
С учётом этих факторов мы рассчитываем реальную стоимость перевозки. Например, трак объёмом 70 кубических метров стоит 300 тысяч рублей, а его утилизация составляет 90%. В этом случае перевозка одного кубического метра в среднем будет стоить 4,7 тысячи рублей. Различные цены на разные автомобили позволяют нам получить разные средние цены перевозки 1 кубического метра.
Как это работает. Пользователь выбирает склад, нажимает «Рисовать регион» и обводит на карте зону доставки. Затем он указывает типы автомобилей, которые могут использоваться для перевозки, и среднюю стоимость доставки одного кубического метра.
Эти данные попадают в расчёты «Анализ закрытия» и «Анализ открытия» (начал его разрабатывать).
Мы понимаем, что машина может следовать по рейсу, поэтому в отчёте программа автоматически рассчитывает рейсы. Но возникает вопрос: что делать, если машина утилизирована не полностью? Например, если товары для магазинов А и В попали в один маршрут, но их хватило только на 70% утилизации?
На этот случай тоже есть решение. Логика учитывает ближайшие объекты и дополняет рейс товарами для них. Если объём отгрузки небольшой, программа определяет оптимальный тип транспорта. В итоге мы получаем более-менее верное решение.
Данную логику сидел, проверял вручную в EXCEL и с помощью обычной карты. Попадание в 97% точности. Где-то не учла верность перераспределения и тем самым занизила на 3% стоимость перевозок. Но 3% (а вообще до 5%) в рамках погрешности, поэтому можно сказать что "Успех".
Доработка с транспортом - не сама тяжелая, она отняла у меня буквально 3 вечера.
Декомпозиция старого кода
Когда начинал писать программу, особо еще не знал правильность. Был такой юношеский максимализм. Писал огромные модули в одном файле, вследствие чего те же «Дашборды» разрослись на 5 файлов по 4к строк кода в каждом.
Сидел на прошлой неделе и думал: «Надо добавить пару новых графиков, а как делать-то? Я уже не помню этот код, куча вызовов, да и он больше на монолит похож». Пытался добавить спарку «График + гистограмма» — получил ошибку методов, начал ковырять глубже — так вообще пришлось откат из репозитория делать.
Новая структура выглядит более удобной, и можно вносить изменения с минимальными правками:
Для сравнения вот старая модель:
Это был настоящий кошмар. Стили, логика и подключения были объединены в один файл. Оркестратор "Менеджер" тоже содержал много лишнего..
UI — это то, что мы видим на экране. При любом взаимодействии с интерфейсом система вызывает посредника, который отправляет сигнал в логику. Логика получает сигнал и решает, нужно ли ей работать с хранилищем. Если да, она собирает данные и отправляет их обратно посреднику. Посредник проверяет, нет ли ошибок, и передает данные в UI, который их отображает.
Такая структура позволяет легко и быстро вносить изменения. Новые стили, графики, страницы и меню можно добавить за один вечер, не нарушая логику работы всей системы.
В целом вообще сейчас стараюсь переписывать часть старого кода, с опытом многое понял про правильность и оптимизацию. Старые методы которые я писал с кучей подключений на 200-300 строк, получается сократить до 100-150. Первое - много принтов для логирования (часть убрал), второе - лишние проверки переменных. Добавлял на случай "Что бы на верняка".
Анализ открытия
Вечером пятницы сидел и понимал что пора развивать новый отчет. В начале набросал UI составляющую сотканную из заглушек.
На скриншоте выше - это только концепт-макет.
Накидал быстро файловую структуру которая будет для данного анализа.
По структуре видно что планируются такие логики как "Каннибализации". Это когда объект может забрать часть продажи у другого объекта
ROI с учетом всяких вводных типа "ФОТ, Аренда, опексы, стоимость транспортировки товара на магазин". Так как программа для компаний с большой историей, то и считать она будет исторические данные для точки. Например ближайшие магазины и какие продажи, какие тут были доставки и тп. Исходя из этого, строится предполагаемая модель продаж, выручка, считаются долгосрочные вложение и получаем сколько надо месяцев на окупаемость магазина.
Продуктовая матрица - как раз в ROI частично описал. Смотрим ближайшие магазины, смотрим что уходило в эту зону на доставку, считаем ABC, смотрит запас товара в регионе - формируем матрицу.
Логистическая карта - обратная функция от закрытия. Как измениться зона курьерских доставок и времени если именно тут открыть магазин.
И т.д.
Сейчас даже не знаю сколько потребуется времени на реализацию всей задумки. Пока что закладываю месяц на стартовый отчет и еще недели 2 на правки. Но впереди праздники, возможно стоит приступить к этому после Нового Года, а до этого момента исправить старые недочеты.
Как обычно, всем спасибо за прочтение. Если есть какие-то идеи, предложения по улучшению UI или логики программы - пишите, буду рад принять что-то новое!😊
Следующие новости - после праздников. Всех с Наступающим Новым Годом!☃️











Программирование на python
934 поста11.9K подписчика
Правила сообщества
Публиковать могут пользователи с любым рейтингом. Однако!
Приветствуется:
• уважение к читателям и авторам
• конструктивность комментариев
• простота и информативность повествования
• тег python2 или python3, если актуально
• код публиковать в виде цитаты, либо ссылкой на специализированный сайт
Не рекомендуется:
• допускать оскорбления и провокации
• распространять вредоносное ПО
• просить решить вашу полноценную задачу за вас
• нарушать правила Пикабу