Dmitry Develop
winAPIWrapperProject.png
Сделал я необходимый минимум обёрток, который занимает 500 строк кода и это только начало.
И написал простой проект с созданием окна.
У моего стиля есть куча недостатков, но он мне всё равно нравится.
Теперь всегда можно единообразно обрабатывать ошибку, не обращая внимания, что это за функция.
Также нужно будет скоро начать писать тесты для всех этих функций.
Над этим проектом работаю только я, поэтому у меня нет привычки писать тесты.
Хотя в прошлом уже были случаи, когда в своей стандартной библиотеке я изменял логику работы какой-то фундаментальной функции, а потом ломалась какая-то другая зависимая функция.
ссылка на канал | ссылка на группу
И написал простой проект с созданием окна.
У моего стиля есть куча недостатков, но он мне всё равно нравится.
Теперь всегда можно единообразно обрабатывать ошибку, не обращая внимания, что это за функция.
Также нужно будет скоро начать писать тесты для всех этих функций.
Над этим проектом работаю только я, поэтому у меня нет привычки писать тесты.
Хотя в прошлом уже были случаи, когда в своей стандартной библиотеке я изменял логику работы какой-то фундаментальной функции, а потом ломалась какая-то другая зависимая функция.
ссылка на канал | ссылка на группу
👍1
Dmitry Develop
winAPIWrapperDefinition.png
Я довольно консервативен к стилю форматирования кода.
Я всегда писал объявление и определение функций в одну строку, даже с большим количеством параметров.
Но у меня планируется около сотни, а то и более, функций, которые в таком стиле форматирования просто превратятся в кашу (смотри фото в предыдущем посте).
Поэтому я задумался над тем, чтобы немного изменить свой стиль ради удобства.
Что скажете чтобы это:
Превратить в это:
Очень непривычно будет оформлять функции в таком стиле, но читать и работать с таким кодом станет одно удовольствие.
Бонусом я смогу сделать моё любимое выравнивание по левому краю по колонкам отдельно по типам данных, отдельно по названию параметров.
Также вероятность просмотреть и не заметить опечатку или ошибку значительно уменьшается.
ссылка на канал | ссылка на группу
Я всегда писал объявление и определение функций в одну строку, даже с большим количеством параметров.
Но у меня планируется около сотни, а то и более, функций, которые в таком стиле форматирования просто превратятся в кашу (смотри фото в предыдущем посте).
Поэтому я задумался над тем, чтобы немного изменить свой стиль ради удобства.
Что скажете чтобы это:
void CreateWindowExAWrapper(HWND* returnValue, DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam, status_s* status);
Превратить в это:
void CreateWindowExAWrapper
(
HWND* returnValue,
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam,
status_s* status
);
Очень непривычно будет оформлять функции в таком стиле, но читать и работать с таким кодом станет одно удовольствие.
Бонусом я смогу сделать моё любимое выравнивание по левому краю по колонкам отдельно по типам данных, отдельно по названию параметров.
Также вероятность просмотреть и не заметить опечатку или ошибку значительно уменьшается.
ссылка на канал | ссылка на группу
👍2💊1
Dmitry Develop
createWindowExAWrapper.png
Когда уже сделал обёртку для 23 функций на 1000 строк кода, сделать 24-ую с уже написанной документацией с шаблонами было даже слишком легко и быстро.
Добавил корректировку размера окна, чтобы можно было указывать размер клиентской области.
Пока что мне стиль форматирования и написанный код нравятся, довольно удобно.
(Проверки status в коде пока что нет, чтобы не портить внешний вид кода 😏)
ссылка на канал | ссылка на группу
Добавил корректировку размера окна, чтобы можно было указывать размер клиентской области.
Пока что мне стиль форматирования и написанный код нравятся, довольно удобно.
(Проверки status в коде пока что нет, чтобы не портить внешний вид кода 😏)
ссылка на канал | ссылка на группу
👍2
Dmitry Develop
pythonNTreeDFS.png
Недавно на работе мне поставили задачу написать метод, который должен сделать запрос к API yandex, получить в ответ JSON структуру, обработать её и преобразовать, чтобы потом сохранить это в нашу базу данных.
Условия задачи мне показались совсем несложными, но как же я ошибался...
Я структуры данных посложнее массива не изучал, поэтому задача резко стала очень сложной, когда я понял, что столкнулся с деревом (N tree): практических умений-то нет, ни то что теоретических знаний.
Спустя очень много часов я всё-таки смог написать код обработки, но мне не хотелось писать рекурсивный метод, хотя это была бы самая простая реализация.
Ну, ладно, когда-нибудь потом перепишу этот метод, я всё-таки люблю алгоритмы, но не когда надо здесь и сейчас их изучить и понять).
Я такого говнокода давно не писал).
ссылка на канал | ссылка на группу
Условия задачи мне показались совсем несложными, но как же я ошибался...
Я структуры данных посложнее массива не изучал, поэтому задача резко стала очень сложной, когда я понял, что столкнулся с деревом (N tree): практических умений-то нет, ни то что теоретических знаний.
Спустя очень много часов я всё-таки смог написать код обработки, но мне не хотелось писать рекурсивный метод, хотя это была бы самая простая реализация.
Ну, ладно, когда-нибудь потом перепишу этот метод, я всё-таки люблю алгоритмы, но не когда надо здесь и сейчас их изучить и понять).
Я такого говнокода давно не писал).
ссылка на канал | ссылка на группу
👍2
Dmitry Develop
ссылка на канал | ссылка на группу
Благодаря программированию я научился слепой печати.
А вот к кнопкам графического планшета до сих пор не смог привыкнуть, запомнить где какой инструмент привязан.
Поэтому я решил сделать небольшую подсказку, на которой будут иконка и английское название инструментов.
Опыт написания html и css, составления различных документов, печати в нужном масштабе и редактирования в моём любимом редакторе paint.net очень пригодились.
Процесс создания от эскиза до чернового варианта был похож на моделирование.
Сначала нужно снять реальные размеры и пропорции с планшета, потом перенести их в виртуальное пространство графического редактора, прикинуть единицы измерения, плотность пикселей, придумать макет и довести его до идеала, а в конце пытаться распечатать в реальном масштабе.
Очень жаль, что не получилось показать видео ускоренного процесса создания с нуля до конечного результата, проект уже был закрыт вчера, а значит ctrl + Z / Y уже не помогут).
Да, конечный результат выглядит неидеально и как-то просто, но мне был интересен весь процесс, начиная от идеи и заканчивая реализацией.
ссылка на канал | ссылка на группу
А вот к кнопкам графического планшета до сих пор не смог привыкнуть, запомнить где какой инструмент привязан.
Поэтому я решил сделать небольшую подсказку, на которой будут иконка и английское название инструментов.
Опыт написания html и css, составления различных документов, печати в нужном масштабе и редактирования в моём любимом редакторе paint.net очень пригодились.
Процесс создания от эскиза до чернового варианта был похож на моделирование.
Сначала нужно снять реальные размеры и пропорции с планшета, потом перенести их в виртуальное пространство графического редактора, прикинуть единицы измерения, плотность пикселей, придумать макет и довести его до идеала, а в конце пытаться распечатать в реальном масштабе.
Очень жаль, что не получилось показать видео ускоренного процесса создания с нуля до конечного результата, проект уже был закрыт вчера, а значит ctrl + Z / Y уже не помогут).
Да, конечный результат выглядит неидеально и как-то просто, но мне был интересен весь процесс, начиная от идеи и заканчивая реализацией.
ссылка на канал | ссылка на группу
👍4
Dmitry Develop
image_2024-04-05_07-30-48.png
Я устраивался на работу, как python backend разработчик.
Кто бы мог подумать, что в будущем я буду работать и с PHP проектами...)
Меня всё продолжает радовать vs code — своей универсальностью, а сообщество — готовыми инструкциями и расширениями.
На каждый язык программирования или стек технологий у меня один редактор кода (или IDE) — vs code).
Развернул окружение, установил проект, и начал с настройки, конечно же, отладки: без неё никуда.
Ещё лет 10 назад я вообще не знал и не думал, что PHP сайты можно отлаживать...
Эх, сколько бы времени и нервов мне сэкономила отладка в прошлом.
ссылка на канал | ссылка на группу
Кто бы мог подумать, что в будущем я буду работать и с PHP проектами...)
Меня всё продолжает радовать vs code — своей универсальностью, а сообщество — готовыми инструкциями и расширениями.
На каждый язык программирования или стек технологий у меня один редактор кода (или IDE) — vs code).
Развернул окружение, установил проект, и начал с настройки, конечно же, отладки: без неё никуда.
Ещё лет 10 назад я вообще не знал и не думал, что PHP сайты можно отлаживать...
Эх, сколько бы времени и нервов мне сэкономила отладка в прошлом.
ссылка на канал | ссылка на группу
👍2🔥1
В моей программе есть модули, которые надо инициализировать перед использованием их функционала.
Также есть модули, которые также сначала надо инициализировать и только потом создавать ресурс, с которым будет происходить работа.
Контекст модуля может быть на уровне процесса и быть неизменным всё время выполнения программы, он хранится в глобальной и статической памяти.
Если контекст модуля должен быть на уровне потока, то он хранится в памяти потока.
Хочется сделать однозначные и непохожие названия, чтобы не путать инициализацию модуля и создание ресурса в модуле.
Какие названия предложите для каждого шага?
Различные названия, которые я видел: ctor, constructor, dtor, destructor, init, initialize, deinit, deinitialize, terminate, begin, end, start, end, create, new, delete, alloc, free, destroy, clean, setup, load, unload, finalize, release, reset, close.
Если это важно, создание и удаление ресурса не всегда может быть связано с динамической памятью.
Хотя, если сделать это разделение, станет ещё проще запутаться.
Пока что остановился на варианте:
initialize и deinitialize, create и destroy.
ссылка на канал | ссылка на группу
Также есть модули, которые также сначала надо инициализировать и только потом создавать ресурс, с которым будет происходить работа.
Контекст модуля может быть на уровне процесса и быть неизменным всё время выполнения программы, он хранится в глобальной и статической памяти.
Если контекст модуля должен быть на уровне потока, то он хранится в памяти потока.
Хочется сделать однозначные и непохожие названия, чтобы не путать инициализацию модуля и создание ресурса в модуле.
Какие названия предложите для каждого шага?
Модуль с созданием ресурса:
1) начать работу
2) создать ресурс
3) использовать ресурс
4) удалить ресурс
5) закончить работу
Модуль без создания ресурса:
1) начать работу
3) использовать модуль
5) закончить работу
Различные названия, которые я видел: ctor, constructor, dtor, destructor, init, initialize, deinit, deinitialize, terminate, begin, end, start, end, create, new, delete, alloc, free, destroy, clean, setup, load, unload, finalize, release, reset, close.
Если это важно, создание и удаление ресурса не всегда может быть связано с динамической памятью.
Хотя, если сделать это разделение, станет ещё проще запутаться.
Пока что остановился на варианте:
initialize и deinitialize, create и destroy.
ссылка на канал | ссылка на группу
🤔2
Dmitry Develop
escapeSequencesVT100.png
/*
g++ -fexec-charset=cp1251 -o vt100.exe vt100.cpp
*/
#include <windows.h>
/*
Функция управляет обработкой управляющих последовательностей VT100 у консоли.
В случае успеха возвращает ERROR_SUCCESS.
В случае ошибки возвращает код последней ошибки.
*/
DWORD controlVT100Sequences(HANDLE hConsoleHandle, bool enable = true)
{
// сбросить lastError
SetLastError(ERROR_SUCCESS);
// получить режим консоли
DWORD mode { };
if(GetConsoleMode(hConsoleHandle, &mode) == 0)
{
return GetLastError();
}
// изменить режим консоли
if(enable)
{
mode |= (DWORD)ENABLE_VIRTUAL_TERMINAL_PROCESSING;
}
else
{
mode &= ~(DWORD)ENABLE_VIRTUAL_TERMINAL_PROCESSING;
}
// сбросить lastError
SetLastError(ERROR_SUCCESS);
// установить режим консоли
if(SetConsoleMode(hConsoleHandle, mode) == 0)
{
return GetLastError();
}
return ERROR_SUCCESS;
}
int main()
{
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
const HANDLE consoleOutput { GetStdHandle(STD_OUTPUT_HANDLE) };
const char* coloredText
{
" \033[44mСиний фон\033[49m\n"
" \033[44m\033[31mКрасное слово\033[39m"
" | "
"\033[32mЗелёное слово\033[39m\033[49m\n"
};
const char* VT100DisabledText { "Disabled VT100:\n" };
const char* VT100EnabledText { "Enabled VT100:\n" };
// обработка управляющих последовательностей VT100 отключена
controlVT100Sequences(consoleOutput, false);
WriteConsoleA(consoleOutput, VT100DisabledText, strlen(VT100DisabledText), nullptr, nullptr);
WriteConsoleA(consoleOutput, coloredText , strlen(coloredText) , nullptr, nullptr);
// обработка управляющих последовательностей VT100 включена
controlVT100Sequences(consoleOutput, true);
WriteConsoleA(consoleOutput, VT100EnabledText, strlen(VT100EnabledText), nullptr, nullptr);
WriteConsoleA(consoleOutput, coloredText , strlen(coloredText) , nullptr, nullptr);
return 0;
}
Решил попробовать в первый раз управляющие последовательности VT100 и написать код, который включит их обработку в терминале.
Документация:
GetConsoleMode
SetConsoleMode
windows console virtual terminal sequences
ANSI/VT100
ссылка на канал | ссылка на группу
🔥5
Dmitry Develop
open_server_panel_5_4_3_setup.exe
OpenServer (OSPanel) это некоммерческая портативная программа для web-разработчиков, полноценный локальный web-сервер с плагинами, базой данных и многим другим.
Звучит, как реклама, но я начал пользоваться этой программой более 5 лет назад.
И вот, даже на работе он мне понадобился).
Я хотел скачать установочный файл программы, но на официальном сайте намеренно занижена скорость скачивания до ~0.1 MB/s, а размер файла почти гигабайт.
Поэтому я решил скачать с других сайтов, что очень рискованно.
Можно скачать модифицированный файл или вообще что-то другое.
И на помощь пришла верификация контрольной суммой.
В windows можно без сторонних программ вычислить контрольную сумму файла.
Для этого нужна программа
Контрольные суммы MD5 и SHA1 полностью идентичны заявленным на официальном сайте разработчика, что подтверждает оригинальность скачанного файла.
ссылка на канал | ссылка на группу
Звучит, как реклама, но я начал пользоваться этой программой более 5 лет назад.
И вот, даже на работе он мне понадобился).
Я хотел скачать установочный файл программы, но на официальном сайте намеренно занижена скорость скачивания до ~0.1 MB/s, а размер файла почти гигабайт.
Поэтому я решил скачать с других сайтов, что очень рискованно.
Можно скачать модифицированный файл или вообще что-то другое.
И на помощь пришла верификация контрольной суммой.
В windows можно без сторонних программ вычислить контрольную сумму файла.
Для этого нужна программа
certutil.exe (документация).certutil -hashfile "open_server_panel_5_4_3_setup.exe" MD5
Хэш MD5 open_server_panel_5_4_3_setup.exe:
420078689ee2b5c743d7b3bb578fb662
certutil -hashfile "open_server_panel_5_4_3_setup.exe" SHA1
Хэш SHA1 open_server_panel_5_4_3_setup.exe:
bba5646cef239f32dd77fac742e55926d81b450f
Контрольные суммы MD5 и SHA1 полностью идентичны заявленным на официальном сайте разработчика, что подтверждает оригинальность скачанного файла.
ссылка на канал | ссылка на группу
👍4🤯1
Мой таймер возвращает время, как беззнаковое число, в количестве наносекунд.
Нужно вычислять разницу между двумя промежутками времени.
Бывает, уменьшаемое меньше вычитаемого, поэтому результат вычитания будет меньше нуля, и в беззнаковой переменной из-за underflow результат будет ооочень большим.
Поэтому я написал эту небольшую функцию:
Функция вычитает два беззнаковых числа left - right без underflow.
Модуль результата вычитания сохраняется в difference.
Если результат выражения был отрицательным, в negitiveSign сохраняется true, иначе false.
Если
Если
Получается, вместо этого кода:
Будет такой:
(Раньше тут вместо 15'625'000 был 0 😏)
ссылка на канал | ссылка на группу
Нужно вычислять разницу между двумя промежутками времени.
Бывает, уменьшаемое меньше вычитаемого, поэтому результат вычитания будет меньше нуля, и в беззнаковой переменной из-за underflow результат будет ооочень большим.
Поэтому я написал эту небольшую функцию:
Функция вычитает два беззнаковых числа left - right без underflow.
Модуль результата вычитания сохраняется в difference.
Если результат выражения был отрицательным, в negitiveSign сохраняется true, иначе false.
void uint64AbsoluteSubtract(uint64_t left, uint64_t right, uint64_t* difference, bool* negitiveSign, status_s* status);
Если
left = 10, right = 5, тоdifference = 5, negitiveSign = false.Если
left = 5, right = 10, тоdifference = 5, negitiveSign = true.uint64 left { X }, right { Y };
uint64 difference { };
bool negitiveSign { };
uint64AbsoluteSubtract(left, right, &difference, &negitiveSign, nullptr);Получается, вместо этого кода:
if(left - right >= 15'625'000) { ... } else { ... }Будет такой:
if(negative) return;
if(difference >= 15'625'000) { ... } else { ... }
ссылка на канал | ссылка на группу
👍1
Dmitry Develop
image_2024-04-19_21-22-20.png
Что ж, сделаю небольшое предварительное объявление).
Увидел сегодня картинку кота, а потом фотографию брелка, очень понравилось, как он выглядит.
Решил в видеоредакторе смонтировать видео ради шутки).
Видео пока в процессе работы, половина уже сделана.
ссылка на канал | ссылка на группу
Увидел сегодня картинку кота, а потом фотографию брелка, очень понравилось, как он выглядит.
Решил в видеоредакторе смонтировать видео ради шутки).
Видео пока в процессе работы, половина уже сделана.
ссылка на канал | ссылка на группу