Forwarded from rusta::mann
В этом году я начал задумываться, что, возможно, я выбрал не ту профессию — написание кода перестало меня цеплять, и превратилось в рутину. Подумывал даже в девопсы начать переучиваться, с депрессухи.
Но нет, сегодня я понял, что кодить я люблю — я не люблю C++.
Но нет, сегодня я понял, что кодить я люблю — я не люблю C++.
Человек не ожидал, что Spark это не библиотечка уровня leftpad, а огромный фреймворк. В этой ситуации, увы, только обнять и плакать...😢
===
Lookuut Struchkov:
Всем привет. Ребята есть у кого опыт дебагингга большого опенс сорс проекта, я обнаружил багу в одном проекте(spark), написал тесты которые ловят данную багу, хочется сделать PR но для этого надо понять что конкретно не так работает в самом проекте, но вот уже 2 неделю копаюсь и докопаться не могу (вместо того чтобы готовиться к аикапу:\)
как можно посмотреть в идее лог , типа какие объекты создавались и какие методы вызывались у них?
Roman:
Apache Spark?
Lookuut Struchkov:
да
Roman:
глобальненько
Lookuut Struchkov:
у меня голова уже кругом идет, не знал что он под капотом настолько огромный :(
===
Lookuut Struchkov:
Всем привет. Ребята есть у кого опыт дебагингга большого опенс сорс проекта, я обнаружил багу в одном проекте(spark), написал тесты которые ловят данную багу, хочется сделать PR но для этого надо понять что конкретно не так работает в самом проекте, но вот уже 2 неделю копаюсь и докопаться не могу (вместо того чтобы готовиться к аикапу:\)
как можно посмотреть в идее лог , типа какие объекты создавались и какие методы вызывались у них?
Roman:
Apache Spark?
Lookuut Struchkov:
да
Roman:
глобальненько
Lookuut Struchkov:
у меня голова уже кругом идет, не знал что он под капотом настолько огромный :(
Forwarded from iggisv9t channel
Для любителей странных аттракторов https://www.dynamicmath.xyz/strange-attractors/
Тут картинки, уравнения и ссылки на интерактивные симуляции.
Тут картинки, уравнения и ссылки на интерактивные симуляции.
В процессе решения задачек по курсу Спортивное программирование столкнулся со следующим неудобством Раста, а именно на нём иногда неудобно делать динамическое программирование (не путать с динамической типизацией). Для примера приведу задачу о наилучшем делении множества:
Дан массив `[a_0, a_1,..,a_(n-1)]` длины n, все числа положительные, задача разбить массив на 2 кучи так, чтобы разница между кучами была минимальна.
Скажем, для массива
Каноническое решение этой задачи через динамическое программирование, используя массив
На Rust это в сущности простой цикл:
Очевидный выход из этого положения - склонировать коллекцию перед итерированием по ней:
Где-то невдалеке маячит
Дан массив `[a_0, a_1,..,a_(n-1)]` длины n, все числа положительные, задача разбить массив на 2 кучи так, чтобы разница между кучами была минимальна.
Скажем, для массива
[1,5,3]
оптимальное разбиение будет [1,3]
в одну кучу, [5]
в другую.Каноническое решение этой задачи через динамическое программирование, используя массив
d
boolean-ов размера (n + 1) ⨉ m
, m
это достаточно большое число, можно взять половину суммы. Этот массив мы заполняем сверху вниз строка за строкой, когда d[i][j]==true
это означает, что сумма j
достижима при помощи некоторой комбинации элементов [a_0..a_i]
.На Rust это в сущности простой цикл:
let mut d = vec![vec![false; m]; n + 1];При больших
d[0][a[0] as usize] = true;
for i in 1..n {
d[i][0] = true;
for j in 0..m {
// если выключить элемент i
d[i][j] = d[i - 1][j];
// если включить элемент i
if a[i - 1] <= j as i32 {
d[i][j ] |= d[i - 1][j + a[i] as usize]
}
}
}
// далее ищем максимальный индекс j таких, что d[n][j] == true
// тогда (m - 2*j) будет минимально и это будет решение задачи
m
мы хотим (или даже вынуждены) воспользоваться спецификой задачи и заметить, что массив d
сильно разряжённый. Поэтому от строк-массивов мы переходим ко строкам-множествам. let mut d = vec![HashSet::new(); n];И неожиданно (а для кого-то ожидаемо) получаем cannot borrow `d` as mutable because it is also borrowed as immutable.
d[0].insert(a[0] as i32);
for i in 1..n {
d[i].insert(0);
for j in d[i - 1].iter().copied() {
if d[i - 1].contains(&j) {
d[i].insert(j);
}
if a[i - 1] <= j as i32 {
if d[i - 1].contains(&(j + a[i] as usize)) {
d[i].insert(j + a[i] as usize);
}
}
}
}
Очевидный выход из этого положения - склонировать коллекцию перед итерированием по ней:
// АААААААААА!Не столь очевидный: воспользоваться функцией
for j in d[i - 1].clone().iter().copied() {
...
}
Vec::split_at_mut
:for i in 1..n {Код компилируется, но теперь он не идиоматичный, и это меня несколько расстраивает.
d[i].insert(0);
let (d1, d2) = d.split_at_mut(i);
for j in d1[i - 1].iter().copied() {
// меняем d2[0] как нам угодно!
if d1[i - 1].contains(&j) {
d2[0].insert(j);
}
...
}
}
Где-то невдалеке маячит
unsafe
и напрашивается быть куда-нибудь вкоряченным, но я старательно отмахиваюсь от него. 😊Stepik: online education
Спортивное программирование
Курс посвящен методам решения задач школьных и студенческих олимпиад по программированию. Ориентирован на уровень начинающих участников олимпиад, владеющих основами программирования.
Forwarded from Generative Anton
Нашёл классный курс "Advanced Programming in the UNIX Environment". Всё целиком на C, никакого разжёвывания в начале, есть домашка и лекции в отличном качестве.
Проекты в курсе — реимплементация юниксовых утилит (ls(1) и sws(1)).
Проекты в курсе — реимплементация юниксовых утилит (ls(1) и sws(1)).
Интересная, и в чём-то поучительная история от друзей по ржавому оружию.
https://habr.com/ru/post/537790/
https://habr.com/ru/post/537790/
Хабр
Как мы ржавели. История внедрения и обучения
Все говорили – переходи на rust! Начинай пользоваться самым-самым языком, который самый любимый язык на stackoverflow и всё такое. Я тяжело вздохнул и огляделся. Ну опять двадцать-пять. Ладно, давайте...
Довольно увлекательная статья о том, как человек участвовал в RAIC 2020. В этот раз необходимо было запрограммировать бота для игры в сильно упрощённый Старкрафт.
Человек решил офигенное количество с виду простых задач по разруливанию поведения юнитов на поле. И когда казалось, что все возможные грабли учтены, оказывалось, что находилась ещё ситуация (и не одна!), когда алгоритм действовал не лучшим образом.
Например,
Еще одной важной проблемой, которая не давала покоя было то, что когда мои лучники и лучники противника сближались, и становились стенка против стенки, то новые лучники подходили сзади и подпирали их. Таким образом они были абсолютно неэффективны, т.к. просто стояли и ничего не делали. И так могло накопиться много слоев моих лучников. Это выглядело как явная тактическая ошибка.
В-общем, стоящая статья, я получил удовольствие от прочтения. Краткий вывод:
1. Для участия в RAIC 2021 нужно уволиться с работы или взять отпуск месяца на 2 😊
2. Большинство задач тривиальны, но обобщённое и эффективное решение части из них позволяет разом убить 100 "зайцев" и избавиться от костылей в будущем.
3. Для участия не нужно иметь опыт в AI, ML, DL и других аббревиатурах, нужно просто уметь писать if-ы и циклы😉, но желательно уметь дебажить и профилировать код.
https://m.habr.com/ru/post/535310/
Человек решил офигенное количество с виду простых задач по разруливанию поведения юнитов на поле. И когда казалось, что все возможные грабли учтены, оказывалось, что находилась ещё ситуация (и не одна!), когда алгоритм действовал не лучшим образом.
Например,
Еще одной важной проблемой, которая не давала покоя было то, что когда мои лучники и лучники противника сближались, и становились стенка против стенки, то новые лучники подходили сзади и подпирали их. Таким образом они были абсолютно неэффективны, т.к. просто стояли и ничего не делали. И так могло накопиться много слоев моих лучников. Это выглядело как явная тактическая ошибка.
В-общем, стоящая статья, я получил удовольствие от прочтения. Краткий вывод:
1. Для участия в RAIC 2021 нужно уволиться с работы или взять отпуск месяца на 2 😊
2. Большинство задач тривиальны, но обобщённое и эффективное решение части из них позволяет разом убить 100 "зайцев" и избавиться от костылей в будущем.
3. Для участия не нужно иметь опыт в AI, ML, DL и других аббревиатурах, нужно просто уметь писать if-ы и циклы😉, но желательно уметь дебажить и профилировать код.
https://m.habr.com/ru/post/535310/
Хабр
История 4го места на Russian AI Cup 2020
В этом году поучаствовал в соревновании по написанию игровых ботов Russian AI Cup. И хоть не удалось взять 1е место, как в 2017, но все равно это было увлекательное и невероятно азартное...
В закладки. Очень подробная, хоть и несколько субъективная статья Optozorax-а о разных клавиатурных компромиссах, костылях и решениях.
Forwarded from dev optozorax (илья шепрут)
Как известно, я очень упорот по клавиатурам.
И в этой области я развиваюсь уже много лет, поэтому мне есть что сказать. И вот думал что неплохо было бы написать статью о своей раскладке (а она довольно уникальна). Получилась, конечно, статья о раскладке, но случайно я параллельно рассказал про десятипальцевый метод, про неверность стандартных клавиатур и историю своего развития. Получилась огромная статья на 200к символов, которую читать, наверное, 2 часа.
Так что приятного чтения! 🍿
#клавиатуры
И в этой области я развиваюсь уже много лет, поэтому мне есть что сказать. И вот думал что неплохо было бы написать статью о своей раскладке (а она довольно уникальна). Получилась, конечно, статья о раскладке, но случайно я параллельно рассказал про десятипальцевый метод, про неверность стандартных клавиатур и историю своего развития. Получилась огромная статья на 200к символов, которую читать, наверное, 2 часа.
Так что приятного чтения! 🍿
#клавиатуры
optozorax.github.io
Раскладка Ильи Шепрута — Блог optozorax'а
Моя раскладка, история прихода к ней и объяснение каждого дизайнерского решения.
Sandy Maguire (известный в хаскельных кругах товарищ) дописал книгу, которая раньше имела рабочее название "Structure and Interpretation of Haskell Programs" (отсылка к знаменитой SICP). Можно сейчас уже скачать pdf.
https://reasonablypolymorphic.com/blog/algebra-driven-design/
https://reasonablypolymorphic.com/blog/algebra-driven-design/
Энтузиаст начал переводить эту красоту на русский. Вообще, 3b1b иногда просто приятно смотреть из-за классных анимаций, даже не пытаясь вдумываться в содержание.
https://youtu.be/aCvnUuYaRH8
https://youtu.be/aCvnUuYaRH8
Интервью одного человека, с которым я когда-то работал и которого я уважаю. Сам он говорит, что его застали врасплох и получилось не очень, а по мне так получилось очень хорошо. История с Боингом как будто бы типичная, но ребятам могло на самом деле повезти, мне в аналогичной ситуации повезло и дефектов не случилось.😊
https://www.saratovit.ru/interview/andrej-gusev/
https://www.saratovit.ru/interview/andrej-gusev/
И мы видим, что менеджера в айти все больше и больше воспринимают как ничего не понимающего человека, раздающего малоосмысленные указания и действующего по шаблону в ущерб здравому смыслу.
О недостатках Rust на сегодняшний день
Doge Shibu:
Такая возможность была бы полезна практически везде.
Простейший пример - мы хотим из метода трейта возвращать итератор (абсолютно разумная и естественная идея):
Ок, пишем реализацию:
И теперь выходит, что мы не можем назвать тип, который должен идти в
У нас остаются два варианта - бокс
И вот кажется, что раз уж разрабы выбрали такой дизайн для лямбд, то возможность как-то дать название типу замыкания должна была быть с самого начала.
И, кстати, вот эта проблема - это то из-за чего я почти во всех своих проектах сижу на найтли и считаю, что раст без найтли - не сказать, чтобы сильно удобен.
Doge Shibu:
Такая возможность была бы полезна практически везде.
Простейший пример - мы хотим из метода трейта возвращать итератор (абсолютно разумная и естественная идея):
trait MyTrait<'a> {
type MyIter: Iterator<Item = &'a MyType>;
fn get_iter(&'a self) -> Self::MyIter;
}
Ок, пишем реализацию:
impl<'a> MyTrait<'a> for MyTraitImpl {
type MyIter = ???;
fn get_iter(&'a self) -> Self::MyIter {
let some_value = self.some_method(...);
self.something.iter().map(|x| some_value.wtf(x))
}
}
И теперь выходит, что мы не можем назвать тип, который должен идти в
MyIter
, из-за того, что у нас там будет Map<???, ...>
, в котором надо будет указать имя типа замыкания, чего мы сделать не сможем. И соответственно так реализовать трейт тоже не сможем. У нас остаются два варианта - бокс
+ dyn
, что в случае итераторов смешно, или переходить на найтли и давать имя MyIter
через type MyIter = impl Iterator<...>;
И вот кажется, что раз уж разрабы выбрали такой дизайн для лямбд, то возможность как-то дать название типу замыкания должна была быть с самого начала.
И, кстати, вот эта проблема - это то из-за чего я почти во всех своих проектах сижу на найтли и считаю, что раст без найтли - не сказать, чтобы сильно удобен.
Возможно, боян. Представляю, через лет 10 будут искать Senior Functional Excel Developer.
https://habr.com/ru/news/t/540308/
https://habr.com/ru/news/t/540308/
Хабр
С добавлением лямбда-функций язык программирования Excel стал полным по Тьюрингу
Microsoft теперь называет электронные таблицы Excel языком программирования, а с добавлением лямбд он стал полным по Тьюрингу . Язык программирования считается полным по Тьюрингу, если на нём можно...