Дневник разработчицы
407 subscribers
111 photos
9 videos
14 files
145 links
Откровенные истории о проектах, работе, учебе и открытиях в мире программирования. Присоединяйтесь и вдохновляйтесь вместе со мной!
Download Telegram
Python VS JS. Функция reduce.
В Python https://pythonz.net/references/named/reduce/
В JS https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Смысл функции в том, что она последовательно пройдет по всем элементам массива и на каждой итерации будет выполнять заданное действие с текущим элементом и результатом с предыдущей итерации.

Питонисты не рекомендуют пользоваться этим методом, так как читабельность кода - наше все. И я за, лучше уж цикл написать, так проще и понятнее.

Но JS - гангстер, он не боится грязи.
Я применила эту функцию для поиска максимального id из списка со словарями.


{id: 1, label: 'Going to learn React'},
{id: 2, label: 'That is so good'},
{id: 3, label: 'I need a break...'},
{id: 4, label: "That's good"}
]

const max_id = data.reduce((max, current) => current.id > (max.id ? max.id : 0)? current.id : max.id)
Как будет это выглядеть в Python:


{"id": 1, "label": 'Going to learn React'},
{"id": 2, "label": 'That is so good'},
{"id": 3, "label": 'I need a break...'},
{"id": 4, "label": "That's good"}
]
max_id = 0
for item in data:
if item['id'] > max_id:
max_id = item['id']
или короче, но менее читабельно вот так:
max_id = max([item['id'] for item in data])
На самом деле если присмотреться к коду JS, то можно увидеть, что я в функцию передаю другую неназванную функцию, сократив написание в виде стрелочной функции () => {}, убираю тело, условия возврата записываю в виде тернарного оператора (правда ? если да : иначе), в котором пишу еще одно условие в виде тернарного оператора, чтобы обойти ситуацию, когда в первой итерации у меня ничего нет в переменной max (подставляю 0).
max.id ? max.id : 0
Так вот, я грущу от JS из-за таких конструкций. Если для того, чтобы объяснить что делает 1 строчка кода, нужно рассказывать 5 минут, то это нечитаемая строчка кода.
Иногда от лектора курса JS слышу: "Давайте запишем это красиво", и дальше он сокращает код, делая из 5 строчек одну, но менее читабельную. Так вот, такое "красиво" не значит хорошо или умно. Вот придерживаться code style - это красиво. В остальном, чем проще, тем понятнее. #JS, #Python
Python vs JS. Сделать первую букву заглавной.

Python - все просто, функция str.capitalize(), плюс еще есть str.title(), которая делает все первые буквы в словах заглавными. https://pythonz.net/references/named/str.capitalize/

JS. Не, я так не умею, я могу только str.toUpperCase(). Делай сама... Ну ок:
str[0].toUpperCase() + str.slice(1)
Блин, js, ну ты же язык для создания интерфейсов... Почему?
¯\(°_o)/¯ #JS, #Python
Верни мне... верни мне... верни мне мой друг, и снова верни мне...

```const WithRestoService = () => (Wrapped) => {
return (props) => {
return (
<RestoServiceContext.Consumer>
{
(RestoService) => {
return <Wrapped {...props} RestoService={RestoService}/>
}
}
</RestoServiceContext.Consumer>
)
};
};


```Навеяло https://youtu.be/4TsqlT0rfJI

Компонент высшего порядка. HOC - один из паттернов JS.
Если что - текущий пример из курса)

PS. Я все еще не могу добить курс по JS, я уже отложила AWS и фигачу только JS. Осталось 16 лекций. #JS, #Учеба
JS.xmind
7.7 MB
Я дошла до последнего раздела и осознала, что он практический на нативном JS. Возможно, я к нему вернусь, но позже. Всю теорию я закончила, а это значит, пора возвращаться к своему проекту и начать пилить интерфейс.
Как и обещала, прикладываю свой конспект по этому курсу. Сразу скажу, что js я конспектировала гораздо менее тщательно, чем Python. Ну, и напомню, что самому писать такой конспект гораздо полезнее, чем пользоваться чужим.
Фух. 🤪💪
Надо будет еще потом AWS добить. #JS, #Конспекты
Очередная тру-стори про AWS. Помните, я писала, что ограничила доступ к бд? Привет счета за внутрисетевой перегон данных, так как база данных и инстансы находятся в одном регионе, но в разных зонах. Сижу, разбираюсь как это исправить. #AWS
Что проще перенести: 1 инстанс с бд или 2 сервисных?

Сервисные, конечно, особенно на Elastic Beanstalk. Эта штука позволяет создать рядом новое окружение, поднять на нем нужную версию приложения и просто плавно переключить url с одного окружения на другое. Вжух - и легким движением руки приложение переходит на другой инстанс.
Заодно решила попробовать spot-запрос на инстансы. Надо только на всякий случай поднять второй инстанс, чтобы был резервный. Но для начала послежу как пойдут расходы в бюджете.
Что неожиданно, но приятно, так как я внесла сервисные инстансы в ту же подсеть, что моя бд, они автоматом получили к ней доступ без указания security group. Очевидно, наверное, что так и должно было случится, но я далека от понимания инфраструктуры, поэтому для меня это было внезапно.
Надо будет допройти курс по AWS.
И кстати, включила логи в CloudWatch. Оказывается, это можно сделать, поставив 1 галочку в настройках. Больше не надо скачивать логи, хехей!

Все больше радуюсь возможностям AWS. Правда, пока разберешься с их документацией и настройками, все волосы можно себе оборвать, плюс еще влететь на много денег. #AWS
День инфры. Обновила версию платформы. Одно приложение совершенно спокойно обновилось. Со вторым пришлось плясать с бубном. Все попытки просто обновиться были бесполезны. Пришлось создавать еще одно окружение с новой платформой, а потом опять же свапать. Так прошло удачно. Почему я сразу этого не сделала, когда меняла зону? СТРАШНО!)
Правда, страшно.
(⊙_⊙;) #AWS
Повторила базовую структуру для React-приложения, предложенную в курсе, для своего проекта. Задолбалась создавать папочки. Спасибо Django за то, что базовая структура генерится автоматически. #React
Стейты-фигейты. Раньше я думала, что может быть сложного - сделать одну кнопочку. Сегодня я сделала загрузку одного списка и 3 чекбокса. Это было не очень приятно. Надеюсь, дальше будет проще. #JS, #React
Пару часов убила на регулярку, чтобы завернуть обработку урлов на React. Хотя мне кажется, что Джанга сама могла бы отрулить это все, но я была в этом не уверена.
В итоге получилось так:
re_path(r'^(?!api\/.*|favicon\.ico|admin\/.*|static\/.*|media\/.*).*', index_view, name='index'),

Костыльно, но все же удалось задеплоиться. После плясок с бубном над токенами джанги, очень боялась, что в итоге ничего не заработает. Но, все завелось как надо.

Делюсь кодом на js для подключения к api:
https://pastebin.com/QCXb8BV3
Что тут нужно учитывать? Функция getCookie тянет нужный нам токен getCookie('csrftoken')
Для всех запросов, кроме get, он нужен. Иначе, джанга вернет ошибку.
Дальше, используя fetch (строка 43) с методом PATCH в заголовок передаем наш токен. Будет нам счастье.

Один важный момент. Токен в куке будет только тогда, когда Джанга его установит. Соответственно при запуске фронтенда через React, ничего не получится. И для этого... Рррр, много писать. Добавлю по запросам, если кому-то нужно. Я всю эту механику подсмотрела, когда проходила этот курс https://youtu.be/f1R_bykXHGE

Сразу скажу, что данный курс нифига не дал понимания как вообще че делать с этим Реактом. Сидела, повторяла, но нифига не поняла что там происходит. Чтобы понять js, мне понадобилось прогнать отдельный курс по js. #JS, #React, #Django, #Курсы
Кстати, друзья. Почему-то очень как-то мимо прошла тема про деструктуризацию словарей и списков в Python. В отличие от этого в js эта тема была рассмотрена подробнее (spread и rest).
Не могу найти толковых статей по поводу этой фишки на Python, но увидела я интересные примеры в видео https://youtu.be/HrGg6KTJwhA.
Также нашла не очень понятную статью https://codecamp.ru/blog/python-list-destructuring-aka-packing-and-unpacking/, где только про списки.

Все мы помним любимые
*args и **kwargs

но что это значит? https://pythonz.net/references/named/argymenty-vyzova/
они "собирают" в себя все аргументы, превышающие заданный набор.
На самом деле так собирать и разбирать можно не только в рамках аргументов функций, но и просто разбирать списки:

first, second, *later = tasks # заберем первую и вторую, остальные отложим
first будет 'todo1'
second будет 'todo2'
later заберет в себя оставшийся список ['todo3', 'todo4']

Допустим нам пришли еще задачки:
new_tasks = ['todo5', 'todo6']

Их можно собрать, разложив два списка:
all_tasks = [*later, *new_tasks]
Получим список ['todo3', 'todo4', 'todo5', 'todo6']

Аналогичная история со словарями, но работает через . Собираются они не так. Если разложить keys = [*dict], то в keys получаем ключи словаря.

```person = {"name": "Olga", "age": 15, "weight": 55}
other_params = {'eye_color': 'brown', 'father': 'David'}
all_data = {**person, **other_params}

В all_data будет {'name': 'Olga', 'age': 15, 'weight': 55, 'eye_color': 'brown', 'father': 'David'}

```В JS если что это работает через ...array или ...object.

Если есть что добавить - пишите. #JS, #Python
Дневник разработчицы
Python VS JS. Функция reduce. В Python https://pythonz.net/references/named/reduce/ В JS https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce Смысл функции в том, что она последовательно пройдет по всем элементам массива…
Через JS открываю для себя Python.

Признаю, что я облажалась. Я тут внезапно для себя открыла, что в Python есть функции map(), filter(), reduce()
https://book.pythontips.com/en/latest/map_filter.html
Просто я о них не знала (на самом деле про map у меня даже в конспекте есть) ими никогда не пользовалась.
Ну да, когда начинаешь учиться и что-то сложно понять, оно просто не запоминается. Зачем использовать какие-то непонятные функции, когда есть циклы?)

А вот в JS уже это было как-то понятно, плюс была некоторая практика на этих функциях.

Мне стыдно. Но ура, теперь, надеюсь, я буду ими пользоваться. #JS, #Python
Не видела в статьях про Джанго+Реакт такого решения, но я подцепила шаблоны и статику из Реакта так:
1. Реакт приложение развернуто в директории frontend внутри джанга-проекта.
2. Реакт создан с помощью create-react-app, поэтому готовые файлы собираются в папку build.
3. В settings проекта Джанги прописала:

{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR), 'frontend/build'
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

Добавила директорию 'frontend/build'

os.path.join(BASE_DIR, "static"),
os.path.join(BASE_DIR, 'frontend/build/static'),
]

Аналогично добавила путь до статики.

Во view указала путь до шаблона (полный) 'frontend/build/index.html'

Локально полет нормальный. Если что-то пойдет не так - напишу. #Работа, #JS, #React, #Django
Чем дальше в лес, тем меньше мне нравится React. Грущу. Переписываю логику работы со state. В курсе была предложена оооочень примитивная архитектура. Возможно для старта она ок, но быстро упираешься в потолок ее возможностей, как мне кажется. Нашла альтернативный вариант https://learn-reactjs.ru/training-project/app-state
Но сколько же надо сделать телодвижений, чтобы собрать то, что ты хочешь( #Работа, #JS, #React
В какой-то момент мне показалось, что вот-вот и у меня все получится, я все поняла и осталось только сделать. Начинаю делать и понимаю, что нихрена я не понимаю.
22 зависимости в packege.json, 21 зависимость в requirements.txt. Что-то как-то слишком жирно фронтенда. Стискиваю зубы, вдох-выдох, пилю дальше.

Логично же, логику вызова веб-сервисов переложить на actions. Ну да, логично. Но тут встает вопрос, а как она будет работать с учетом того, что запросы к серверу в js выполяются асинхронно. И дальше начинаю смотреть как это реализовано и теряю нить понимания. Вот тут я еще что-то понимала, а вот тут уже все, все уже, ушло, исчезло. Магия. Черный ящик. Да будет копипаста! Но, что интересно, заработало что-то. Первый раз такое что ли? Попляшешь с бубном, оно заработает. А понимание оно придет, со временем, на интуиции, насмотренности, начитанности. А пока, и так сойдет!

С точки зрения функционала нифига не двигаюсь, топчусь на месте, стелю соломку. Иначе дальше будет хуже.

В какой-то момент хотела все бросить, пошла смотреть Angular. Возможно, реально решу-таки на него перейти, но что-то мне кажется, что там тоже не так все легко и просто. Так что, продолжаю свои Reactивные опыты. #Работа, #JS, #React
Первый релиз интерфейса! Кажется, что функционала почти нет. И это больше всего расстраивает, что на небольшое количество функционала столько плясок с бубном. Но, таков путь.

Завтра будет лучше. #Работа, #JS, #React
Я не понимала, почему на десктопе все прекрасно перестраивается в зависимости от ширины окна, а вот на мобилках была нечитаемая грусть.
Я не верстальшик и плохо владею этим кунг-фу, поэтому я пользуюсь стандартными библиотечками (в моем случае material ui). И было очень грустно, что же не так с мобилками.
Сегодня с совершенно случайно узнала про одну волшебную строчку в мета-тегах:

<meta name="viewport" content="width=device-width, initial-scale=1" />

Короче, без нее была грусть, с ней сетка встала на свои места. Почитать о ней можно тут https://developer.mozilla.org/ru/docs/Mozilla/Mobile/Viewport_meta_tag

Села писать поле с автокомплитом. Одно поле, а заморочек очень много.

Сделала страницу авторизации. Не решила следующую проблему. Если авторизовать пользователя без перезагрузки страницы, то js не получает куку с авторизационным токеном, которую устанавливает бекенд после авторизации. Пока не понимаю как это правильно решить, в коде прописала просто насильно перезагрузку страницы. Выглядит не очень( #Работа
Если честно, неделю не притрагивалась к коду. После обсуждения с Пашей о том как лучше делать архитектуру на Реакте и почему, я выпала в осадок, что в третий раз все придется переделывать. Однако, есть плюс - в новом варианте можно начать писать новое по-новому, не переделывая старое.

Давно на самом деле мне говорили - используй функции, а не классы, выкинь редакс - так будет проще, тебе не нужен редакс. А почему не объясняли. Мало ли, они преуменьшили значимость моего проекта).

Паша объяснил. На ромашках. Говорит, представь, у тебя один маленький компонент меняет общее состояние и все вслед за ним превращаются в ромашки, потому что редакс. Ромашки - это прелоадер, если что. Ну и в целом, я знала половину истории про разработчиков редакса, что их взяли в фейсбук после этого, а Паша мне рассказал вторую половину. Что уже в фейсбуке они сделали более изящное решение.

https://ru.reactjs.org/docs/hooks-intro.html Тут прекрасно расписывается что почему и как.
Я знаю, что полезно читать документацию, но давайте по-чесноку, не может мозг так сразу взять и все переварить. Все приходит с опытом.

Кстати, Паша же помог мне разобраться с моей ошибкой авторизации. Оказалось, что ошибка вообще пустячная и смешная. У меня есть класс для работы с api, я не думая, написала запрос куки при инициализации объекта класса. Объект был инициализирован 1 раз. Соответственно, если в начале не было куки, то до новой инициализации (перезагрузки страницы) объект не мог ее получить. Просто поменяла на логику, что при каждом вызове, запрашивается кука.

А еще я вчера доделала поле автокомплита. Пришлось повозиться, так как простое поле раскладывается на такие вещи:
Получить текущие данные из темы
При клике запросить данные о каналах
При вводе отправлять запрос с учетом введенных данных
Форматировать исходные и новые данные в определенном формате
Спасибо документации по material ui за подробные примеры. https://material-ui.com/ru/components/autocomplete/#multiple-values #Работа, #JS, #React
Уже даже выкатила #Работа, #JS
И что тогда?..

Словила себя на одном незначительном моменте. Когда писала код для страницы создания новой темы, надо было написать функцию отправки формы при нажатии на кнопку. Такой несложный вроде бы функционал, но писала его первый раз.

Сначала ловлю стандартный обработчик события submit event.preventDefault();
Потом использую функцию отправки данных на сервер, которая возвращает обещание.
И что тогда (.then())? Если успешно все ушло на сервер, мне же надо редирект сделать. Все кажется просто, но как это записать?

Если честно, то я даже в первый момент пошла гуглить как сделать редирект, после успешного создания материала. Гугл не выдал сразу хорошего ответа, пришлось напрячь свой мозг. Ага, сделаем новое состояние (created? тема же создана). Сначала это было булево состояние - да/нет, создана/не создана. Так, хорошо пошло. Дальше пишу условие уже для компонента, если создано, то что? То редирект, конечно! А куда? Так, возвращаемся назад, нифига не булево состояние надо, нужен id для редиректа. Хоп-хоп, готово.

Мелочь, конечно, но приятно, что я смогла сама сообразить как это сделать. Начинаю понимать как работать с React, становится проще писать. #Работа, #JS