This media is not supported in your browser
VIEW IN TELEGRAM
#забавы
Интересная рисовалка
🎨 Попалась вот такая интересная рисовалка. Смысл в том что когда начинаешь что то рисовать, она предлагает похожие варианты картинок исходя из того что ты рисуешь. Хоть вариантов выбора не так чтобы очень много, но было очень забавно поиграться. В общем мне показалась полезная штука, теперь использую ее.
======================
P.S. очень понравилось как сделан туториал по использованию. Прямо образец, как надо делать, просто и понятно.
======================
✅ Вот ссылка
Интересная рисовалка
🎨 Попалась вот такая интересная рисовалка. Смысл в том что когда начинаешь что то рисовать, она предлагает похожие варианты картинок исходя из того что ты рисуешь. Хоть вариантов выбора не так чтобы очень много, но было очень забавно поиграться. В общем мне показалась полезная штука, теперь использую ее.
======================
P.S. очень понравилось как сделан туториал по использованию. Прямо образец, как надо делать, просто и понятно.
======================
✅ Вот ссылка
#pattern
Шаблон проектирования - состояние
В формате поста шаблон описать довольно сложно. По этому постараюсь передать самую суть. В детали реализации углубляться не будем, да и не к чему это. Поехали.
Пример приближенный к реальной жизни.
Мы программируем машину (класс Car). Машина может находится в трех состояниях (пусть за это отвечает поле $state)
1 - с выключенным двигателем
2- с запущенным двигателем, но не в движении
3 - в движении соответственно с запущенным двигателем
Из функционала у нее есть пока только возможность включить фары, причем если двигатель выключен, то должны загореться габариты. Если двигатель заведен, то должны загореться фары. Если машина находится в движении, то и фары и габариты.
Попробовав запрограммировать это без использования шаблона мы скорее всего получим примерно такую функцию
1 - Когда мы будем добавлять состояния (например задний ход) нам придется добавлять еще условия.
2 - Когда мы будем добавлять новый функционал (например управление сигналом) он тоже будет зависеть от $state и туда тоже нужно будет добавлять такой же "if"
3 - Если нужно изменить поведение при каком то из состояний то нужно будет отыскать все эти "ифы" и внутри уже работающего кода внести все правки (уверен что с первого раза это не удастся)
Теперь давайте попробуем то же самое запрограммировать с использованием шаблона.
Первое что сделаем - это в переменную $state положим объект который имеет доступ к родительскому классу, то есть к Car и его методам. Таких объектов__ $state__ у нас будет в данном случае три. Каждый отвечает за свое состояние, то есть вызывает из родителя определенные функции. Один $state вызывает только метод turnOnParkingLights(), другой turnOnHeadLights(), третий оба эти метода. Для этого в $state у нас будет метод handle() Итого мы получим примерно следующий код.
1 - При добавлении состояния нам не нужно искать все "ифы" и править их, достаточно добавить новый __$state___
2 - При добавлении нового функционала мы добавляем всего одну функцию в родительский класс, без условий. А весь рабочий код добавляем в файлы состояний.
3 - Меняя какое то поведение мы делаем это в изолированном файле состояния, не затрагивая родительский класс, а значит имеем меньше шансов сломать рабочий код.
P.S. Как и говорил это урезанный вариант шаблона, просто если описать все подробно, не думаю что это будет хоть сколько интересно читать. Тут цель передать самую суть, а уже когда шаблон будет непосредственно применяться, можно и почитать более подробный разбор. Кстати вот тут очень здорово все шаблоны описаны, рекомендую ознакомиться кому интересно. Спасибо.
Шаблон проектирования - состояние
В формате поста шаблон описать довольно сложно. По этому постараюсь передать самую суть. В детали реализации углубляться не будем, да и не к чему это. Поехали.
Пример приближенный к реальной жизни.
Мы программируем машину (класс Car). Машина может находится в трех состояниях (пусть за это отвечает поле $state)
1 - с выключенным двигателем
2- с запущенным двигателем, но не в движении
3 - в движении соответственно с запущенным двигателем
Из функционала у нее есть пока только возможность включить фары, причем если двигатель выключен, то должны загореться габариты. Если двигатель заведен, то должны загореться фары. Если машина находится в движении, то и фары и габариты.
Попробовав запрограммировать это без использования шаблона мы скорее всего получим примерно такую функцию
function lightHandle()В этой функции есть аж 3 большие проблемы.
{
if ($state === 'off') {
turnOnParkingLights();
} else if ($state === 'on') {
turnOnHeadLights();
} else if ($state === 'move') {
turnOnParkingLights();
turnOnHeadLights();
}
}
1 - Когда мы будем добавлять состояния (например задний ход) нам придется добавлять еще условия.
2 - Когда мы будем добавлять новый функционал (например управление сигналом) он тоже будет зависеть от $state и туда тоже нужно будет добавлять такой же "if"
3 - Если нужно изменить поведение при каком то из состояний то нужно будет отыскать все эти "ифы" и внутри уже работающего кода внести все правки (уверен что с первого раза это не удастся)
Теперь давайте попробуем то же самое запрограммировать с использованием шаблона.
Первое что сделаем - это в переменную $state положим объект который имеет доступ к родительскому классу, то есть к Car и его методам. Таких объектов__ $state__ у нас будет в данном случае три. Каждый отвечает за свое состояние, то есть вызывает из родителя определенные функции. Один $state вызывает только метод turnOnParkingLights(), другой turnOnHeadLights(), третий оба эти метода. Для этого в $state у нас будет метод handle() Итого мы получим примерно следующий код.
//код основной функцииИтого как мы этим решили 3 наши проблемы:
function lightHandle()
{
$state->handle();
}
//$state1
function handle()
{
$parentClass->turnOnParkingLights();
}
//$state2
function handle()
{
$parentClass->turnOnHeadLights();
}
//$state3
function handle()
{
$parentClass->turnOnHeadLights();
$parentClass->turnOnHeadLights();
}
1 - При добавлении состояния нам не нужно искать все "ифы" и править их, достаточно добавить новый __$state___
2 - При добавлении нового функционала мы добавляем всего одну функцию в родительский класс, без условий. А весь рабочий код добавляем в файлы состояний.
3 - Меняя какое то поведение мы делаем это в изолированном файле состояния, не затрагивая родительский класс, а значит имеем меньше шансов сломать рабочий код.
P.S. Как и говорил это урезанный вариант шаблона, просто если описать все подробно, не думаю что это будет хоть сколько интересно читать. Тут цель передать самую суть, а уже когда шаблон будет непосредственно применяться, можно и почитать более подробный разбор. Кстати вот тут очень здорово все шаблоны описаны, рекомендую ознакомиться кому интересно. Спасибо.
refactoring.guru
Состояние
Состояние — это поведенческий паттерн проектирования, который позволяет объектам менять поведение в зависимости от своего состояния. Извне создаётся впечатление, что изменился класс объекта.
#лайфхак
Красивый вывод git log
Сандартный вывод git log сложно назвать понятным и информативным. Отчасти по этому приходится пользоваться дополнительными инструментами. Но эту проблему очень легко решить, т.к. git log имеет очень много опций. Так давайте сделаем его понятным и красивым. как на третей картинке.
1. Отформатируем вывод командой
--format - вывод информации производить в соответствии формату
%Cred - задает цвет вывода (тут красный)
%Creset - цвет заканчивается
%h - хэш коммита
%cn - имя автора
%s - описание коммита
%cr - относительное время
2. Чтобы каждый раз не вводить это все руками добавим этот вывод в аллиас, командой
Красивый вывод git log
Сандартный вывод git log сложно назвать понятным и информативным. Отчасти по этому приходится пользоваться дополнительными инструментами. Но эту проблему очень легко решить, т.к. git log имеет очень много опций. Так давайте сделаем его понятным и красивым. как на третей картинке.
1. Отформатируем вывод командой
git log --graph --format=format:"%Cred%h%Creset | %cn => %Cgreen%s%Creset (%Cblue%cr%Creset)"--graph - показывать граф с коммитами
--format - вывод информации производить в соответствии формату
%Cred - задает цвет вывода (тут красный)
%Creset - цвет заканчивается
%h - хэш коммита
%cn - имя автора
%s - описание коммита
%cr - относительное время
2. Чтобы каждый раз не вводить это все руками добавим этот вывод в аллиас, командой
git config --global alias.lg 'log --graph --format=format:"%Cred%h%Creset | %cn => %Cgreen%s%Creset (%Cblue%cr%Creset)"'Все теперь мы добавили для этого вывода простой и понятный алиас. Все что нам нужно теперь это им пользоваться.
git lg
🥚Сегодня вроде как Пасха, тогда вот парочка незамысловатых "пасхалок"
1️⃣ Пользователи "фейсбука" видимо часто подвергаются атакам. Ну не зря же там большими красными буквами вас попросят остановиться 🙅♂️
2️⃣ А вот ребята из "Тинькофф" даже консоль используют для продвижения. Там они ищут разработчиков и собирают баги. Считаешь что потянешь? тогда пиши им, почта в консоли) 📨
3️⃣ Тот кто юзает убунту, может попробовать поставить себе пакет moo. Ха-ха, а ведь серьезные люди! 🐄
Спасибо, надеюсь ни кто не обижен 🤷♂️
1️⃣ Пользователи "фейсбука" видимо часто подвергаются атакам. Ну не зря же там большими красными буквами вас попросят остановиться 🙅♂️
2️⃣ А вот ребята из "Тинькофф" даже консоль используют для продвижения. Там они ищут разработчиков и собирают баги. Считаешь что потянешь? тогда пиши им, почта в консоли) 📨
3️⃣ Тот кто юзает убунту, может попробовать поставить себе пакет moo. Ха-ха, а ведь серьезные люди! 🐄
Спасибо, надеюсь ни кто не обижен 🤷♂️
This media is not supported in your browser
VIEW IN TELEGRAM
XSS ну или наполовину XSS
Недавно просматривал один агрегатор в поисках каналов в телеграме и увидел вот такую интересную штуку. В графе где указано название канала, пользователь ввел очень длинный текст. Из за этого строка растянулась в высоту и перекрыла кнопки навигации, сделав их неактивными 😭😭😭. Усугубилось все тем что та часть которая все перекрыла - прозрачная и создается полное ощущение что кнопки просто не работают, а на самом деле просто поверх этих кнопок лежит прозрачный контейнер. 🤷♂️👏
Конкретно в данном случае врядли это нанесло большой ущерб, а в представьте например если бы на каком то условном "авито" чье то объявление перекрыло навигацию. Думаю кто-то, а может быть и не один искал работу. 🚷
✅ И да это конечно не совсем XSS, но внедрение в принципе удалось, хоть и не специально.
❗️❗️❗️Мораль - всегда проверяй пользовательский ввод.
Недавно просматривал один агрегатор в поисках каналов в телеграме и увидел вот такую интересную штуку. В графе где указано название канала, пользователь ввел очень длинный текст. Из за этого строка растянулась в высоту и перекрыла кнопки навигации, сделав их неактивными 😭😭😭. Усугубилось все тем что та часть которая все перекрыла - прозрачная и создается полное ощущение что кнопки просто не работают, а на самом деле просто поверх этих кнопок лежит прозрачный контейнер. 🤷♂️👏
Конкретно в данном случае врядли это нанесло большой ущерб, а в представьте например если бы на каком то условном "авито" чье то объявление перекрыло навигацию. Думаю кто-то, а может быть и не один искал работу. 🚷
✅ И да это конечно не совсем XSS, но внедрение в принципе удалось, хоть и не специально.
❗️❗️❗️Мораль - всегда проверяй пользовательский ввод.
Очень удобная штука, позволяет сделать в проекте иконки в виде шрифтов. Как например Glyphicon в Бутстрапе.
Но при этом не нужно будет подключать ни какие библиотеки.
1️⃣ На сайте icomoon.io создаем новое приложение.
2️⃣ Выбираем нужные иконки, нажимаем создать шрифт и скачиваем все что получилось.
3️⃣ То что скачалось разархивируем в папку с проектом.
4️⃣ И того из того что скачается нам нужен только файл style.css там лежат необходимые стили и содержимое папки fonts, там непосредственно шрифты.
5️⃣ У меня в тестовом проекте только индексный файл, по этому все что нужно сделать - это подключить к нему скачанный файл style.css.
6️⃣ Затем добавим в индексный файл простые дивы с классами указанными в style.css.
7️⃣ Вот и все, смотрим, что у нас получилось.
icomoon.io
Но при этом не нужно будет подключать ни какие библиотеки.
1️⃣ На сайте icomoon.io создаем новое приложение.
2️⃣ Выбираем нужные иконки, нажимаем создать шрифт и скачиваем все что получилось.
3️⃣ То что скачалось разархивируем в папку с проектом.
4️⃣ И того из того что скачается нам нужен только файл style.css там лежат необходимые стили и содержимое папки fonts, там непосредственно шрифты.
5️⃣ У меня в тестовом проекте только индексный файл, по этому все что нужно сделать - это подключить к нему скачанный файл style.css.
6️⃣ Затем добавим в индексный файл простые дивы с классами указанными в style.css.
7️⃣ Вот и все, смотрим, что у нас получилось.
icomoon.io
Небольшая задачка по PHP
========================================
Правильный ответ - "что то третее"
Почему? Потому что как и везде для каждого скалярного типа данных в PHP предусмотрена определенная длинна. Например для типа int она будет равна либо 32 либо 64 бита, в зависимости от вашей системы. У меня например на убунте это 64 бита то есть 9 223 372 036 854 775 807, в 32 разрядной винде это будет 2 147 483 647.
То есть получается что когда строку '99999999999999999999999999999999999' мы приводим к integer то максимум что мы туда можем записать - это 9 223 372 036 854 775 807 (в моем случае)
========================================
Правильный ответ - "что то третее"
Почему? Потому что как и везде для каждого скалярного типа данных в PHP предусмотрена определенная длинна. Например для типа int она будет равна либо 32 либо 64 бита, в зависимости от вашей системы. У меня например на убунте это 64 бита то есть 9 223 372 036 854 775 807, в 32 разрядной винде это будет 2 147 483 647.
То есть получается что когда строку '99999999999999999999999999999999999' мы приводим к integer то максимум что мы туда можем записать - это 9 223 372 036 854 775 807 (в моем случае)
Надо быть осторожным с функцией CONCAT в MYSQL
Потому что она имеет один неочевидный момент в своем поведении. Если хоть один из аргументов переданных ей NULL то весь результат будет также NULL
Вот пример. Есть у нас такая таблица с customers
+----+-—-------+----—-----+
| id | name | deposit |
+----+--—------+-----—----+
| 1 | misha | 500 |
| 2 | sveta | 700 |
| 3 | oleg | 234 |
| 4 | inga | NULL |
+----+----——--+--—------+
И хотим мы вывести в красивом виде пользователей с их депозитами. Для этого написали такой вот запрос
+----------------------------————--------+
| concat(name, ' - ', deposit, 'RUB') |
+--------------------------————----------+
| misha - 500RUB |
| sveta - 700RUB |
| oleg - 234RUB |
| NULL |
+---------------------------————---------+
Строка с покупателем inga отобразилась как NULL.
Чтобы этого избежать нужно в функцию добавить условие, проверки значения на NULL
+-----------------------------+
| concat |
+-----------------------------+
| misha - 500RUB |
| sveta - 700RUB |
| oleg - 234RUB |
| inga - 0RUB |
+-----------------------------+
Потому что она имеет один неочевидный момент в своем поведении. Если хоть один из аргументов переданных ей NULL то весь результат будет также NULL
Вот пример. Есть у нас такая таблица с customers
+----+-—-------+----—-----+
| id | name | deposit |
+----+--—------+-----—----+
| 1 | misha | 500 |
| 2 | sveta | 700 |
| 3 | oleg | 234 |
| 4 | inga | NULL |
+----+----——--+--—------+
И хотим мы вывести в красивом виде пользователей с их депозитами. Для этого написали такой вот запрос
selectНо результат окажется не совсем тот который нужен.
concat(name, ' - ', deposit, 'RUB')
from customers;
+----------------------------————--------+
| concat(name, ' - ', deposit, 'RUB') |
+--------------------------————----------+
| misha - 500RUB |
| sveta - 700RUB |
| oleg - 234RUB |
| NULL |
+---------------------------————---------+
Строка с покупателем inga отобразилась как NULL.
Чтобы этого избежать нужно в функцию добавить условие, проверки значения на NULL
selectВот теперь все в порядке, получили то что и ожидалось.
concat(name, ' - ',
if (deposit is null, 0, deposit), 'RUB')
from customers;
+-----------------------------+
| concat |
+-----------------------------+
| misha - 500RUB |
| sveta - 700RUB |
| oleg - 234RUB |
| inga - 0RUB |
+-----------------------------+
Представления чисел в PHP
⁉️✅ Все привыкли к представлению чисел во всех ЯП в десятичном формате, это практично и удобно, но не нужно забывать что числа можно предствить не только в этом формате. Хоть этим и редко пользуются, но все же знать это все таки нужно.
❗️❗️❗️Сейчас будет немного теории, после которой вы сможете пройти тесть по данному материалу.
Итак - представления чисел в PHP
1️⃣❎ - Всем известный десятичный формат. Тут думаю не стоит ни чего объяснять, все его прекрасно знают
⁉️✅ Все привыкли к представлению чисел во всех ЯП в десятичном формате, это практично и удобно, но не нужно забывать что числа можно предствить не только в этом формате. Хоть этим и редко пользуются, но все же знать это все таки нужно.
❗️❗️❗️Сейчас будет немного теории, после которой вы сможете пройти тесть по данному материалу.
Итак - представления чисел в PHP
1️⃣❎ - Всем известный десятичный формат. Тут думаю не стоит ни чего объяснять, все его прекрасно знают
$decimal = 3852️⃣❎ - Двоичный формат. Позволяет записать число в виде нулей и единиц. Для того чтобы сообщить интерпретатору что далее пойдет двоичная запись числа служит префикс 0b
$binary = 0b1001013️⃣❎ - Восьмеричный формат. Использует числа от 0 до 8. Для идентификации того что далее идет число в восьмеричном формате перед числом ставится ведущий ноль.
$octal = 03754️⃣❎ - Шестнадцатеричный. Число записывается в шестнадцатеричной системе. Идентифицируется по префиксу 0x
$hex = 0xAB4
🎲 Тест «Представление чисел в PHP»
Небольшой тест который легко можно пройти ознакомившись с постом выше. В каждом вопросе в левом верхнем углу будет подсказка-объяснение ответа. Можно на нее кликнуть и прочитать.
🖊 5 вопросов · ⏱ 1 мин
Небольшой тест который легко можно пройти ознакомившись с постом выше. В каждом вопросе в левом верхнем углу будет подсказка-объяснение ответа. Можно на нее кликнуть и прочитать.
🖊 5 вопросов · ⏱ 1 мин
Раскрашиваем console.log 🎨🤹♂️
🖥⁉️Иногда полезно бывает вывести в консоль текст другого цвета, или подчеркнутый, или большие буквы. И это довольно легко сделать.
✅👏 Для форматирования текста используется специальная директива "%с". Текст который будет идти после нее отформатинуется в соответствии с CSS стилями переданными во втором параметре в console.log()
Итого для форматирования текста нужно всего две вещи:
1️⃣ - Указать перед текстом директиву "%c"
2️⃣- Вторым параметром передать CSS стили для форматирования.
Вот как это выглядит:
🖥⁉️Иногда полезно бывает вывести в консоль текст другого цвета, или подчеркнутый, или большие буквы. И это довольно легко сделать.
✅👏 Для форматирования текста используется специальная директива "%с". Текст который будет идти после нее отформатинуется в соответствии с CSS стилями переданными во втором параметре в console.log()
Итого для форматирования текста нужно всего две вещи:
1️⃣ - Указать перед текстом директиву "%c"
2️⃣- Вторым параметром передать CSS стили для форматирования.
Вот как это выглядит:
console.log('%cБольшие красные буквы', 'color: red; font-size: 25px;')
console.log('%cБольшие красные буквы на желтом фоне', 'color: red; font-size: 25px; background: yellow;')
console.log('%cБольшие красные буквы в рамке', 'color: red; font-size: 25px; border: 2px solid #fff;')
console.log('%cБольшие зеленые буквы в рамке', 'color: green; padding: 10px; font-size: 25px; border: 2px solid #fff;')
console.log('%cБольшие красные буквы в рамке', 'color: red; font-size:Нужен ли "идеальный" код
Недавно закончил работу над одним личным проектом, который натолкнул меня на размышления на эту тему. Начиналось все собственно как обычно с большим энтузиазмом и рвением и твердой решимостью написать код как по книгам - соблюдая все лучшие практики, изолируя все что можно, вынося все зависимости. Если хоть немного класс не соответствовал SOLID он переписывался, если логика хоть немного становилась путанной то все опять же переписывалось.
В общем проковырялся я так недели две и убил на этот проект все свободное время. Получив в итоге нечто ужасное. Проект получился настолько сложный что расширять его было бы просто адской задачей. Это даже не учитывая то что написан был только основной функционал, много всего чего хотелось бы, так и осталось даже не начатым.
Попробую проанализировать почему так вышло.
1 - Это то, что проект был новый для меня, такого раньше никогда не делал, и было невозможно продумать заранее все подводные камни. В итоге часто получалось так, что после долгого обдумывания и планирования приступив к работе, сталкивался с какой нибудь проблемой, которая не позволял использовать данное решение и все приходилось начинать заново. Избежать этого помогло бы создание прототипа. То есть простого на коленке собраного приложения без всяких заморочек с кодом и оптимизацией. Его цель была бы лишь в том чтобы понять каков должен быть конечный вид продукта.
2 - Угасание энтузиазма. С каждой неудачей и переписыванием кода, энтузиазма становилось все меньше и меньше, и то что начиналось с горящими глазами в конце превратилось в рутину. До конца проект так и не удалось реализовать. Хоть до какой то осмысленной стадии его довести получилось только приложив массу усилий. Как можно решить эту проблему, опять же нужно выделять главное и реализовывать это частями. Если вы пишете какой то по вашему мнению очень крутой код постоянно его правите, думаете, переписываете, снова думаете, снова переписываете. То очень велика вероятность, что вы не знаете что делаете. И в этом случае очень велика вероятность что энтузиазма не хватит до финишной прямой и проект так и останется серединка-на-половинку.
Какой вывод в целом можно сделать? То что идеальный код - это конечно хорошо, но только когда вы точно знаете что делаете. Ели что то делаете впервые, лучше сперва создать прототип, понять что действительно нужно, как это должно работать и уже после этого переписать все это, но уже хорошо.
И еще один момент - работающий через задницу прототип будет лучше чем неработающий вовсе "крутой проект"
P.S. это всего лишь небольшие размышления и естественно все не так однозначно и стопроцентно. Но здравое зерно в них точно есть.
P.P.S. ты просто мегакрут если смог осилить это до конца!
Недавно закончил работу над одним личным проектом, который натолкнул меня на размышления на эту тему. Начиналось все собственно как обычно с большим энтузиазмом и рвением и твердой решимостью написать код как по книгам - соблюдая все лучшие практики, изолируя все что можно, вынося все зависимости. Если хоть немного класс не соответствовал SOLID он переписывался, если логика хоть немного становилась путанной то все опять же переписывалось.
В общем проковырялся я так недели две и убил на этот проект все свободное время. Получив в итоге нечто ужасное. Проект получился настолько сложный что расширять его было бы просто адской задачей. Это даже не учитывая то что написан был только основной функционал, много всего чего хотелось бы, так и осталось даже не начатым.
Попробую проанализировать почему так вышло.
1 - Это то, что проект был новый для меня, такого раньше никогда не делал, и было невозможно продумать заранее все подводные камни. В итоге часто получалось так, что после долгого обдумывания и планирования приступив к работе, сталкивался с какой нибудь проблемой, которая не позволял использовать данное решение и все приходилось начинать заново. Избежать этого помогло бы создание прототипа. То есть простого на коленке собраного приложения без всяких заморочек с кодом и оптимизацией. Его цель была бы лишь в том чтобы понять каков должен быть конечный вид продукта.
2 - Угасание энтузиазма. С каждой неудачей и переписыванием кода, энтузиазма становилось все меньше и меньше, и то что начиналось с горящими глазами в конце превратилось в рутину. До конца проект так и не удалось реализовать. Хоть до какой то осмысленной стадии его довести получилось только приложив массу усилий. Как можно решить эту проблему, опять же нужно выделять главное и реализовывать это частями. Если вы пишете какой то по вашему мнению очень крутой код постоянно его правите, думаете, переписываете, снова думаете, снова переписываете. То очень велика вероятность, что вы не знаете что делаете. И в этом случае очень велика вероятность что энтузиазма не хватит до финишной прямой и проект так и останется серединка-на-половинку.
Какой вывод в целом можно сделать? То что идеальный код - это конечно хорошо, но только когда вы точно знаете что делаете. Ели что то делаете впервые, лучше сперва создать прототип, понять что действительно нужно, как это должно работать и уже после этого переписать все это, но уже хорошо.
И еще один момент - работающий через задницу прототип будет лучше чем неработающий вовсе "крутой проект"
P.S. это всего лишь небольшие размышления и естественно все не так однозначно и стопроцентно. Но здравое зерно в них точно есть.
P.P.S. ты просто мегакрут если смог осилить это до конца!
Стреляю себе в ногу 🎯🏹
🤦♀️🛠🧹Случился недавно небольшой фейл, пустяковое дело на самом деле. Но если задуматься то произошел он из за нарушения основного принципа программирования. Не то чтобы это какой то очень примечательный случай но хорошо подойдет для разбора.
👨🏫🙇♂️🚴♀️Итак начнем с первой картинки. Там 2 функции, первая инитит какие то значения, а вторая приводит время из вида "00:00" в формат "00". Проблема в том что иногда время приходило с разделителем запятой вместо двоеточия. Нужно было это срочно хотфиксить, а так как голову в тот момент включить было лень (очень небольшой казалась проблема) то сделано было как на второй картинке.
⭕️🛑⛔️А именно в первой функции инитере просто в двух местах взял и зареплейсил запятую на двоеточие. Поленился заглянуть в функцию toStringFormat(), а зря). Именно в этот момент произошло нарушение, а конкретно был задублирован фрагмент (хоть и небольшой) кода. И кара не заставила себя ждать, в event.start и event.finish пришли значения NULL. Конечно метод replace вызванный из NULL сразу же все завалил))).
Вот так вот. 1️⃣ Поленился заглянуть в toStringFormat, а там NULL как видите был учтен. 2️⃣ Также поленился посмотреть интерфейс Event, в котором тоже обозначено что эти поля могут быть нулами. Правильный вариант как понимаете на 3 картинке.
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
P.S. Это не прямо реальный код из прода (как то это не хорошо реальный код выкладывать) а переработанный, просто чтобы отразить суть, реальный код там немного сложнее был. По этому если в коде заметите какие то несостыковки не удивляйтесь как он вообще работал. Это простоя его отформатировал чтобы передать суть, там могут быть недочеты)))
🤦♀️🛠🧹Случился недавно небольшой фейл, пустяковое дело на самом деле. Но если задуматься то произошел он из за нарушения основного принципа программирования. Не то чтобы это какой то очень примечательный случай но хорошо подойдет для разбора.
👨🏫🙇♂️🚴♀️Итак начнем с первой картинки. Там 2 функции, первая инитит какие то значения, а вторая приводит время из вида "00:00" в формат "00". Проблема в том что иногда время приходило с разделителем запятой вместо двоеточия. Нужно было это срочно хотфиксить, а так как голову в тот момент включить было лень (очень небольшой казалась проблема) то сделано было как на второй картинке.
⭕️🛑⛔️А именно в первой функции инитере просто в двух местах взял и зареплейсил запятую на двоеточие. Поленился заглянуть в функцию toStringFormat(), а зря). Именно в этот момент произошло нарушение, а конкретно был задублирован фрагмент (хоть и небольшой) кода. И кара не заставила себя ждать, в event.start и event.finish пришли значения NULL. Конечно метод replace вызванный из NULL сразу же все завалил))).
Вот так вот. 1️⃣ Поленился заглянуть в toStringFormat, а там NULL как видите был учтен. 2️⃣ Также поленился посмотреть интерфейс Event, в котором тоже обозначено что эти поля могут быть нулами. Правильный вариант как понимаете на 3 картинке.
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
P.S. Это не прямо реальный код из прода (как то это не хорошо реальный код выкладывать) а переработанный, просто чтобы отразить суть, реальный код там немного сложнее был. По этому если в коде заметите какие то несостыковки не удивляйтесь как он вообще работал. Это простоя его отформатировал чтобы передать суть, там могут быть недочеты)))