Около it
289 subscribers
1K photos
219 videos
36 files
362 links
Складчина одного программиста.
Задерживаем развитие с 22.12.2017

Материалы и статьи сюда разные закидываю. Личное, интересное, неинтересное.
Программирование, администрирование, то-сё, пятое, десятое.
В основном непутёвые заметки.

Чат - @okoloit_talk
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
До чего же прекрасен fallout V
Forwarded from Geeks (Aleksandr Mikheev)
Ноутбуки Apple на собственном чипе M1 только появились в продаже, но люди уже ринулись ставить приложения с iOS на новенькие компьютеры. Как оказалось, даже не нужно, чтобы разработчик разрешил подобную установку - достаточно скопировать приложение с телефона и оно почти всегда будет запускаться. Так, например, наконец можно получить настоящие приложения Netflix, Hulu и даже Instagram - вот уж неожиданно, что оно запускается и работает без проблем. Конечно, есть определённые ограничения: в основном это связано со специфичными запросами вроде обязательной сим-карты в устройстве или с тем, что приложение невозможно открыть на полный экран.

Но очень круто, что гигантская библиотека iOS-программ сразу стала доступна, ведь есть куча софта, которая на компьютерах или не работает или открывается только в браузере. Те же приложения, которые разработчики указали совместимыми с компьютерами, доступны уже сейчас в Mac App Store для загрузки. Они работают даже лучше обычных программ, ведь изначально они оптимизировались под слабое железо телефонов, которое ещё и ограничено небольшой батарейкой. В ноутбуках таких ограничений по питанию нет, поэтому приложения могут подгружать и обновлять информацию намного быстрее. M1 пока выглядит очень многообещающе! https://9to5mac.com/2020/11/18/how-to-install-iphone-ipad-app-m1-mac/
https://artsandculture.google.com/project/ancient-egypt

Тут Гугл в рамках проекта Art and Culture запустили проект по истории, культуре и искусству Древнего Египта. Залипалово
Ладно, сейчас тут будет что-то по истине важное.
Ни для кого не секрет, что работа с регулярками = боль. Раньше и я так думал (на самом деле и сейчас думаю) пока не нашел для себя лучший сервис для работы с ними. Огромный словарь паттернов, удобство в использовании и адекватный интерфейс. Пожалуй, это лучшее что я встречал из онлайн сервисов для работы с выражениями.
Сам сайт: https://regexr.com/
Что-то генераторы фонового шума все платные стали. Вот нашелся один хороший (и бесплатный, разумеется) которым и сам пользуюсь и другим с советую
https://noises.online/
Попутно еще сервис по конвертированию сюда вкину чтобы не забыть.
Удобно, быстро, качественно. Побольше бы такого
https://convertio.co/
Кто бы мог подумать.
Оказывается, московский музей Дарвина имеет свой аккаунт на скетчфаб. Отсканированы более 260 позиций с хорошим описанием. Посмотреть/покрутить тут
https://sketchfab.com/darwinmuseum.ru/models
Оу, оказывается у Smithsonian есть нечто подобное.
https://3d.si.edu/explore
Тут можно и на перчатки экипажа Apollo 11 посмотреть (или даже распечатать).
Тут даже слепок лица Линкольна есть. ЧОТКА
Для галочки в голове
Forwarded from Doque Embedded
По мотивам вчерашнего обсуждения в https://t.me/theyforcedme/2895

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

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

void foo(){
// выделяем память
DataType* data = malloc(sizeof(Data));

// работаем с памятью
process(data);

// освобождаем память
free(data);
}

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

void foo(){
DataType* data = malloc(sizeof(Data));

if(process_1(data)){
if(process_2(data)){
if(process_3(data)){
process_4(data);
}
}
}

free(data);
}

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

void foo(){
DataType* data = malloc(sizeof(Data));

if(!process_1(data)){
free(data);
return;
}

if(!process_2(data)){
free(data);
return;
}

if(!process_3(data)){
free(data);
return;
}

process_4(data);

free(data);
}

Это выглядит и читается приемлимо, но поддерживать этот код стало еще сложнее, например очень легко можно забыть освободить память перед возвратом. Для борьбы с этим человечество придумало блоки finally и идиому "Получение ресурса есть инициализация" (RAII). К сожалению мы любим простреленные ноги и пишем на языке Си, в котором подобное невозможно реализовать не превратив код обмазанный макросами в некрономикоподобный диалект. Что же мы можем сделать?

void foo(){
DataType* data = malloc(sizeof(Data));

if(!process_1(data)) goto finally;
if(!process_2(data)) goto finally;
if(!process_3(data)) goto finally;
process_4(data);

finally:
free(data);
}

К сожалению столь лаконичный код получился с использованием goto. Использование оператора goto в целом критикуется, так как программу с его использованием читать на порядки сложнее, как минимум неявны начала и концы переходов, для подробной критики см "Go To Statement Considered Harmful" Эдсгера Дейкстры. Нам нужен блок который бы исполнялся один раз и из которого мы можем выйти оператором отличным от goto, например возьмем отдельную функцию.

void process_data(DataType* data){
assert(data);

if(!process_1(data)) return;
if(!process_2(data)) return;
if(!process_3(data)) return;
process_4(data);
}

void foo(){
DataType* data = malloc(sizeof(Data));
process_data(data);
free(data);
}

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

Чтобы не отвлекать программиста на другие функции мы можем использовать что-то наподобие "анонимной функции", например цикл из одной итерации. Цикл из одной итерации может быть любого вида, while, for, но do {} while (false); это довольно распространенная и понятная идиома, не требующая дополнительных переменных.

void foo(){
DataType* data = malloc(sizeof(Data));

do {
if(!process_1(data)) break;
if(!process_2(data)) break;
if(!process_3(data)) break;
process_4(data);
} while(false);

free(data);
}

В результате мы получили идиому которая явно указывает начало-конец перехода, выделяет блоком код который можно менять не отвлекаясь на освобождение ресурса, и в целом код который довольно лаконично выглядит.
Ну собсна
Forwarded from 112
Российского хакера Павла Ситникова вызвали на допрос после обысков в Group-IB.

Известно, что у Ситникова был конфликт с основателем компании Ильей Сачковым, который накануне был арестован по делу о госизмене.
Тут же явно кому-то не хватало кнопок с фразами из мемасов, по этому добавлю тоже сюда
https://www.myinstants.com/categories/memes/
Тут у notion появился промокод для стартапов - ADALOVELACE
Работает для всех. На счет получаете 500$ (при стоимости годовой подписки в 50$)