~xОчень редкий зверь - значок тильды в python. Не так просто найти о нем информацию.
Еще иногда встречается использование & и |, когда я впервые увидела их использование, меня это поставило в тупик: а что это и как это понимать.
Самый лучший список всех-всех вариантов разных операторов я нашла тут https://pythonworld.ru/osnovy/peregruzka-operatorov.html
Если стандартные операторы довольно часто используются и легко найти как их "перегружать", то вот с битовым операциями сложнее. И как гуглить такое непонятно. Поэтому сохраняю в закладки).
В некоторых библиотеках перегружают такие операторы для удобства работы.
Например, в Pandas для объединения условий внутри выражения используется как раз операторы & и |:
df.loc[(df.cnt < 1000) & (df.workingday == 0), 'hum']
В исходниках можно найти как они реализованы:
# -------------------------------------------------------------
# Logical Methods
def _logical_method(self, other, op):
return NotImplemented
@unpack_zerodim_and_defer("__and__")
def __and__(self, other):
return self._logical_method(other, operator.and_)
@unpack_zerodim_and_defer("__rand__")
def __rand__(self, other):
return self._logical_method(other, roperator.rand_)
@unpack_zerodim_and_defer("__or__")
def __or__(self, other):
return self._logical_method(other, operator.or_)
@unpack_zerodim_and_defer("__ror__")
def __ror__(self, other):
return self._logical_method(other, roperator.ror_)
Глубже не осилила.
Просто решила поделиться. #Python
Хочется написать про поиск работы.
Я иногда посматриваю вакансии и прохожу тестовые. Нет, не так, я ткнулась в пару вакансий и сделала их тестовые.
Первое тестовое было - 4 задачки на базовый синтаксис и алгоритмы. По функционалу я сделала полностью, но вот забыла про магию множеств python - функцию set.intersection() https://pythonz.net/references/named/sets.intersection/. Теперь буду пользоваться.
После меня позвали на интервью с 10 техническими вопросами. Воспроизведу то, что помню:
1. Какие СУБД знаете. Чем SQLite отличается от остальных.
2. Join и его виды, чем отличаются.
3. Сложность алгоритмов, бинарный поиск, его сложность.
4. Индексы в бд, что такое, какая сложность получения экзмепляра по индексу.
5. POST и GET запросы, в чем отличие и применение.
6. Зачем нужен GIT и его команды.
7. Базовые команды линукса. Как можно посмотреть файл, с какими редакторами работала. (не ответила, не помню).
8. Миграции джанги, зачем нужны, как создавать, как применять, какие команды соответствуют.
9. Students.objects.filter(age__gte=18).exclude(sex="F").values_list('name', flat=True) - попросили объяснить что тут происходит.
Десятый не помню) В целом я на все ответила, кроме линукса, потому что не применяю ничего, кроме cd и ls, ну, и установки пакетов, выполнения команд.
Вторая вакансия - наоброт, сначала вопросики, потом тестовое. Вопросики были на софт-скиллы.
https://meta-test-mandrianova.herokuapp.com/ - вот, что собрала для демо в итоге на тестовое. Надо было сделать загрузку данных по докторам через стороннее api и страничку доктора на vue. Чтобы сделать демку пришлось подставлять костыли, так как не хотелось ради тестового задания подключать aws s3 для загрузки media. Я еще бы с этим просидела денек.
Впервые что-то собирала на vue, впервые, кстати, выкачивала и сохраняла файлы по урлу. Мне кажется, что то, как я в итоге сделала сохранение файла в джанге - ну такое.
Решила не писать тесты, не обкладывать логами, не залипать на неделю над задачкой. В общем, сделала минимум, если честно.
Хочу еще поделиться менеджерским хаком проверки неизвестного работодателя:
- Ищем юр. лицо потенциального работодателя (на сайте, в гугле, еще может помочь сервис https://www.nic.ru/whois/)
- Идем смотреть по юр.лицу сюда https://www.list-org.com/ или на подобные ресурсы. Там видим доходы-расходы за прошлый год, фактическую инфу о компании, какие есть судебные тяжбы у работадетеля.
- Еще можно проверить соцсети, поискать нет ли знакомых, кто там работает и спросить у них как и что.
Жду ответа)
PS. Не поняла почему все так прутся от Vue (не распробовала, видимо). Надо будет еще Ангуляр потыкать палочкой. #Работа
Я иногда посматриваю вакансии и прохожу тестовые. Нет, не так, я ткнулась в пару вакансий и сделала их тестовые.
Первое тестовое было - 4 задачки на базовый синтаксис и алгоритмы. По функционалу я сделала полностью, но вот забыла про магию множеств python - функцию set.intersection() https://pythonz.net/references/named/sets.intersection/. Теперь буду пользоваться.
После меня позвали на интервью с 10 техническими вопросами. Воспроизведу то, что помню:
1. Какие СУБД знаете. Чем SQLite отличается от остальных.
2. Join и его виды, чем отличаются.
3. Сложность алгоритмов, бинарный поиск, его сложность.
4. Индексы в бд, что такое, какая сложность получения экзмепляра по индексу.
5. POST и GET запросы, в чем отличие и применение.
6. Зачем нужен GIT и его команды.
7. Базовые команды линукса. Как можно посмотреть файл, с какими редакторами работала. (не ответила, не помню).
8. Миграции джанги, зачем нужны, как создавать, как применять, какие команды соответствуют.
9. Students.objects.filter(age__gte=18).exclude(sex="F").values_list('name', flat=True) - попросили объяснить что тут происходит.
Десятый не помню) В целом я на все ответила, кроме линукса, потому что не применяю ничего, кроме cd и ls, ну, и установки пакетов, выполнения команд.
Вторая вакансия - наоброт, сначала вопросики, потом тестовое. Вопросики были на софт-скиллы.
https://meta-test-mandrianova.herokuapp.com/ - вот, что собрала для демо в итоге на тестовое. Надо было сделать загрузку данных по докторам через стороннее api и страничку доктора на vue. Чтобы сделать демку пришлось подставлять костыли, так как не хотелось ради тестового задания подключать aws s3 для загрузки media. Я еще бы с этим просидела денек.
Впервые что-то собирала на vue, впервые, кстати, выкачивала и сохраняла файлы по урлу. Мне кажется, что то, как я в итоге сделала сохранение файла в джанге - ну такое.
Решила не писать тесты, не обкладывать логами, не залипать на неделю над задачкой. В общем, сделала минимум, если честно.
Хочу еще поделиться менеджерским хаком проверки неизвестного работодателя:
- Ищем юр. лицо потенциального работодателя (на сайте, в гугле, еще может помочь сервис https://www.nic.ru/whois/)
- Идем смотреть по юр.лицу сюда https://www.list-org.com/ или на подобные ресурсы. Там видим доходы-расходы за прошлый год, фактическую инфу о компании, какие есть судебные тяжбы у работадетеля.
- Еще можно проверить соцсети, поискать нет ли знакомых, кто там работает и спросить у них как и что.
Жду ответа)
PS. Не поняла почему все так прутся от Vue (не распробовала, видимо). Надо будет еще Ангуляр потыкать палочкой. #Работа
Дотянулись ручки до Ангуляра, пока чисто ради интереса прохожу туториал. Столько всего замечательного!
Магия тегов!
Типизация!
Удобное создание компонентов и вообще все для людей.
А это я только начала...
Королева в восхищении!
Не претендую на умные мысли и споры на тему выбора технологий, просто захотелось поделиться, мне понравилось.) #JS
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)" >
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
Магия тегов!
id: number;
name: string;
}
Типизация!
ng generate service hero
Удобное создание компонентов и вообще все для людей.
А это я только начала...
Королева в восхищении!
Не претендую на умные мысли и споры на тему выбора технологий, просто захотелось поделиться, мне понравилось.) #JS
Пришел ко мне мой друг Никита и принес вот такое задание от своего знакомого:
И вроде слова все знакомые, но с ходу я даже не поняла, а что вообще требуется.
Мы начали обсуждать и Никита поделился своим вариантом решения, в котором он по сути реализовал дерево с помощью вложенных списков (на базе класса, конечно).
Тут уже у меня возник вопрос, а при чем тут ООП, кроме того, что структура задается с помощью класса. Где тут инкапсуляция, наследование, полиморфизм.
И зацепила меня мысль о том, а как вообще корректно сделать индексы в классе. И как индексы совместить со структурой дерева. Вроде вложенные списки это логично, но это же уже есть в Python, что-то не так.
В общем, пока размышляла, вспомнила, что есть замечательный магический метод getitem, который как раз обеспечивает доступ по индексу или ключу. В итоге, добавив к решению Никиты магические методы, как мне кажется, мы решили задачу.
Заодно поигрались с созданием новых нод в дереве через указание конкретных индексов и просто добавлением в конец списка. Заодно добавили инкапсуляцию)
Вроде задачка простая, все слова знакомые, но лично я раньше не прописывала методы getitem и setitem, поэтому решение пришло не сразу.
А закончили мы еще интересным обсуждением эффекта:
Так как экземпляры внутри списка того же класса, то обращения вида tree[0][0][2] двигаются по ступенькам, очень похоже на рекурсию, только это не вызов самого себя, а просто проход по разным экземплярам одного класса, где используются одни и те же методы для получения следующего. Как глубока кроличья нора!)
Интересная структура и интересная задачка, да. #Python
на собеседовании попросили от руки написать на листочке класс который бы реализовывал хранение данных с доступом по индексу в виде дерева
И чтобы можно было получить доступ по индексу в этом дереве
И вроде слова все знакомые, но с ходу я даже не поняла, а что вообще требуется.
Мы начали обсуждать и Никита поделился своим вариантом решения, в котором он по сути реализовал дерево с помощью вложенных списков (на базе класса, конечно).
Тут уже у меня возник вопрос, а при чем тут ООП, кроме того, что структура задается с помощью класса. Где тут инкапсуляция, наследование, полиморфизм.
И зацепила меня мысль о том, а как вообще корректно сделать индексы в классе. И как индексы совместить со структурой дерева. Вроде вложенные списки это логично, но это же уже есть в Python, что-то не так.
В общем, пока размышляла, вспомнила, что есть замечательный магический метод getitem, который как раз обеспечивает доступ по индексу или ключу. В итоге, добавив к решению Никиты магические методы, как мне кажется, мы решили задачу.
Заодно поигрались с созданием новых нод в дереве через указание конкретных индексов и просто добавлением в конец списка. Заодно добавили инкапсуляцию)
class Node:
def __init__(self, data=None):
self.nodes: List[Node] = []
self.data = data
def add(self, data):
self.nodes.append(Node(data))
def _create_empty_elements(self, key):
for n in range(len(self.nodes), key + 1):
self.nodes.append(Node())
def __setitem__(self, key, value):
if key > -1 and len(self.nodes) < key + 1:
self._create_empty_elements(key)
self.nodes[key].data = value
def __getitem__(self, item):
if item > -1 and len(self.nodes) < item + 1:
self._create_empty_elements(item)
return self.nodes[item]
Вроде задачка простая, все слова знакомые, но лично я раньше не прописывала методы getitem и setitem, поэтому решение пришло не сразу.
А закончили мы еще интересным обсуждением эффекта:
tree[0][0][2] = 'data'
tree[0][0][2].data # вернет 'data'
Так как экземпляры внутри списка того же класса, то обращения вида tree[0][0][2] двигаются по ступенькам, очень похоже на рекурсию, только это не вызов самого себя, а просто проход по разным экземплярам одного класса, где используются одни и те же методы для получения следующего. Как глубока кроличья нора!)
Интересная структура и интересная задачка, да. #Python
Про собеседования.
Говорят, что на собеседования надо ходить с мыслью, что не только компания подбирает сотрудника, но и сотрудник компанию.
Я очень не люблю собеседования, крайне. Если уж я решилась пойти, то значит я для себя уже решила, что компания мне ок. Мне обычно нечего спрашивать на собеседованиях, мне интереснее то, что спрашивают у меня, как люди реагируют на мои ответы. Если будущий руководитель задает странные вопросы, разговаривает пренебрежительно, спрашивает про стрессоустойчивость (разные люди испытывают стресс от разных вещей, но чаще это значит, что сам руководитель признает, что у них состояние филиала ада), меня это напрягает.
Вопрос денег. В нашей сфере разные компании могут себе позволить разный уровень зарплат. И при выполнении одной и той же по сути работы в одной компании специалист одного и того же уровня будет получать x, а в другой 2x. Можно получать много в финансовом секторе, на госах, в больших корпорациях, а можно меньше в стартапах или, например, идти за сколько угодно лишь бы в Яндекс. Это не значит, что в Яндексе мало платят, но у них своя религия, где ты либо с ними, либо нет. Я что хочу сказать, на самом деле, как мне кажется (и на основе небольших исследований на коллегах), для многих деньги не главный фактор выбора работы и не то, что их держит. Но это безусловно важно.
Так вот, когда меня спрашивают - сколько? У меня всегда встречный вопрос - сколько вы готовы платить мне? А дальше уже я могу согласиться, либо мы можем обсуждать. В случае, если я скажу сумму, которая кажется работодателю слишком высокой, происходит странная реакция. Часто они не торгуются, а просто сливаются. "Вас таких толпа за забором", "Зажралась", "Не, чет ссыкотно, слишком дорогой специалист" - почему нельзя просто поговорить открыто? Зачем все эти манипуляции еще на этапе начального договора?
Когда я влияла на зп людей, я всегда пыталась открыто говорить могу и готова ли я дать/повысить им зп или нет. Но большинство руководителей предпочитают скользить по этим вопросам, чтобы переиграть и сэкономить. Вопрос, а какой в этом профит? Просто у сотрудника останется осадок, он начнет смотреть налево не из-за денег, а из-за того, что будет чувствовать себя обманутым.
Про странные и "правильные" вопросы. Как человек решает проблемы, какие проблемы были на его пути и что он делал, какой у него был релевантный опыт, что интересно/неинтересно человеку - это, я считаю правильными вопросами. Очень не люблю всякие абстрактные задачки, которые направлены на то, чтобы выявить о том, как человек мыслит. Например, вот вас попросили сделать это и это, как будете действовать. Хз, может у меня фантазия не очень, но то как я рассуждаю на собеседовании и то, как я реально буду делать - абсолютно разные пути. Я в реальности прежде чем что-то делать 100 раз подумаю и посмотрю на проблему с разных сторон, чтобы понять с чего начать. В фантазиях же ответом на вопрос, как правило, ожидается конкретный алгоритм, который составил для себя тот, кто спрашивает. И вот, давай поиграем в игру, угадайте, что задумал ваш собеседник.
Помню, было смешно, когда я дала определение одному понятию, а человек по ту сторону стола сказал, что это неправильно и сказал тоже самое, но другими словами. Ну ок, вам виднее, ведь правильность ответа в данном случае вещь субъективная.
Вопросы про знания. Человек знающий не равно человек применяющий, умеющий применять. Но со знанием всегда лучше, чем совсем без него.
Ну и на последок. Всякие психологические вопросы на выявление характера. На самом деле, и без них невербально чаще всего каждый участник считывает было ли ему комфортно общаться, чаще выбирают тех, с кем было приятно. Но бывает, что и нет. Я один раз согласилась пойти туда, где гендир мне прямым текстом сказал "вы мне не очень нравитесь, но я готов попробовать", в итоге мы с ним неплохо сработались, хотя процесс "притирки" был довольно долгим. И да, это с их стороны меня месяц уговаривали все же пойти к ним. Казалось бы, обе стороны на собеседовании не были в восторге друг от друга, но в итоге нас удалось продуктивно работать вместе. #Работа
Говорят, что на собеседования надо ходить с мыслью, что не только компания подбирает сотрудника, но и сотрудник компанию.
Я очень не люблю собеседования, крайне. Если уж я решилась пойти, то значит я для себя уже решила, что компания мне ок. Мне обычно нечего спрашивать на собеседованиях, мне интереснее то, что спрашивают у меня, как люди реагируют на мои ответы. Если будущий руководитель задает странные вопросы, разговаривает пренебрежительно, спрашивает про стрессоустойчивость (разные люди испытывают стресс от разных вещей, но чаще это значит, что сам руководитель признает, что у них состояние филиала ада), меня это напрягает.
Вопрос денег. В нашей сфере разные компании могут себе позволить разный уровень зарплат. И при выполнении одной и той же по сути работы в одной компании специалист одного и того же уровня будет получать x, а в другой 2x. Можно получать много в финансовом секторе, на госах, в больших корпорациях, а можно меньше в стартапах или, например, идти за сколько угодно лишь бы в Яндекс. Это не значит, что в Яндексе мало платят, но у них своя религия, где ты либо с ними, либо нет. Я что хочу сказать, на самом деле, как мне кажется (и на основе небольших исследований на коллегах), для многих деньги не главный фактор выбора работы и не то, что их держит. Но это безусловно важно.
Так вот, когда меня спрашивают - сколько? У меня всегда встречный вопрос - сколько вы готовы платить мне? А дальше уже я могу согласиться, либо мы можем обсуждать. В случае, если я скажу сумму, которая кажется работодателю слишком высокой, происходит странная реакция. Часто они не торгуются, а просто сливаются. "Вас таких толпа за забором", "Зажралась", "Не, чет ссыкотно, слишком дорогой специалист" - почему нельзя просто поговорить открыто? Зачем все эти манипуляции еще на этапе начального договора?
Когда я влияла на зп людей, я всегда пыталась открыто говорить могу и готова ли я дать/повысить им зп или нет. Но большинство руководителей предпочитают скользить по этим вопросам, чтобы переиграть и сэкономить. Вопрос, а какой в этом профит? Просто у сотрудника останется осадок, он начнет смотреть налево не из-за денег, а из-за того, что будет чувствовать себя обманутым.
Про странные и "правильные" вопросы. Как человек решает проблемы, какие проблемы были на его пути и что он делал, какой у него был релевантный опыт, что интересно/неинтересно человеку - это, я считаю правильными вопросами. Очень не люблю всякие абстрактные задачки, которые направлены на то, чтобы выявить о том, как человек мыслит. Например, вот вас попросили сделать это и это, как будете действовать. Хз, может у меня фантазия не очень, но то как я рассуждаю на собеседовании и то, как я реально буду делать - абсолютно разные пути. Я в реальности прежде чем что-то делать 100 раз подумаю и посмотрю на проблему с разных сторон, чтобы понять с чего начать. В фантазиях же ответом на вопрос, как правило, ожидается конкретный алгоритм, который составил для себя тот, кто спрашивает. И вот, давай поиграем в игру, угадайте, что задумал ваш собеседник.
Помню, было смешно, когда я дала определение одному понятию, а человек по ту сторону стола сказал, что это неправильно и сказал тоже самое, но другими словами. Ну ок, вам виднее, ведь правильность ответа в данном случае вещь субъективная.
Вопросы про знания. Человек знающий не равно человек применяющий, умеющий применять. Но со знанием всегда лучше, чем совсем без него.
Ну и на последок. Всякие психологические вопросы на выявление характера. На самом деле, и без них невербально чаще всего каждый участник считывает было ли ему комфортно общаться, чаще выбирают тех, с кем было приятно. Но бывает, что и нет. Я один раз согласилась пойти туда, где гендир мне прямым текстом сказал "вы мне не очень нравитесь, но я готов попробовать", в итоге мы с ним неплохо сработались, хотя процесс "притирки" был довольно долгим. И да, это с их стороны меня месяц уговаривали все же пойти к ним. Казалось бы, обе стороны на собеседовании не были в восторге друг от друга, но в итоге нас удалось продуктивно работать вместе. #Работа
🔥1
Так, а вообще из конкретных методик, мне очень понравилась STAR https://hr-portal.ru/story/metodika-star-dlya-prohozhdeniya-strukturirovannyh-sobesedovaniy
https://www.youtube.com/watch?v=kR6WrMLWaPA&ab_channel=EPAdvisory
Готовилась в свое время по ней к менеджерским интервью. А сейчас понимаю, что я ее уже на автомате применяла на вопросах по своему опыту джуна-программиста)
Всем удачи и лучших работодателей! #Работа, #Tools
https://www.youtube.com/watch?v=kR6WrMLWaPA&ab_channel=EPAdvisory
Готовилась в свое время по ней к менеджерским интервью. А сейчас понимаю, что я ее уже на автомате применяла на вопросах по своему опыту джуна-программиста)
Всем удачи и лучших работодателей! #Работа, #Tools
Вышла на работу.
Первый день. Дали мне доступы, скачиваю проекты, смотрю на них у меня начинается адская паника - как вообще это разворачивать, с чего начать. Версия python у меня стоит другая, докер для локального разворачивания не предусмотрен, с дампами баз я почти ничего не делала, с ssh толком не работала.
Короче, целый день я провозилась с тем, чтобы хоть как-то поднять проект, при этом дамп пришлось оставить на следующий день.
День второй, дали первую задачу, удалось пообщаться на счет архитектуры. Долго возилась с бд, зато научилась складывать дамп в контейнер и запускать разворот базы локально. Пора писать баш-скрипты для этого.
Сделала свою маленькую первую задаченьку, отправила реквест. Божечки-кошечки. Хотела работы в команде - нате, получите, распишитесь. На 10 строк кода 100500 комментариев - тут не так, это не этак. >_< не поговнокодишь, ага!
Ладно, я не унываю, ведь комментировали даже то, что я тупо взяла из уже существующего кода. Так что нет предела совершенству!)
Завтра будет лучше.
Новым коллегам, привет!) #Работа
Первый день. Дали мне доступы, скачиваю проекты, смотрю на них у меня начинается адская паника - как вообще это разворачивать, с чего начать. Версия python у меня стоит другая, докер для локального разворачивания не предусмотрен, с дампами баз я почти ничего не делала, с ssh толком не работала.
Короче, целый день я провозилась с тем, чтобы хоть как-то поднять проект, при этом дамп пришлось оставить на следующий день.
День второй, дали первую задачу, удалось пообщаться на счет архитектуры. Долго возилась с бд, зато научилась складывать дамп в контейнер и запускать разворот базы локально. Пора писать баш-скрипты для этого.
Сделала свою маленькую первую задаченьку, отправила реквест. Божечки-кошечки. Хотела работы в команде - нате, получите, распишитесь. На 10 строк кода 100500 комментариев - тут не так, это не этак. >_< не поговнокодишь, ага!
Ладно, я не унываю, ведь комментировали даже то, что я тупо взяла из уже существующего кода. Так что нет предела совершенству!)
Завтра будет лучше.
Новым коллегам, привет!) #Работа
Познакомилась с интересной библиотекой для работы с excel. Хочу поделиться.
https://formulas.readthedocs.io/en/stable/
Итак, у меня был здоровый excel с формулами, ссылающимися на разные листы, а листов было довольно много. Внутри куча справочников, зависимостей и тд и тп. Переносить такую логику на бекенд придется месяц, разбирая по ниточке все нюансы.
Почему бы не оставить всю логику в excel и просто заполнять нужные данные? Потому что для получения результата нужно исполнение всех этих формул = открыть excel, чтобы он посчитал.
Что делает магическая библиотека formulas? Она берет excel, парсит из него все формулы и данные, переводит это на python и пересчитывает все, что нужно. Можно даже данные в исходном excel не менять.
Как пользоваться?
Подробности и разные варианты использования смотрите в документации.
Обращаю внимание, что библиотека использует numpy, поэтому ее также придется подключать к проекту. В файле не должно быть битых ссылок, перед использованием проверьте, что все ок.
Пробовала в аргумент outputs для calculate() передать массив значений, которые я хочу получить в результате, но что-то пошло не так и я получила все равно все подряд. Также пыталась вытащить график зависимостей из файла, но тоже безуспешно. #Python, #Tools, #Работа
https://formulas.readthedocs.io/en/stable/
Итак, у меня был здоровый excel с формулами, ссылающимися на разные листы, а листов было довольно много. Внутри куча справочников, зависимостей и тд и тп. Переносить такую логику на бекенд придется месяц, разбирая по ниточке все нюансы.
Почему бы не оставить всю логику в excel и просто заполнять нужные данные? Потому что для получения результата нужно исполнение всех этих формул = открыть excel, чтобы он посчитал.
Что делает магическая библиотека formulas? Она берет excel, парсит из него все формулы и данные, переводит это на python и пересчитывает все, что нужно. Можно даже данные в исходном excel не менять.
Как пользоваться?
input_fileds = {"'[файл]НАЗВАНИЕ ЛИСТА(uppercase)'!A1": "значение"} # А1 - номер ячейки как в excel. Это словарь, можно указать в нем список всех нужных значений для расчета.
solution = xl_model.calculate(inputs=input_fileds) # в результате получаем граф со всеми-всеми заполненными ячейками из excel
result = solution.get_node("'[файл]НАЗВАНИЕ ЛИСТА(uppercase)'!B1") # Для получения конкретного поля из solution
result[0].value[0, 0] # пример как можно вытащить само значение для выбранного поля
Подробности и разные варианты использования смотрите в документации.
Обращаю внимание, что библиотека использует numpy, поэтому ее также придется подключать к проекту. В файле не должно быть битых ссылок, перед использованием проверьте, что все ок.
Пробовала в аргумент outputs для calculate() передать массив значений, которые я хочу получить в результате, но что-то пошло не так и я получила все равно все подряд. Также пыталась вытащить график зависимостей из файла, но тоже безуспешно. #Python, #Tools, #Работа
👍1
Продолжаю возиться с Ангуляром, теперь уже на проекте.
Бекенд (модельки, админку, апишки) собрала за 1 день. Потом приступила к фронту. Сначала я долго ковырялась с конфигами, но таки разобралась в итоге, чтобы разделить конфиг сборки для прода и обычный. Все это делается в angular.json. По сути я добавила только в projects->project->architect-> configurations -> production следующее:
Ну, и кроме этого в build -> options заменила outputPath на привычный "build/static" вместо dist.
Все это нужно было, чтобы подружить Ангуляр и Джангу. Я так уже делала для реакта. Получается, что когда я делаю билд для прода, у меня автоматом подставляются верные пути к статике (за это как раз отвечает deployUrl) и index.html не складывается в ту же папку статики, которую парсит джанга, а генерит рядышком, куда я прописала путь для шаблона Джанге. Шикарно!
Ну, и в переменные среды для dev версии прописала локальные хост и порт, где крутится джанга, а вот в прод оно уже будет собираться с относительными путями (вроде как абсолютные лучше, но у меня пока нет необходимости). Это нужно для подключения к web-сервисам.
Заманалась искать все эти нюансы, потому что в документации все неочевидно было для меня. И более того, я долго тупила как же вообще загуглить, чтобы найти нужную информацию.
Потом я еще долго воевала как подключить шрифты. Тоже было весело.
И наконец, сама разработка. С одной стороны структура проекта вполне себе понятная, особенно после прохождения туториала. Работать довольно приятно. Надо только еще разобраться как пользоваться material ui, а то как-то верстальщик из меня не очень.
Я тащусь от того, что ангуляр сам генерит необходимую структуру компонентов, сам тянет нужные зависимости, очень удобно.
Но! Как же непривычно со строгой типизацией type-script. Иногда горит, потому что не понимаю, что ему не нравится. А ему на все структуру подайте. ВСЕ ДОЛЖНО БЫТЬ ЧЕТЕНЬКО! Это вам не js и не python. 12 интерфейсов для отражения структуры всех-всех типов объектов. Что? Ты хочешь передать объект и обращаться к его ключам? Будь добра зафиксируй, что у тебя ключи - это строки:
Не уверена, что это правильный путь, но я не придумала как иначе сделать свой цикл:
А иначе - не, type-script топал ножкой и не хотел заводить мне мой цикл( Вот такие дела.
Но мне понравилось!) #JS, #Работа
Бекенд (модельки, админку, апишки) собрала за 1 день. Потом приступила к фронту. Сначала я долго ковырялась с конфигами, но таки разобралась в итоге, чтобы разделить конфиг сборки для прода и обычный. Все это делается в angular.json. По сути я добавила только в projects->project->architect-> configurations -> production следующее:
"index": {
"input": "src/index.html",
"output": "../index.html"
},
Ну, и кроме этого в build -> options заменила outputPath на привычный "build/static" вместо dist.
Все это нужно было, чтобы подружить Ангуляр и Джангу. Я так уже делала для реакта. Получается, что когда я делаю билд для прода, у меня автоматом подставляются верные пути к статике (за это как раз отвечает deployUrl) и index.html не складывается в ту же папку статики, которую парсит джанга, а генерит рядышком, куда я прописала путь для шаблона Джанге. Шикарно!
Ну, и в переменные среды для dev версии прописала локальные хост и порт, где крутится джанга, а вот в прод оно уже будет собираться с относительными путями (вроде как абсолютные лучше, но у меня пока нет необходимости). Это нужно для подключения к web-сервисам.
Заманалась искать все эти нюансы, потому что в документации все неочевидно было для меня. И более того, я долго тупила как же вообще загуглить, чтобы найти нужную информацию.
Потом я еще долго воевала как подключить шрифты. Тоже было весело.
И наконец, сама разработка. С одной стороны структура проекта вполне себе понятная, особенно после прохождения туториала. Работать довольно приятно. Надо только еще разобраться как пользоваться material ui, а то как-то верстальщик из меня не очень.
Я тащусь от того, что ангуляр сам генерит необходимую структуру компонентов, сам тянет нужные зависимости, очень удобно.
Но! Как же непривычно со строгой типизацией type-script. Иногда горит, потому что не понимаю, что ему не нравится. А ему на все структуру подайте. ВСЕ ДОЛЖНО БЫТЬ ЧЕТЕНЬКО! Это вам не js и не python. 12 интерфейсов для отражения структуры всех-всех типов объектов. Что? Ты хочешь передать объект и обращаться к его ключам? Будь добра зафиксируй, что у тебя ключи - это строки:
[index: string]: any;
}
Не уверена, что это правильный путь, но я не придумала как иначе сделать свой цикл:
getFilters(filters: Filter): string {
let result = '';
for (const filter of Object.keys(filters)) {
const value = filters[filter];
result += `&${filter}=${value}`;
}
return result;
}А иначе - не, type-script топал ножкой и не хотел заводить мне мой цикл( Вот такие дела.
Но мне понравилось!) #JS, #Работа
Закончилась короткая, но дивная неделька!
Познакомилась с новым:
- декоратор lru_cache.
https://pythonz.net/references/named/functools.lru_cache/
Эта штука кэширует результат выполнения функции для одинаковых атрибутов. В моем случае при использовании библиотеки formulas парсинг excel файла занимал около 9 секунд. Закэшировав функцию с парсингом, я получила постоянный и быстрый доступ к уже готовой xl_model:
```python
@lru_cache(maxsize=2)
def get_model():
xl_model = formulas.ExcelModel().loads(EXCEL_SOURCE).finish(circular=True)
return xl_mod
```
- По умолчанию в PyCharm стоит длина строки 120, а в PEP 79. Я была уверена, что PyCharm мне показывает 79, но нет. Пришлось идти в настройки и править. 79 символов - это так мало(
Есть еще такая штука https://tirinox.ru/flake8-pycharm/, но надо настраивать. Попробую как-нибудь.
- Правильный импорт файла, если он лежит в той же директории, что и скрипт:
- 1_000_000 == 1000000. Божечки-кошечки, это круто. Смысл в том, что число с пробелами не напишешь, а вот так норм.
- ssh и работа с ним (сейчас у опытных чуваков рука-лицо, но да, я никогда не делала этого).
Научилась выполнять команды на сервере через ssh-подключение без переключения на терминал внутри сервера.
Это типа таких вещей:
```shell
scp -i ~/.ssh/key user@host:file . # копирует файл с сервера к себе (если ключ по дефолту, то указывать его не нужно
ssh user@host 'rm file' # в кавычках команда для выполнения
```
Спасибо коллегам за развитие. Познавательно.
И вроде столько всего делала сама, но из таких мелочей, наверное, начинает складываться мастерство. #Python, #Работа, #Tools
Познакомилась с новым:
- декоратор lru_cache.
https://pythonz.net/references/named/functools.lru_cache/
Эта штука кэширует результат выполнения функции для одинаковых атрибутов. В моем случае при использовании библиотеки formulas парсинг excel файла занимал около 9 секунд. Закэшировав функцию с парсингом, я получила постоянный и быстрый доступ к уже готовой xl_model:
```python
@lru_cache(maxsize=2)
def get_model():
xl_model = formulas.ExcelModel().loads(EXCEL_SOURCE).finish(circular=True)
return xl_mod
el```
- По умолчанию в PyCharm стоит длина строки 120, а в PEP 79. Я была уверена, что PyCharm мне показывает 79, но нет. Пришлось идти в настройки и править. 79 символов - это так мало(
Есть еще такая штука https://tirinox.ru/flake8-pycharm/, но надо настраивать. Попробую как-нибудь.
- Правильный импорт файла, если он лежит в той же директории, что и скрипт:
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
EXCEL = 'file.xlsx'
EXCEL_SOURCE = os.path.join(DIR_PATH, EXCEL)
Я видела, конечно, как в Django прописаны импорты, но никогда не делала сама.- 1_000_000 == 1000000. Божечки-кошечки, это круто. Смысл в том, что число с пробелами не напишешь, а вот так норм.
- ssh и работа с ним (сейчас у опытных чуваков рука-лицо, но да, я никогда не делала этого).
Научилась выполнять команды на сервере через ssh-подключение без переключения на терминал внутри сервера.
Это типа таких вещей:
```shell
scp -i ~/.ssh/key user@host:file . # копирует файл с сервера к себе (если ключ по дефолту, то указывать его не нужно
ssh user@host 'rm file' # в кавычках команда для выполнения
```
Банально и все знают? Я раньше не работала с ssh, для меня это все было в новинку.Спасибо коллегам за развитие. Познавательно.
И вроде столько всего делала сама, но из таких мелочей, наверное, начинает складываться мастерство. #Python, #Работа, #Tools
В - внимательность.
После прохождения код-ревью своих задач осознала, что мне очень сильно не хватает внимательности к мелочам. Часто вылезают даже не ошибки, а дублирование проверок, повторные однотипные действия, которые стоило бы замечать.
Например, 5 строчек назад стояло условие if value is None, а я внутри этого условия присваиваю value = None. Зачем? Просто потому что) И потом не вижу этого. Ну, я ж все правильно написала?!)
И таких мелочей довольно много. Сама за собой, естественно, я этого не замечала.
Интересно, как прокачать этот скилл? #Работа
После прохождения код-ревью своих задач осознала, что мне очень сильно не хватает внимательности к мелочам. Часто вылезают даже не ошибки, а дублирование проверок, повторные однотипные действия, которые стоило бы замечать.
Например, 5 строчек назад стояло условие if value is None, а я внутри этого условия присваиваю value = None. Зачем? Просто потому что) И потом не вижу этого. Ну, я ж все правильно написала?!)
И таких мелочей довольно много. Сама за собой, естественно, я этого не замечала.
Интересно, как прокачать этот скилл? #Работа
Из менеджера в разработчики.
Я была неплохим менеджером - Кромеритой. Сейчас пишу код и наслаждаюсь этим. Мне нравилась моя работа, нравилось управлять проектами, командами, нравилось писать тз, заниматься бизнес-аналитикой, выстраивать процессы, я спокойно, в целом, брала на себя ответственность, что важно для менеджера. Но я все время хотела программировать. Я хотела сама писать код, сама собирать проекты, сама придумывать архитектуру. Я верила, что если я стану разработчиком, то я буду неплохим специалистом.
Мне было очень жаль, что я не начала программировать еще в школе, что не знала об этом дивном мире тогда. Мне было довольно сложно начинать все с нуля, когда я все же решилась перейти в программирование. И даже теперь, я иногда испытываю отчаяние от того, что как разработчику мне еще расти и расти, что нужно еще много времени, чтобы подняться на хороший уровень. Но я на пути и это главное. #Работа, #Истории
Я была неплохим менеджером - Кромеритой. Сейчас пишу код и наслаждаюсь этим. Мне нравилась моя работа, нравилось управлять проектами, командами, нравилось писать тз, заниматься бизнес-аналитикой, выстраивать процессы, я спокойно, в целом, брала на себя ответственность, что важно для менеджера. Но я все время хотела программировать. Я хотела сама писать код, сама собирать проекты, сама придумывать архитектуру. Я верила, что если я стану разработчиком, то я буду неплохим специалистом.
Мне было очень жаль, что я не начала программировать еще в школе, что не знала об этом дивном мире тогда. Мне было довольно сложно начинать все с нуля, когда я все же решилась перейти в программирование. И даже теперь, я иногда испытываю отчаяние от того, что как разработчику мне еще расти и расти, что нужно еще много времени, чтобы подняться на хороший уровень. Но я на пути и это главное. #Работа, #Истории
Итоги недели)
Я тут решаю занимательную задачу - выделение существующего функционала в отдельный сервис. Хочу поделиться впечатлениями.
Django.
Отдельный сервис, свежая джанга, но та же бд. Копирую существующие модели в новое приложение, прописываю существующие таблицы так:
Никаких миграций. Прописываю для admin те же модели, чтобы вывести существующие данные. Запускаю новую джангу, захожу под существующим в базе пользователем, вижу данные. Все ок, работает!
Не то, чтобы это было сложно или неожиданно, но я реально не подозревала как оно заведется.
Celery и Telegram.
Я уже работала с Celery ранее на своем проекте. Использовала админку для создания нужного расписания. Смотрела ход выполнения в логах.
Сейчас я научилась выводить список задач в очереди и список выполняемых задач:
app в данном случае приложение Celery:
Это все я выведу на страничку, чтобы пользователь мог видеть, что происходит. Эдакий кастомный мониторинг. На самом деле для Celery есть Flower https://docs.celeryproject.org/en/stable/userguide/monitoring.html#flower-real-time-celery-web-monitor, но он избыточен в нашем случае.
А по результатам выполнения задачек настроила уведомления в Telegram. Делаю это на базе Celery Signals https://docs.celeryproject.org/en/stable/userguide/signals.html
С названиями функций у меня пока не очень( Сама чувствую, что идиотское название, но ничего пока лучше не пришло. Буду еще причесывать.
Из странного. Почему-то когда попыталась перенести отлавливание сигналов из стандартного файла tasks.py, сохранив все зависимости и тп, сигналы перестали срабатывать. Подозреваю, что для Celery важно прописывать пути, где лежат задачи и сигналы, при этом tasks.py в приложении вроде как работает по умолчанию. Но не копала пока точно эту тему, оставила в tasks.py.
Docker! Куда ж без него.
В docker-compose для того, чтобы локально поднять новый сервис, но подключиться к бд и Redis другого сервиса пришлось прокинуть network от исходного сервиса (venv_my-network):
И прописать в исходном проекте в конфиге алиасы для бд и Redis:
Есть еще вариант прокидывать connect с помощью команды:
Задача очень интересная. Надеюсь, что в результате все получится классно и удобно. Пока это только наброски. #Django, #Docker, #Работа
Я тут решаю занимательную задачу - выделение существующего функционала в отдельный сервис. Хочу поделиться впечатлениями.
Django.
Отдельный сервис, свежая джанга, но та же бд. Копирую существующие модели в новое приложение, прописываю существующие таблицы так:
class Meta:
db_table = 'old_app_model'
Никаких миграций. Прописываю для admin те же модели, чтобы вывести существующие данные. Запускаю новую джангу, захожу под существующим в базе пользователем, вижу данные. Все ок, работает!
Не то, чтобы это было сложно или неожиданно, но я реально не подозревала как оно заведется.
Celery и Telegram.
Я уже работала с Celery ранее на своем проекте. Использовала админку для создания нужного расписания. Смотрела ход выполнения в логах.
Сейчас я научилась выводить список задач в очереди и список выполняемых задач:
i = app.control.inspect()
active_workers_tasks: dict = i.active()
scheduled_workers_tasks = i.scheduled()
app в данном случае приложение Celery:
from celery import Celery
app = Celery('name')
Это все я выведу на страничку, чтобы пользователь мог видеть, что происходит. Эдакий кастомный мониторинг. На самом деле для Celery есть Flower https://docs.celeryproject.org/en/stable/userguide/monitoring.html#flower-real-time-celery-web-monitor, но он избыточен в нашем случае.
А по результатам выполнения задачек настроила уведомления в Telegram. Делаю это на базе Celery Signals https://docs.celeryproject.org/en/stable/userguide/signals.html
@task_success.connect
def task_success_notify(signal, sender, result, **kwargs):
tag = make_tag('success')
notify_data = make_notify_task_params(sender.request)
notify_data["Результат"] = result
text = tag + make_text_from_dict(notify_data)
send_message(text)
С названиями функций у меня пока не очень( Сама чувствую, что идиотское название, но ничего пока лучше не пришло. Буду еще причесывать.
Из странного. Почему-то когда попыталась перенести отлавливание сигналов из стандартного файла tasks.py, сохранив все зависимости и тп, сигналы перестали срабатывать. Подозреваю, что для Celery важно прописывать пути, где лежат задачи и сигналы, при этом tasks.py в приложении вроде как работает по умолчанию. Но не копала пока точно эту тему, оставила в tasks.py.
Docker! Куда ж без него.
В docker-compose для того, чтобы локально поднять новый сервис, но подключиться к бд и Redis другого сервиса пришлось прокинуть network от исходного сервиса (venv_my-network):
networks:
venv_my-network:
driver: bridge
external: true
И прописать в исходном проекте в конфиге алиасы для бд и Redis:
networks:
my-network:
aliases:
- redis
Есть еще вариант прокидывать connect с помощью команды:
docker network connect --alias db venv_my-network container_id
Задача очень интересная. Надеюсь, что в результате все получится классно и удобно. Пока это только наброски. #Django, #Docker, #Работа
Индексы, бл**Ь! Говорили мне все, говорили... Я им - у меня вон gin-индекс! У меня все хорошо с ними, вот только память чет уходит и вообще боль.
Ну что же. Я сегодня добавила индексы для дат. БД наконец-таки отпустило! Ура!
Просто. Тупо. Индексы для дат.
Но заметила еще периодическую ошибку, хз с чем связано, но в какой-то магический момент на функцию bulk_create начинает стабильно лететь ошибка connection already closed. При чем перезапуск приложения эту проблему решает. Надо шаманить работу с бд в этом моменте.
Но это мелочи по сравнением с тем, что я наконец смогла скинуть ресурсы для бд до 2 cpu и 2 ГБ памяти. Ура, товарищи! #Работа
Ну что же. Я сегодня добавила индексы для дат. БД наконец-таки отпустило! Ура!
Просто. Тупо. Индексы для дат.
add_date = models.DateTimeField(auto_now_add=True, db_index=True)
Но заметила еще периодическую ошибку, хз с чем связано, но в какой-то магический момент на функцию bulk_create начинает стабильно лететь ошибка connection already closed. При чем перезапуск приложения эту проблему решает. Надо шаманить работу с бд в этом моменте.
Но это мелочи по сравнением с тем, что я наконец смогла скинуть ресурсы для бд до 2 cpu и 2 ГБ памяти. Ура, товарищи! #Работа
Сижу, тыкаю цены Яндекс Облака, выглядит вроде как несколько дешевле, чем aws. С другой стороны, я использую дешевые споты на aws за 1.2 - 1.4 цента в час или около 650 рублей в месяц за t3.medium 2 cpu и 4 памяти. Но вот бд у меня в RDS - это отдельный специальный инстанс, очередь в sqs, логи в cloud watch, не говоря про то, что крутится на lambda и использование api gateway для endpoint. Очень распределенная система, так сказать. Не хватает только подключение к S3 для хранения медиа, о чем я давно думаю, но никак не соберусь сделать.
И вот все начинают с одной машины, на которой все это поднимают. А я сразу строила чертов замок. И как-то ненормально пытаться теперь все это собрать на одну машинку. Да?)
И вроде я все это сделала не от большого ума и опыта, а просто потому что просто как-то так вышло. Один очень влиятельный господин сразу запинал меня в aws и пришлось крутиться) Как смогла, так и выкручивалась. Мы ж не ищем легких путей.
В общей сумме за февраль за aws было выплачено 83.52 доллара (около 6300 рублей). Это на самом деле как-то дофига. Но я жду, что после оптимизации базы данных стоимость упадет почти на 26 долларов до 57.6 долларов или будет около 4500 рублей в месяц.
На облаке если посчитать все, что мне нужно, наверное, в итоге выйдет примерно также.
Еще есть вариант с Digital Ocean, там тоже вроде цены не кусачие.
Но! Если aws еще подкрутить, то там тоже можно еще немного сбить цену. Плюс я уже начала любить aws (стокгольмский синдром?!). На самом деле ковыряться с инфрой - то еще удовольствие. Наверное, оставлю пока все как есть. #AWS
И вот все начинают с одной машины, на которой все это поднимают. А я сразу строила чертов замок. И как-то ненормально пытаться теперь все это собрать на одну машинку. Да?)
И вроде я все это сделала не от большого ума и опыта, а просто потому что просто как-то так вышло. Один очень влиятельный господин сразу запинал меня в aws и пришлось крутиться) Как смогла, так и выкручивалась. Мы ж не ищем легких путей.
В общей сумме за февраль за aws было выплачено 83.52 доллара (около 6300 рублей). Это на самом деле как-то дофига. Но я жду, что после оптимизации базы данных стоимость упадет почти на 26 долларов до 57.6 долларов или будет около 4500 рублей в месяц.
На облаке если посчитать все, что мне нужно, наверное, в итоге выйдет примерно также.
Еще есть вариант с Digital Ocean, там тоже вроде цены не кусачие.
Но! Если aws еще подкрутить, то там тоже можно еще немного сбить цену. Плюс я уже начала любить aws (стокгольмский синдром?!). На самом деле ковыряться с инфрой - то еще удовольствие. Наверное, оставлю пока все как есть. #AWS
Дневник можно переименовать в еженедельник)
Отчет за недельку:
Докер
Продолжаю познавать докер и перестаю его бояться. Узнала про команды:
- docker stats - выводит состояние запущенных контейнеров (использование CPU, памяти, сети и тп).
Узнала знаете как? Первый раз у меня докер сожрал 18 ГБ памяти, а второй раз проц ушел в полку. Я решила, что хватит это терпеть, пора все же посмотреть, что там происходит.
- docker-compose up container -d
Эта приставка -d делает так, чтобы докер не начал срать своими логами в терминал, когда его запускаешь. Надоело переоткрывать терминал, поэтому сходила и посмотрела как это нормально делается.
Ну и плюс узнала как задать лимит по памяти для контейнера. Но почему-то то, что работало у меня на компе, не завелось на сервере.
logging
Когда я писала логирование для своего проекта, я просто узнала как логировать, написала свою простенькую функцию для логирования (вроде писала о ней выше) и мне было норм. Все мои логи aws заботливо собирает в CloudWatch, там прекрасный интерфейс и я довольная всегда имею доступ ко всем последним событиям на своем проекте, и не только к последним. AWS все сделал за меня! Почти все, функции обкладывала логами все же сама.
А тут на работе понадобилось логи складывать в текстовые файлики и очищать их со временем чем-нибудь, чтобы не засоряли пространство. При этом еще стоило их разделять на отдельные файлики. И пришлось мне таки разобраться как вообще работает logging.
Мне посоветовали https://www.youtube.com/watch?v=qqdgynJ5ATU это видео, но это уже после того как я перерыла кучу инфы в интернете и наваяла вот это:
```python
import logging
import logging.handlers
import os
def get_logger(filename: str):
"""
Функция возвращает logger по имени и сохраняет логи в файлы с
соответствующим названием, разделяя по часам
:param filename: название для logger
:return: logger
"""
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
logger = logging.getLogger(filename)
logger.propagate = False
if not logger.handlers:
log_path = os.path.join(LOG_DIR, f"{filename}.log")
file_handler = logging.handlers.TimedRotatingFileHandler(
log_path, when='h', interval=1, backupCount=90
)
log_formatter = logging.Formatter("[%(levelname)s] "
"%(asctime)s %(message)s")
file_handler.setFormatter(log_formatter)
logger.addHandler(file_handler)
logger.setLevel('INFO')
return logger
```
- обработчики (handlers) сделают всю грязную работу за меня. TimedRotatingFileHandler разделяет файлы по заданным промежуткам времени, параметр backupCount указывает на то, через какое количество созданных файлов их надо чистить.
- форматирование Formatter. Для него полезно знать о том, какие атрибуты вообще есть у лог-записи https://docs.python.org/3/library/logging.html#logrecord-attributes. Я там обнаружила, что есть та вещь, которую я в свое время прописывала ручками в своей функции, а именно funcName - название функции, в рамках которой залогирована запись.
Это круто. Я понимаю, что языки программирования не дураки пишут и библиотеки тоже. Дураки (незнающие) пользуются всем этим добром криво-косо и страдают. А там такое вот чудо.
О дивный новый мир. #Python, #Docker, #Работа
Отчет за недельку:
Докер
Продолжаю познавать докер и перестаю его бояться. Узнала про команды:
- docker stats - выводит состояние запущенных контейнеров (использование CPU, памяти, сети и тп).
Узнала знаете как? Первый раз у меня докер сожрал 18 ГБ памяти, а второй раз проц ушел в полку. Я решила, что хватит это терпеть, пора все же посмотреть, что там происходит.
- docker-compose up container -d
Эта приставка -d делает так, чтобы докер не начал срать своими логами в терминал, когда его запускаешь. Надоело переоткрывать терминал, поэтому сходила и посмотрела как это нормально делается.
Ну и плюс узнала как задать лимит по памяти для контейнера. Но почему-то то, что работало у меня на компе, не завелось на сервере.
logging
Когда я писала логирование для своего проекта, я просто узнала как логировать, написала свою простенькую функцию для логирования (вроде писала о ней выше) и мне было норм. Все мои логи aws заботливо собирает в CloudWatch, там прекрасный интерфейс и я довольная всегда имею доступ ко всем последним событиям на своем проекте, и не только к последним. AWS все сделал за меня! Почти все, функции обкладывала логами все же сама.
А тут на работе понадобилось логи складывать в текстовые файлики и очищать их со временем чем-нибудь, чтобы не засоряли пространство. При этом еще стоило их разделять на отдельные файлики. И пришлось мне таки разобраться как вообще работает logging.
Мне посоветовали https://www.youtube.com/watch?v=qqdgynJ5ATU это видео, но это уже после того как я перерыла кучу инфы в интернете и наваяла вот это:
```python
import logging
import logging.handlers
import os
def get_logger(filename: str):
"""
Функция возвращает logger по имени и сохраняет логи в файлы с
соответствующим названием, разделяя по часам
:param filename: название для logger
:return: logger
"""
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
logger = logging.getLogger(filename)
logger.propagate = False
if not logger.handlers:
log_path = os.path.join(LOG_DIR, f"{filename}.log")
file_handler = logging.handlers.TimedRotatingFileHandler(
log_path, when='h', interval=1, backupCount=90
)
log_formatter = logging.Formatter("[%(levelname)s] "
"%(asctime)s %(message)s")
file_handler.setFormatter(log_formatter)
logger.addHandler(file_handler)
logger.setLevel('INFO')
return logger
```
Главные открытия:- обработчики (handlers) сделают всю грязную работу за меня. TimedRotatingFileHandler разделяет файлы по заданным промежуткам времени, параметр backupCount указывает на то, через какое количество созданных файлов их надо чистить.
- форматирование Formatter. Для него полезно знать о том, какие атрибуты вообще есть у лог-записи https://docs.python.org/3/library/logging.html#logrecord-attributes. Я там обнаружила, что есть та вещь, которую я в свое время прописывала ручками в своей функции, а именно funcName - название функции, в рамках которой залогирована запись.
Это круто. Я понимаю, что языки программирования не дураки пишут и библиотеки тоже. Дураки (незнающие) пользуются всем этим добром криво-косо и страдают. А там такое вот чудо.
О дивный новый мир. #Python, #Docker, #Работа
Фух, я закончила фронтовую часть проекта.
Очень сложно пилить интерфейс по дизайну, не зная верстки. Еще один пунктик в копилку того, что стоит, наверное, все же изучить плотнее - css и все, что с ним связано. Также сложно было пилить проект на Angular, почти не зная его.
Больно было сделать банальную штуку - листание блоков контента по кнопке, чтобы так тык и блок плавно докрутился до следующих элементов. Я гуглила как бешенная, я хотела уже применить "помощь друга", что я делаю на самом деле не очень часто, как мне кажется. Но в последний момент вспомнила, что я подобную штуку делала, когда проходила курс по JS. Просто мне не доводилось применять это и я не запомнила как она делается. Открыла курс, код курса и бинго! Сделано!
Еще довелось прикрутить генерацию кропа для изображения по заданной площади. Нет, конечно, я честно использовала готовые решения. В первый момент было забавно, когда я осознала, что новый кроп то я сохраняю, но и старый файл остается, он никуда сам не исчезает. Это вроде на поверхности, но осознала я это случайно, когда заглянула в папку с медиа, пока проверяла локально. А там... 100500 почти одинаковых картиночек. Пришлось дописать логику удаления предыдущего файлика. Так что готовые решения иногда не такие уж и готовые.
С цитатами еще пришлось повозиться, чтобы они выделялись на фоне красивыми большими кавычками. Спасибо интернет за примеры решений.
Что я могу сказать? Жесть какая-то, я потратила часов 20-30 на весь бекенд и где-то больше 70 часов на фронтенд.
Waka time насчитал мне за март уже больше 250 часов кода, в среднем где-то по 65-70 часов в неделю. Чет я усталь немножко.
И! Прошел год, как я начала ковырять программирование. Я тут ковыряюсь в своем первом проекте, который работает и я в нем иногда кое-что допиливаю. Не сказать, что там все прямо плохо, но на многие вещи без слез не взглянешь. Спасибо, кстати, отчасти коллегам за науку в плане внимания к мелочам. Я стала несколько щепетильнее относится к тому, что и как я пишу.
Сумбурно. Я просто хочу как-то подвести итоги года, но, наверное, не в этот раз. Напишу чуть позже.
Реально, я устала. Простите.
С работы ушла, кстати. Пилю сама по себе, как та кошка. Есть в этом свои минусы и свои плюсы. Скучаю немножко по общению и по каким-никаким задачам (в смысле формальности, вот тебе задачи, иди делай, а не так, что вот тебе набор мыслей, надо бы из них сделать хорошо). Могу и сама себе задачи ставить, по сути так и делаю, но как-то нет в этом кайфа) чисто ради порядка и истории. #Работа
Очень сложно пилить интерфейс по дизайну, не зная верстки. Еще один пунктик в копилку того, что стоит, наверное, все же изучить плотнее - css и все, что с ним связано. Также сложно было пилить проект на Angular, почти не зная его.
Больно было сделать банальную штуку - листание блоков контента по кнопке, чтобы так тык и блок плавно докрутился до следующих элементов. Я гуглила как бешенная, я хотела уже применить "помощь друга", что я делаю на самом деле не очень часто, как мне кажется. Но в последний момент вспомнила, что я подобную штуку делала, когда проходила курс по JS. Просто мне не доводилось применять это и я не запомнила как она делается. Открыла курс, код курса и бинго! Сделано!
Еще довелось прикрутить генерацию кропа для изображения по заданной площади. Нет, конечно, я честно использовала готовые решения. В первый момент было забавно, когда я осознала, что новый кроп то я сохраняю, но и старый файл остается, он никуда сам не исчезает. Это вроде на поверхности, но осознала я это случайно, когда заглянула в папку с медиа, пока проверяла локально. А там... 100500 почти одинаковых картиночек. Пришлось дописать логику удаления предыдущего файлика. Так что готовые решения иногда не такие уж и готовые.
С цитатами еще пришлось повозиться, чтобы они выделялись на фоне красивыми большими кавычками. Спасибо интернет за примеры решений.
Что я могу сказать? Жесть какая-то, я потратила часов 20-30 на весь бекенд и где-то больше 70 часов на фронтенд.
Waka time насчитал мне за март уже больше 250 часов кода, в среднем где-то по 65-70 часов в неделю. Чет я усталь немножко.
И! Прошел год, как я начала ковырять программирование. Я тут ковыряюсь в своем первом проекте, который работает и я в нем иногда кое-что допиливаю. Не сказать, что там все прямо плохо, но на многие вещи без слез не взглянешь. Спасибо, кстати, отчасти коллегам за науку в плане внимания к мелочам. Я стала несколько щепетильнее относится к тому, что и как я пишу.
Сумбурно. Я просто хочу как-то подвести итоги года, но, наверное, не в этот раз. Напишу чуть позже.
Реально, я устала. Простите.
С работы ушла, кстати. Пилю сама по себе, как та кошка. Есть в этом свои минусы и свои плюсы. Скучаю немножко по общению и по каким-никаким задачам (в смысле формальности, вот тебе задачи, иди делай, а не так, что вот тебе набор мыслей, надо бы из них сделать хорошо). Могу и сама себе задачи ставить, по сути так и делаю, но как-то нет в этом кайфа) чисто ради порядка и истории. #Работа
Столько разговоров про CI/CD... Меня добила фраза "Только ленивый сейчас себе не сделал еще CI/CD". Ну раз это так просто, значит можно раз-раз и сделать, да? Посмотрела видео про github actions. Удобная штука, не поспоришь.
Вот, я начала на спотах в aws поднимать дешевые инстансы для тестирования. У меня есть подключение по ssh к ним, а сервисы поднимаются через docker-compose (web, db и тд).
Короче, я крутила-мутила. Поняла что, либо копать в сторону реджистри и каким-то образом прикручивать автодеплой через него, либо настраивать автодеплой в самом aws. Потому что иначе, это вышло как-то боком. Использовала https://circleci.com/, потому что в нем можно хранить приватный ssh-ключ. Это вообще законно?)
И у меня теперь есть типа ci/cd. Хах. Суть его в одной команде
```ssh instance 'git pull && docker-compose up -d --build'
```И все это подписано на обновление мастера в гите.
Потом, может, прикручу что-то более "умное", ну или таки научусь юзать aws во всей красе "занидорога".
Про actions неплохо рассказывают и дают общее понимание вот в этом ролике https://www.youtube.com/watch?v=Yg5rpke79X4 #Работа
Вот, я начала на спотах в aws поднимать дешевые инстансы для тестирования. У меня есть подключение по ssh к ним, а сервисы поднимаются через docker-compose (web, db и тд).
Короче, я крутила-мутила. Поняла что, либо копать в сторону реджистри и каким-то образом прикручивать автодеплой через него, либо настраивать автодеплой в самом aws. Потому что иначе, это вышло как-то боком. Использовала https://circleci.com/, потому что в нем можно хранить приватный ssh-ключ. Это вообще законно?)
И у меня теперь есть типа ci/cd. Хах. Суть его в одной команде
```ssh instance 'git pull && docker-compose up -d --build'
```И все это подписано на обновление мастера в гите.
Потом, может, прикручу что-то более "умное", ну или таки научусь юзать aws во всей красе "занидорога".
Про actions неплохо рассказывают и дают общее понимание вот в этом ролике https://www.youtube.com/watch?v=Yg5rpke79X4 #Работа
Трубопровод. Кстати, с SSH вышел забавный момент, он требует подтверждения хоста при первом подключении для добавления в доверенные. Никак не могла понять как бы это обойти. В общем, нужна была просто опция
ssh -o StrictHostKeyChecking=no#Работа
Новый друг для спины. К вопросу, если вам немного за тридцать и начала болеть поясница) Я давно думала о нем, смотрела отзывы и вот, начинаю испытания на себе. #Tools