Сообщество - Лига программистов

Лига программистов

1 728 постов 11 639 подписчиков

Популярные теги в сообществе:

Мод в Mehanic Car Simulator

Сила Пикабу, очень - очень нужен мод, позволяющий ремонтировать ВСЕ детали в игре. Такого мода не существует для MCS 2021, но он есть для MCS 2018. Но он очень нужен для 2021...

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

Обновление проги мониторинга ковров Artisan. Практически 2.0

Продолжаю программировать)

Ссылка на первую часть: https://pikabu.ru/story/monitoring_dostupnosti_geymerskikh_kovrikov_artisan_11613910

Переписал своего бота мониторинга ковров практически с нуля.

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

Новые функции:

- Команды телеграм-бота. То есть они в принципе появились и ими можно пользоваться.

- Команда /get. Основное нововведение. Если вам не нужно постоянно получать уведомления о том какие ковры появились, а какие закончились, можно отписаться от уведомлений через /stop, но при этом по команде /get получать все доступные на данный момент ковры или только интересные вам.

То есть "/get 99" вернёт только ковры у которых в коде продукта есть 99, а "/get 99 xxl" - только те у которых в коде есть и 99 и xxl.

Обновление проги мониторинга ковров Artisan. Практически 2.0 Linux, Программа, Приложение, Microsoft, Программирование, Csharp, Dotnet

Кстати, сегодня вышел новый ковёр (キ83) . На сайте появился, а больше нигде никаких анонсов пока нет.

- Индивидуальные фильтры уведомлений. Если лично вам не нужны уведомления о том, что в продаже появились классические ковры размера S - это можно организовать. Пока фильтр настраивается только с моей стороны.

Обновление проги мониторинга ковров Artisan. Практически 2.0 Linux, Программа, Приложение, Microsoft, Программирование, Csharp, Dotnet

из переписки с пользователем бота

Немного технической информации для любителей программирования:

- Это всё ещё приложение на NET8.
- Пишу и собираю всё в линуксе в VS Code.
- Для основы сервиса использовал шаблон Worker, но так как кода не особо много и он не сложный, дополнительно на микросервисы внутри ихней HostedService инфраструктуры не стал дробить. Просто в пределах одного воркера на функциональные классы поделил и всё.
- Конфиги и данные храню в JSON. Сериализую периодически в файл встроенным сериализатором (System.Text.Json.JsonSerializer)

Прочая обвязка

- Для телеграм-бота использую `Telegram.Bot`
- Для логгирования `log4net`
- Для прикручивания к линуксовому диспетчеру служб Systemd - `Microsoft.Extensions.Hosting.Systemd`
- Для отображения таблички у себя на сайте использую `DataTables` (офигенная штука). И снова планировщик cron, который с бэкенда во фронтенд копирует периодически файлик с данными.
- Для персональных фильтров изпользовал `Dynamic.Linq` - тоже классная вещь, не надо самому мутить свой контракт и парсер для него.

Вроде всё... Программа простая, но так приятно смотреть как оно всё само работает)

Показать полностью 2

Дробедробилка

Я хочу сыграть с вами в одну игру...
(с) Дж. Конвей, про игру "Жизнь"

Я знаю, что пикабу - это место, куда ходят разлагаться, а не вот это вот всё. Но в этот раз хочу разложиться, так сказать, со всей айтишной пролетарской яростью! А то мотоциклистам, вишь, можно разложиться на дороге на радость публике, а мы, ботаны, чем хуже?

Итак, представьте себе следующую работёнку для калькулятора.

Вы пишете список положительных дробей: например, 6655 / 1372, 1715 / 5324, 55 / 686 и т.п.
Берёте некоторое натуральное число, и начинаете играть. Находите в списке первую дробь, такую, что при умножении на ваше число получается не дробное, а натуральное.
Берёте результат умножения, снова находите дробь, произведение с которой даёт натуральное.
И так далее, пока не выяснится, что ни одна дробь не подходит.
Смотрите на последний результат и ищете в нём глубинный смысл.

Эта забава - не просто забава, а внезапно, запуск программы на языке фрактран. От английского fraction trans...что-нибудь. По-русски - дробедробилка.

И его тоже прудумал Джон Конвей.

Удивительное дело, но фрактран - тьюринг-полный язык, то есть, на нём можно запрограммировать что угодно, и вы даже не докажете, что эта программа зациклится либо остановится!

И это не просто "фиг знает что понавыдумывали", а имеет под собой твёрдую теоретическую базу: это реализация абстрактной машины Минского.

Про фрактран есть статьи на википедии, энциклопедии эзотерических языков (там, кстати, совершенно безумный интерпретатор фрактрана на языке J, - помехи в телетайпе), на хабре.

Я полтора года ходил вокруг фрактрана, как хатуль мадан вокруг сметанного дерева, и тоже родил статью на хабре. Это демонстрация задачи "измерить длину последовательности Коллаца - она же 3x+1 - до зацикливания"

Статья, конечно, TL;DR - но я же предупреждаю, что мы, задротские панки и панковские задроты, знаем толк в расшибании башки. Пожалею пикабушников-мимокрокодилов и не стану тащить её сюда.

Минимальная программа у меня получилась из 16 дробей, более-менее эффективная - из 68.

6655 / 1372
1715 / 5324
55 / 686
35 / 2662
605 / 343
245 / 1331
242 / 245
98 / 605
3 / 49
3 / 121
704 / 35
448 / 55
48 / 7
48 / 11
1331 / 4
3 / 2

(а вот как я её нашёл, - это уже в статье!)

Если начать с числа 2^x, то, когда программа остановится, мы получим число 3^n, где n - длина последовательности до достижения элемента 1.

Например, для x = 3, n = 8.
Действительно, последовательность выглядит так:
x1 = 3, нечётное
x2 = x1 * 3 + 1 = 10, чётное
x3 = x2 / 2 = 5, нечётное
x4 = x3 * 3 + 1 = 16, чётное
x5 = x4 / 2 = 8, чётное
x6 = x5 / 2 = 4, чётное
x7 = x6 / 2 = 2, чётное
x8 = x7 / 2 = 1, стоп.

Попробуйте взять 2^3 = 8, и убедиться, что на выходе получите 3^8 = 6561.

В общем, оказывается, программировать на фрактране не так уж сложно. За ширмой тяжеловесной арифметики прячется простая логическая структура. Любой школьник в программическом кружке её освоит, это почти как бейсик.

Так что, если кто тут увлекается программированием или преподаёт его, - развлекайтесь и развлекайте.

Показать полностью

Больше нет работы для сеньоров

ну правда) есть мидловская работа за зарплату джуна и тимлидская работа за оплату сеньора. Какие у вас ощущения? Мысли?

Ответ на пост «Планирование»5

В который раз этот баян постят(а сейчас еще и шакалят), видимо стоит рассказать почему так происходит и кто ошибается.

Для ЛЛ: Косячат все. В том числе работодатель, который не нанял аналитика и пустил представителя бизнеса напрямую к разрабу-социопату.

В нормальной ситуации действующих лиц должно быть минимум 3.

Заказчик(З), аналитик(А) и разраб(Р).

Приходит однажды заказчик и встречает аналитика.

З: Привет! Нам нужно разгрузить машину.

А: Привет! Хммм, звучит как изян. Но я помню "универсальную таблицу оценки", поэтому нужно расспросить побольше и декомпозировать эту, казалось бы простую, задачу.

А: Можешь рассказать немного подробнее о ситуации? Какой груз, где находится машина?

З: Это грузовик с песком. Он сейчас под водой в озере, на глубине 10 метров.

А: Понял. Давай разберёмся с задачей. Попробую в этот раз метод 5W1H для декомпозиции.

А: Что?

З: Разгрузка грузовика с песком.

А: Почему?

З: Нужно освободить место для следующего груза.

А: Где?

З: Под водой, на глубине 10 метров.

А: Когда?

З: Как можно скорее.

А: Кто?

З: Твой один разрабочик.

А: Как?

З: Работая вручную, так как инструментов нет.

Аналитик зовет разрабочика и сообщает ему все что узнал, начинается оценка сроков.

Р: Это звучит сложно, но давай попробуем, тем более подобные вещи мы уже делали.

А: Уважаемый З, нам нужно немного посовещаться и мы сообщим тебе сроки.

З: Хорошо, я вас слушаю.

А: Я предлагаю использовать метод PERT. Нам нужно определить три оценки: оптимистичную, пессимистичную и наиболее вероятную.

Р: Хорошо, давай начнём. Оптимистичная оценка — это когда всё идёт гладко. Я думаю, это может занять месяц.

А: Отлично! А что насчёт пессимистичной оценки?

Р: Если учесть все сложности — холод, вода, отсутствие инструментов — это может занять до лета, пока река не оттает сама.

А: Понятно. А какая наиболее вероятная оценка?

Р: Я думаю, что наиболее вероятно пера-тройка месяцев.

А: Замечательно! Теперь давай подставим эти значения в формулу PERT:

E = O + 4M + P / 6

где E — ожидаемое время, O — оптимистичная оценка, M — наиболее вероятная, P — пессимистичная.

• Оптимистичная (O): Месяц

• Наиболее вероятная (M): 3 месяца

• Пессимистичная (P): 6 Месяцев

Е=3,16

А: Ожидаемое время для разгрузки составляет чуть больше трех месяцев.

Р: Но стоит помнить о возможных задержках из-за холода и других факторов.

А: А у нас уже были подобные проекты? Добавим метод аналогий к более точной оценке сроков.

А: Помнишь, мы уже разгружали Газель с камнями, которая тоже был частично под водой?

Р: О, даааа. В прошлом случае нам потребовалось около 2 месяцев. Я думаю, что в этом случае может быть немного больше времени из-за особенностей песка, глубины и холодов.

А: Согласен, я бы точно добавил месяц к тому сроку.

Р: Да. Кстати, у нас же в прошлый раз были инструменты, это тоже влияет.

А: Да добавим еще месяц. Тогда по этому методу у нас получается 4 месяца, по тому чуть больше трех. Ну в среднем за три с половиной сделаем наверное.

З: Ну что, какой результат?

А: Мы оценили, что разгрузка займет около 3 с половиной месяцев, основываясь на аналогиях с предыдущими проектами.

Р: Но стоит помнить о возможных задержках из-за отсутствия инструментов и условий на месте.

З: Понятно. Спасибо за информацию! Давайте готовиться к разгрузке!

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

Поэтому если встречаются жадный заказчик, неопытный разраб и отсутствует аналитик, то происходят такие тупые ситуации.

Если аналитик с разрабом в команде отлично сработались, имеют хороший бэкграунд и отличную коммуникацию, то все упрощается намного, часто аналитик и сам способен оценить бОльший объем, выставить сроки и стоимость. В этом случае заказчик получил бы примерный срок сильно точнее.

Ну и картиночку на всякий случай вставлю для красоты

Ответ на пост «Планирование» IT, Планирование задач, Скриншот, Повтор, IT юмор, Зашакалено, Ответ на пост, Длиннопост, Волна постов
Ответ на пост «Планирование» IT, Планирование задач, Скриншот, Повтор, IT юмор, Зашакалено, Ответ на пост, Длиннопост, Волна постов
Показать полностью 2

Ctrl+...

Ctrl+... Ctrl, Комбинация, Кот
Показать полностью 1

Пока ты спишь — враг качается

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

Как организовать процесс постоянного поиска информации? Нужно на постоянной основе (в идеале ежедневно, нормально раз в несколько дней, приемлемо еженедельно) потреблять разнородную информацию как в своей профессиональной области, так и в различных соседних. Это существенно расширяет кругозор и повышает вероятность решения новой задачи впоследствии. Не стоит забывать и про не-технические скиллы, куда входят управление людьми, воспитание детей, истории из жизни — это позволит ориентироваться не только в технологиях, но и в жизни.

Неплохим источником информации для постоянного потребления могут быть проверенные книги, телеграм-каналы, подкасты, хабр, площадки вроде hackernews. Решать прикладные задачи самому тоже не следует забывать.

На хабре каждый день читай топ-3 статьи за сегодня, еженедельно читай лучшие 20 статей за неделю. При этом смотри не только саму статью. Часто более полезным является чтение комментариев, где сторонние люди любыми способами постараются доказать, что автор не прав. Чужие мнения могут развить твоё критическое мышление — умение видеть проблему в предлагаемом способе решения задачи.

В году чуть больше 50 недель. При еженедельном чтении десятка статей за год ты прочитаешь около 500 статей. Эти 500 статей и комментариев с обсуждением пополнят копилку решений и обсуждений. Ещё обсуждая с коллегами очередную задачу, можно приобрести опыт решения 500 других задач. И подойти к следующей задаче во всеоружии.

Помни: пока ты спишь, враг качается.

В телеграм-канале DevFM пишу о полезном для разработчика: инструментах, например, Raycast, или об архитектурных схемах, или записываю видео разного уровня, например, для начинающих по FastAPI + Docker. А ещё у нас есть бесплатный курс cli-for-dev по Linux на степике, немного подкастов и видео. Вливайся!

Показать полностью

Каждый год зимой происходят странности

Например, что-то пропадает. У одних важные вещи, у других новогоднее настроение. В этот раз — потерялись помощники Деда Мороза. Но есть хорошая новость: вы можете их найти! Вернее, помочь им найтись…

Dead lock

Перед тем, как разобрать, что такое live lock, вспомним, что такое dead lock.

Deadlock bug на простейшем примере
Два потока захватывают мьютексы в разном порядке. Это может привести к ситуации, что планировщик запустит на выполнение поток 1, поток 1 захватит мьютекс 1, после чего планировщик приостановит выполнение потока 1 и запустит на выполнение поток 2. Поток 2 захватит мьютекс 2. Независимо от того, какой поток будет выполняться дальше, программа зависнет, т.к. потоки будут ждать разблокировки мьютексов (поток 1 - мьютека 2, поток 2 - мьютека 1), которая никогда не произойдет.

#include <iostream>
#include <thread>
#include <mutex>

void thread1(std::mutex& mutex1, std::mutex& mutex2)
{
std::lock_guard<std::mutex> lock1(mutex1);
std::cout << "Thread 1 acquired mutex1\n";

std::lock_guard<std::mutex> lock2(mutex2);
std::cout << "Thread 1 acquired mutex2\n";
}

void thread2(std::mutex& mutex1, std::mutex& mutex2)
{
std::lock_guard<std::mutex> lock2(mutex2);
std::cout << "Thread 2 acquired mutex2\n";

std::lock_guard<std::mutex> lock1(mutex1);
std::cout << "Thread 2 acquired mutex1\n";
}

int main()
{
std::mutex mutex1;
std::mutex mutex2;

std::thread t1(thread1, std::ref(mutex1), std::ref(mutex2));
std::thread t2(thread2, std::ref(mutex1), std::ref(mutex2));

t1.join();
t2.join();
}

Fix dead lock bug
В современном C++ баг, описанный выше, исправляется с помощью использования std::scoped_lock

#include <iostream>
#include <thread>
#include <mutex>

void thread1(std::mutex& mutex1, std::mutex& mutex2)
{
const std::scoped_lock lock(mutex1, mutex2);
std::cout << "Thread 1 acquired mutex1 and mutex2\n";
}

void thread2(std::mutex& mutex1, std::mutex& mutex2)
{
const std::scoped_lock lock(mutex1, mutex2);
std::cout << "Thread 2 acquired mutex1 and mutex2\n";
}

int main()
{
std::mutex mutex1;
std::mutex mutex2;

std::thread t1(thread1, std::ref(mutex1), std::ref(mutex2));
std::thread t2(thread2, std::ref(mutex1), std::ref(mutex2));

t1.join();
t2.join();
}

Больше технических постов тут t.me/neverending_cpp

Показать полностью
Отличная работа, все прочитано!