Тег ‘программирование’

Про учебники по C++

Прочитал недавно рецензию на учебник Столярова, где тот обозвали “плохой методичкой“. Ну да, я и сам согласен с тем, что оставлять студентов наедине с книгами Столярова нельзя – но при всех недостатках книжка по C++ (полностью вошедшая в четвертый том многотомника) более-менее подходит для того, чтобы понять основные принципы языка (всякие там rule of three, RAII и так далее). И кстати, не могу согласиться с тезисом о том, что автор не “сделал хоть что-нибудь положительно отличающее текст от бесконечного числа вузовских методичек, призванных помочь студенту сдать экзамен автору методички” – особенно когда перед этим в трех пунктах утверждается, что автор – ебанутый фанатик (в хорошем смысле). В конце концов, большая часть софта, которым мы все пользуемся, была сделана как раз ебанутыми.

А если говорить о dark side образования – ознакомился на днях с конспектом курса “С++ для математиков”, который в TU D-stadt читают Dr. Alf Gerisch и Dr. Adrien Semin. Курс представляет собой какую-то смесь из странным образом подобранных элементов C++ и взятых из численных методов примеров.

Из положительного хочется отметить разве что довольно подробную лекцию о IEEE 754 с некоторыми примерами правильных вычислений с плавающей запятой (например, с решением “плохих” квадратных уравнений). А вот отрицательного, к сожалению, гораздо больше. Во-первых – разбираемое в лекциях подмножество C++, как бы это сказать… совершенно недостаточно для нормальной продуктивной работы. Это такой поверхностный обзор в стиле введения в “Язык программирования C++” Страуструпа – вот у нас есть классы, вот как выглядит наследование и полиморфизм (множественное наследование не разбирается), вот есть шаблоны (делаем класс Polynom), вот библиотека STL (в ней есть класс vector).

Во-вторых – вот за такое можно поймать лектора в темной подворотне и отпиздить, желательно ногами по голове (классы все здесь по размеру маленькие, максимум два числа и ссылка на функцию):

int main(void)
{
    // list of two base class pointers
    numInt1D** integrator = new numInt1D*[2];
    // fill with two pointers to derived class objects
    integrator[0] = new numInt1D_rectangleLeft(0.0, 1.0, &f);
    integrator[1] = new numInt1D_trapezoidal(0.0, 1.0, &f);
    // output numerical integral approximations
    std::cout << "Integral approximation using rectangle rule = "
        << integrator[0]->integrate() << std::endl;
    std::cout << "Integral approximation using trapezoidal rule = "
        << integrator[1]->integrate() << std::endl;
    // clean up
    delete integrator[0]; delete integrator[1];
    delete [] integrator;
    return 0;
}

Вообще, не раз наблюдал вот такую ничем не объяснимую любовь к new в C++ у быстро переученных на него джавистов.

Есть, конечно, одно обоснованное возражение - а зачем студентам-математикам учить C++ в каком-то приближенном к реальной жизни объеме, тем более, что для численных методов этого достаточно? Вот возьмем для примера мехмат МГУ - который, в отличие от факультета математики провинциального немецкого ВУЗа, все-таки пытается готовить профессиональных математиков (а пошедшие в программисты выпускники для факультета - третий сорт, после преподавателей этой самой математики). Что входит в "Практикум на ЭВМ" на втором курсе? Отнюдь не только численные методы, но еще и "тонкости" вроде "Десять способов неправильного описания прототипов методов сложения (operator+) и "увеличить на" (operator+=) и единственный правильный способ", да и совершенно "практические" вещи типа библиотеки Qt стороной не обошли. В курсе есть достаточно мест, где можно наступить на стандартные C++-ные грабли и навсегда их запомнить (а нормальное обучение C++ и должно строиться на том, что все эти многочисленные "грабли" надо собрать в процессе обучения самостоятельно и больше их не забывать).

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

PS PDFку с лекциями очень просили не распространять, если будут какие-то вопросы - пишите.

Про COBOL, американскую компьютерную выставку и Госуслуги

Вот пишут, что IBM предлагает бесплатные курсы по изучению COBOL – популярного лет 40 назад языка программирования для всяких бухгалтерских, окологосударственных и прочих “учетных” систем:

https://www.inputmag.com/tech/ibm-will-offer-free-cobol-training-to-address-overloaded-unemployment-systems

Якобы учет безработных в американской службе занятости сделан давным-давно, разумеется, на COBOL, и сейчас из-за массового роста обращений туда требуется эту систему поддерживать, как-то развивать и все такое. В “давным-давно” охотно верится – в брошюре с выставки “Информатика в жизни США” – а это 1987-1988 год, вообще-то! – рассказывается про почти современный уровень компьютеризации (ну с поправкой разве на то, что фронтендеров тридцать лет назад еще не придумали).

Но вот гляжу я на всякие отечественные кривые поделия типа тех же Госуслуг или творчества ДИТа г. Москвы и с ужасом думаю – а что будет с этим через три десятка лет, и что будет тогда вместо COBOL?

Боженька, жги, здесь уже ничего не исправить

Чуваки запускают маленькую и простую программу почти без всяких внешних зависимостей (OpenSSL разве что нужен) с помощью docker:

https://fossil-scm.org/forum/forumpost/5f106b752f

При этом (проверено) fossil работает на любой более-менее разумной платформе – от настольного Windows до shared-хостинга с Linux, легко собирается из исходников в практически любом unix-подобном окружении, и зачем при этом паковать его в docker – решительно непонятно.

Опенсорс здорового человека и опенсорс курильщика

Здоровый человек – когда к нему обращается Motorola с просьбой доделать SQlite до пригодного для применения в продакшене состояния, отвечает: “Да, конечно, деньги платить сюда“:

The first release of version 2.0 came out just a couple days after the 9/11 event… But that got to be really popular, and before long I started getting phone calls, and I got a phone call from Motorola. I don’t know if you remember, but back then Motorola was the world’s leading manufacturer of cell phones. And they said, “Hey, we wanna put SQLite on all our cell phones, but we need you to make some enhancements for us. Can we bring you on contract to make these enhancements and to support it?” I said, “Sure, of course.” I hung up the phone and felt “Wow! You mean you can make money off of open source software?” Who knew…?

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

About this time last year a 48-year-old software developer in Sweden named Daniel Stenberg received a panicked call one evening from a large German automaker. The car company, which Stenberg declines to name, asked that he fly to Germany immediately because an application Stenberg had written was causing the entertainment system software in 7 million cars to crash. “I had to inform them that, you know, this is a spare-time project for me and that I have a full-time job and can’t just go to Germany for them,” Stenberg says. “They started out pretty demanding, but then switched when they realized the situation they were in.”

Ебучее красноглазие

Вот какого хера, простите, я решил сегодня уже вчера вечерком собрать пару малораспространенных, но полезных опенсорсных программ для NAS Synology? И господи, какой же в этом вашем линуксово-опенсорсном мире творится бардак с кросс-компиляцией, когда серьезно советуют не тащить на нормальную рабочую машину всякий кал в виде вендорского SDK, а поставить это в виртуалке. Вообще не понимаю, как с этим можно нормально жить и не ругаться матерно.

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

Обожаю, сука, теоретиков

Вот некоторые люди, не будем показывать пальцем, любят строить свою картину мира (в последнем абзаце) по рекламным листовкам типа таких:

https://www.techbriefs.com/component/content/article/tb/techbriefs/aerospace/28025

Так вот, немного оторвавшись от разгребания нагенерированного MATLAB Coder’ом говна, скажу – все эти заявления про торжество “model-based design” на основе MATLAB – чистая реклама, к реальности имеющая очень опосредованное отношение. Для тех, кто не знает – MATLAB – это такой весьма кривой и уебищный язык программирования в комплекте с не менее кривой и уебищной IDE, имеющий, впрочем, ровно два достоинства:

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

Так вот, что мы имеем в процессе “кодогенерации” из матлаба? Во-первых – генератор местами тупит и требует писать код с “грязными хаками” для учета его особенностей. Во-вторых – нагенерированный код страшен и уебищен с точки зрения человека (нет, пресловутой readability из матлабовской же рекламы там не пахнет). В третьих… Нет, если вам нравится копаться в коде вроде такого (нет, ошибок в нем нет) – я не могу вас винить:

i100500 = b_mxA->size[0] * b_mxA->size[1];
b_mxA->size[0] = b_mxB->size[0];
b_mxA->size[1] = b_mxB->size[1];
emxEnsureCapacity_creal_T(b_mxA, i100500);

Ругаться закончил.

Вот интересно даже

Кто заказал вебинар по трансляции кода из Matlab с упором на процессоры Миландр?

https://exponenta.ru/events/avtomaticheskaya-generatsiya-koda-dlya-ekb-milandr

ЕСПД и программисты

Напишу-ка я очередную проповедь про программистов – точнее, об их взаимодействии с внешним миром. Глупый и наивный программист думает, что конечный результат его работы – это код программы. Программист, побитый жизнью, обычно догадывается, что код этот сам по себе малоинтересен, и к нему нужна еще какая-то документация. Если это удается сочетать с живительными пиздюлями менеджмента – то к проекту прикручивается какой-нибудь Doxygen или Javadoc, и на выходе получается автоматически сгенерированная портянка рафинированной чуши.

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

Примерно тут возникает еще одна проблема – “код и документация” нужны заказчику в удобоваримом для него виде. Скажем, “код валяется в разных местах на диске у Васи, документация – в виде обрывков бумажек в столе у Пети” ни одного заказчика не устроит; “исходники и Javadoc лежат на гитхабе там-то и там-то” – приемлемый вариант для “технарей”; “все документы по проекту находятся в CVS-системе фирмы, а также записаны на компакт-диски и находятся в двух разных помещениях архивов” – вариант повышенной энтерпрайзности, ну и так далее.

И тут мы приходим к одной поучительной истории – про ЕСПД. Идея 19 и 34 серии ГОСТов, если вдуматься – это решение проблемы, описанной в предыдущем абзаце. Если говорить на языке более современных подходов к разработке ПО – типа RUP или OpenUP – то они описывают “артефакты”, которые должны возникнуть в ходе разработки программы или автоматизированной системы, и требования к содержанию и оформлению этих “артефактов”, позволяя заказчику, разработчику и потребителю ПО говорить “на одном языке”.

Проблем с ЕСПД две – откровенный саботаж всякого процесса документирования своего творчества со стороны программистов и (как позже увидим, непосредственно вытекающая из этого) устарелость стандартов. Но начнем мы все же с саботажа. Давайте попробуем “изготовить” полагающийся по ГОСТ 19.401-78 “Текст программы”. Поймайте программиста и попросите у него “текст программы”. Ответом вам будет либо набор файлов (хорошо, если он сопровождается каким-нибудь Makefile), либо, если вы используете много “чужого” кода – долгая дискуссия, где заканчивается ядро Linux и начинаются ваши доработки. Дальше вы смотрите на ГОСТовские требования и понимаете, что распечатка ядра Linux или какого-нибудь веб-фреймворка на бумаге – это, конечно, прикольно – но отдел технической документации у вас это не примет.

Дальше выясняется – со слов коллег, сдававших сделанную по ЕСПД документацию раньше – что архив и нормоконтроль удовлетворятся сделанным в Word документом, содержащим что-то, похожее на исходники программы. Не вопрос! – думаете вы, и лихим Ctrl+C – Ctrl+V набиваете вордовский шаблон неработающими исходниками. Собственно, где-то на этом этапе в 1937 году вас бы ждал расстрел за подлог документов и саботаж (кстати, вы никогда не задумывались, что сокращение ИТР обозначает одновременно инженерно-технических работников и иностранные технические разведки?) – но сейчас времена более вегетарианские. и за такое очковтирательство никому ничего не будет.

Маленькое отступление – если бы вы не слушали “более опытных” коллег, а пошли бы в архив с тортиком, то вы смогли бы выяснить, что записанный на компакт-диск zip-архив с исходниками тоже сойдет. Впрочем, особо красноречивые товарищи могут попробовать научить работающих в архиве девушек пользоваться TortoiseHg.

Примерно так же происходит подготовка любых других документов “по ГОСТ” – вместо минимально читаемого Javadoc “Руководство программиста” будет куцей компиляцией форменного бреда; “Руководство системного программиста” будет описывать все, кроме того, что действительно нужно. В конечном итоге на написание документации будет посажена “девочка”, совершенно не задумывающаяся о сути производимой работы, но неплохо умеющая писать формально удовлетворяющую требованиям нормоконтроля документацию.

priplyli

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

В принципе, с чем-то подобным столкнулись и обычные инженеры, конструктора и так далее – но в отличие от программистов, там довольно быстро осознали, что стоит привести ГОСТы в соответствие с реальностью XXI века – поэтому в ЕСКД где-то в начале 2010-х легализовали, к примеру, “электронный документ” (собственно, ГОСТ 2.051-2006 приняли еще раньше, как несложно догадаться – в 2006). Технически продвинутые программисты – наоборот, предпочитают оставаться в реалиях 1970-х годов по причине полной неспособности взаимодействовать с “нехорошими бюрократами”. Остается их с этим поздравить.

PS Написано по мотивам личного опыта автора, your mileage may vary.

Патч брамина

Почти как патч Бармина, но в переводе на хинди.

Интересно, как это называется?

Смотрю тут один опенсорсный проектик на гитхабе и понимаю, что в Cisco работают такие же индусы, как и везде (хотя нет, кое-где за такое могут и уебать):

https://github.com/cisco/ns3-802.11ax-simulator/blob/master/ns-3.26/src/wifi/model/rrm-wifi-manager.cc

Совершенно шикарны строки со 149 по 155, да и все их многочисленные копипасты. Поневоле задумываешься, как же в принципе может более-менее стабильно работать современный софт и тем более железо, разработанное “клоунами под руководством мартышек”.

PS Посмотрел профили указанных в заголовке индусов на линкедине. Сильно опечалился.

Ще не вмерла Java (но вже смердит)

Интересно, а автор этого Java 8 Tutorial понимает, насколько смешной он взял эпиграф?

https://winterbe.com/posts/2014/03/16/java-8-tutorial/

Кто все эти люди?

Увидел на Stackoverflow шедевральный вопрос – как на питоне посчитать коэффициент корреляции Пирсона:

http://stackoverflow.com/questions/3949226/calculating-pearson-correlation-and-significance-in-python/5713856

Ответы типа “используй SciPy/NumPy/WhateverPy” в принципе понятны – но кто поставил 12 “лайков” ответу пользователя compski?

import math

# calculates the mean
def mean(x):
    sum = 0.0
    for i in x:
         sum += i
    return sum / len(x) 

# calculates the sample standard deviation
def sampleStandardDeviation(x):
    sumv = 0.0
    for i in x:
         sumv += (i - mean(x))**2
    return math.sqrt(sumv/(len(x)-1))

# calculates the PCC using both the 2 functions above
def pearson(x,y):
    scorex = []
    scorey = []

    for i in x:
        scorex.append((i - mean(x))/sampleStandardDeviation(x)) 

    for j in y:
        scorey.append((j - mean(y))/sampleStandardDeviation(y))

# multiplies both lists together into 1 list (hence zip) and sums the whole list
    return (sum([i*j for i,j in zip(scorex,scorey)]))/(len(x)-1)

И прошло целых три года, прежде чем Николай Фоминых сподобился написать крайне токсичный по нынешним понятиям комментарий “ты мудак, тебе надо оторвать руки, а клавиатуру засунуть в жопу, чтобы ты больше не мог написать ни одной строчки кода” “У этого способа ужасающая сложность и низкая производительность на списках из 500+ элементов”.

Так вот – ладно, я не регистрируюсь на SO, потому что влом – но кто-то же проходил мимо этого образца говнокода, и за несколько лет так никто и не обложил хуями автора. Почему?

Еще один сборник задач по программированию

Наткнулся на опубликованные на сайте 57 школы “листочки” с задачами по программированию для математических и биологических классов:

https://prog.sch57.ru/

Это подборка из достаточно большого количества задач, укладывающихся в содержание хорошего школьного курса информатики “с программированием” (Python, основные алгоритмы, немного разной экзотики от machine learning до представления о веб-программировании) – к сожалению, на сайте она разбита по годам и классам, поэтому собрать курс целиком (или даже несколько – кажется, у “математиков” и “биологов” программа слегка отличается) в более-менее адекватном порядке может быть слегка затруднительно. По сложности – где-то между Pythontutor и книжкой Шеня. Из достоинств – задач больше, чем на Pythontutor, и в отличие от книжки, здесь есть задачи на “элементарные” темы. Есть критерии оценок – например, из листочка “Строки” на тройку надо решить 5 задач из 12, на четверку – 8, на пятерку – 10. Пользоваться для переворота строки всякими дебильными способами в явном виде запрещено, что не может не радовать.

Мир должен знать, что я пью

Так, передо мной 0,7 Havana Club, полторашка колы и исходники микрокода для процессора 1839 серии. Хз, что из этого получится, но явно что-то плохое :)

Кружевных трусиков псто

Чуваки и чувихи, а что вам показывает гуглопоиск первым результатом на запрос “C string”? Руководства по программированию или трусы оригинальной конструкции?

99 cans of beer on the wall

99cans

…take one down, pass it around!

С праздником!

Очень оригинально решил поздравить российских программистов с государственным праздником Gitlab:

https://gitlab.com/gitlab-com/www-gitlab-com/issues/5555

Если коротко – то предложили выставить на мороз сотрудников из России и Китая – а то они могут подсмотреть какие-то секреты у некоего неназванного “customer considering using GitLab.com”. Ну я думаю, перечень таких “customer considering using”, ради которых Гитлаб готов делать все, что угодно – не такой большой. Если вспомнить еще и недавнюю историю с “телеметрией” для платных пользователей – то ну его нахрен, такой гитлаб?

Про Agile

Навеяно беседами (раз, два) в фейсбуке, в которых железячники и к ним примкнувшие гнобят программистов за общую инфантильность и неспособность в предсказуемые сроки выдавать работающий результат. Так вот, хоть я и зарекся писать про TU D-stadt – что взять с убогих? – но не могу пройти мимо темы того, как в немецком программистском образовании освещены методологии разработки программного обеспечения. Их обзору посвящена целая лекция в конце первого семестра “общей информатики” (где учат в основном каким-то азам Java, да и тем плохо).

Краткое содержание лекции – “водопад это плохо, много ненужного бюрократизма, чуть получше – спиральная и V-модель, но истинное «наше все» – это гибкие методологии, Agile и прочий Scrum”. Под стать ей – и вопросы в итоговой экзаменационной работе – например, “назовите недостатки Waterfall model”. Напомню, что лучшее средство для того, чтобы студенты усвоили какую-то непреложную истину – вынести ее на экзамен, а в такой вот форме – будьте уверены, запомнят они именно недостатки.

Пожалуй, неправильно будет обвинять профессора в какой-то злонамеренности, он вроде бы хороший чувак, но ни дня не работал в “индустрии” – так что просто вынужден некритически пересказывать модные сейчас штуки про “гибкие методологии разработки”. Что получается на выходе – разумеется, такие же жизнерадостные программисты, обитатели страны розовых пони.

PS Да, что касается шуточек о том, что скоро курс информатики будут преподавать по материалам ebanoe.it. Уже! В Штатах в University of Massachusets Boston в рамках курса CS410 (Introduction to Software Engineering) читается лекция What to Expect from Tech Companies and their Hiring Processesразъясняется, что такое галера, гребцы, хрюши и все такое (нет, до такого еще не дошли – но скоро, очень скоро все будет!).

Ретрокомпьютинга пост

Уволок с прошлой работы первое русское издание “Архитектуры компьютера” Таненбаума (”Многоуровневая организация ЭВМ”, издательство “Мир”, 1979 год). Для развлечения читаю руководство по архитектуре VAX. На новой работе пришлось освежить в памяти, как работать с текстовым редактором vim.

Так, а что за последние 30 лет нового придумали?

Боже, какой ужас

Джаваскриптеры и не только решают задачку:

Написать функцию, которая для заданного отсортированного массива чисел (все числа разные) выводит текстовую строку диапазонов:

getRanges([0, 1, 2, 3, 4, 7, 8, 10]); // 0-4,7-8,10
getRanges([4, 7, 10]); // 4,7,10
getRanges([2, 3, 8, 9]); // 2-3,8-9

Кто-то создает на каждый чих по объекту, кто-то собирается писать “с помощью гугла и Stackoverflow”, обсуждают читаемость простынки в несколько десятков строк с нетривиальной логикой… Ребята! Неужели приведенное на хабре решение более “читаемо”, чем такое (простите, но это будет plain old C), написанное за десять минут?

void printRanges( int *arr, int len ) {
    int start = arr[0];
    int prev = arr[0];
    int printed = 0;
    int i;
    for ( i = 1; i < len + 1; i++ ) {
        if ( i == len || arr[i] != prev + 1 ) {
            if ( printed ) {
                printf( "," );
            }
            if ( start == prev ) {
                printf( "%i", start );
            } else {
                printf( "%i-%i", start, prev );
            }
            printed = 1;
            if ( i < len ) {
                start = arr[i];
            }
        }
        if ( i < len ) {
            prev = arr[i];
        }
    }
    printf( "\r\n" );
}

Да, тут есть возможные улучшения - но неужели решение из поста кажется более понятным?