Python, Delphi и C++ глазами учёного

    Статья про использование Python в научных вычислениях подтолкнула меня написать эту статью. Это история, случившаяся со мной и с коллегами 6 лет назад. На тот момент я уже достаточно подразобрался с Delphi и Python, но только теперь я ощущаю что достаточно поработал с C/C++, чтобы здраво оценить время на «ремонт» сломанного кода и вообще — общее время разработки. Да, это статья про код, который был написан разными людьми на Delphi, Python и C++ для одной и той же задачи, внутри одной команды.



    Перед описанием ситуации, хочу оставить вторую преамбулу для тех программистов, которые не сталкивались с программированием в науке, и не имеют базовых представлений об этом. Осторожно, далее будет несколько мини-инфарктов:
    — В коде просто обязано иметь много переменных. И многие из них должны иметь названия типа mu_e, mu_m, E, T_f, T и так далее — просто потому, что в формулы эти величины входят именно так, и учёным, которые в этой области занимаются исследованиями, могут потратить много времени вспоминая как расшифровывается название коэффициента в полном виде, зато безошибочно узнают букву, которой он обозначается во всех статьях, и скажет — «Ага! Это наша мю...»
    — Код никто не защищает от неправильного ввода и нет никакого UX. Код пишется для того чтобы с ним работали учёные, аспиранты, и специально обученные студенты, и никогда — типичные_пользователи и хакеры.
    — Технического задания у вас нет. Вы ведёте исследование, значит вы пишете один код, смотрите на результат, который он выдал, анализируете, и в зависимости от результатов формируется следующая задача, под которую будет дописываться существующий проект.
    — Большая часть кода будет использоваться один, или два раза. Один — если аспирант, или научный сотрудник делает некий расчёт. Два — если студент делает некий расчёт, а затем демонстрирует работу кода своему научному руководителю. Соответственно, код почти никогда не абстрактен, и в нём может повстречаться костыль любого вида и размера.

    На первое время хватит, начну свой рассказ. Я был слегка моложе, голова моя была чистой, сердце — горячим, а руки были холодными и чесались что-то делать. И так случилось, что одним из первых заданий в новой исследовательской группе (после смены руководителя), для меня стал разбор чужого кода, который по неясным его создателю причинам — не работал. Далее последуют три истории отладки и настройки программы. Одна из них слегка уходит в сторону размышлений, две другие про реально предпринятые действия, и столь же достоверно описывают среднестатистический опыт работы учёного с соответствующим языком программирования.

    Задача была одна на всех — решение дифференциального уравнения (у которого не существует аналитического решения) с разными начальными условиями. Уравнение было большим и пёстрым — f(x) и x, описывающие состояние системы в некоем нестационарном процессе, входили в нём и в производные, и в производные их частного, и в экспоненты, и в логарифмы, и в разнообразные степенные функции. Некоторые коэффициенты при степенях неявно также зависели от них, и их необходимо было пересчитывать на каждом шаге. В дипломах и диссертациях такие уравнения встречаются довольно часто, и обычно в таких выражениях вводят замены, чтобы уместить в одну строку, но часто и замены не помогают — тогда уже расписывают на весь лист. Предсказать вид такой функции (он же — поведение системы) просто по виду задающего её уравнения — задача абсолютно неподъёмная для человека, пусть даже и человека с самыми развитыми способностями к анализу функций и самыми благими намерениями. Соответственно задача программы — тут же вывести этот самый вид, начертив график.
    Решаются такие задачи просто: есть одна приблизительно известная точка, которая берётся за исходные данные. Затем от неё на каждой итерации цикла делается шаг в сторону, с расчётом новых значений из старых. В случае метода Эйлера величина шага пропорциональна производной в исходной точке. В случае метода Рунге-Кутты зависимость несколько сложнее, чтобы быть слегка точнее. Есть и другие методы, когда точка, строго говоря, вам неизвестна. Но вам известна y координата одной точки, и x координата другой. Тогда применяются слегка более извращённые методы, но сводятся они всегда к перебору всех возможных вариантов и множественному использованию Эйлера, или РК. Ну а найдя точки — надо тут же отправлять их на интерфейс в график. Звучит несложно, приступим.

    Начнём с С++
    После проверки всего кода, с множеством переменных с одно- и двухбуквенными названиями, вы приходите к выводу, что программа должна правильно рассчитать все коэффициенты, правильно найти значения для следующего шага, правильно перейти на следующий шаг, и правильно вывести данные на график. Следовательно, программа в целом должна отработать правильно, решаете вы, и запускаете.
    Компьютер зависает и происходит какая-то очень нехорошая ошибка каким-то непонятным образом связанна с памятью.
    Вы остаётесь с задачкой как это всё отладить. Очевидный путь — включить дебаггер и пройтись по потоку вычислений — в данном случае пока не подходит. Ведь вы не знаете сколько раз успел отработать цикл, вдруг миллион, два? Выходит, чтобы начать отладку, вам нужно найти точку вылета. То есть намечается целых четыре новых этапа: переписать код так, чтобы он выводил в лог номер цикла, чтобы заметить последний номер итерации, где происходит вылет, затем переписать код ещё раз, чтобы остановиться на этой итерации и выставить красную точечку в дебаггере, и пройтись по последней итерации дебаггером, надеясь на то что ошибка станет ясной. При этом
    а) у вас нет гарантий что лог сохранится, в связи с падением ОС. Возможно придётся проводить работу визуально, разбив первый этап на на два: сначала выводить номер цикла в консоль и пытаться запомнить последнее число примерно, затем переписать код чтобы включить в цикл искусственный замедлитель после этой запомненной итерации — тогда на следующем тесте можно будет увидеть как числа перед падением начинают поступать медленнее, и успеть прочитать последнюю итерацию (скажем, 6524-ая), значит количество падений будет не 3, а 4.
    б) у вас нет гарантий, что вы поймёте, или даже найдёте ошибку с первого раза. Скорее всего где-то перед самой ошибкой код начнёт уводить вас вглубь кроличьей норы — по извилистым лабиринтам стандартных библиотек, и хоть вы пройдётесь всего по одной ветке, вам потребуется изучить значительную часть дерева возможностей вокруг этой ветки, чтобы понять что вообще произошло, ведь функции в ней зачастую просто перебрасывают какие-то ошмётки данных от одних проверок к другим, для понимания многих из них вам понадобиться ещё и разбираться в физическом устройстве машинных операций, а понимание значения иных приходит к человеку только после попытки написать свою ОС. Более того, после того как вы решите что нашли в чём проблема, нет никаких гарантий, что вы правы. Начался длительный процесс отладки, и вам предстоит ещё много тестов… Вместо четырёх падений мы получаем n, где n>3.
    в) необходимые для тестов падения, вообще говоря, вещь довольно стрёмная. Мало ли что произойдёт? А тем более, когда предстоит сделать это много раз.

    Теперь вы сидите и думаете, а стоит ли вообще приступать к реализации такого плана? Он выглядит громоздко, и неизвестность вас слегка пугает — мало ли где зарылась ошибка.

    Pascal/Delphi
    Проверка кода. Вообще говоря она может занимать больше времени, но в данном конкретном случае вам нравится, что все 66 коэффициентов объявлены и заданы в начале, а не в любом месте кода, например перед использованием. Вы сверили коэффициентики, отбросили табличку и теперь просто сверили все формулы. Опять таки, всё хорошо. Запускаете программу, и — о чудо, график рисуется. График рисуется, доходит до конца оставленного для него участка числовой оси и останавливается. Программа не вылетела, ничего страшного с ОС не произошло. Но произошло с данными. Он плавно доходит до координаты 6524, а затем вдруг его кусает бешеная блоха. Он скачет вверх и вниз абсолютно случайно и заполняет всё оставшееся полупространство справа кромешной тьмой.
    На этом этапе вы удручены неудачей. Но всё же находитесь в выигрышной позицией по сравнению с си, ведь:
    а) система не упала
    б) вы уже локализовали итерацию, где возникает ошибка
    в) вы можете пробовать новые исправления, не боясь что система вдруг упадёт

    и г) — вы видите одно выведенное значение. Оно неверно. И возможно, уже на этом этапе предполагаете что это может быть, скажем, переполнение, либо ошибка чисел с плавающей точкой. Осталось понять где именно, чтобы не создавать тысячи экстендедов. Вы дописываете строчку кода чтобы остановить на номере 6524. Проходитесь дебаггером и замечаете подозрительную операцию очень маленького числа на очень большое, начиная с которой тянется ошибка, которая приводит к расходимости. Есть оказывается, в вашей функции такая особая точка, крохотный участок, где состояние имеет локальный минимум, но за пределами небольшого ограждения в потенциале начинается крутой спуск, приводящий к расходимости всего решения, и уводящий значения за пределы и дальше — в переполнение их типов. И естественно, численный метод немного промахивается на этом шаге мимо нужного локального минимума, из-за банальной нехватки точности для всего двух коэффициентов. И заметно это становится только здесь — в том узком месте, где даже незначительно отклонение отправляет итерации по дурной дорожке расходимости. Значит надо ещё разок переписать код, ввернув пару экстендед вариэйблс… Но опять какой-то косяк происходит, хотя график выглядит уже немного по другому. Я имею ввиду, конечно же, чёрную его часть. Брыкающуюся. Сколько ещё надо колдовать над кодом? Ну, поработать над реализацией работы с длинными числами. И обнаружить (после исправления этих двух) ещё один «протекающий»* коэффициент.
    *протекающий — это потому что выход за пределы типа должен приводить к изменению бита слева от места его физического хранения, т. е. Нам нужен ещё один, либо несколько бит, которые не содержаться по нашей ссылке на объект такого типа. Ок, это заняло не так уж много времени.

    перепишем на Python
    Проверяем код, запускаем. Проблема не наблюдается. График чертится полностью, на всей области. Никаких скачков и черноты, никаких вылетов.
    Волшебство интерпретатора помогает доброму питону увидеть, сколько памяти требует моё число, и выделить ровно столько, сколько ему будет достаточно.

    график изменения теплоёмкости при структурной релаксации АМС

    Разработка закончена.

    Внимательный читатель может заметить, что вскоре мы, учёные, можем захотеть выполнить этот код перебирая параметры, и поместив его во вложенный цикл. И тогда скорость выполнения Python нанесёт нам удар ножом в спину. Однако должен заметить, что код для других значений параметров мог иметь слабые места в других точках, на других рассчитанных коэффициентах. И тогда у человека есть выбор — либо оставить код на Python работать всю ночь ради одного графика. Либо оставить код на С++ работать пока он сходит сделать себе чай. Но когда он вернётся — есть колоссальный шанс увидеть зависание системы, или ошибки другого рода. Он сядет их исправлять для нового слабого места, потом потратит ещё один поход за чаем впустую, в итоге плюнет и начнёт писать более абстрактный код, который подойдёт его растущим требованиям к программе. Вот только написать абстрактный код, который следит за переменными в потоках самых разнообразных вычислений и даёт им больше памяти при необходимости — не забывая в итоге приводить типы к менее ёмким, чтобы не засорять память — это значит написать значительную часть интерпретатора Python.

    Так что я с тех самых пор пользуюсь именно Python’ом почти для всех научных работ (одну я всё-таки сделал в спец пакете, и только ради красивой визуализации под случай), и даже разобрался в некоторых его тонкостях. Чего и вам желаю.
    Используйте Python. Двигайте науку. Лучей добра.
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 431
    • +4
      Разные задачи, разные ситуации — в одном из проектов программка на C полтора месяца считала коэфициенты для алгоритма обработки данных с радара (на разогнанном i7 «x» процессоре с водяным охлаждением). Python в этом случае был бы вообще нерациональным выбором
      • +1
        Python+numpy с интелловским MKL вполне мог бы быть выбором, если в задаче много линейной алгебры
      • 0
        Если вы пишете код на 1/2 раза — почему-бы не объявить все «вариэйблс» «экстендедами», чтобы оно не падало? Ну и в статье всё-таки писать «переменные типа extended».
        • –1
          1) Если решается интегродиффур, то нужно вычислять значение из массива всех предыдущих, т.е. само выделение памяти уже грузанёт систему. (например — если расчитав изменение теплоёмкости, вы хотите сверить итоговую полученную теплоту с экспериментом и проверить правильность симмуляции — это к дальнейшему использованию этого же кода)
          2) В данном конкретном случае предыдущие значения были не нужны, но extended не хватило бы. Нужны были именно операции вычислений над длинными числами.
          • +2
            Ситуации бывают совершенно разные, так что моя интуиция может оказаться в вашем случае и неправильной, но несколько лет работы над похожим сортом задач привели меня к выводу: если при решении физических задач численными методами не хватает двойной точности, значит, выбран неудачный метод.
        • +32
          С куска про C++ просто бомбануло.

          а) «у вас нет гарантий что лог сохранится, в связи с падением ОС» Как выполнение пользовательской программы может привести к падению ОС? На Linux бывало, что память заканчивается и вываливаются какие-нибудь штуки, которые ошибочно считают частью ОС (например, какие-то куски GUI). Но даже такого я уже долго не встречал. Кстати в этом сценарии Python вешает систему с таким же успехом, причем из-за своей любви к отжиранию памяти это произойдет быстрее.

          Что мешает вывести лог в файл, чтобы его даже после падения посмотреть? Почему вы считаете, что дебагер — это стартануть с первой инструкции и жать F(цифра) до того места когда упадет?

          Про «кроличью нору»: сам видел, как люди включают тот же дебагер и начинают входить все глубже и глубже в какие-то дебри системных библиотек. Вопрос: зачем? Наличие ошибки в таких местах маловероятно. В первую очередь нужно понять, правильно ли вы вызвали функцию (нулевые указатели и т.п.). Всегда есть valgrind, memory-sanitizer для поиска проблемных мест с перезаписыванием чужой памяти и т.п.

          По-поводу неожиданных падений. Неужто в python не встречали такой же штуки? Приходишь через час, а там уже все лежит и написано «nonetype is not iterable»? Имхо, если вы не умеете писать программы, которые работают, то 1) никакой язык вам не поможет 2) тупо сохраняйте результаты вычислений регулярно на диск, чтобы потом продолжить не с нуля.
          • –14
            Если у вас коєффициент расчитывается в цикле while до значения, которое вы расчитываете, то неправильный расчёт может нагрузить компьютер хоть и формально не бесконечным, но экспоненциально раздувающимся на каждой итерации циклом, который грузанёт систему, да так что придётся перезагружать. Пайтон в такой ситуации, конечно, грузанулся бы быстрее. Но он в неё в этом случае никак не попадает.
            Код на винде, по крайней мере, может залезть в область памяти с кодом ОС, и крашнет её. Я помню, как мы с одноклассниками нечаяно 2 компа на уроках информатики, причём не на си писали.

            Вывод в лог файл — у вас никогда не пропадали данные из документа, если он был открыт когда выдернули штепсель? Не вижу причин, почему данные в логи должны сохранятся, разве что открывать на запись новый файл на начале каждой итерации, и закрывать в конце. Тогда будет 100% гарантия, и очень неудобная система записи.

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

            Касательно падений Python — ни разу не падал на долгих вычислениях. Ошибался я, конечно, и на Python, кто не ошибается? Но вот разбирался быстрее.

            Касательно кодов — все три были написаны не-программистами, а учёными. Которые знают как должны работать алгоритмы, и лексику этих трёх языков. Но интуитивный «наивный» код на пайтон почти всегда работает так, как ожидается. Аналогичный код на паскале далеко не всегда работает корректно. Ну а наивный код на си почти 100% даже не скомпилируется без каких-то специальных знаний.
            Плюс к тому, на примере описаной задачи видно, что предсказать что где-то там на этапе исполнени возникнет в опасной близости расходимость решения диффура — нереально. И для языков вроде Пайтон это не проблема, а в си — для оптимального решения двух диффуров понадобится по разному выделять память, причём вам заранее неизвестно на что именно её понадобится больше. Вы видите число — а компьютер видит 32 или 64 и более битов. Пайтон немного сглаживает это недопонимание, а си — нет. В итоге вы просто переписали правильное уравнение, и вдруг выясняется, что когда а в диапазооне от 0.1 до 0.3 вам нужно выделять в два раза больше памяти на B и C, а затем обрезать результат их умножения, или деления в короткий тип… А затем выясняется что когда а > 0.3 вам надо делать это не с B и C, а с D и F. Тут знание языка не поможет, нужно ещё и знание ответов, до того как мы их ещё посчитали.
            Так что думается мне, что ваши претензии к умению учёных писать программы не оправданы.
            • +8
              Тут знание языка не поможет, нужно ещё и знание ответов, до того как мы их ещё посчитали.
              Так что думается мне, что ваши претензии к умению учёных писать программы не оправданы.

              Но факт-то остается фактом. На C++ написать ниасилили, разобраться, в чем именно проблема — тоже. На Delphi написать ниасилили, разобраться, в чем именно проблема — тоже.
              Но в итоге виноваты не разработчики, нет, виноваты языки программирования :)
              • +10
                Странный вы человек. Статья — взгляд человека из мира науки с его точкой зрения и объяснением его понимания причины популярности питона в науке. Для него ЯП — это один из инструментов, далеко не единственный. Эдакая помесь доски с формулами с жутко мощным калькулятором.

                Я не говорю, что Си плох или еще что-то. Но по моим ощущениям у вас взгляд на вещи однобокий. Особенно эта фраза:
                виноваты не разработчики, нет, виноваты языки программирования

                Вы же понимаете, что автор не разработчик и не обязан им быть? Зачем ему осиливать кресты? Вы бы еще асм предложили и тыкали пальцем, что автор «ниасилил».

                Вопрос: зачем ему вникать в тонкости разработки на крестах, когда он в разы быстрее напишет все свои формулы на питоне, получит результат и пойдет дальше? Был бы инструмент для почти любых задач более высокого уровня с низким порогом вхождения — использовали бы его.
                • 0
                  Для него ЯП — это один из инструментов, далеко не единственный. Эдакая помесь доски с формулами с жутко мощным калькулятором.

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

                  • +4
                    ИМХО. Как вы относитесь к учены, так и они к вам.
                    Качество кода не гарантирует верность вычислений при «дефектед бай дизайн». Так что я бы опасался пользоваться результатом работы именно такого кода.
                    • +1
                      Как вы относитесь к учены, так и они к вам.

                      Лично я к учёным отношусь с большим уважением.


                      Качество кода не гарантирует верность вычислений при «дефектед бай дизайн».

                      Зато плохое качество кода гарантирует наличие ошибок.

                    • –3
                      Для учёных компьютер это такой большой калькулятор.

                      И что характерно — учёные правы! :)
                      Передача «котиков в контактике» посредством этого самого калькулятора есть по сути его нецелевое использование.
                      • +1

                        Калькулятор это такое устройство, которое позволяет делать вычисления практически любому человеку. Обучение тут нужно минимальное, квалификация тоже не требуется. К компьютеру учёные нередко относятся так же. А между тем писать код надо уметь и квалификация тут очень важна.

                        • –2
                          Одно не исключает другого:
                          1. Писать код надо уметь.
                          2. Квалификация кодера важна.
                          3. Компьютер по своей сути — большой калькулятор.
                          4. Учёные относятся к нему соответственно п.3 и совершенно правы.
                          5. Следствие: учёные используют тот инструмент, который им более подходит исходя из пп.1-4. О чём и рассказывают.

                          А навязывать C/C++ в качестве инструмента для обработки числовых результатов опытов, да и вообще для разработки кода, связанного с математикой, это уж извините.
                          В далеком 1987 году я имел перед глазами пример, как шёл процесс на четырёх разных ЯП в части реализации как раз численных методов (ТОЭ).
                          Это были:
                          1. Turbo C 2.0
                          2. Turbo Pascal 3.0
                          3. Quick Basic 4.5
                          4. Fortran 80 (или 77).
                          Наименьшие трудозатраты были в реализации на «фортране», как и минимальный срок до получения результатов, затём был «паскаль», потом «бэйсик» и только потом C.
                          На вопрос к товарищу, писавшему на С — «а собственно зачем?», ответ был — на нём графика есть. Причём графика не для построения результатов расчёта, а для отрисовки модели ЛЭП.

                          Как показывает практика — прошло 30 лет, а ситуация с выбором инструмента, подходящего исходным условиям почти никак не поменялась :)
                          • 0
                            Одно не исключает другого:

                            Я писал, что калькулятор это устройство, которое не требует никакой квалификации от пользователя.


                            Вы пишите:


                            1. Писать код надо уметь.
                            2. Квалификация кодера важна.
                            3. Компьютер по своей сути — большой калькулятор.

                            Как одно может не исключать другого?

                            • 0
                              Ну что же, попробуем внести ясность:
                              1. Компьютер, он же ЭВМ, это устройство предназначенное для выполнения вычислений. В первую очередь. Наличие в нём логических операций (введённых, как ни странно, тоже для управления расчетами) позволяет ему выполнять функции управляющего устройства или устройства коммуникации.
                              2. С точки зрения ученого естественнонаучника — это и есть большой калькулятор, который позволяет ему обсчитывать результаты, выполнять моделирование, рассчитывать прогнозные значения.
                              3. Соответственно учёному нужно, чтобы язык общения с этим калькулятором был максимально приближен или к его предметной области, или к используемому мат.аппарату. Что мы и видим в исходной статье.
                              4. Если инструмент отвечает требованиям п.3, то это означает, что наш абстрактный учёный с большой долей вероятности «умеет писать» нужный ему код. То есть обладает необходимой квалификацией.
                              5. А вот «писать код» на уровне системного программиста он не умеет. И его квалификация не позволяет этого делать.

                              На мой взгляд тут противоречий нет.

                              И если вы в своей практике используете компьютер для других целей и являетесь не прикладным разработчиком, то это не означает, что нет людей, использующих компьютер как «большой калькулятор», практически по его прямому предназначению :)
                              • 0

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


                                Питон из статьи не ближе к предметной области, чем С++. И к используемому мат аппарату тоже не ближе. Питон из статьи просто производит впечатление языка, который требует меньшей квалификации. Но это обманчивое впечатление — автор написал, что он написал код, который, в отличии от кода на C++ не упал. Почему — непонятно. Явно в коде есть какие-то проблемы, которые Питон маскирует, а С++ нет. Может это проблемы не критичные. А может очень критичные. Но на Питоне же там чего-то завелось, так что разбираться никому не охота.

                                • 0
                                  Прямо, так прямо: калькулятор требует определённой квалификации пользователя.
                                  Если сложить 2+2 — это одно, а вот провести цепочку расчётов без потери точности (не выписывая данные на бумагу), даже на инженерном калькуляторе — это ещё тот цирк. В своё время этому даже специально учили.

                                  Кстати, не знаю как сейчас, но когда я учился в ВУЗе нас учили выполнению сложных инженерных (и математических) расчётов на разных инструментах, включая и ЭВМ (как тогда предпочитали называть компы :)). И с тех пор я не считаю ни калькулятор, ни даже счёты таким уж простым устройством :). Не говоря уж про логарифмическую линейку :)

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

                                  Надеюсь, что моя позиция стала более понятной.
                                  Просто всякому овощу своё место, и что не сделаешь на питоне, то можно сделать на плюсах. Обратное же скорее не верно :)
                    • +8
                      Статья — взгляд человека из мира науки с его точкой зрения и объяснением его понимания причины популярности питона в науке. Для него ЯП — это один из инструментов, далеко не единственный.

                      Для учёного и диффуры вместе с матаном и функаном тоже инструмент, если это не специализирующийся на этих областях математик. Но если этот учёный, скажем, применит какую-нибудь теорему Фубини, не проверив её условия, потому что ну а что, это же инструмент, и он слышал, что интегралы можно переставлять туда-сюда, а чего там конкретно, так он не математик, и потом ой, у меня тут чо-т интегралы какие-то странные, плохой, негодный матан, плохо зделоли тупо, то этого учёного, я думаю, немножко заклюют.
                      • 0
                        Все до безумия просто. Пример:
                        Если в расчетах потребуется найти пределы и по условиям можно применить правило Лопиталя, то оно будет применено. Нет нужды выбирать что бы применить из нескольких десятков возможных способов нахождения пределов. Тут прикол в том, что способ выбирается из условий.
                        В то же время, если нужно выполнить некоторые расчеты, то есть множество инструментов, которые позволяют это сделать. Зачастую инструмент выбирается исходя из трудозатрат на вычисления, в том числе (и зачастую на первом месте) человеческих. Я тут особо хочу подчеркнуть, что под инструментом для расчетов я совсем не обязательно имею в виду ЯП — это всего лишь одно из подмножеств инструментов.
                        • 0
                          Так ведь никто же не говорит о том, чтобы знать концепты из C++20, протоколы синхронизации кешей в процессоре и прочую подобную ерунду. Нужно знать свой инструмент на уровне, достаточном для его эффективного применения. Просто так получается, что правило Лопиталя и даже теорема Фубини сильно проще программирования с нуля.
                        • 0
                          если этот учёный, скажем, применит какую-нибудь теорему Фубини, не проверив её условия, то этого учёного, я думаю, немножко заклюют.


                          На старших курсах я теоретически обосновывал один экспериментально наблюдавшийся эффект. Вообще-то экспериментаторы его и сами обосновали, но у них были странные результаты, и это неудивительно: они записали два уравнения и разложили в ряд до третьей степени, только одно разлагали по x в предположении малого x, а второе — по 1/x в предположении малого 1/x. Их работа была опубликована в приличном журнале и часто цитировалась.

                          На защите курсовой я имел глупость проехаться по этой статье: обоснование там ошибочно, а мы, мол, подготовили хорошее обоснование. Но заклевали не их, а меня за апломб и панибратское отношение к научным зубрам. Конечно, комиссия признала неправильность подхода «зубров» и правильность — моего, поставив «отл» за работу и пожелав успехов в публикации, но за наглый доклад влепила мне тройку: негоже прямо называть математическую ошибку химиков-экспериментаторов ошибкой, нужно было критиковать попозитивнее и попочтительнее.
                          • +1
                            И это, на самом деле, очень грустная история, на мой взгляд.
                            • –1
                              А что в ней такого страшного? Члены комиссии на защите курсовой — это в первую очередь преподаватели, а не только оценщики. В идеале, задача преподавателя — научить добиваться успеха в своей области и всему что для этого требуется. Для того что бы добиться успеха нужны не только «технические» навыки непосредственно в области деятельности, но и коммуникативные, организационные — soft skills. Комиссия преподала студенту важный урок: мало сделать что-то хорошо, важно ещё грамотно это «продать» другим людям, не настроить людей против себя. Какой смысл в том чтобы прямолинейно говорить «экспериментаторы дураки — неправильно формулы записали»? Кому от этого лучше будет? Никому! Можно же конструктивно подойти, может даже пригласить их в соавторы, сказав: «давайте улучшенную версию вашей теории разработаем».

                              Неумение избегать профессиональных конфликтов — это тоже недостаток компетенции. Так что и с точки зрения оценки, комиссия права — не только «техническая» сторона содержания доклада имеет значение, но и «социальная», а также качество самой презентации (выступления) и прочее.
                              • 0
                                У меня сильно другой взгляд на вузовское обучение.

                                В идеале, задача преподавателя — научить добиваться успеха в своей области и всему что для этого требуется.

                                Неа, задача преподавателя — дать возможность получить знания. Прям подход старого Физтеха: не хочешь — не ходи на лекции, не ходи на семинары, никто этого не контролирует, сессия всё решит.

                                Поэтому если у вас нет выделенного предмета типа тех самых soft skills или хотя б какой-нибудь психологии, то вешать это на других преподов не очень оптимально.
                                • –1
                                  Я далее буду использовать выделения, не воспринимайте это пожалуйста как «повышение голоса», это ради акцентов.
                                  дать возможность
                                  Я согласен, и это не противоречит тому, тому определению, что я привел. Когда я написал «научить», я имел ввиду «научить, если студент проявляет соотв. интерес». О принуждении речи не было.
                                  Студент пришел защищать курсовую — значит он хочет получить обратную связь и что бы члены комиссии засвидетельствовали его навыки и дали им оценку.
                                  Курсовая — это тренировочный мини диплом. Таким образом, комиссия, которая оценивает курсовую, делает комплексную оценку способности студента вести профессиональную деятельность. Оценивается не только способность применять навыки непосредственно связанные с курсом, но и оформление курсовой и способность решить все сопутствующие проблемы, необходимые для выполнения задачи курсовой. Социальные навыки входят в эти задачи. Тем более, что в данном случае проявились достаточно специфические «обычаи», характерные именно для академической среды. Их тоже необходимо знать и учитывать.
                        • +1
                          Ну, питон в научных задачах тоже надо уметь готовить. Лично видел, как объявление переменной внутри цикла приводило к выжиранию памяти на совершенно тривиальной задаче.
                          На самом деле, если уж сравнивать, особенно на задачах, подобных описываемой, то смотреть надо не на python vs C++, а на python vs fortran. И тут уже все не очевидно.
                          Фортран компилируется и работает на счетных задачах не медленнее (а зачастую — и быстрее), чем C++. При этом бережет границы массивов. Срезы и всякие хитрые выборки из массивов — из коробки. Передача параметров функциям — всегда по ссылке, но объяснить компилятору, что вот-эту-вот переменную трогать не надо и если я по глупости попытаюсь в неё написать — то это точно очепятка, надавай мне по рукам — это оно уже умеет. Горы кода — тот же lapack написан на фортране, например. Но няшных штук тит «pip install что-то-там» — я не видел (хотя, может уже и есть, не знаю).
                          Другое дело, что современные гики уже затянули, всё что могли, из фортрана в numpy и scipy, а знание python-а в современном мире куда более конвертируемо в ненаучные области, чем знание фортрана.
                          • 0
                            Да хоть эксель — тоже надо уметь готовить. Я ни разу не утверждал, что используя питон нужно вообще не глядя без мозгов что-то писать. Просто оказалось, что автору питон проще и быстрее приготовить. Вообще на питоне проще готовить, чем на крестах.
                          • +4
                            Для него ЯП — это один из инструментов, далеко не единственный.

                            Он взял молоток для забивания гвоздей (хорошо не микроскоп), но бьёт ручкой и плохой именно молоток, а другой молоток совершенно случайно взял правильно и у него получилось. Зачем осиливать молоток? Чтобы забивать гвозди, иначе не получится.

                            • 0
                              Когда я был маленький, знаете какой стороной я гвозди молотком забивал? Боком, ибо правильно у меня еще руки не могли нормально забивать — все время по пальцам норовил попасть.

                              Если человек вырос для владения молотком, то отлично! Молодец! Но если он еще не дорос до этого, то как его можно упрекать за то, что он не умеет пользоваться молотком правильно, если он все равно забил гвоздь и объяснил почему так делают многие?
                              • 0
                                Эта аналогия с молотком так разрослась, что я просто обязан ответить :)
                                дело в том что у молотка, шуруповёрта, и отбойного молотка почему-то наличествуют деревянные ручки, на которых надпись «ручка молотка». Только у молотка это действительно ручка, за которую надо браться, вид и название предмета соответствует его интуитивно понятному назначению. Но у шуруповёрта она торчит на месте кнопки включения, а у отбойного молотка это просто декоративный элемент. И даже если всё это написано в спецификациях к этим трём чудным моделям, это всё равно запутывает людей.
                                • 0
                                  на которых надпись «ручка молотка»

                                  Из тех десятков молотков, которыми работал и тех тысяч, которые видел, ни у одного не было надписи на ручке о том что это ручка. То же касается топоров, колунов, кос, вил, лопат и всего другого инструмента.


                                  Но у шуруповёрта она торчит на месте кнопки включения, а у отбойного молотка это просто декоративный элемент.

                                  Что на месте кнопки? У шуруповёрта и молотка это НЕ декоративный элемент, в обоих случаях ручка — это именно конструктивный элемент, предназначенный для удержания инструмента.


                                  У меня складывается мнение что представление об окружающем мире некоторых айтишников несколько… мультипликационны.

                                  • 0
                                    Вы не поняли аналогию. Под молотком подразумевалось нечто более сложное, чем непосредственно молоток. Равно как и под остальными инструментами.
                                    • +1
                                      Из написанного этого никак не видно, а видно лишь фактические ошибки.
                            • 0
                              Секундочку. Но ведь Пайтон осилили. Значит проблема не в алгоритме была, а в том, какая логика выполнения. Если написать все вычисления от руки — результат будет как у пайтона, просто медленно. А проблемы более низкоуровневых языков, что вам приходится писать далеко не то же самое, что видите у себя в тетради. Их реализация того же синтаксического сахара менее полная, и в каких-то случаях даже самые элементарные абстракции вроде «число» или «строка» выявляют свою дырявую природу. Пайтон (а точнее, тот кто написал интерпретатор) реализовал абстракцию полнее, то есть лучше. Значит и язык — лучше, если все описанные на нём объекты ведут себя лучше. Си реализует массивы по примитивной формуле ссылка+индекс — в итоге это приводит к ошибкам в доступе к памяти. Делфи реализует переполнение для индексов массивов — и не вылетает, массивы Делфи лучше сишных. К массивам Пайтона можно применять кучу функций, которые мы можем сделать с обычным набором чисел в своих мыслях — его массивы ещё лучше. Точно так, как строки, числа, и многое другое. int — это целое число, но только от сих до сих. float — число не обязательно целое, но только пока вам не нужно очень маленькое, либо слишком большое, и есть ошибка представления, и потому оно творит мелкие гадости, которые в сумме могут наворотить больших дел. Если есть язык в котором эти две базовые абстракции менее дырявы — хотя бы могут запросить для себя больше памяти, или быть выведеными без конвертации — это уже большой плюс, и я написал о том, как этот плюс помог научному исследованию.
                              PS Абстракции пайтона тоже имеют свой предел, и свои дыры, но их меньше чем у си и паскаля.
                              • +2
                                А вот попробуйте GNU guile тут есть автоматическое повышение точности чисел Целые (5) > с плавающей точкой (real 5.0 ) > Дроби (ratio 10/2 ) > Точные (exact #e5.0) c длинной арифметикой и + Комплексные (5.0r + 0.0i).
                                Guile Manual: Numbers
                                • +1
                                  И ещё: LUSH
                                  Тоже умеет расширять численные типы и имеет кучу научных «батареек» (линейная алгебра, обработка сигналов и прочее). Эдакий фортран в скобочках.
                                  • +6
                                    Си реализует массивы по примитивной формуле ссылка+индекс — в итоге это приводит к ошибкам в доступе к памяти.

                                    Далеко не это приводит к «ошибкам в доступе к памяти».
                                    • –5
                                      Положим вы ожидали, что на вход придёт изображение четырёхканальное, а оно пришло с тремя (без прозрачки). Аллокатор встроен куда-то глубоко в готовую функцию из библиотеки, которую вы используете. А вот работать с данными нужно вам конкретно здесь, в этой программе. Тогда вы начинаете перебирать пиксель за пикселем, и производить некие операции, скажем свёртки. При чём библиотека эта устроена так, что перевыделяет память на набор строк изображения, скажем на 3, либо на 5. В какой-то момент вы в коде продолжаете умножать до упора. А данных картинки под вашим свёрточным ядром уже нет. Какое-то время откомпиленный код перемножает случайные числа в неизвестных областях памяти, затем доходит до защищённой области и программа вываливается.
                                      Да, безусловно, есть ошибка программиста, что не предусмотрен ввод изображений с разным количеством каналов. Но в любом языке где массив данных — это какая-никакая абстракция имитирующая реальный массив чисел, такого бы не могло случится — потому что реальные наборы чисел не включают ничего, что находится за их пределами, и ссылки на элементы должны вести себя подобно отдельному новосозданному типу — переполнятся, и всегда оставаться в нужных пределах. Даже если сам массив динамический — это никак не мешает делать поправки, пока выделяешь ему память на рантайме. Данные в таком языке всё равно были бы неправильные, что сказало бы программисту о проблеме. Но вылетать такая программа бы не стала. И никакой опасности для системы и других потоков вычислений представлять в принципе не способна. Почему-то для меня эррейтый элемент нуля не является чем-то осмысленным, а у С это будет точно такое же разыменование. Задумывались ли вы, как так то? Абстрактное понятие о масивах у человека есть, а реализации в C по сути нет. Не говоря уже о строках — это вообще для человека ясная вещь. Для С — ткой же дырявый массив слегка дырявых чаров. А если язык не стремится создавать более высокоуровневые абстракции, и с презрением отзывается о них как о синтаксическом сахаре, тогда чем он лучше кода ассемблера? (кроссплатформенность не в счёт, можно с таким же успехом написать транслятор одного ассемблера в другой, любой нестандартный (подобно тому как делают компилятор С отдельно для каждой платформы)).

                                      К ошибкам в доступе к памяти приводит (чаще всего) неизолированность динамических массивов, которая является прямым следствием того, что массивы С — на самом деле не настоящие массивы данных — цельные объекты, а всего-лишь ссылки на 0-элемент, с прикрученным парсингом обращений в стиле массив[переменная-число]=>*(массив+переменная-число).
                                      • +6
                                        Какая разница, каким именно некорректным образом ведет себя программа, если она реализована неверно? Или вам для «научных» статей важен хоть какой-нибудь результат, даже если он неверно посчитан?
                                        • +10
                                          1) Если вы находитесь где-то в середине 2000-х годов и у вас там уже есть Windows XP, а Linux перевалил за 2.4, то вот вам радостная новость: ОС пристально следит за тем, чтобы процесс не уходил за пределы своей памяти. Вы НЕ сможете считать и, тем более, переписать произвольный блок данных. И ОС НЕ рухнет, если вдруг вы попытаетесь из своего приложения залезть в память драйвера. Даже под рутом этого добиться очень сложно.

                                          2) Новость оттуда же: ваша ОС НЕ упадёт, если у неё закончилась память. Пошатнётся — безусловно, но что винда, что никсы уже давно пришли к тому, что пользователи приходят и уходят, а стабильность стабильно остаётся. Все системные процессы и драйвера имеют нужный запас памяти, а что будет с вашей difur.exe — это лично ваши проблемы.

                                          3) Питон ЗАПРОСТО повалит комп из вашего сценария. Он сожрёт больше памяти, дольше будет мурыжить свои переменные, а потом с вашими же неверными параметрами вызовет сишный библиотечный метод. И перейдёт от стадии обеда в стадию танца. Питон ВЫГЛЯДИТ безопаснее, безусловно, на питоне гораздо быстрее пишутся одноразовые задачи — это тоже так, лично я порекомендую писать на питоне одноразовые маленькие задачи — скорее всего, да. Но это не серебряная пуля, и, тем более, не платиновый M60.

                                          4) Тот поток мюслей, который вы написали, справедлив для С98-с-классами. Современные плюсы значительно отличаются по методологии написания. Банально, try{} catch(){} попробуйте использовать. std::bad_alloc, std::out_of_range, для любого более-менее продвинутого плюсовика ловить подобные исключения за собой — правила этикета.

                                          5) Если вам написали, что вы должны передать в файл, скажем, png, а вы пихаете туда jpegrar, это, пардон пур мон франсе, разгильдяйство в терминальной стадии. «Ха-ха-ха, расстрелять.» И фразы типа "Я учёный, а не программист", "У меня нет времени писать проверки", "Я женщина, а не посудомойка" — это всё ещё более ужасные оскорбления самого себя. Не надо так.

                                          6) На большинстве языков есть очень мощные фреймворки для решения математических — и не только — задач. Если начать с банального, оболочкой для вашей картинкомешалки можно взять тот же Qt, которому достаточно сообщить, в каком формате ты хочешь картинку — и уже он будет отвечать за её обработку. А ещё пропихнуть свой код обработки в QtConcurrent::mapped, Qt-шным эквивалентам питоновского map.
                                          А если очередной отличник от науки вместо использования Blitz++ или gsl начинает своими кривенькими похотливыми ручками набирать те же алгоритмы самостоятельно, в процессе игнорируя любые обработки ошибок и пытаясь параллелить потоки без атомарок, это вопрос не к языку, а к отличнику.

                                          7) Очень интересно, как легко будет портировать питоновый код на GPU? Не будет ли в Numpy лапшекода того же уровня, что и на сях? Не сожрёт ли Питон весь прирост производительности, который можно было бы получить от Xeon Phi?
                                          Когда вы говорите «математические задачи», передо мной всплывает расчёт трёхмерных газовых объектов в миллиарде точек или построение карты загрязнённости города Кемерово на основании томов ПДВ всех производств в радиусе 150 км с шагом сетки в 20 метров. Сотни гигабайт входных данных, недели непрерывной работы расчётных блоков на очень мощном оборудовании. Прирост производительности на 1% — это 5-10 часов работы. И тут — питон. Приехали.
                                          • 0
                                            1)-2) после включения программы я не могу работать в системе. Виновата этом программа, но систему всё равно придётся перезагружать, ничего не отвечает, процесс съел всё. Вы знаете что это не падение системы. Для меня — разницы никакой. Машина не функционирует.
                                            3) Не валит. Я использю одну и ту же библиотеку из пайтона и из С++.
                                            4) Если вы продвинутый плюсовик — ок. Объясните, откуда человек впервые открывший код на новом языке будет знать такие вещи? Есть for, else, array — вещи, которіе узнаются во многих языках и понятны. try{} catch(){}, std::bad_alloc, std::out_of_range — это есть не везде. Более того, когда вы открываете чужой код, и видите все расчёты без этих вот штук — вы не знаете что их нужно дописать. Это нифига не очевидно. (на всякий случай напоминаю, что нерабочие коды на си и делфи написал не я — я только пытался помочь разобраться людям написавшим их, почему они не заработалали (а люди, которые их писали — знают совершенно точно, что языки программирования — это ада, фортран, паскаль и сиплюсплюс, они во многом ещё электронную почту и интернет не освоили, потому что впервые столкнулись с необходимостью моделирования. Обратились они ко мне, поскольку в отличие от них я изучал один язык в школе и в университете, и это в любом случае больший опыт чем у них. К си ни их, ни нас жизнь тогда не подготовила.))
                                            5) иногда файл повреждён, и хотя имеет правильный формат, в нём неправильное число каналов. Я сталкивался с такими картинками. Если подтягиваете из интернета картинку с расширением png — ожидаете 4 канала. Но это не всегда так, в чём я и убедился, после написания той программы.
                                            6) Надо было использовать формат той библиотеки, которая была нужна.
                                            Если очередной отличник не переписывает алгоритм — программа работает в разы медленнее чем нужно, поскольку отличник оптимизирует код под конкретную задачу, а создатель библиотеки его задачи не знал.
                                            7) Я расчитывал рост нанокристалов в 3д среде на миллиард частиц на пайтоне, было дело. И собирал данные шумовой загрязнённости в городе) Как ни странно оба названных вами примера очень близки к тем вещам которые делал я. Только одно я делал прямо пайтоном, а другое — в специализированном матпакете (без программируемых частей). У меня всё было достаточно быстро на мощном компе. Плюс, иногда программа работала где-то на фоне в течение дней, это да. Но прочитать все нужные статьи по вопросу и потом анализировать данные — это всё равно дольше. Так что время полного исследования не особо экономится.
                                            • –1
                                              Объясните, откуда человек впервые открывший код на новом языке будет знать такие вещи?

                                              Ну как бы для того чтобы писать на некотором языке — надо его знать.

                                              • 0

                                                Человек говорит о том, что пайтон ближе к математическому языку (что достаточно перевести его под необходимый синтаксис и многое будет работать). И что вы подразумеваете под знать язык? Знание синтаксиса языка, не обеспечивает умение корректного его использования. Приводя пример выше, есть массив в си — это ссылка и сдвиг, и собственно если использовать все аккуратно, то не будет никаких проблем. Но массив для программиста — это одни кейсы использования, а массив для ученого — это другая история, для них все более абстрактно и кейсов сишных массивов недостаточно. Получается, что вместо того чтобы прочитать синтаксис языка и использовать его, человеку надо знать как его использовать, знать какие могут быть ошибки-крайние случаи, и указать для своего конкретного примера решения для тех случаев, которые актуальны в его конкретной задаче. И весь рассказ о том, что на пайтоне уже много сделано, абстракция настолько высока, что массу задач можно решить просто просмотрев синтаксис и написав "как на бумаге" почти один в один задачу интерпретатору. Другое дело, что:
                                                -если хочешь быстрее — используй методы оптимизации;
                                                -хочешь защиту от некорректного использования — делай кучу проверок и обработок входных данных и оборачивай все в исключения и тому подобное;
                                                И во многих случаях, проще подождать выполнения задачи, чем сделать тоже самое в языках, которые ниже по уровню абстракции или не предназначены для выполнения данного класса задач.

                                                • +2
                                                  В плюсах точно так же, нужно только выбрать подходящую библиотеку (но на Питоне тоже нужно ее найти и выбрать).

                                                  А ближе всего к математическому языку Хаскель
                                                  • 0
                                                    А ближе всего к математическому языку Хаскель

                                                    К маленькой доле математики — из прикладной математики так сходу и не сказать, к чему же он близок.
                                                    • 0
                                                      А что не так в нем с прикладной математикой?
                                                      • 0
                                                        Ну вы же утверждаете, что хаскель ближе всего к математическому языку — покажите, каким образом он ближе (питона например) к написанию численных методов решения уравнений, статистическому анализу данных, ...?
                                                        Правда интересно, писал всякую мелочь на хаскеле (даже пост на хабре :) ), но реальной пользы к сожалению не увидел.
                                                        • +1
                                                          Там же есть repa, accelerate, hmatrix и куча других ништяков вроде какого-нибудь ad. Статистический анализ данных — тут лучше R на самом деле, но если вам нужно запилить какого-нибудь Монте-Карло или что-то такое вероятностное, то был пакет с очень приятной монадой для рандома, забыл название, увы.

                                                          Да даже сама форма задания функций как уравнений (и STG оттуда же) — любая прикладная математика. Я как-то ещё в студенческие над отцом, который у меня физик, издевался ради интереса, показывал ему свой вычислительный код на хаскеле и код на питоне сокурсника, мол, что понятнее. Вот хаскель с формулками, паттерн-матчингом и иммутабельностью-чистотой был понятнее.

                                                          А за счёт определения своих операторов и уникодных литералов из коробки можно даже синтаксис особо не переводить, писать себе формулы, и всё. Да, у меня есть код, в котором уникодные лямбды и фи, оператор дельта для взятия дифференциала, и так далее.
                                                          • 0
                                                            Вот взял первый попавшийся пример со страницы hmatrix:
                                                            m ?? (All, Pos $ sortIndex (m!1))

                                                            Чем же это лучше (ближе к математической записи), чем
                                                            m[:, argsort(m[1])]

                                                            ? И это всё оставляя за рамками вопрос, что все упомянутые библиотеки есть и для питона, а касательно
                                                            если вам нужно запилить какого-нибудь Монте-Карло или что-то такое вероятностное, то был пакет с очень приятной монадой для рандома

                                                            то в питоне (и в R, например) есть далеко не один пакет, причём достаточно зрелый.
                                                            Идейно мне хаскель очень понравился, но относительно большие проекты, особенно с этим самым переопределением всяких операторов, выглядят намного менее понятно «обычных» языков.
                                                            • 0
                                                              Чем же это лучше (ближе к математической записи)

                                                              Не знаю, потому что я не понимаю вторую запись.

                                                              Идейно мне хаскель очень понравился, но относительно большие проекты, особенно с этим самым переопределением всяких операторов, выглядят намного менее понятно «обычных» языков.

                                                              Так вам ближе к математическому языку (а значит, и eDSL со своими операторами), или чтобы понятно случайному человеку? Вы случайную человеку формулу какую-нибудь рандомную покажите, ему тоже непонятно будет.
                                                              • 0
                                                                Так вам ближе к математическому языку (а значит, и eDSL со своими операторами)

                                                                Ну «ближе к математическому языку» и «повсюду операторы $$, <|>, >|<, ?? т.п.» — это всё-таки две большие разницы.

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

                                                                Обычный математический язык:
                                                                aargmaxi bi
                                                                Питон:
                                                                a[argmax(b)]

                                                                странно, как можно понимать первую запись и не понимать вторую (если хоть немного знаком с любым программированием).
                                                                А вот
                                                                a ?? (Pos $ maxIndex b)

                                                                (написал примерно, не искал точное название функции) намного менее понятно.
                                                                • 0
                                                                  Ну «ближе к математическому языку» и «повсюду операторы $$, <|>, >|<, ?? т.п.» — это всё-таки две большие разницы.

                                                                  Увы, чтобы прямо совсем везде математический язык и юникодовые закорючки — это в Agda. В Idris, что характерно, от этого отказались, кстати.

                                                                  странно, как можно понимать первую запись и не понимать вторую (если хоть немного знаком с любым программированием)

                                                                  В исходной записи было ещё какое-то двоеточие, какая-то запятая, какой-то argsort. argmax понимаю, argsort — нет. Это такая перестановка индексов, что аргумент становится отсортированным? Или просто отсортированный набор чисел? Что такое m[1], m — матрица, что ли? Иначе зачем сортировать скаляр?

                                                                  a ?? (Pos $ maxIndex b)

                                                                  Ну было бы a ?? (Pos (argmax b)), было бы лучше? $ — оператор из стандартной библиотеки, позволяет избежать лишних скобочек, а ?? или [] — вопрос опыта от предыдущих языков программирования, а не от математики, скорее.
                                                                  • 0
                                                                    В исходной записи было ещё...

                                                                    Если что, это две записи разных вещей :) Первая — взятый из примера к библиотеке, второй — простой argmax.

                                                                    Ну было бы a ?? (Pos (argmax b)), было бы лучше? $ — оператор из стандартной библиотеки, позволяет избежать лишних скобочек, а ?? или [] — вопрос опыта от предыдущих языков программирования, а не от математики, скорее.

                                                                    Нет, не было бы существенно лучше. Вы так легко отметаете «опыт от предыдущих языков», что достаточно странно — грубо говоря, все кто хоть немного программировал на чём-нибудь знают, что обращение к массиву идёт через [] (notable exception — матлаб, но круглые скобки оттуда всё равно к "??" не ближе). Ещё какой-то непонятный «Pos» стоит.

                                                                    argmax понимаю, argsort — нет. Это такая перестановка индексов, что аргумент становится отсортированным?

                                                                    Сёрьзно, не понимаете? А sortIndex так прям понятнее? Абсолютно простая запись — argmax возвращает аргумент (индекс), который при подстановке в массив даёт его максимальный элемент; argsort — возвращает аргумент(ы), при подстановке в массив даёт его элементы в отсортированном виде.

                                                                    Что такое m[1], m — матрица, что ли? Иначе зачем сортировать скаляр?

                                                                    Посмотрите на хаскель-код, там ведь это всё тоже есть — "(m!1)".
                                                                    • 0
                                                                      Если что, это две записи разных вещей :) Первая — взятый из примера к библиотеке, второй — простой argmax.

                                                                      Поэтому я и говорю снова об исходной записи :)

                                                                      Вы так легко отметаете «опыт от предыдущих языков», что достаточно странно — грубо говоря, все кто хоть немного программировал на чём-нибудь знают, что обращение к массиву идёт через []

                                                                      Да, с этим трудно не согласиться.

                                                                      Ещё какой-то непонятный «Pos» стоит.

                                                                      Типобезопасность же. Негоже напрямую элементами массива индексироваться.

                                                                      Сёрьзно, не понимаете? А sortIndex так прям понятнее? Абсолютно простая запись — argmax возвращает аргумент (индекс), который при подстановке в массив даёт его максимальный элемент; argsort — возвращает аргумент(ы)

                                                                      argmax я встречаю регулярно вот прям в формулах, argsort видел хорошо если раза два, и оба этих раза не отложились у меня в памяти. А зная иную наркоманистость разработчиков библиотек, лучше предполагать худшее.

                                                                      Кстати, в этом профит статической типизации: по Ord a => [a] -> [a] и Ord a => [a] -> [Int] (а ещё лучше — Ord a => [a] -> [Idx] или вроде того) сразу очевидно, что каждая из них делает. Даже в документацию лезть не нужно, достаточно нажать :t в репле или магическое словосочетание в вашем редакторе.
                                                                      • 0
                                                                        Типобезопасность же. Негоже напрямую элементами массива индексироваться.

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

                                                                        Кстати, в этом профит статической типизации: по Ord a => [a] -> [a] и Ord a => [a] -> [Int] (а ещё лучше — Ord a => [a] -> [Idx] или вроде того) сразу очевидно, что каждая из них делает. Даже в документацию лезть не нужно, достаточно нажать :t в репле или магическое словосочетание в вашем редакторе.

                                                                        Хотя с общим посылом я согласен, но в чуть более сложных случаях всё-таки намного надёжнее смотреть название + docstring функции (который выводится по «func?» в репле или тоже по кнопке в редакторе). Да даже в этих простейших функциях я сходу вижу как минимум несколько вариантов: сортировка (2 штуки: по убыванию и возрастанию); или например в дополнение к сортировке может происходить выкидывание повторяющихся элементов.

                                                                        Опять же, идейно это всё выглядит реально круто и полезно… Но если взять хотя бы небольшой кусок кода (например, ваш расчёт карандаша) и написать абсолютно такие же функции на питоне, а потом спросить обычного человека, который прошёл курс в универе по какому-нибудь C и всё — то я уверен, что ему хаскель будет намного менее понятен. Ну и удобств многих там нет, чего только стоят сразу бросающееся в глаза отсутствий named arguments и нормального форматирования (`show x ++ " " ++ show y` vs `f'{x} {y}'`).
                                                                        • 0
                                                                          Кстати, в математике спокойно бывает запись в духе aai — вот и индексация элементом массива.

                                                                          Рефакторинг в математике, к счастью, выглядит совсем не так, как в программировании.

                                                                          Хотя с общим посылом я согласен, но в чуть более сложных случаях всё-таки намного надёжнее смотреть название + docstring функции (который выводится по «func?» в репле или тоже по кнопке в редакторе).

                                                                          В более новых языках это очень хорошо решено:
                                                                          Prelude> :doc InBounds
                                                                          Data type Prelude.List.InBounds : (k : Nat) -> (xs : List a) -> Type
                                                                              Satisfiable if k is a valid index into xs
                                                                              Arguments:
                                                                                  k : Nat  -- the potential index
                                                                                  
                                                                                  xs : List a  -- the list into which k may be an index
                                                                                  
                                                                          Constructors:
                                                                              InFirst : InBounds 0 (x :: xs)
                                                                                  Z is a valid index into any cons cell
                                                                                  
                                                                              InLater : InBounds k xs -> InBounds (S k) (x :: xs)
                                                                                  Valid indices can be extended
                                                                          

                                                                          Но рекомендовать Idris для прикладных учёных — это перебор.

                                                                          Ну и удобств многих там нет, чего только стоят сразу бросающееся в глаза отсутствий named arguments

                                                                          data Args = Args { foo :: Int
                                                                                           , bar :: Double
                                                                                           , baz :: Float
                                                                                           }
                                                                          
                                                                          instance Default Args where
                                                                              def = Args { foo = 0, bar = 0, baz = 0 }
                                                                          
                                                                          doFoo :: Args -> Smth
                                                                          doFoo Args { .. } = doSmthWith foo baz bar
                                                                          
                                                                          callFoo = doFoo Args { baz = 0.3, foo = 10, bar = 3.14 }
                                                                          callFooDef = doFoo $ def { foo = 20 }
                                                                          


                                                                          и нормального форматирования (`show x ++ " " ++ show y` vs `f'{x} {y}'`)

                                                                          Я был молод и не знал про Data.String.Interpolate (такие вещи в библиотеке вместо ядра языка — это офигительно изящно, как по мне). С ним оно просто [i|#{x} #{y}|].
                                                                          • 0
                                                                            Да уж, interpolate действительно выглядит красиво, особенно если учесть что это библиотека. Про named arguments — не очень понял, то есть это всегда было в хаскеле, получается?

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

                                                                            А про
                                                                            Prelude> :doc InBounds

                                                                            — там всё кроме Test if k is a valid index into xs несёт какую-то полезную информацию пользователю функции?
                                                                            • 0
                                                                              Да уж, interpolate действительно выглядит красиво, особенно если учесть что это библиотека.

                                                                              Да, в этом прелесть квазиквотеров и вообще template haskell. Можно библиотекой сделать интерполяцию строк, raw string literals, вызов системных команд с аналогичной интерполяцией аргументов, компил-тайм-парсинг матриц и всё такое.

                                                                              Про named arguments — не очень понял, то есть это всегда было в хаскеле, получается?

                                                                              Ну, да (кроме того места, где Args { .. }, это расширение {-# LANGUAGE RecordWildCards #-}), но это немножко читерство. У вас теперь функция не n аргументов, а одного аргумента — рекорда с соответствующими полями. Её ни частично применять, ни flip'ать, ни что-то ещё не получится.

                                                                              Наверное, можно было бы запилить синтаксис для частичного применения таких «именнованных аргументов», и это было бы полезным упражнением для изучения фронтенда ghc.

                                                                              Кстати, можете кинуть пару примеров реальных проектов на хаскеле (а то и ещё на чём-нибудь необычном типа idris), которые адекватно написаны, с использованием соответствующих фич?

                                                                              Раз мы тут за машинное обучение трём, вот, например. Но там хардкор :) Ещё в голову сразу, например, pandoc приходит, но там качество кода не везде образец для подражания — однобуквенные локальные переменные иногда смущают людей.

                                                                              У меня ещё всякие вещи были, но, увы, закрытые. Может, когда-нибудь получится открыть.

                                                                              там всё кроме Test if k is a valid index into xs несёт какую-то полезную информацию пользователю функции?

                                                                              Только это не функция, а тип данных, используемый для доказательства некоторых свойств других данных :)

                                                                              А так — да, несёт. Видно, как строится это самое доказательство, и это можно напрямую использовать в моём коде.

                                                                              Собственно, я сам только учу Idris, и вчера как раз примерно в это время столкнулся с соответствующим вопросом. Документация по деталям доказательства позволяет на него эффективно опираться.
                                              • 0
                                                Вы вручную разбираете PNG-картинку, или используете для этих целей какую-нибудь библиотеку? Если вручную, то должны были как минимум ознакомиться со спецификацией PNG, а там аж целых 5 возможных вариантов каналов есть (это не считая того, что бит на канал может быть не обязательно 8).
                                                Если используете чужую библиотеку, которая этих нюансов не учитывает, то поздравляем, библиотеку писал рукожоп и проблем там может быть куда больше.
                                                В любом случае, если вы «подтягиваете из интернета» — то должны относиться к этим данным с повышенной осторожностью.
                                                • 0
                                                  Да, я использовал библиотеку человека, который такое не предусмотрел. Но он великолепно реализовал другие нужные мне вещи, потому я просто дописал кейс с другим числом каналов. Просто когда я запускал, то не ожидал таких вещей, и несколько раз программа таки завершилась с ошибкой, пока я разобрался в чём дело.
                                                • +3
                                                  1-2) Помните, что пишется в уголовных кодексах в преамбуле?
                                                  Незнание законов государства не освобождает от ответственности.
                                                  То, что вы не знаете — и не хотите знать, что у вас происходит в ОС, крайне негативно характеризует вас как специалиста.

                                                  3) Давайте не будем спорить. Хотя бы в силу 1-2), просто примите 3) как данность.
                                                  4) Объясните, откуда человек впервые открывший код на новом языке будет знать такие вещи?
                                                  Объясните, откуда человек, впервые открывший код на Питоне, будет знать, что блоки определяются отступами и прерываются пустыми строками?

                                                  5) О том и речь, вы физически не можете написать реализацию для открытия и преобразования всех типов файлов в ваш формат. (Число каналов, в общем, произвольно, битность каналов не фиксирована, цветовых схем куда больше дюжины, многие форматы вообще защищены патентами) Не проще ли скачать библиотеку, которая, если смогла распознать файл, ГАРАНТИРУЕТ вывод сырых данных именно в нужном вам формате? Проще.

                                                  6) Только, Богом молю, не пишите свою ОС из-за того, что шиндовс виснит!
                                                  Кстати, а как этот пункт корреспондируется с тем, что вы же голосуете за Питон, в котором всё, что сложнее завершения приложения импортируется из готовых модулей?

                                                  7) Значит, при созвучности названных действий их реальная алгоритмическая сложность несколько отличается. У шума вообще достаточно простые формулы, ибо погрешности измерения в поле таковы, что дробные части можно просто отбрасывать за ненадобностью. У воздуха, всё-таки, и формулы позаковыристее, и число веществ под 500 уходит, и проходов до 10 штук для каждой из 16 сторон света.
                                                  Про рост кристаллов не скажу, но как-то у меня сомнения закрадываются. Такое чувство, что вы приукрасили число частиц на пару-тройку порядков. Иначе бы мы рассуждали не про питон и домашние пеки под виндой, а про выделенную никсовую ноду одного из суперкомпов о 64 cuda-ускорителях или таком же числе фишек, не говоря об mpi-архитектуре самого приложения. Признаюсь честно, расчёт газового облака я только видел у препода, и только в сокращённом виде, но даже так счётчик терабайт отработанных данных завораживал. (Даже Копатель бы работал на максималках с модами без тормозов.)

                                                  А вообще, мораль статьи проста: если вы не являетесь специалистом в какой-либо сфере, и вам нужно срочно использовать нетривиальный инструмент из неё, не беритесь сами. Найдите действительно хорошего специалиста и узнайте его мнение по данному поводу. Иначе вы всё равно ничего не добьётесь, но потратите время, силы, нервы, да ещё и осмеяны на хабре будете.
                                                  • 0
                                                    Кстати, а как этот пункт корреспондируется с тем, что вы же голосуете за Питон, в котором всё, что сложнее завершения приложения импортируется из готовых модулей?

                                                    Мне кажется что люди, занимающиеся переписыванием библиотек си под пайтон — очень грамотные и разумные. В некоторых случаях они реализуют лучшую работу чем оригинал.
                                                    У воздуха, всё-таки, и формулы позаковыристее, и число веществ под 500 уходит, и проходов до 10 штук для каждой из 16 сторон света.

                                                    3 вещества, часть уже превращённая в кристал не просчитывается в рамках оптимизации, из-за диффузионного контроля. Проход один на итерацию, 8 связей по 3 координатам 3d сетки. Значит мой миллиард в среднем где-то в 40 раз меньше того, что упомянули вы. 40 раз тот мой код считался бы около 10 часов. На практике миллиард я запустил пару раз, чтобы показать справедливость эргодической гипотезы в рамках такой модели процесса, а дальше использовал 100млн ячеек, они за минуту просчитывались по сути, и можно было много модификаций попробовать. Для чего-то нужно большие куски, для чего-то хватает поменьше, такая жизнь.
                                                    А со звуком и правда простенько всё было.

                                                    А вообще, мораль статьи проста: если вы не являетесь специалистом в какой-либо сфере, и вам нужно срочно использовать нетривиальный инструмент из неё, не беритесь сами.

                                                    Проблема в том что где-то в жизни есть момент, когда человек вдруг захотел таким специалистом стать. Например, когда ему впервые понадобилось программировать для научной задачи. И тогда он смотрит на свой питон, потом на си, и снова на питон…
                                                    • 0
                                                      переписыванием библиотек си под пайтон
                                                      О чём речь?
                                                      • 0
                                                        Мне кажется что люди, занимающиеся переписыванием библиотек си под пайтон — очень грамотные и разумные.

                                                        Не знаю, как сторонние, но о стандартных библиотеках питона сложилось диаметрально противоположное мнение:
                                                        os.path.exists который робил через раз (по крайней мере на винде); довольно странный popen; thread, которые совершенно не thread (вот на кой их было так называть?).

                                                        Проблема в том что где-то в жизни есть момент, когда человек вдруг захотел таким специалистом стать. Например, когда ему впервые понадобилось программировать для научной задачи. И тогда он смотрит на свой питон, потом на си, и снова на питон…

                                                        В этом случае гораздо логичнее начать с гугла.
                                                  • 0

                                                    Ловить std::bad_alloc, std::out_of_range? Ой-ой-ой, что-то совсем плохо в мире С++.

                                                    • 0
                                                      4. Сильно bad_alloc поможет на линуксах с оверкоммитом?

                                                      6. Не надо этих blitz++ и тем более gsl, есть же относительно прекрасный Eigen и чуть менее распространённый, но чуть более прекрасный dlib.
                                                      • 0
                                                        Новость оттуда же: ваша ОС НЕ упадёт, если у неё закончилась память.

                                                        Память не сожрёт, но какой-нибудь цикл с тонной итераций по крайней мере XPшку запросто мёртво вешает. Не знаю, как с этим на Linux и более современных Windows: с такими ситуациями больше особо не сталкивался. Но почему при этом файл в лог не писать тоже не особо понятно.
                                                        • 0
                                                          Если запускать не от рута (администратора) и с пониженным приоритетом, то проблемы не должно быть. От используемого языка программирования это не зависит :)
                                                          • 0

                                                            У однажды повесил винду скриптом на питоне утечкой зомбяков.
                                                            Примерно так:


                                                            def frequently_called():
                                                                popen = Popen()
                                                                if some_condition:
                                                                    return
                                                                popen.communicate()

                                                            К слову о безопасности питона — даже на нем система вешается запросто.
                                                            И я не был админом.

                                                      • +5
                                                        В дополнение к Antervis и iCpu я лишь могу добавить, что код на Си ведёт себя именно так, как и должен — если программа написана неверно, то не стоит ожидать от неё решения ваших проблем.

                                                        Ну и нельзя обойтись без самого детского аргумента о том, что на Си пишут оперрационные системы и ничего, как-то работают.

                                                        И я не спорю с тем, что возможно Си не подходит именно под вашу задачу. Но вы говорите о преимуществе одинх языков над другими в целом, а это не выдерживает никакой критики.
                                                    • 0
                                                      В аналоге Дельфи — Лазарус, есть ключи, которые включат контроль за переполнением в разных случаях, по умолчанию это не контролируется, что бы ускорить выполнение программы, что бы использовать их, надо прочесть документацию, а не быть программистом.
                                                      ключи
                                                      {$OVERFLOWCHECKS OFF}//Проверка переполнения целых чисел отключена
                                                      {$RANGECHECKS OFF}//проверка выхода за пределы массивов и диапазонов
                                                      {$S OFF}//Проверка на переполнение стека

                                                      В других языках, я подозреваю, всё — аналогично.
                                                      • –1
                                                        Зря подозреваете. В Си/С++ никакого контроля выхода за границы массивов нет. В C# и Java — есть и он неотключаемый.
                                                        • –1
                                                          В C# и Java — есть и он неотключаемый.

                                                          В C# он слабо контролируемый, т.к. он может отключаться JIT-ом.
                                                          Если совсем невмоготу, включаем unsafe и поинтерами тычем в элементы массива.


                                                          Про Java не знаю, но подозреваю что ситуация похожая.

                                                          • 0
                                                            В Си/С++ никакого контроля выхода за границы массивов нет.

                                                            Про C++ Вы уверены?
                                                            cpp.sh/2dfvh
                                                            • –1
                                                              Это не совсем массив… К тому же, если обращаться как раньше, через индексатор — проверки пропадут.
                                                              • +1

                                                                У вектора так же. И для ТС замедление расчета на 1% явно лучше, чем некорректные данные (судя по тому, что он даже к питону готов).

                                                        • +1
                                                          Си реализует массивы по примитивной формуле ссылка+индекс
                                                          Но мы ведь говорим о C++, где есть std::vector, если надо. В C тоже есть аналоги.
                                                          Делфи реализует переполнение для индексов массивов — и не вылетает
                                                          Вылетает, с исключением.
                                                          Если есть язык в котором эти две базовые абстракции менее дырявы — хотя бы могут запросить для себя больше памяти, или быть выведеными без конвертации — это уже большой плюс
                                                          Python/C++/Delphi этого не обеспечивают непосредственно. Это обеспечивается библиотеками для длинной арифметики, которые есть везде.
                                                          написал о том, как этот плюс помог научному исследованию.
                                                          Или о том, как набор принятых конвенций в Python и ваша конкретная реализация случайно привели к удачному для Вас результату. Вы не дали никаких обоснований для того, что бы утверждать что в следующий раз ситуация не поменяется и реализация на C++ заработает, а на Python провалится.
                                                        • 0
                                                          "… глазами учёного" и этим всё сказано. Вывод был предсказуем. Конечно это не языки виноваты, C++ и Pascal — языки для программистов, а не для учёных. Учёным лучше выбрать язык попроще и время на науку тратить, а не изучать ЯП по многу лет.
                                                          • +1
                                                            Ситуация меняется. А так то «Учёным лучше выбрать арифметику, а не изучать высшую метматику много лет».
                                                        • +5
                                                          Не вижу причин, почему данные в логи должны сохранятся, разве что открывать на запись новый файл на начале каждой итерации, и закрывать в конце. Тогда будет 100% гарантия, и очень неудобная система записи.

                                                          У ОС есть механизмы гарантированной записи в файл, в правильной реализации логирования вы ничего не теряете. Для повышения производительности обычно используется файловый буфер на уровне ОС и именно он может потеряться при неожиданном завершении процесса. Но если вы вручную инициируете сброс буфера на диск, то почти гарантированно ничего не потеряете.

                                                          Случайно залезть в память системы можно как из Си так и из Delphi, но это скорее верно только для старых версий Windows. Разницы в этом моменте между Delphi и Cи нет.
                                                          • –7
                                                            Вот я таких тонкостей не знал. К сожалению, принципы функционирования ОС на таком уровне не изучаются физиками и химиками, и приходится выкручиваться.
                                                            Вот наглядный пример того разного взгляда: вы, как программист, знаете как решить проблему, сбросив на диск. Я, как учёный, этого не знал (кстати, не знаю и сейчас, хотя уже поработал немного программистом), вот и имел другое виденье — как нечто, чего не хочется повторять со своим компьютером в принципе, и в страхе за свои данные.
                                                            • +3
                                                              Я всегда думал, что ученные отличаются от людей тем, что любую вещь сначала изучают, потом проверяют изученное и только потом лезут с ней работать
                                                              • 0
                                                                То есть человек для численного решения условного дифура должен разобраться в устройстве ОС, серьёзно? Почему ж не в устройстве процессора и как он получен из песка?
                                                                • +1
                                                                  А где был разговор про устройство ОС? Устройство ОС тут вообще непричем. Речь шла про язык программирования, который является основным инструментом при решении задачи.
                                                                  • +1
                                                                    К сожалению, принципы функционирования ОС на таком уровне не изучаются физиками и химиками, и приходится выкручиваться.

                                                                    ваш ответ:
                                                                    Я всегда думал, что ученные отличаются от людей тем, что любую вещь сначала изучают, потом проверяют изученное и только потом лезут с ней работать


                                                                    Мне показалось, что отсюда и следует, что вы хотите всех учёных заставить изучать строение ОС.
                                                                  • +1
                                                                    А в вычматах-то хоть он должен разбираться?
                                                                    • 0
                                                                      Очевидно да, так как без этого скорее всего не получится написать нормальный метод решения. А вот без знания устройства ОС — легко.
                                                              • +2
                                                                Все даже проще — вывод в stderr буферизуется подстрочно. ЕМНИП, можно установить построчную буферизацию и для произвольного потока вывода.

                                                                И кстати в отладчике можно ставить условные брейкпойнты.
                                                                • 0
                                                                  И кстати в отладчике можно ставить условные брейкпойнты.

                                                                  И каким будет условие? if (somewhere in the nearest future there will occur an error)
                                                                  *Это не сарказм, если что, я правда не понимаю как компилятор может предвидеть рантайм ошибку и заранее начать показывать мне несколько предыдущих действий пошагово с выводом значений. Мб есть какие-то аналогичные интерпретатору оболочки, которые так и делают?
                                                                  • +1
                                                                    В момент краша дебаггер останавливает выполнение и можно посмотреть стек вызова и конкретное место, где произошла ошибка, откуда вызвана эта функция и т.д.
                                                                    • 0
                                                                      Проще надо быть.
                                                                      У вас цикл? Вы примерно представляет, сколько раз он выполняется вообще? Допустим, миллион. Ок, поставили брейкпойнт на первой команде цикла с условием остановиться через миллион проходов. Упс, рантайм ошибка. Перезагрузка (если все так плохо), заново запустили, поставили с условием остановиться через полмиллиона проходов. Оно думает-думает и остановилось. Ок, значит полмиллиона отрабатывает. Сказали — остановись еще через четверть миллиона проходов.
                                                                      Таким макаром локализовали (хорошо, если точно, а если нет — так хоть примерно) количество проходов цикла, после которого возникает ошибка. Теперь останавливаемся заведомо до ошибки, но близко к ней и смотрим, что у нас происходит. Не залезли ли мы где-то в чужую память или может стек переполнен.
                                                                      • 0
                                                                        зачем? Номер итерации — одна из переменных, значение которой в момент краша можно просто глянуть в дебаггере.
                                                                        • 0
                                                                          Ну если так, то хорошо. Просто у меня сложилась несколько иная картина. Цикл while, и краш сносит не только программу, но вешает операционку.
                                                                        • 0
                                                                          Задачи нередко запускают на много часов, дней и даже недель. Запускаешь моделирование, через двадцать часов всё падает. Отлаживаешь и обнаруживаешь, что падает-то на двадцатом часу, но причины этого падения возникли раньше, на восемнадцатом.
                                                                          • 0
                                                                            Могло бы быть хуже. Запускаешь на несколько недель, ничего не падает, получаешь результат. Но можно ли ему доверять? Может быть, там на восемнадцатом часу случилось прописывание памяти, оно попортило все вычисления, но программа не упала, так как прописывание проехалось только по внутренней памяти процесса.
                                                                  • +2
                                                                    Я прочитал ваш комментарий, и это какой то феерический поток сознания гуманитария. Давайте попробуем разобраться.

                                                                    Если у вас коєффициент расчитывается в цикле while до значения, которое вы расчитываете, то неправильный расчёт может нагрузить компьютер хоть и формально не бесконечным, но экспоненциально раздувающимся на каждой итерации циклом, который грузанёт систему, да так что придётся перезагружать.
                                                                    Насколько я понял, у вас есть программа и из-за её работы вы не можете управлять компьютером? Тут проблема с самой программой, которая некоректно потребляет ресурсы системы, ну или учёные что-то наковыряли в балансировщике ядра.

                                                                    Код на винде, по крайней мере, может залезть в область памяти с кодом ОС, и крашнет её.
                                                                    Кхм, тоесть учёные наговнокодили так что программа лезет в системную память и даже что-то там переписывает, потом учёные запустили эту программу под рутом(админом) и виноват, конечно, ц++. Гуманетарненько.

                                                                    Я помню, как мы с одноклассниками нечаяно 2 компа на уроках информатики, причём не на си писали.
                                                                    Сразу видно будущих учёных.

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

                                                                    Касательно кодов — все три были написаны не-программистами, а учёными. Которые знают как должны работать алгоритмы, и лексику этих трёх языков.
                                                                    Дак чтож вы это сразу то не сказали, а я тут распинаюсь.

                                                                    Дальше следует поток слов, которые очень сложно парсить, но насколько я понял там что-то про выделение памяти и какой питон крутой.
                                                                    • 0
                                                                      Каждуют секунду(или долю секунды) вы дописываете данные в лог, это происходит автоматичеки, на уровне библиотеки логгирования, которую учёные будут использовать, и да учёные не будут писать свою библиотеку логгирования с нуля.

                                                                      Библиотека логирования, говорите? Обычно используется print :) И хорошо если только для информационного вывода, а то бывает что и основной результат вычислений выводится принтом.

                                                                      Понятно, что это не отменяет простого перенаправления в файл в shell'е.
                                                                      • –1
                                                                        Насколько я понял, у вас есть программа и из-за её работы вы не можете управлять компьютером? Тут проблема с самой программой, которая некоректно потребляет ресурсы системы

                                                                        Ну именно поэтому программу нужно было исправлять — если бы она хоть раз заработала, она сразу после этого стала бы не нужной, т.к. уже спродуцировала нужные данные.
                                                                        Сразу видно будущих учёных.

                                                                        imgs.xkcd.com/comics/the_difference.png
                                                                        что-то про выделение памяти и какой питон крутой

                                                                        Нет, про типизацию, и какой пайтон крутой. Я где-то в другом комментарии боле подробно расписал.
                                                                        • +3

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

                                                                      • 0
                                                                        Если у вас коєффициент расчитывается в цикле while до значения, которое вы расчитываете, то неправильный расчёт может нагрузить компьютер хоть и формально не бесконечным, но экспоненциально раздувающимся на каждой итерации циклом, который грузанёт систему, да так что придётся перезагружать.

                                                                        Один поток не может нагрузить ядро процессора больше чем на 100%. О каком "экспоненциально раздувающимся на каждой итерации цикле" речь?


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

                                                                        • 0
                                                                          Не вижу причин, почему данные в логи должны сохранятся, разве что открывать на запись новый файл на начале каждой итерации, и закрывать в конце

                                                                          При работе с файлами независимо от языка существует команда flush, которая физически сохраняет данные на диск, достаточно вызывать после каждого write (работать будет медленнее, но для лога важнее надежность), как говорится «было бы желание».
                                                                          • 0

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

                                                                          • +7
                                                                            Вот тоже, абзац про C++ удивил.
                                                                            Я реально не представляю, что нужно сделать такого в коде, чтобы наглухо завалить современную ОС (мы же не говорим про Windows 98 и прочий олдскул — там такое легко делалось) из юзерспейса с ограниченными правами. Вот серьезно, расскажите, кто-нибудь :)
                                                                            Да, можно, конечно, отожрать все ресурсы, вызвать активный сброс страниц в своп, полностью забить дисковое I/O, что в купе с каким-нибудь багом типа известного 12309 сделает систему практически неработоспособной… Но такое можно при желании или при совпадении обстоятельств устроить на любом языке программирования, разве что в плюсах по неопытности можно утечек памяти наделать, а на языке со сборкой мусора GC в большинстве случаев подберет все что навалилось.

                                                                            То же самое с записью логов «чтоб узнать, где упало». Не обязательно sync'ать буфер при каждой записи, можно писать блоками, и тогда при падении мы будем знать уже примерно в каком именно месте что призошло, и при следущем прогоне в этом месте логгировать более часто и детально. А для крэшей самого процесса почти всегда есть возможность посмотреть стектрейс. Короче, какая-то мутная история.

                                                                            Может, выложите код на всех трех языках куда-нибудь на гитхаб?
                                                                            • 0
                                                                              Ну с си в итоге так и не разобрались, по скольку времени пожалели на это. Не могу сказать в чём конкретно проблема была, но это явно связано с сошибкой в вычислениях на том этапе.
                                                                              Но, как я уже писал в комментарии, в школе на 2-ух компах уронили WindowsXP двумя разными кодами на паскале (даже не си). Потом, конечно, таких ошибок уже не допускали, но такие вещи вполне себе компилируются, сегфолты делают.

                                                                              Ваш вариант с записью блоками аналогичен методу описаному как «поиск на глаз» в пункте а), по количеству необходимых падений системы. Так что принципиальная возможность всё поломать — очень даже есть.

                                                                              Давно уж это было, могу только пайтоновский поискать, я его сам писал с нуля, значит должен быть в наличии где-то на старых дисках… Но я помню что первые версии все кодов отличались только синтаксисом. Т.е. просто циклы, в которых считались итерации, и в каждом блоке подряд операции. Ничего сверх-особого, никакого использования особенностей языка. Разве что в делфи визуальная часть была в родном борланде нарисовано от руки, а так всё то же самое.
                                                                              • +2

                                                                                Andrey2008, подозреваю заинтересовался бы кодом и с полпинка дал несколько мест, где написано не совсем то, что хотели :)

                                                                                • 0
                                                                                  Думаю, там для начала -Wall -Wextra -pedantic бы хватило.
                                                                                • 0

                                                                                  А что, какой паскаль-то был?

                                                                                • –1
                                                                                  Ну, можно сделать какой-нибудь while(fork()) {}; например.
                                                                                  • –1

                                                                                    Но зачем вообще нужны форки в числомолотилке?

                                                                                • 0
                                                                                  «nonetype is not iterable», о даа, детка!
                                                                                  • +2
                                                                                    Знаете, а у меня больше всего бомбануло с комментариев, подобных вашим, а не со статьи. Ну вызвало у вас возмущение то, что автор не осилил кресты, а где причинно-следственная связь с посылом статьи и вашим негодованием?

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

                                                                                    Замечу, что при этом до сих пор никто не дал ответ зачем автору вникать во множество нюансов используя кресты, когда он может с меньшими усилиями и быстрее по времени выполнить задачу используя другой ЯП?
                                                                                  • –2
                                                                                    Не люблю JS, но почему не JS? У меня вообще складывается ощущение, что ему несколько параллельно что у него внутри там упало — он продолжит считать :)
                                                                                    • +1
                                                                                      Есть мнение, что в JS 0.3 + 0.1 != 0.4. И это только самый простой пример.
                                                                                      • +4
                                                                                        Дак и в питоне 0.1+0.2 != 0.3
                                                                                        • –1

                                                                                          Вы меня пугаете) я в нём расчеты делаю. Что за фигня с типами/точностью?

                                                                                          • 0
                                                                                            Просто особенность представления чисел с плавающей точкой — десятичные дроби точно не представимы, возникает погрешность. Числа с плавающей точкой нельзя сравнивать на равенство (почти) никогда.
                                                                                            • 0

                                                                                              Да это везде так, где идет работа с плавающей точкой. Числа с плавающей точкой нельзя проверять на равенство, нужно делать как то так: abs(a-b) > 0.001

                                                                                              • 0
                                                                                                Спасибо, учту. Хотя у меня таких коллизий не возникало, не было сравнений в структуре.
                                                                                                • 0
                                                                                                  В 3.5 добавили `math.isclose(a,b)`, который как раз проверяет что-то типа «Значения настолько близки, что (при дефолтных kwargs) разница между ними где-то порядка погрешности float».
                                                                                                  • 0
                                                                                                    О, благодарю. Хотя не вижу преимуществ перед abs(a-b) > 0.001. math.isclose хуже читается в плане порога разницы.
                                                                                                    • +2
                                                                                                      Чушь. Разные операции дают разную погрешность, нельзя так просто выбрать некоторую константу и всегда сравнивать с ней — а math.isclose, похоже, именно это и делает…
                                                                                                  • –2
                                                                                                    Не уверен, но вроде нынче для ряда языков это почти что не актуально. Компили сами подменяют сравнение. Где-то слышал, что так, но не проверял. Хотя, стоит отметить, на проблемы со сравнением со времён VB6 не натыкался.
                                                                                                  • +1