Как стать автором
Обновить
-3
0
Андрей Ежгуров @eandr_67

Пользователь

Отправить сообщение

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

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

Тот же GC противопоказан только в системном программировании и в Real-Time. А в прикладном софте (которого несравнимо больше, чем системного софта и систем управления физическим процессами вместе взятых) GC - это безусловное увеличение надёжности кода.

Язык C - прекрасный инструмент для системного программирования. Но как язык прикладного программирования он обладает фатальным недостатком: вся ответственность перекладывается на кодера. В C-коде очень просто допустить ошибку и очень сложно её найти. Это инструмент для очень опытных разработчиков, но кодеры нижнего-среднего уровня мало того, что неизбежно будут ошибаться, так ещё и не смогут понять, что ошиблись. Microsoft по меньшей мере десятилетие активно вычищала баги из ядра Windows, написанного на C.

А ещё у C абсолютно ужасный синтаксис. Да, с появлением C++ многое в C причесали, но, например, кошмарное объявление типа как шаблона никуда не делось: https://habr.com/ru/articles/116255/. В этом отношении из всех известных мне C-style языков наиболее удачен Go (язык прикладного уровня) - в котором из C выбросили всё, что делает язык ненадёжным, и добавили ровно то, что реально необходимо, при этом максимально унифицировав и упростив синтаксис.

Да, при использовании компилируемых языков такое решение безусловно эффективнее. Но в интерпретируемых языках (к коим относится и Python) всё не столь однозначно.

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

Так что без реальных экспериментов на разных входных данных невозможно сказать, что именно в Python будет эффективнее: две операции (однократное создание среза длины N и однократное сравнение среза и исходной строки) над длинными строками, или (N/2)*5 операций (цикл, дополнительный курсор, доступ по индексу слева, доступ по индексу справа, сравнение двух строк длины 1) выполняемых в оптимизированном алгоритме.

Статья заявлена, как простая, а не докторская.

Статья называется: "Очистка данных перед загрузкой в хранилище. Подробное руководство с техническими деталями". В реальности же в статье нет ни "подробного руководства", ни "технических деталей". И даже о том, как именно надо очищать данные до загрузки, в статье нет ни слова. Зато все три примера демонстрируют очистку данных после загрузки в хранилище. Причём очистка производится модификацией данных в таблице, из которой эти данные были прочитаны. Подобные запросы прекрасно смотрелись бы в статье "Как нельзя производить очистку данных", но предлагать такое как образец очистки...

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

Никто не писал в статье, что мы рассмотрим все варианты кода на все языках программирования.

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

P.S. Спасибо, что поправили теги и хабы.

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

t = x.lower() # у нас уже строка, а палиндром без учёта регистра букв
print(['no', 'yes'][t == t[::-1]]) # слабая типицация: bool -> int

Хотелось бы понять, где именно в статье показано использование Python, R, ETL для "очистки данных"? Зачем эти абсолютно бессмысленные упоминания, выставление тегов и размещение в хабах, никак не относящихся к содержательной части статьи? Информационный мусор в надежде привлечь посетителей?

И где вообще объявленная в заголовке статьи "очистка перед загрузкой в хранилище"? Вся содержательная часть статьи (после отжима воды) - три SQL'ных костыля, применяемых к уже загруженным в хранилище данным и необходимых только потому, что структура реляционной базы данных разрабатывалась абсолютно некомпетентными "специалистами".

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

Второй запрос не нужен, т.к. дефолтные значения для столбцов задаются, опять же, при создании таблицы. И если в столбце таблицы не должно быть NULL, такой столбец изначально создаётся с модификатором NOT NULL.

Но если два первых запроса ещё более-менее понятны (напахали со структурой, бывает, но в этом случае корректирующий запрос выполняется единственный раз - перед внесением правок в структуру таблиц), то третий SQL-запрос вызывает, мягко говоря, недоумение... Во первых, функция ISDATE существует только в MS SQL Server и не может иметь никакого отношения к хабу PostgreSQL (в котором статья находится в настоящий момент). Во вторых, если столбец даты имеет тип DATE, то весь этот запрос абсолютно бессмысленен, т.к. никак не меняет данные в таблице. Но если столбец для хранения даты имеет тип VARCHAR, то это даже не некомпетентность, а невежество создателя таблицы.

P.S. Сама идея "очищать данные", записанные в реляционную СУБД - показатель непонимания автором того, что такое РСУБД. Реляционные базы предназначены для уже "очищенных" и полностью структурированных данных и использовать их для "сырых" данных - это как пытаться спилить столетний дуб ножовкой по металлу. Для хранения "сырых" данных предназначены совсем другие хранилища, не имеющие никакого отношения к РСУБД.

Именно на Python? Банально сравниваем на равенство исходную и инвертированную (срез [::-1]) строки, предварительно приведя их к одному регистру. Сложность - как и требуется - линейная, объём кода минимален (причём без ухудшения читабельности), а то, что коэф-т в несколько раз больше, чем у варианта @SUNsung, так Python и не предназначен для написания высокоэффективного кода.

Полагаю, вы не знакомы с теорией алгоритмов? В которой понятие "алгоритм" аксиоматически определяется через понятие "абстрактный исполнитель" (абстрактная вычислительная машина). Классическим абстрактными исполнителями являются: лямбда-исчисление, машина Тьюринга, машина Поста, нормальные алгорифмы Маркова.
Любая компьютерная программа реализует именно это строго математическое определение понятия "алгоритм" и никакие иные "алгоритмы", выходящие за рамки математической теории алгоритмов, в цифровых дискретных вычислительных системах невозможны.

Нет, это не алгоритм. Известный ролик на данную тему: https://www.youtube.com/watch?v=cDA3_5982h8
А в программировании "алгоритм" имеет именно математический смысл, т.к. для любой программы можно построить эквивалентную машину Тьюринга.

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

Цитат из этой самой статьй в Википедии.

  1. Любая современная кремниевая "нейросеть" представляет собой дискретную цифровую вычислительную систему, жёстко ограниченную рамками теории алгоритмов. Аналоговая белковая нервная система таких рамок не имеет.
    Компьютер не может воспроизвести аналоговые физические / химические процессы - он лишь может их приблизительно (в рамках ограничений, задаваемых дискретной цифровой природой компьютеров) моделировать численными методами.

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

  3. Кремниевый "нейрон" - примитивная и неизменная алгебраическая функция. Всё, что мы делаем в процессе "обучения" - лишь меняем коэф-ты, на которые умножаются числа, поступающие на вход этой функции. При этом и сами "нейроны", и топология "нейросети" никак не меняются. Тогда как и биологическая нервная клетка представляет собой аналоговый компьютер, меняющий свое поведение во времени. И структура связей между нейронами мозга тоже меняется во времени.

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

  5. Пункт о котором часто забывают: мозг - не самодостаточный механизм, а часть намного более сложной системы. Железы внутренней секреции вырабатывают гормоны, регулирующие работу мозга, а мозг влияет на работу желез внутренней секреции. Даже банальный кофеин уже меняет работу мозга, а можно вспомнить и то, что случилось с Аланом Тьюрингом, когда ему изменили гормональный баланс. Мозг - система с множеством обратных связей, которых даже близко нет в кремниевых "нейросетях".

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

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

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

Это не "алгоритм", а вульгаризация понятия "алгоритм" для кодеров.

"Алгоритм" - то и только то, для чего можно построить эквивалентный абстрактный исполнитель: машину Тьюринга, лямбда-исчисление, нормальный алгорифм Маркова и т.п.

А то, о чём говорите вы, не алгоритм, а реализация алгоритма каком-то кодом на каком-то языке программирования. И допиливают, чаще, не алгоритм, а код. И не потому, что алгоритм ошибочен, а потому, что в коде напахали.

Хотелось бы понять, чем данная статья лучше, например, вот этой статьи https://frontender.info/a-guide-to-flexbox/ 2013 года? Я бы понял, если бы в современной статье подробно описывались механизмы, добавленные в flexbox за последние 10 лет. Но нет: тот же space-evenly лишь упомянут, а про gap вообще нет ни слова. Так какой смысл в этих бессистемных обломках информации, лежащей на каждом углу интернета?

Именно так построена обработка ошибок в языке Go.

По две фотографии от каждого ребёнка, "обучили" на 1610 фотографиях, протестировали на 280 фотографиях... И при этом громкий заголовок о 100% точности? Серьёзно?

P.S. Если нейросеть даёт 100% результат, значит, существует алгоритм решения задачи, не требующий использования нейросети.

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

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

Инженер - прикладной специалист. Он не должен помнить доказательства. Он должен понимать математический аппарат и уметь его использовать.

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

DS без высшей математики - дрессированная мартышка, обученная на уровне "в ситуации А нажать кнопку Б". Да, дешёвая работая сила, способная лишь бездумно выполнять заученные типовые действия, бизнесу тоже нужна. Но называть этот придаток к арифмометру "DS" по меньшей мере странно.

А диуфры?

Крайне неудачный пример. "Физика" в играх, моделирование физических процессов, системы управления (от ядерного реактора до автопилота) - это всё дифуры. И если матанализ действительно встречается нечасто, то дифуры активно используются во многих областях программирования.

Да, если вы занимаетесь только web-разработкой, не содержащей нетривиальных вычислений с плавающей запятой (требующих знания вычислительной математики), понадобится только дискретная математика. Но для других областей программирования понадобятся другие разделы математики. Из того, что мне преподавали в ВУЗе, нет ни одного раздела математики, который не использовался бы в реальных программистских задачах.

Показательно, что в статье нет четвёртого варианта, единственно способного дать необходимый программисту объём теоретических знаний: ВУЗ.

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

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

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

P.S. Даже в российском госреестре профессий "программист" (обязательно имеющий высшее образование) - отдельно, "техник-программист" (высшего образования не имеющий) - отдельно. Это разные профессии, решающие разные задачи.

Если "на расстоянии друг от друга", значит "синхронно" быть не может - в соответствии с СТО.

  1. Всего у нас 19 возможных сумм двух цифр: от 0 (0 + 0) до 18 (9 + 9). При этом для каждой суммы k количество способов её получения n[k] = 10 - |k - 9| (я не стал вычислять циклом, а просто загнал все значения в массив, где индекс - сумма, а кол-во способов - значение).

  2. Всего существует n[k]² комбинаций двух групп с суммой k каждая.

  3. Из невозможности тройного равенства получаем, что для каждой левой группы цифр со значением k существует n[k]² - 1 счастливая комбинация двух правых групп.

  4. Если первая цифра билета - i, то k может принимать значения от i до i + 9. И для получения кол-ва счастливых билетов s[i] достаточно просуммировать значения от n[i]² - 1 до n[i + 9]² - 1 включительно.

  5. Если у нас уже вычислено s[i], то не надо пересчитывать s[i + 1] целиком - достаточно от s[i] отнять n[i]² - 1 и прибавить n[i + 10]² - 1 (скользящее окно).

А т.к. и исходная сумма чисел 1²-1 .. 10²-1, и каждое из значений n[i]² - 1 считаются простыми формулами без циклов (которые ещё и сокращаются в процессе вычислений), то всю программу можно ужать до единственного цикла:

sm = 10 * (10 + 1) * (2 * 10 + 1) // 6 - 10 # сумма 1²-1 .. 10²-1 без цикла
for i in range(0, 10): # в программе осталось 10 итераций
  print(sm)
  sm += 80 - 20 * i # скользящее окно после раскрытия скобок и сокращений

1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность