Изучаем Python за 6 месяцев. Подробный план обучения / Хабр | Веб-студия Nat.od.ua
Изучаем Python за 6 месяцев. Подробный план обучения / Хабр
Простой и красивый синтаксис, множество библиотек под самые разные задачи и большое комьюнити делают Python одним из самых популярных языков программирования на сегодняшний день, который активно используется в data science и машинном обучении, веб-разработке и прочих областях.
Когда я начал изучать питон, у меня возникло несколько вопросов:
какие темы необходимо изучить;
насколько это будет сложно;
сколько это займёт времени;
где найти хорошие источники информации?
Вкратце, на мой взгляд, необходимо знать следующие темы:
стандартные типы данных;
условия;
циклы;
функции;
основы алгоритмов;
объектно-ориентированное программирование (ООП);
конкурентность;
тестирование кода;
полезные библиотеки типа itertools, collections и тому подобное.
Если вы прежде не занимались программированием, то поначалу будет сложновато, но потом мозги «настроятся» в нужное русло и будет норм.
На этом преамбула окончена и переходим непосредственно к плану обучения.
Основы Python (3 месяца)
Советую начать с прочтения книги Билла Любановича «Простой Python. Современный стиль программирования» (второе издание) чтобы иметь представление о том, что такое программирование и как выглядит код на Python.
Далее переходим к курсам на платформе Stepik:
Очень хорошие курсы с морем задач.
После рекомендую посмотреть плейлист декораторы канала luchanos и для практики пройти на Stepik «Декораторы в Python»: часть 1 и часть 2.
Введение в алгоритмы (2 недели)
Вообще, о том, как шатать leetcode и проходить алгоритмические фиды на собесах, следует написать отдельную статью, поэтому пока обойдемся основами основ и здесь на сцену вступает небезызвестная книга Адитьи Бхаргавы «Грокаем алгоритмы».
У автора получилось сделать очень дружелюбное к новичкам пособие по алгоритмам – однозначно рекомендасьон.
Объектно-ориентированное программирование (3 недели)
Рекомендую плейлист Python OOP канала JimShapedCoding и курс Олега Молчанова по ООП – лучшее объяснение из всех, что я видел (курс как бы платный, но интернет – такая вещь, что….ну вы поняли).
Также параллельно с курсами было бы хорошо углубляться в пройденные темы и здесь мне понравилась книга «Object-oriented Python», Irv Kalb.
В отличие от курсов, в ней также уделяется внимание магическим методам и некоторым другим аспектам. Писать игры необязательно, как это делается в книге, но ознакомиться с ней стоит.
Для практики подойдет codewars. Когда получится решать 4-5 кату по ООП, то можно двигаться дальше.
Конкурентность (2 недели)
По основам многопроцессорности и многопоточности советую плейлист канала luchanos Конкурентность в Python.
По асинхронному программированию однозначно плейлист Олега Молчанова Асинхронность в Python и плейлист import asyncio: Learn Python’s Asyncio канала EdgeDB.
Для углубления переходим к книге Мэттью Флауэра «Asyncio и конкурентное программирование на Python».
Отсюда вы узнаете о выполнении конкурентных запросов к базам данных, сочетании многопоточной обработки с asyncio, управлении подпроцессами и многом другом.
Тестирование кода (1 неделя)
Уметь покрывать свой код тестами хотя бы на базовом уровне – точно не будет лишним и поэтому я предлагаю начать с просмотра плейлиста Pytest тестирование канала luchanos.
Для углубленного изучения есть неплохая книга «Python Testing with pytest» (second edition), Brian Okken, с которой стоит ознакомиться.
Больше продвинутых тем (3 недели)
В принципе, может показаться, что всего вышеперечисленного уже достаточно, но, на мой взгляд, для лучшего понимания как устроены функции и классы, как работает сборщик мусора, в чем отличие итераторов от генераторов, в каком случае лучше использовать асинхронность, а в каком многопоточность, как пользоваться библиотеками типа itertools, collections и т.д., еще необходимо немного углубиться, и в этом нам помогут 2 книги:
«Python – к вершинам мастерства» (второе издание), Лусиану Рамальо.
«Dead simple Python», Jason C. Mcdonald.
Книги плюс-минус об одном и том же, однако в последней некоторые темы рассматриваются на немного более поверхностном уровне. За счёт этого она читается легче.
Какую из них выбрать? Трудно ответить: лучше читать наиболее непонятные темы из обеих книг.
Best practices (1 неделя и больше)
После того, как вы уже научитесь немного писать код, неплохо бы научиться писать его красиво и в этом нам поможет книга «Effective Python. 90 specific ways to write Python better» (second edition), Brett Slatkin.
Солянка из лучших практик, показывающая как сделать код более лаконичным и эффективным с «питоновской» точки зрения.
Дополнительные источники
Ещё несколько полезных ссылок для изучения Python:
Что в итоге
Занимаясь по 10 часов в день, на изучение всех вышеперечисленных тем уйдёт около полугода – это цифры из собственного опыта, так что можно их брать в качестве ориентира.
Что дальше
Дальше можно смело двигаться в выбранное вами направление: будь то веб-разработка с Django и Flask или же машинное обучение с Numpy, Pandas, Pytorch и другими прелестями жизни – полученных знаний хватит за глаза.
Надеюсь, данный гайд оказался для вас полезным.
Всем успехов!
Как я 30 дней автообновление валюты чинил: Opencart 3.0 / Хабр | Веб-студия Nat.od.ua
Как я 30 дней автообновление валюты чинил: Opencart 3.0 / Хабр
Я новичок, совсем недавно начал изучать JavaScript, HTML, CSS и вот я web-администратор в офисе.
Все началось с обычного замечания на утренней планерке — генеральный директор сказал мне: «Видел? На сайте, сумма в рублях за доллар соответствует завтрашнему дню, а должна быть еще сегодняшняя!» Все товары, рекламные площадки, клиенты, заказы — все это завязано на валюте, которая обновляется на сутки раньше, чем должна.
И тут я понял что меня ждет очень сложная и почти не выполнимая задача. Ведь я совсем не секу в PHP и с Opencart только месяц как знаком. «Сделаю, конечно!», ответил я, не бить же в грязь лицом.
Как я с этим справился?
Опишу ситуацию как я её видел:
У меня есть интернет магазин, на Opencart 3 версии. Товары на нем отображаются как в рублях, так и в долларах. Каким-то волшебным, магическим образом, интернет магазин берет котировки валют и отображает на экране + записывает и подстраивает цены всех товаров под актуальный курс валют. Как это происходит еще предстояло узнать.
На сайте ЦБ РФ https://www.cbr.ru/ курс на следующий день известен уже в 14.00 ежедневно. И в моем интернет магазине, почему-то валюта обновляется в промежутке с 14.00 до 16.00 — это все что было мне известно.
Неделя №1 поиск и знакомство
Первое что я сделал, зашел на сайт, кликнул правой кнопкой просмотреть код и узнал какой класс отвечает за вывод валюты на экран.
Меню после клика правой кнопкой на элемент сайта
Далее начал шерстить по всем файлам, где только находил данный класс и пытался хоть что-нибудь понять. Файл за файлом я находил, открывал, искал, запоминал. Но кроме массива строк кода, не видел ничего. Ответов было 0.
Списки кода в котором сложно что то понять и разобраться с наскока
Позже, я нашел нужную мне функцию, но что с ней делать — не представлял даже. Так как я единственный разработчик в компании, мне не с кем было посоветоваться. Почему бы не написать в ЦБ РФ? По-моему отличная идея! Пишу — получаю примерно такой ответ: «Не понятно почему у Вас обновляется валюта раньше чем нужно, попробуйте вычесть из настоящего времени часы, чтобы подгадать обновление валюты» (с) разработчик ЦБ РФ
Нормально? Скинул мне ссылку на туториалы на сайте, про то как настраиваются XML запросы http://www.cbr.ru/development/sxml/
Следующие несколько дней я тестил собственные разработки. Создал новую переменную и присвоил ей значение (данный момент минус 7 часов)
кусочек функции где мы обращаемся к ЦБ РФ за XML форматом валют
А скрипты ЦБ РФ говорят, что бы получить конкретные котировки от определенной даты, то пожалуйста, запрашивайте по дате.
Один из примеров на сайте ЦБ РФ
Если скрипт http://www.cbr.ru/scripts/XML_daily.asp
Файл XML от ЦБ РФ с котировками валют
вызывает XML файл с валютами всего мира, то придерживаясь логики, я свою переменную добавляю в конец, вместо конкретной даты req=02/02/2000 и будет мне счастье. НО не тут то было.
Все это не сработало и никак не хотело чинить вывод валюты.
Неделя №2 обращение за помощью
Решил написать на форум, спросить мнения экспертов из интернета. В силу своей неопытности, я криво описал задачу и получал неправильные ответы на неправильные вопросы.
Почему-то я думал, что мне необходимо запускать функцию в определенное время и это решение показалось верным, но я пока не понимал какую же функцию и как запускать.
Совершенно наивно, без опыта и понимания о чем идет речь. Выудил на форуме помощь в виде составления функции и привязки ко времени, которую необходимо было поместить в некий файл помощник
Функция для определения времени
После необходимо было прописать новые условия в вызове в другом файле, что бы совместить все вместе
Функция проверки времени и вызова авто обновления
Добавляем функцию в условия проверки перед запуском
Применил
До 23.00 валюта не обновлялась и я думал что это победа, что вот-вот в 23.55.55 она обновится и я гордо расскажу о решении этой задачи!
Ничего не вышло
Утром пришлось откатывать все настройки назад. Потому что обновление не сработало вовсе. В этот момент я понял, что нужно начинать поиски заново.
Неделя №3 разгадка где-то рядом
Написал на хостинг администраторам. Что мне нужно запустить CRON задачу на файл. Но какой конкретно, я не знал. Поэтому пробовал всю неделю, просил хоста запустить на разные php файлы вызов.
CRON это планировщик заданий
Параллельно с тестированием настройки крона я стал активно изучать Opencart на просторах YouTube. Начал смотреть видео про MVC и как там все устроено в целом.
Например, теперь, мне понятно, что система ООП (объектно ориентированного программирования) в php для CMS системы Opencart строится по системе Model View Controller. Когда они обращаются друг к другу и взаимодействуют между собой.
Спасибо каналу «Opencart» там все доходчиво объясняется автором канала и показывается на примерах.
В самом конце 3 недели, примерно в пятницу, написал в комментариях на ютуб канале о своей проблеме с валютой и подумал, вдруг кто-то даст мне подходящий совет.
Комментарий — просьба о помощи
Оттуда я узнал, что на Opencart мы с помощью отключения ЧПУ (человеко подобного url) можем смотреть путь наших файлов в адресной строке.За счет этих знаний можем находить нужные нам файлы в проекте.
Код отвечающий за обновление
Новые знания, приобретенные с помощью ютуб канала и 3 недель мучений с валютой, помогли мне понять, что основную манипуляцию нужно проводить с данной проверкой.
Обращение по этой схеме идет к папке Model и если там есть функция refresh() то она вызывается и отправляет ответ в папку Controller, которая в свою очередь уже приказывает папке View отобразить новые данные для пользователя.
MVC модель для CMS OpencartНеделя №4 кто ищет тот всегда найдет
В понедельник утром, отчаявшись и окончательно запутавшись, я получаю видео ролик, на ютуб канале где писал просьбу о помощи. Это видео на 30 минут с пояснением как нужно подготовить файл и запустить его через CRON. Дабы выполнение скрипта авто обновления валюты работало строго как нужно мне.
Новые знания снова пришли ко мне в руки и я с удовольствием их впитал. Изучив все файлы, содержащие нужные мне 4 строчки кода, я понял, что обновление валюты запускается в 2-х случаях. Когда я или кто-то еще заходит на страницу админ панели в Opencart, некий dashboard. А второй момент, когда мы заходим в настройки в той же админ панели.
Как будто срабатывает кнопка обновить, при входе на данные страницы.
настройки -> локализация -> валюты
Так как все работает на взаимодействии MVC мне нужно было добавить новую функцию в файл по пути controller/common/home.php например
Как нужно было написать новую функцию что бы починить валютуинтерфейс CRON планировщика
И в середине 4 недели, проверив работоспособность данной схемы, я наконец смог выдохнуть и с гордостью заявить, что вопрос решен! Валюта обновляется в 12 ночи, как мне необходимо и ошибки перестали сыпаться.
Получается, валюта на сайт подтягивалась с сайта ЦБ РФ каждый раз, когда кто-то заходил в админ панель из менеджеров или я сам. Поэтому она и обновлялась с 14 до 16 часов вечера.
Пример с указанием отдельной переменной и привязке к времени не сработал, так как вызов функции происходит при заходе в админ панель и никак иначе.
Мы же с помощью CRON смогли добиться вызова этой функции, будто кто-то нажимает за нас кнопку «обновить»
Я закомментировал 2 вызова функции, чтобы не мешать работе скрипта, а галочку на авто обновление оставил включенной. Ведь по условиям скрипта, кнопка авто обновление — должна быть активна.
Да, я все еще junior с маленьким опытом, но я на верном пути и пусть медленно, но верно двигаюсь вперед. Еще тысячи задач ждут меня впереди. И я очень этому рад!
Как итог
Учите базу и узнавайте как работает движок и его нюансы, как например Opencart;
Учитесь читать чужой код, даже если не разбираетесь в синтаксисе, обращайтесь к дополнительным источникам за знаниями (Youtube, habr, stackoverflow);
Читайте про дополнительные помощники в вашей работе, CRON или что-либо еще;
Не бойтесь сложных задач, ведь только за счет них вы по настоящему растете
P.S.: Если у Вас похожая задача, но Вам сложно, пишите, помогу чем смогу.
«И швец и жнец» или обзор полезных расширений для XWiki / Хабр | Веб-студия Nat.od.ua
«И швец и жнец» или обзор полезных расширений для XWiki / Хабр
Вот уже второй год, как мы используем XWiki вместо Confluence.
За это время я к ней привык и даже в некотором роде полюбил. Поэтому не могу пройти мимо такого важного события как выход новой LTS версии 4.10.X.
Если вы не знакомы с релизным циклом XWiki, то вас может удивить, что LTS версия согласно выходит в конце года и в течение следующего года получает обновления. Иногда бывает, так, что обновления версии XWiki, что-то правит и одновременно что-то ломает, но в целом как обновление того стоит. Например, в 14 версии неплохо улучшили работу с вложениями, экспортом PDF и диалогом вставки изображений в редакторе.
Сегодня я не буду вдаваться в технические подробности, а просто сделаю беглый обзор функционала, рассчитанный в первую очередь на людей только что узнавших об XWiki. Обозревать мы будем самую последнюю на текущий момент версию 14.10.2 со Standard Flavor, установленную через Docker образ.
______________
Для начала оставлю ссылки на другие статьи цикла:
Теперь оглавление:
Введение
Если вы прочитали мою самую первую статью про XWiki, то уже знаете, что я при установке обычно рекомендовал выбрать Demo Flavor, Данный пакет подтягивал набор расширений, которые переносили пользователя вики “в мир роскоши и комфорта”. Фактически мы могли сделать простенький портал для управления проектом или проектной командой.
К сожалению, не так давно Demo Flavor перестал поддерживаться, а значит новые пользователи могут никогда не узнать о том, как из XWiki сделать блог, форум или даже таск-менеджер.
Но это не беда! Ведь сегодня мы посмотрим на несколько интересных расширений для XWiki, которые вы сможете легко установить в любой момент после завершения инсталляции. Просто введите название расширения в строку поиска менеджера расширений. Если ничего не нашлось, нажмите на кнопку “Все совместимые расширения”.
Расширения из пакета Demo flavorДобавляем Markdown
Расширение: CommonMark Markdown Syntax 1.2
На текущий момент, XWiki не совсем полноценно работает с Markdown (например, реализован не весь функционал таблиц), но в целом очень полезно иметь возможность работы с markdown, особенно если вы копируете тексты из других систем документирования.
Таск-менеджер
Прежде чем перейти непосредственно к расширению Task Manager Application, стоит сказать, что в Demo Flavor были пакеты для интеграцией с Jira:
JIRA Macro + JIRA Admin Application, с помощью которых можно подключиться к Jira и посмотреть последние обновления в проектах.
Но я ими почти не пользовался, поэтому перейдем к полноценному такс-менеджеру.
Расширение: Task Manager Application
Если вы очень не прихотливы в вопросах управления проекта или у вас небольшая команда, то возможно вам вполне хватит функционала этого расширения.
Можно создать проект, настроить статусы и приоритеты.
А потом завести и посмотреть задачи.
С помощью макроса, любую страницу можно превратить в Kanban доску
{{kanbanboard space=”TaskManager” /}}
Само собой решения от крупных производителей выглядят интереснее, но поскольку это open source вы всегда сможете допилить базовое расширение под свои нужды.
Файловый менеджер
Расширение: File Manager Application
Не то чтобы самое полезное приложение, но вдруг вам понадобится превратить Xwiki в хранилище файлов и папок.
Подсветка кода
Расширение: Syntax Highlighting Application
Повышает читаемость кода редактируемого в XWiki. Если вдруг не установится со Standard Flavor, то рекомендую поставить.
Блог
Расширение: Blog Application
Можно превратить вики в блог команды разработки или отдать на откуп отделу персонала, чтобы писали мотивирующие публикации.
Совещания и календарь
Для календаря и совещаний в Demo Flavor устанавливаются Meeting Manager Application (но оно слегка устарело) и Mocca Calendar Application.
Вы можете попробовать и другие приложения например, Meeting Application
Форум
Расширение: Forum Application
Если вы с начала нулевых ждали, 2023 чтобы стать админов на форуме и упиваться властью баня неугодных, то самое время взглянуть на Forum Application.
Обсуждение идей
Расширение: Ideas Application
Расширение для сбора идей, с возможностью проголосовать. Сейчас такое можно сделать в любом чате, но вдруг вы захотите, чтобы все процессы были только в XWiki.
P.S. На момент написания статьи у меня не работали кнопки голосования, может что-то криво встало.
Опросы
Расширение: XPoll Application
Расширение похоже на предыдущее, можем опросить пользователей вики.
Часто задаваемые вопросы
Расширение: FAQ Application
В принципе функционал можно реализовать с помощью обычных страниц, но и такое решение имеет право на жизнь.
Еще несколько интересных расширений
Если вы планируете использовать XWiki как портал для документации, то следующие приложения тоже могут быть полезны.
Диаграммы
Расширение: Diagram Application
Очень сильно устаревшая версия интеграции с draw.io. Тем не менее базовый функционал есть. Вы можете купить или изучить PRO версию приложения, она регулярно обновляется.
UML
Расширения: PlantUML Macro и PlantUML Administration
Первое расширение позволяет вставить plantUML код в страницу, а второе позволяет выбрать сервер для рендеринга.
Программирование
Расширение: PHP Macro и Python Macro
Позволяет обрабатывать PHP и Python код внутри страниц XWiki.
Формулы
Расширение: MathJax Macro
Рендеринг формул.
Заключение
Это далеко не полный список, расширений для XWiki. Еще можно найти много интересного функционала от построения графиков, до рендеринга гитарных аккордов.
А еще если приложить руки, то всегда можно написать свое приложение или модифицировать существующее.
Благодаря огромным возможностям по расширению функционала, на базе XWiki можно не только организовать сайт технической документацией, но и полноценный корпоративный портал для небольшой и непритязательной команды разработки.
Как из браузера открыть папку в проводнике Windows / Хабр | Веб-студия Nat.od.ua
Как из браузера открыть папку в проводнике Windows / Хабр
Представьте, что у вас возникла необходимость прямо с веб-страницы заказа в вашей CRM-системе открывать папку с файлами, которые к этому заказу относятся. Но не просто отображать содержимое папки, а прямо на компьютере открывать проводник с этой папкой.
К сожалению, сделать это «в лоб» не получится. Во-первых, браузеры умеют открывать только веб-страницы, а не программы на компьютере. Во-вторых, политика безопасности браузеров запрещает доступ ко всему, что явно не разрешено, тем более, доступ к файловой системе.
Вы можете резонно предположить, что есть протокол file:// (я позволю себе использовать здесь и далее слово протокол, хотя правильнее, конечно, схема URI), который позволяет браузерам открывать локальные файлы, но с ним также есть две проблемы:
1) он не может отобразить список файлов в папке;
2) такие ссылки нельзя открывать с внешних (не локальных) веб-страниц.
Чтобы решить данную проблему, мы будем использовать свой протокол с собственным обработчиком. Метод будет работать в Windows и потребует некоторых (очень простых) действий на компьютере.
В HTML-коде это будет выглядеть как-то так:
открыть папку
Можно из JavaScript:
window.open(“https://habr.com/ru/post/708760/myproto://C:/My Folder/123”);
Сначала необходимо придумать название протокола (у меня будет myproto) и зарегистрировать его в системе. Для этого в любом месте (хоть на рабочем столе) создаём файл с расширением .reg (например, myproto.reg) и следующим содержимым:
Windows Registry Editor Version 5.00
“URL Protocol”=””@=”URL:Myproto Protocol” @=””C:\myproto.bat” “%1″”
Здесь myproto — название моего только что созданного протокола. Можете изменить на своё (но не используйте стандартные названия протоколов типа http, ftp, mailto и прочие).
Запускаем файл. Винда выдаст несколько вопросов и предупреждений, со всеми соглашаемся. Всё, больше этот файл на этом компьютере не нужен, можно удалять.
Далее в корне диска C: необходимо создать файл myproto.bat со следующим содержимым:
@echo off
set “path=%~1”
setlocal enabledelayedexpansion
set path=%path:myproto://=%
set path=%path:”=%
set path=%path:/=%
set path=!path:%%20= !
set path=!path:%%5C=!
C:Windowsexplorer.exe “%path%”
Здесь также меняем myproto на название вашего протокола. Это и будет его обработчик.
Всё готово. Теперь вы можете прямо из браузера (абсолютно любого) на данном компьютере открывать папки в проводнике в отдельном окне, просто открыв ссылку вида myproto://C:/My Folder/123.
К сожалению, данные действия придётся проделать на всех компьютерах, где необходима такая функциональность. Но, как правило, подобные вещи используются во внутрикорпоративных приложениях, где число пользователей известно и ограничено.
Субъективные итоги года в мире Python / Хабр | Веб-студия Nat.od.ua
Субъективные итоги года в мире Python / Хабр
Привет, я Михаил Корнеев, вместе с Григорием Петровым и другими ребятами из сообщества мы ведем подкаст о Python на русском. В прошлую пятницу мы собрались в онлайне обсудить, что запомнилось в уходящем году.
Это — текстовая выжимка из выпуска. Если вам удобнее слушать и иногда смотреть, это можно сделать на ютубе. Если только слушать, подкаст также можно найти на популярных платформах: Apple Podcasts, Spotify, Яндекс.Музыка.
Есть тренд на ускорение Python, но
Гвидо ван Россум рассказал, что он с товарищами начал думать, как ускорить Python. В python 3.12 будет pre-JIT, в 3.13 будет более обширный JIT.
Но есть вопросики. Если втаскивать эти фичи по-взрослому, можно столкнуться с проблемами обратной совместимости. Едва ли сообщество и core-разработчики хотят повторения всей той драмы, которая была при переходе с двойки на тройку.
Еще одна часть тренда на ускорение — избавление от GIL. Но кажется проблема в том, что в этом направлении есть интересные эксперименты, но нет четкого плана внедрения.
Мы стали на шаг ближе к тому, чтобы уйти от GIL
30 лет назад, на заре Python, казалось, что не получится сделать высокоуровневый язык программирования с виртуальной машиной, в которой был бы быстрый garbage collector, который бы не тормозил многопоточность из-за синхронизации структур данных.
В конце 2021 года появился nogil — форк Python с системой мультитрединга, в которой получилось отказаться от GIL без потери производительности. Эта неофициальная имплементация показала, что задача решаема. Более того, на тестах для всяких околовеб историй прибавка производительности составляла 10-20%. Репозиторий оставался активен и в 2022, работа в нем ведется.
Много лет у Steering Council была примерно следующая позиция: если кто-нибудь принесет версию Python без GIL, которая будет работать не медленнее, чем текущая версия, то мы выпилим GIL. Конечно, просто так GIL не выпилят. В начале это скорее всего будет флаг компиляции. Потом флаг интерпретатор. А через много лет, если экосистема нормально перенесет отсутствие GIL’a, могут сделать поведением по умолчанию. Что-то похожее было в Node.js, когда туда имплантировали ECMAScript modules: небольшими шагами за 10 лет пришли к тому, что подавляющее большинство библиотек и фреймворков поддерживало ESM из коробки, и просто выключили флаг.
Будем надеяться, что эта тема не остановится, потому что все в общем согласны, что быстрее — это хорошо.
Релиз Python 3.11 стримили в прямом эфире
Открытые каналы коммуникации тоже привлекают людей к технологиям. Популярность языков, популярность фреймворков — она во многом и про то, насколько хорошо люди продвигают их, общаясь с другими людьми. Очень приятно видеть, что для развития языка делают шоу.
Сидишь на YouTube, maintener’ы в прямом эфире за бокалом пива рассказывают и показывают, как делают релиз. Это круто!
Из MacOS убрали Python 2.7
Ушла эпоха. Пару десятков лет назад, когда Python еще не был таким распространенным, то, что Apple добавили его в систему, помогло его популярности. Понятно, что это был только один из множества факторов, но тем не менее.
Со временем встроенный в MacOS Python стал как трехколесный велосипед: люди уже научились ездить, и маленькие колесики только мешают. Но когда ты даешь технологию в комплекте с операционной системой, на нее начинают рассчитывать другие люди. И ты не можешь делать большие обновления, не сломав кому-то обратную совместимость. До сих пор куча программ рассчитывает, что в MacOS есть Python. Поэтому он будет доступен для нужд операционной системы и ее софта, но недоступен из командной строки. Пользователь же будет ставить отдельный user mode Python в отдельной песочнице — как это сейчас все и делают.
Что же, мы откинули дополнительные колеса трехколесного велосипеда. И стало только лучше.
В JetBrains Python Developer Survey включили вопрос про менеджмент зависимостей
И мы видим интересную статистику про package-менеджеры. Подавляющее большинство использует «голый» pip. Без особых изысков.
Полное исследование https://lp.jetbrains.com/python-developers-survey-2021/#PythonPackaging
Интересно, что в вопросе про менеджмент зависимостей нет явного лидера: poetry — 27%, pipenv — 26%, pip-tools — 26%. Это круто. Значит, идет активная конкуренция, и каждый будет внедрять какие-то новые штуки, чтобы выбрали его.
Полное исследование https://lp.jetbrains.com/python-developers-survey-2021/#PythonPackaging
Что еще запомнилось
Black вышел из беты. Кажется, куча людей его уже использовала, забив на статус беты. Очень полезная штука, если все в команде придерживаются одного стиля. Это существенно облегчает чтение чужого кода. С другой стороны, если у тебя или в команде уже сложились предпочтения, где-то расходящиеся с PEP8, «делать как все» может быть тяжело.
Asyncio постоянно допиливают. В 3.11 добавили exception group и task group. Приятно видеть эволюционное развитие.
Что еще запомнилось, одной строкой:
PEP 581, работу с issues перенесли на Github.
Анонсировали PyScript — возможность выполнять Python в браузере.
Обратно несовместимое изменение в Python, чтобы избежать ValueError: Exceeds the limit (4300) for integer string conversion.
Релиз Django 4.1.
Релиз Pandas 1.5.0.
Наш подкаст продолжает выходить, несмотря на
В этом году запись Moscow Python Podcast переехала с уютной московской кухни в онлайн. Бывали периоды затишья, огромное спасибо Злате Обуховской, Илье Лебедеву и Валентину Домбровскому, что продолжали драйвить историю.
В 2022 мы остановились на отметке в 159 выпусков. Все их можно найти тут.
В 2023 планируем выходить пару раз в месяц и добавить новостные выпуски.
Пара мыслей о том, что будет дальше
Этот блок создан на основе вопросов слушателей, подключившихся к записи в прямом эфире.
Будет ли Python 4. На самом деле, как пользователи языка, мы сами не хотим, чтобы была четвертая версия. Потому что она будет обратно несовместимой с третьей. И нам придется мигрировать свою кодовою базу с третьей на четвёртую. А кто помнит переход с 2.7 на 3, тот в цирке не смеется.
Возможно, когда-то в языке назреют критические изменения, которые будут того стоить. Но не в ближайшее время. Да и сам Гвидо ван Россум говорит, что за Python 3.11 будет 3.12, потом 3.13, 3.14, а там 3.99 и 3.100.
Могут ли какие-то фреймворки взлететь в следующем году. Кажется, чего-то нового на слуху нет. Все фреймворки, которые имеют хотя бы 2-3% в исследовании JetBrains, довольно старые. Конечно, появляются и новые фреймворки, но они сталкиваются с проблемой курицы и яйца. Чтобы стать популярными и юзабельным, им надо собрать тысячи и десятки тысяч пользователей. А как собрать вокруг себя столько энтузиастов, когда Django, Flask и FastAPI лидируют с огромным отрывом?
Полное исследование https://lp.jetbrains.com/python-developers-survey-2021/#FrameworksLibraries
Пока активнее всего аудиторию набирает именно FastAPI (3-е место в исследовании). До его появления Tornado (4-е место в исследовании) было единственным способом сделать быструю асинхронную систему, когда у тебя основная нагрузка идёт на Input и Output. Думаю, FastAPI продолжит отъедать долю Tornado для таких задач.
С Новым годом! И услышимся в 2023.
История про Growth hacking на практике / Хабр | Веб-студия Nat.od.ua
История про Growth hacking на практике / Хабр
Всем привет! Меня зовут Андрей Никишин, я бэкенд-разработчик hh.ru в команде “Карьерные сервисы”. Существует распространенное мнение, что hh — это просто сайт с вакансиями и резюме, но это совсем не так. У нас есть множество сервисов: от досуга и развлечений до построения карьеры. Количество сервисов постоянно растет — и никогда не узнаешь заранее, какой из них выстрелит, а какой улетит в пустоту. Или узнаешь? В этой статье поделюсь небольшой кулстори, как мы нагроусхачили на новый сервис, и что из этого вышло.
Суть гроусхакинга
Гроусхакинг в разработке — это быстрые и недорогие эксперименты. Происходит всё это действо чаще всего так: приходит продакт с новой задачей и мы вместе думаем, как ее можно решить. Оцениваем идеи, выбираем лучшие и быстренько, буквально на коленке, реализовываем в черновом варианте. Смотрим, что из этого выстрелит, а затем решаем, стоит ли реализовывать в чистовом варианте то же самое. Гроусхаки обычно про “подвинуть” или “перекрасить кнопки” — ничего особенного. Но сегодня у нас в меню история одного гроусхака, который был действительно хорош.
Фабула
В начале квартала мы проводили гроусхак-сессию, целью которой было создание нового сервиса. Среди победителей оказался сервис под кодовым названием “Проверь процент качества резюме”. Для реализации мы просто создали кнопочку с двумя вариантами текста “Экспертные рекомендации за коробок спичек” и “Проверь качество резюме за коробок спичек”.
После того, как пользователь жал на кнопочку, мы выводили текст “Извините, сервис пока не готов, но вы можете отправить нам свое резюме, а мы обязательно его посмотрим”. За первый час нам прилетело так много резюмешек, что мы были вынуждены отключить эксперимент, поменять текст и запустить заново. Но необходимость данного сервиса стала очевидна. Метрика прокрасилась в зеленый.
По результатам эксперимента мы выбрали название “Экспертная рекомендация”. Название сервиса — важная штука. Однажды мы проводили похожий эксперимент, только кнопка называлась “Узнай свою цену за 199 рублей”. Этот сервис позволял оценить пользователю собственную потенциальную зарплату, но из-за названия люди стали возмущаться: “Мы что, рабы за 199 рублей?”
Дальше мы стали экспериментировать с ценами: сделали три варианта кнопки “Экспертная рекомендация” за 50 аден, за 50 крышек, либо за 50 золотых. И следили за тем, какую кнопку и сколько людей жмет. Посчитав потенциальную прибыль, исходя из нажатий, мы определились с ценой — осталось только сделать сам сервис.
У нас уже были похожие сервисы: Готовые резюме, Карьерные консультации, Репетиции собеседования, но Рекомендация проще — у нее меньше шагов. Есть эксперты, которые решают похожие задачи, есть оплата через внешнюю систему Assist. Мы решили оставить кнопку на прежнем месте, но чтобы в этот раз она вела на создание заявки, где пользователь выбирает резюме и отправляется к оплате в Assist. Assist, в свою очередь, отправляет пользователя на страницу заказа, а нам присылает информацию об оплате. При получении этой информации мы меняем статус, чтобы заказ появился в админке у экспертов. Любой эксперт может взять заказ и написать рекомендацию.
Изначально мы думали добавить if-else в уже написанные сервисы. Но так как в “Готовом резюме” уже были и “Карьерные консультации”, и “Репетиция собеседования”, добавленные таким образом, условных операторов получилось бы слишком много. Поэтому мы решили сделать рядом похожий сервис, в большей степени копипастой. Исключение составила админка: ее мы решили оставить оставить, потому что эксперты к ней привыкли, и права решили оставить те же. Так мы сделали новый сервис в два счета.
Эпилог
Когда сервис начал работать, мы столкнулись с небольшими трудностями. Некоторые пользователи стали отправлять пустое резюме в ожидании того, что мы напишем готовое. Но мы были готовы к такому развитию событий, поэтому таким стали отвечать обобщенной рекомендацией.
Также мы столкнулись с тем, что экспертам иногда требовалось менять текст после отправки пользователю. Мы стали выпускать оперативные скрипты, изменяющие текст, но раза с третьего мы решили выпустить фичу, позволяющую менять главному эксперту текст рекомендации. Только главному — во избежание человеческого фактора.
Еще мы боялись того, что может произойти каннибализация “Готового резюме”, но этого не произошло. Более того, “Готовое резюме” пользователи стали чаще покупать благодаря “Экспертной рекомендации”.
Мораль моей маленькой истории проста: не стоит делать сразу готовый продукт. Лучше сначала напилить простенький дешевый прототип, посмотреть, как он работает, потихоньку его доработать и зарелизить на чистовую.
Изучение TypeScript — полное руководство для начинающих. Часть 4 — Литералы и дженерики | Веб-студия Nat.od.ua
Изучение TypeScript — полное руководство для начинающих. Часть 4 — Литералы и дженерики
Привет! В новой части руководства будут рассмотрены такие важные понятия, как литералы и дженерики. Итак, приступим.
Предыдущие части: Часть 1 – Введение и примитивы Часть 2 – Ссылочные типы данных Часть 3 – Классы и интерфейсы
Литералы в TypeScript
Кроме основных типов string и number, мы можем использовать конкретные строки и числа в качестве типов:
// Объединенный тип с литералами
let favoriteColor=”red” | ‘blue’ | ‘green’ | ‘yellow’;
favoriteColor=”blue”;
favoriteColor ‘black’; // ОШИБКА: Тип “‘black'” не может быть присвоен типу “‘red’ | ‘blue’ | ‘green’ | ‘yellow'”Дженерики
Generic-типы (дженерики) позволяют создавать компоненты, которые будут работать с несколькими типами, а не с каким-то определенным, что помогает сделать компонент более переиспользуемым.
Давайте взглянем на пример, чтобы понять, что это значит.
Функция addId принимает любой объект и возвращает объект со всеми полями, которые были у входного объекта, добавляя ему поле id со случайным значением от 0 до 1000. Говоря проще, эта функция добавляет ID к любому объекту.
сonst addId = (obj: object) => {
let id = Math.floor(Math.random() * 1000);
return { …obj, id };
};
let person1 = addId({ name: ‘Джон’, age: 40 });
console.log(person1.id); // 271
console.log(person1.name): // ОШИБКА: Свойство ‘name’ не существует для типа ‘{ id: number; }’.
Как вы могли заметить, TypeScript выдает ошибку, когда мы пытаемся вывести свойство name . Это происходит из-за того, что, когда мы передаем объект в функцию addId, мы не указываем, какие свойства должен иметь этот объект – поэтому TypeScript не знает о них. Так что единственное свойство, которое он знает в этом объекте – это id.
Как же мы можем передать любой объект в addId таким образом, чтобы TypeScript знал, какие у него есть свойства? Мы можем использовать дженерики. Они обозначаются как
//
const addId =
let id = Math.floor(Math.random() * 1000);
return { …obj, id };
};
Как это работает? Сейчас, когда мы передаем объект в addId, мы должны сказать TypeScript захватить тип – так что Т становится любым типом, который мы передаем. addId теперь будет знать, какие свойства имеет объект, который мы передаем в эту функцию.
Однако теперь у нас есть проблема: мы может передать в addId все что угодно, и TypeScript примет это, не выводя никаких ошибок:
let person1 = addId({ name: ‘Джон’, age: 40 });
let person2 = addId(‘Салли’); // Передаем строку и никакой ошибки
console.log(person1.id); // 271
console.log(person1.name): // Джон
console.log(person2.id); // 890
console.log(person2.name); // ОШИБКА: Свойство ‘name’ не существует для типа ‘”Салли” & { id: number; }’.
Когда мы передаем строку, TypeScript не видит проблемы. Он сообщает об ошибке только когда мы пытаемся обратиться к свойству name. Надо поставить ограничение: необходимо сказать TypeScript, что можно передавать только объекты. Для этого надо сделать наш дженерик T расширением object:
const addId =
let id = Math.floor(Math.random() * 1000);
return { …obj, id };
};
let person1 = addId({ name: ‘Джон’, age: 40 });
let person2 = addId(‘Салли’); // ОШИБКА: Невозможно задать аргумент типа ‘string’ для параметра типа ‘object’.
Теперь мы сразу видим ошибку – это хорошо, но не совсем то, что нам нужно. Массивы в JavaScript так же являются объектами, так что мы до сих пор можем передать в нашу функцию массив вместо объекта:
let person2 = addId(); // Передаем в функцию массив – никаких проблем
console.log(person2.id); // 890
console.log(person2.name); // ОШИБКА: Свойство ‘name’ не существует для типа ‘(string | number)[] & { id: number; }’.
Мы можем решить эту проблему указав, что объект-аргумент должен иметь свойство name со строковым значением:
const addId =
let id = Math.floor(Math.random() * 1000);
return { …obj, id };
};
let person2 = addId(); // ОШИБКА: Аргумент должен содержать свойство ‘name’ со строковым значением.
Тип можно передать в угловых скобках при вызове функции, как показано ниже, однако это не обязательно, так как TypeScript сам проверяет это.
// Ниже мы явно указываем между угловыми скобками, какого типа должен быть аргумент
let person1 = addId<{ name: string; age: number }>({ name: ‘Джон’, age: 40 });
Дженерики добавляют проверку типов для аргументов и возвращаемых значений функции, которые до этого были неизвестны.
В TypeScript дженерики используются, когда мы хотим описать соответствие между двумя значениями. В примере выше тип возвращаемого значения был связан с типом входящих даных и дженерики позволяют описать эту зависимость
Другой пример: если нам нужна функция, которая принимает разные типы, то лучше воспользоваться дженериком, чем типом any. Ниже показана проблема, которая возникает при использовании any:
function logLength(a: any) {
console.log(a.length); // Все в порядке
return a;
}
let hello = ‘Hello world’;
loglength(hello); // 11
let howMny = 8;
logLength(howMany); // undefined (TypeScript не показывает ошибку, а хотелось бы)
Теперь попробуем реализовать это с использованием дженерика:
function logLength
console.log(a.length); // ОШИБКА: TypeScript не уверен, что ‘a’ имеет свойство ‘length’
return a;
}
Теперь мы хотя бы видим обратную связь, которая нам пригодится для улучшения нашего кода.
Решение: использовать дженерик, который наследует интерфейс, требующий, чтобы у аргумента было свойство length:
interface hasLength {
length: number;
}
function logLength
console.log(a.length); // Теперь ошибки нет
return a;
}
let hello = ‘Hello world’;
loglength(hello); // 11
let howMny = 8;
logLength(howMany); // ОШИБКА: у числа нет свойства ‘length’
Мы также можем написать функцию, в которой аргументом будет массив, в котором все элементы будут иметь свойство length:
interface hasLength {
length: number;
}
function logLengths
a.forEach(element => {
console.log(element.length);
});
}
let arr = ,
{ material: ‘plastic’, length: 40 },
];
logLengths(arr);
// 24
// 3
// 40
Таким образом – дженерики очень крутая особенность TypeScript!
Дженерики с интерфейсами
Когда мы не знаем, какой конкретно тип у определенного объекта будет в будущем, мы можем использовать дженерик, чтобы передать этот тип:
// Тип T будет передан в интерфейс
interface Person
name: string;
age: number;
documents: T;
}
// Мы должны передать тип поля ‘documents’, в данном случае – массив строк
const person1: Person
name: ‘Павел’,
age: 21,
documents: ,
};
// Теперь мы снова добавляем интерфейс ‘Person’, на этот раз передаем ему тип ‘string’
const person1: Person
name: ‘Павел’,
age: 21,
documents: ‘паспорт, зачетка’,
};Перечисления в TypeScript
Перечисления (enums) – это еще одна интересная возможность TypeScript. Они позволяют нам определить или объявить коллекцию связанных значений (строк или чисел) в виде набора именованных констант.
enum ResourceType {
BOOK,
AUTHOR,
FILM,
DIRECTOR,
PERSON,
}
console.log(ResourceType.BOOK); // 0
console.log(ResourceType.AUTHOR); // 1
// Начать с 1
enum ResourceType {
BOOK = 1,
AUTHOR,
FILM,
DIRECTOR,
PERSON,
}
console.log(ResourceType.BOOK); // 1
console.log(ResourceType.AUTHOR); // 2
По умолчанию, перечисления основаны на числах – они хранят строковые значения, в виде чисел. Однако они так же могут быт строками:
enum Direction {
Up = ‘Up’,
Right=”Right”,
Down = ‘Down’,
Left=”Left”,
}
console.log(Direction.Right); // Right
console.log(Direction.Down); // Down
Перечисления полезны, когда у нас есть набор связанных констант. Например, вместо использования неинформативных чисел в вашем коде можно использовать более понятные константы.
Перечисления также помогают избежать багов, когда вы введете название перечисления, intellisense подскажет вам возможные опции, которые можно выбрать.
На этом четвертая часть руководства заканчивается, надеюсь, она вам будет полезна.
В следующей (и заключительной) части мы рассмотрим строгий режим в TypeScript и сужение типов. До встречи!
Разрешение и «Полу-пиксель» / Хабр | Веб-студия Nat.od.ua
Разрешение и «Полу-пиксель» / Хабр
Изучив оба стандарта: IBM VGA и EXIF, написав пару публикаций по теме, у меня все равно ушло два дня, чтобы понять, откуда берется «полу-пиксель». И речь не о рендеринге сложных форм типа литер шрифта или иконок, а о стандартных ректанглах формата 100×100. Который по логике должен масштабироваться хорошо. Однако.
Полу-пиксель не новость. В любом редакторе, который умеет работать с вектором такие объекты как литеры шрифтов, иконки могут и будут, по своей форме, не совпадать с пиксельной сеткой.
В растровых же программах и в браузере применяются алгоритмы растеризации, которые заполняют соседние пиксели определенным оттенком в зависимости от занимаемой формой площади. С этим все давно понятно. Но откуда берется полу-пиксель у куба размером 105×105 px? И как это возможно? Разбираемся с матчастью.
Сценарий
Разрабатываешь ты интерфейсы и нужно в макет поставлять баннера или часть чужого интерфейса: фрейм apple music, spotify, платежки сбера и тд. Заходишь на сайт, где это можно взять и делаешь принтскрин. Принтскрин в Figm’у и….
… и все четенько, пиксель в пиксель. Баннер 300×600 px. Идем за следующим. Делаем принтскрин на том же устройстве, на том же сайте и странице и …
… полу-пиксель.
Эффект полу-пикселя можно получить в двух случаях: при целом значении размеров объекта и при дробном. Если при дробном параметре, как на виджете с яндекс музыкой, полу-пиксель напрашивается сам собой, то откуда он появляется при целом значении?
Спойлер: в обоих случаях имеем дело с увеличенным двукратно рендерингом логических пикселей. Но по порядку.
Раньше
До 2022 считалось, что у графического файла нет «разрешения». Оно конечно было, но использовалось только для печати, а в общей практики диджитал дизайнеров и верстальщиков отсутствовало. Ибо «до retina» и стандартизации DIP смысла в этом не было — не умели операционки, проф. софт и браузеры работать с этим параметром.
О путаннице в терминологии и понятии «Разрешение», я подробно уже писал в статье.
Во второй половине 2022 основные браузеры и проф ПО / Photoshop стали в полной мере поддерживать стандарт EXIF и научились работать с параметром “Resolution” почти как принтеры. И теперь Resolution по стандарту EXIF или Dancity по стандарту Material design , и «плотность пикселей» по русски, в полной мере используется в цифровых интерфейсах.
Разрешение / с одной стороны
Если на Retin’е сделать Принтскин, то параметры о разрешении запишутся в метаданные файла как 144 по высоте и 144 по ширине. Что соответствует двукратному увеличению от IBM стандарта в 72ppi.
На снимке у меня больше размер и разрешение, но в тексте использую стандартное соотношение.
В самих параметрах файла будет указан размер по ширине и высоте, например 1440х900. Не стоит обманываться — это не реальный размер графического файла, а логический.
Если стереть метаданные в файле и открыть его в фотошопе, то мы увидим файл размером 2880х1800. И он будет пиксель в пиксель. Так уж логика у OSX.
А то разрешение, которое вы видите на мониторе, это вообще отдельная песня и к разрешению файла имеет косвенное отношение и к полу-пикселям тоже, поэтому опустим разговоры о разрешении монитора.
Если вы открывали такой принтскрин в фотошопе или в Figm’е в начале 2022 года, то он открывался бы как файл с размером 2880х1800 и там и там. Сегодня этот же принтскрин и в фотошопе или в Figma откроется как изображение 1440х1800.
Т.е. ПО научилось считывать данные о “resolution” и обрабатывать их, а точнее уменьшать изображение вдвое. Вдвое, потому, что Figma, значения отличные от 144 или 72 не понимает.
Браузер / с другой стороны
Браузеры же работают с логическими пикселями, перерисовывая изображение в двукратном увеличении от количества логических пикселей по ширине и высоте. Поэтому в свойствах объекта при просмотре кода появляется полу пиксель.
В случае с фреймом Яндекс музыки — это был бы полу-пиксель, если бы вы смотрели изображение с разрешением 72ppi и при выводе такого объекта линия бы сгладилась дорисовав в соседних пикселях оттенко. А для 144ppi это целый пиксель. Здесь надеюсь, понятно.
А вот пример с баннером хоть значение объекта и целое, при открытии файла в Figma тоже даст полу-пиксель. Откуда — спрашивается?
Во первых, если очистить метаданные и бросить файл в фигму, то он откроется никак 1440х1800, а в два раза больше — 2880х1800, и на этом изображении все будет четко — пиксель в пиксель. То же будет если метаданные не тереть, а просто двукратно увеличить размеры файта.
А вот в браузере не кратные двум значения объектов при определенных свойствах позиционирования, например в процентах или выровненные по центру, могут отрисовываться со смещением в 1 графический пиксель те половину логического. ведь математически для построения четкого изображения браузер работает с размером 2880х1800. да сам банер тоже рендерится в двукратном размере, но нечеткий параметр позиционирования например в 33% будет считаться и откругляться 2880х1800, а не от 1440х1800, что и может дать сдвиг на полпикселя.
P.S.
Под рукой нет устройства на винде с матрицей на 13-15 дюймов и 2/4к разрешением, чтобы посмотреть, как файлы пишет и масштабирует винда. Буду признателен за освещение этого вопроса в комментариях.
И с выравниваниями, позиционированием и алгоритмами рендеринга браузера мало экспериментировал. Такой эффект встречал только на не кратных двум параметрам. Если встречались другие случае появления полу-пикселя на ретинах, напишите пожалуйста в комментариях, проверю.
Развертывание ASP.NET MVC приложения на Ubuntu 20.04 на VPS. Установка SSL / Хабр | Веб-студия Nat.od.ua
Развертывание ASP.NET MVC приложения на Ubuntu 20.04 на VPS. Установка SSL / Хабр
В этой статье я по шагам покажу как:
Развернуть ASP.NET приложение
Установить и настроить MS SQL
Установить SSL сертификат
Все это на VPS с чистой системой Ubuntu 20.04.
MS SQL требует минимум 2GB свободной оперативной памяти для установки и запуска.
Показывать я буду на примере готового ASP.NET сайта для просмотра аниме (японская анимация). Оно работает и запускается без ошибок на localhost. Приложение использует MS SQL базу данных, которую мы установим и настроим на Шаге шесть.
ASP.NET Core 3.1 Application | MS SQL
Шаг первый: публикация приложения
В обозревателе решений нажмите правой кнопкой мыши по проекту -> опубликовать.
Если у вас нет профиля, нажмите “Добавить профиль публикации” -> Целевой объект выбираем папка -> Указываем удобно место, куда файлы выгрузятся -> Готово.
Мои настройки профиля:
Конфигурация: Release
Целевая платформа: netcoreapp3.1
Режим развертывания: Зависит от платформы
Целевая среда выполнения: Переносимая версия
Нажимаю опубликовать.
Если у вас другая целевая платформа, то на Шаге три вам нужно будет скачать версию .NET-SDK которая вам нужна.
Шаг второй: отправить файлы через SFTP и установить SSH соединение
Имя пользователя и пароль пришли мне на e-mail, указанный при регистрации. Обычно имя пользователя стоит root. IP адрес написан в настройках VPS на сайте.
Чтобы подключиться по SFTP (SSH File Transfer Protocol) для передачи файлов, я использую программу FileZilla.
Запускаю -> Файл -> Менеджер сайтов -> Новый сайт
Протокол надо выбрать SFTP – SSH File Transfer Protocol.
Хост – это IP от VPS.
Логин и пароль ввожу из письма, нажимаю соединиться.
На VPS я создал директорию /var/netcore/ и файлы опубликованного приложения, при помощи Drag&Drop перенес в созданную директорию. FileZilla в логах показывает какие-то ошибки, но я их просто игнорирую, и все работает.
Установка SSH соединения. Большинство сайтов предоставляют возможность открыть консоль с SSH прямо в браузере нажатием одной кнопки, но он какой-то лагучий. Сделать это через CMD на windows 10 мне на много удобнее.
ssh
Шаг третий: установить .NET Core 3.1 на Ubuntu
У меня по умолчанию не было установлено репозиториев Microsoft с .NET Core, поэтому я скачал и установил их этими командами:
sudo wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
Теперь я устанавливаю .NET Core 3.1 и необходимые библиотеки:
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1
Шаг четвертый: установить и настроить Apache
Устанавливаю Apache и подключаю нужные модули:
sudo apt-get install apache2
sudo a2enmod proxy proxy_http proxy_html proxy_wstunnel
sudo a2enmod rewrite
Следующие, что надо сделать – это создать файл конфигурации, который будет перенаправлять запросы по порту 80 (а в будущем и 443 для SSL) на наше ASP.NET приложение. Файл конфигурации надо создать по пути /etc/apache2/conf-enabled/netcore.conf
Можете создать файл на вашей ОС и при помощи FileZilla перенести его по пути, указанному выше, или создать его при помощи текстового редактора nano/vim. Я воспользуюсь nano.
sudo nano /etc/apache2/conf-enabled/netcore.conf
Содержание файла:
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
Если ваше .NET приложение запущено на другом порте, указывайте его вместо 5000.
Проверяем конфиг на ошибки и перезапускаем apache, чтобы обновить конфиг:
sudo apachectl configtest
sudo service apache2 restart
Шаг пятый: создать сервис с ASP.NET приложением
По сути этот шаг необязательный и его можно просто пропустить, заменив командой dotnet YourApp.dll. Теперь вы можете в строке браузера написать IP адрес VPS и увидеть ваш сайт. У меня сейчас ошибка 500 из-за отсутствия MS SQL на VPS, исправив ее на Шаге шесть, сайт будет работать. Но держать в потоке (я не уверен, как это в unix называется) вашего пользователя всегда запущенное приложения – это не вариант, поэтому давайте настроим сервис, который будет делать это постоянно на фоне.
Чтобы завершить выполнение приложения, нажмите сочетание клавиш Ctrl + C.
Я создал файл по пути /etc/systemd/system/AspNetServer.service AspNetServer – это имя нашего сервиса, позже мы будем его использовать, чтобы запускать, останавливать, перезапускать приложение, читать его журналы и т.д. Можете указать любое имя, главное оставьте .service в конце.
Кому проще создать файл на своей ОС и отправить его через FileZilla, делайте так, я же просто воспользуюсь командой sudo nano /etc/systemd/system/AspNetServer.service и вставлю следующий код:
Description=ASP .NET Web ApplicationWorkingDirectory=/var/netcore
ExecStart=/usr/bin/dotnet /var/netcore/AnimeSite.dll
Restart=always
RestartSec=10
SyslogIdentifier=netcore-demo
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
WantedBy=multi-user.target
На 5 строчке вместо AnimeSite.dll укажите dll файл вашего приложения.
Теперь запустим сервер:
sudo systemctl enable AspNetServer
sudo systemctl start AspNetServer
Проверить статус сервиса можно командой:
sudo systemctl status AspNetServer
Чтобы выйти из режима просмотра статуса, нажмите Ctrl + C.
Если ваше приложение не использует базы данных, то все готово, введите IP от VDS в строку браузера и проверяйте. Если приложение выдает ошибку или вы просто хотите почитать вывод приложения, используйте команду:
journalctl -u AspNetServer
При помощи ввода цифр можете выбрать, на какую строчку перескочить. Я пишу 9999, чтобы перейти в конец и посмотреть, какое исключение появляется.
Шаг шестой: установка и настройка MS SQL
Установим необходимую библиотеку и репозитории MS SQL:
sudo apt-get install software-properties-common
sudo add-apt-repository “$(wget -qO- https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2022.list)”
Затем установим загрузчик MS SQL:
sudo apt-get update
sudo apt-get install -y mssql-server
И при помощи этой команды перейдем к установке MS SQL:
sudo /opt/mssql/bin/mssql-conf setup
Нам предлагают выбрать, какую версию установить, я выберу Express под номером 3. Соглашаюсь с условиями пользования, устанавливаю свой супер сложный пароль и готово. Проверим, работает ли MS SQL командой systemctl status mssql-server –no-pager
Я изменяю строку подключения в appsettings.json, указав свой супер сложный пароль:
Server=localhost;Database=animesitedb;User Id=sa;Password=
И перезапускаю сервис AspNetServer командой:
sudo systemctl restart AspNetServer
Готово! Сайт работает. Следующий шаг будет посвящен настройке SSL сертификата.
Шаг седьмой: настройка SSL сертификата
При покупке домена мне в подарок дали SSL сертификат. На почту пришли все данные. Чтобы установить его на сайт я создал 3 файла:
yourdomain.crt – сам сертификат
privatekey.key – приватный ключ
intermediate.crt – промежуточный сертификат
Важно! Данные в эти файлы надо вставлять вместе с
—–BEGIN CERTIFICATE—–
—–END CERTIFICATE—–
В директории с Asp.Net приложением я создал директорию ssl-certificates.
Я перенес все файлы сертификатов по пути /var/netcore/ssl-certificates/
Добавим к нашему Apache серверу модуль SSL:
sudo a2enmod ssl
Теперь надо изменить файл конфигурации Apache, я открываю редактор nano командой sudo nano /etc/apache2/conf-enabled/netcore.conf и изменяю код:
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
SSLEngine on
SSLCertificateFile /var/netcore/ssl-certificates/yourdomain.crt
SSLCertificateKeyFile /var/netcore/ssl-certificates/privatekey.key
SSLCertificateChainFile /var/netcore/ssl-certificates/intermediate.crt
Если хотите, чтобы HTTP автоматический перенаправлялся на HTTPS, измените содержимое
Redirect permanent / https://example.com/
example.com – замените на ваш домен.
Проверяем правильность конфига и перезапускаем Apache:
sudo apachectl configtest
sudo service apache2 restart
Итог
На этом все, спасибо всем, кто прочел, надеюсь помог вам.
Большая часть информации взята отсюда – https://www.c-sharpcorner.com/article/how-to-deploy-net-core-application-on-linux/
Про настройку SSL на Apache узнал из этой инструкции – https://support.globalsign.com/ssl/ssl-certificates-installation/apache-http-server-ssl-certificate-installation
Как составить Customer Journey Map и почему не надо игнорировать этот инструмент / Хабр | Веб-студия Nat.od.ua
Как составить Customer Journey Map и почему не надо игнорировать этот инструмент / Хабр
Customer Journey Map (CJM) или карта пути пользователя — это один из способов найти новые гипотезы по увеличению количества заявок и продаж.
CJM считается маркетинговым инструментом, но в YuSMP Group используем его на этапе прототипирования. Так мы создаем продукты, которые будет проще продвигать в будущем.
Что такое Customer Journey Map
Карта пути пользователя — это визуальная сюжетная линия каждого взаимодействия клиента с вашей услугой, брендом или продуктом.
CJM дает наглядный пример поведения потребителя. Благодаря такой «карте» можно увидеть узкие места на пути достижения цели, будь то покупка, заявка или другое действие. Customer Journey Map показывает, что вы делаете правильно и где можно внести улучшения на протяжении всего жизненного цикла клиента.
На карте пути показаны все точки соприкосновения с брендом: от того момента, как пользователи впервые услышали о компании, до их прямого взаимодействия с продуктом, веб-сайтом или мобильным приложением. CJM включает все действия, которые совершает клиент на пути к достижению цели в течение определенного периода времени.
Зачем нужна карта пути клиента
Чем раньше появится понимание CJM клиентов, тем результативнее станет маркетинг. Понимание опыта клиента на каждом этапе пути к покупке имеет решающее значение для превращения бизнес-идей в долгосрочные стратегии улучшения.
Дизайн карты пути клиента
Не существует правильного или неправильного способа создать карту пути клиента. Она может быть выполнена в виде временной шкалы, таблицы или доски. Главное — продумать какие пути и этапы наиболее целесообразно отобразить.
CJM в виде доски (шаблон miro)Как создать собственную Customer Journey Map
Ставьте цели. Подумайте о том, чего хотите достичь. Это может быть проблема, которую вы пытаетесь решить, продукт, который нужно запустить или обновить, а может быть это опыт, о котором хотите узнать больше. Сформулируйте проблемы, с которыми сталкиваетесь, чтобы лучше использовать CJM.
Создавайте образы. Создайте подробный портрет клиента, путешествие которого вы отобразите на карте. Используйте все доступные демографические и психографические данные для создания своих персонажей.
Составьте список точек соприкосновения. Точки соприкосновения — это все места на вашем веб-сайте или на пути к бренду, где клиенты могут взаимодействовать с компанией, продуктами, товарами или услугами. Перечислите те точки, с которыми ваши клиенты уже взаимодействуют. Затем перечислите те, которые вы хотели бы использовать.
Определите ресурсы, которые у есть и которые нужны. Как только начнете составлять карту, вы заметите проблемы на пути к покупке. По мере разработки карты используйте интерактивную доску, чтобы составить список ресурсов, которые понадобятся для заполнения пробелов. Наполните карту, добавив ресурсы и инструменты. Таким образом, вы можете более точно предсказать, как добавление или вычитание точек взаимодействия может повлиять на бизнес и увеличить доход.
Пройдите путь сами. Поработайте с CJM и посмотрите, сможете ли вы ответить на вопросы, которые задали в начале процесса. Тогда вы сможете лучше представить себе, как достичь целей вашей команды.
При необходимости выполните итерацию. После тестирования карты внесите необходимые изменения. Вы можете повторять этот процесс с течением времени, добавляя новые функции и обновления.
Создание карты пути пользователя может помочь компании наглядно представить, как клиенты чувствуют себя во всех точках соприкосновения с брендом. Так вы сможете заранее избежать потенциальных проблем, дольше удерживать внимание клиентов и получить ключевую информацию для решений.