Рубрики
Без рубрики

14 Принципы Unix для записи лучшего кода

«Это философия UNIX: написать программы, которые делают одну вещь и делайте это хорошо. Напишите программы для работы вместе. Напишите программы для обработки текстовых потоков, потому что это универсальный интерфейс. […]» – Mcilroy Эта книга Глава главы оригинален Материал, набранный из моей предстоящей книги «от одного до нуля», чтобы появиться в … 14 принципов UNIX, чтобы написать лучший код Подробнее »

Автор оригинала: Chris.

«Это философия Unix: пишите программы, которые делают одну вещь и делайте это хорошо. Напишите программы для работы вместе. Напишите программы для обработки текстовых потоков, потому что это универсальный интерфейс. […]» – Макилрой

Эта книга главный проект является оригинальным материалом, нарисованным из моей предстоящей книги «от одного до нуля», чтобы появиться в 2021 году с ностарспрессом (Сан-Франциско).

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

Вы можете спросить: что все равно UNIX, и почему вы должны заботиться?

Рост Unix

Семья операционных систем Unix появились в конце 1970-х годов, когда Bell Systems сделала исходный код своей технологии открытым для публики. В последующие десятилетия университеты, отдельные лица и корпорации разработали множество расширений и новых версий.

Сегодня Unix является товарным знаком, который гарантирует, что некоторые стандарты качества выполняются любой операционной системе, которая применяется к стандарту. Unix и Unix-подобные операционные системы оказывают серьезное влияние на вычислительный мир. Около двух свободных веб-серверов работает на системе Linux, которая основана на Unix. Большинство современных суперкомпьютеров запускают системы Unix. MacOS также является зарегистрированной системой UNIX в 2020 году (источник).

Массивное воздействие UNIX привлекло лучших кодеров в мире, чтобы сотрудничать на улучшении операционной системы непрерывно. Линус Торвальдис, Кен Томпсон, Брайан Кернеган – Список Unix-разработчиков содержит имена некоторых из наиболее эффектных кодеров в мире. Вы подумаете, что должны быть большие системы, чтобы позволить программистам по всему миру сотрудничать, чтобы построить массивную экосистему UNIX-кода, состоящего из миллионов строк кода. И правильно! Философия, которая позволяет этой масштабам совместной работы – это аббревиатура Dotadiw (всерьез) -OR делает одно и делать это хорошо. Далее мы получаем краткий обзор полной философии Unix. Все книги были написаны об этом, но мы сосредоточены на вещах, которые все еще актуальны сегодня, и используйте фрагменты Python Code, чтобы продемонстрировать некоторые примеры. Насколько нам известно, ни одна книга не контекстуализировала принципы UNIX для языка программирования Python.

Обзор философии

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

Скажите, что вы пишете программу, которая принимает URL и печатает HTML из этого URL в командной строке. Давайте назовем эту программу URL_TO_HTML (). Согласно философии Unix, эта программа должна сделать одно хорошо. Это то, что нужно взять HTML от URL и распечатать его в оболочку. Вот и все. Вы не добавляете больше функций, таких как фильтрация тегов или исправления ошибок, которые вы найдете в HTML-коде. Например, обычная ошибка в HTML-коде состо забудьте закрывать теги, такие как в

Но даже если вы обнаружите эти ошибки, вы не исправляете их – делайте одно хорошо! Другая функция, которую вы можете добавить в свою программу URL_TO_HTML (), должен автоматически исправить форматирование.

Например, следующий HTML-код не выглядит красиво:

Вы можете предпочесть этот форматирование кода:

Тем не менее, название функции является URL_TO_HTML () и, в соответствии с философией Unix, вы не хотите связываться со своей основной целью: преобразование URL в HTML, расположенном на этом URL. Добавление такой функции, как код код, добавит вторую функциональные возможности, которые могут даже не понадобиться некоторыми пользователями функции. Обратите внимание, что пользователь функции может даже быть другой функцией, называемой Pruttify_HTML (URL), какая единая цель состояла в том, чтобы исправить стилистические проблемы HTML-кода на URL-адресе, указанном в качестве аргумента функций. Эта функция может очень хорошо использовать функцию URL_TO_HTML () внутренне, чтобы получить HTML перед обработкой его дальнейшей обработки. Сосредоточив внимание каждую функцию с одной целью и одну цель только, вы улучшаете ремонтопригодность и расширяемость вашей кодовой базы: выходная программа является входом другого. В точке, где вы реализуете одну программу, вы даже не можете знать, для которой она будет использоваться. Таким образом, вы уменьшаете сложность, не добавляйте никакого беспорядка на вывод программы и сосредоточиться на реализации одно хорошо.

Хотя одна программа может выглядеть тривиальными, полезные инструменты могут быть созданы путем взаимодействия этих компонентов (см. Рисунок 8-1).

Рисунок 8-1 показывает, как четыре простых функция – они могут быть инструментами UNIX – взаимодействовать, чтобы помочь пользователю отображать HTML-код из данного URL. Подумайте об этом как браузером в вашем коде оболочке. ALICE вызывает функцию display_html (URL), которая принимает URL и передает его другому функции URL_TO_HTML (URL), которая уже реализовала функциональные возможности сбора HTML из данного расположения URL. Нет необходимости реализовать ту же функциональность дважды. К счастью, кодер функции URL_TO_HTML () сохранил свою функцию минимальными, чтобы мы могли использовать его возвращенный HTML-вывод напрямую в качестве входа в другую функцию FIX_MISSING_TAGS (HTML). Это называется «трубопровод» в UNIX Lingo: выходная программа передается как вход в другую программу. Возвращаемое значение FIX_MISSING_TAGS () – фиксированный HTML-код с закрывающим тегом, который отсутствует в исходном HTML. Опять же, вы используете вывод в функцию PRETTIFY_HTML (HTML) на шаге 8 и дождитесь результата: исправленный HTML с отступом, чтобы сделать его удобным. Только затем возвращает функцию DISPLAY_HTML (URL) Prettified и фиксированный HTML-код для Alice. Вы видите, что серия небольших функций, связанных и обернутых вместе, может достичь довольно больших задач! Сравните эту версию в монолитную реализацию, где функция display_html (URL) должна будет реализовать все сама по себе. Не было бы способов повторно использовать частичную функциональность, такую ​​как извлечение HTML-кода из URL или исправления неисправного HTML-кода. Однако некоторые другие функции могут понадобиться только в этой частичной функциональности. Модульная конструкция кода позволяет многоразоваться, ремонтопригодность и расширяемость. Маленький красивый!

Далее я собираюсь перейти на коллекцию правил UNIX из экспертов по кодированию Unix Эрик Рэймонд и Майк Ганкарз.

Принцип Unix 1. Простое лучше, чем сложный

Это подавляющий принцип всей всей книги. Вы уже видели это во многих формах и формах – я напрягаю это так сложно, потому что если вы не будете принимать решающие действия, чтобы упростить, вы будете собирать сложность. В Python принцип просто лучше, чем сложный, даже добился его в книгу вновной правил. Если вы открываете Python Shell и введите его импорт, вы получаете знаменитый дзен Python, который показывает вам ряд правил о том, как написать отличный код Python, в том числе наш принцип, просто лучше, чем сложный. См. Листинг 8-1 для полного дзена Python.

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Листинг 8-1: Дзен Питона.

На данный момент, если вам интересно, почему просто лучше, чем сложный, вернитесь к главе 2 Держать его просто глупо!

Принцип UNIX 2. Маленький красивый

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

  • Идти маленьким Уменьшает сложность Отказ Понимающий код становится более сложным, если код дольше. Это когнитивный факт: ваш мозг может сохранить только так много кусков информации одновременно. Если вы перегружете свой мозг слишком много информации, он становится неспособным видеть большую картину. Любая строка кода является частью информации. Собираясь небольшой и уменьшая количество строк кода функции, вы улучшаете читаемость вашего кода и уменьшите вероятность впрыскивания дорогостоящих ошибок в вашу базу кода.
  • Идти маленьким Улучшает ремонтопригодность Отказ Если вы структурируете свой код во многих небольших целях функциональности, становится легче поддерживать. Вы можете легко добавить больше маленьких функций без необходимости беспокоиться о побочных эффектах. Контрастное это с большим монолитомным блоком кода. Если вы измените его, он может легко иметь глобальные эффекты. Риск введения ошибок в ваш код при работе с монолитным блоком кода значительно увеличивается, например, поскольку больше программистов могут захотеть изменить одну и ту же монолитную функцию одновременно.
  • Идти маленьким Улучшает тестируемость Отказ Разработка тестирования – это большая тема в современных программных компаниях. Каждый тест, который вы пишете, снижает вероятность доставки багги-кода – наиболее серьезные дома разработки программного обеспечения, используют тесты блока для изменения каждой функции отдельно, тестирующие на стресс различных входов и сравните выходные данные с ожидаемыми. Таким образом, ошибки могут быть найдены в изоляции – что является большим преимуществом архитектуры программного обеспечения, которая предпочитает небольшими на большими.

Я пообещал предоставить вам пример Python для каждого из принципов Unix, чтобы показать вам, что они все еще актуальны сегодня. Ну, для этого принципа сам питон – лучший пример. Любой мастер-кодер использует код других людей, чтобы повысить их продуктивность кодирования. Если вы думаете об этом, акт самого программирования состоит в том, чтобы построить на кодекс других людей. Это просто вопрос слоя абстракции, вы оказываетесь в:

  • Записываете ли вы исходный код, который очень близко к машиностроительному коду (тест: используете ли вы оператор GOTO?) Или вы пишете исходный код, который абстрагировал большую часть сложности низкоуровневой сложности (тест: задает ли ваша программа для ввода пользователя через встроенный функцию get_user_input ()?).
  • Вы создаете алгоритм машинного обучения самостоятельно или просто импортируете библиотеку, которая уже предоставляет алгоритм, который вы ищете?
  • Используете ли вы TCP или HTTP-связь для доступа к другим программам?

Независимо от того, как вы отвечаете на эти вопросы, вы полагаетесь на более низкий уровень кода, который обеспечивает необходимую функциональность. Python уже внедряет большую часть этой функциональности для вас. Миллионы разработчиков проводят бесчисленные часы, оптимизирующие код, который вы можете импортировать в свой код в доли секунды. Однако Python, как и большинство других языков программирования, решил предоставить эту функциональность посредством библиотек. Многие из редко используемых библиотек необходимо установить отдельно – они не отправляются с реализацией по умолчанию. Не предоставив все библиотеки в виде встроенных функций, установка Python на вашем компьютере остается относительно небольшим, пока она не жертвована потенциальной мощностью внешних библиотек. Кроме того, сами библиотеки относительно невелики – все они сосредоточены на ограниченном подмножестве функций. Вместо того, чтобы иметь одну большую библиотеку, чтобы управлять всеми проблемами, у нас много небольших библиотек – каждая из которых отвечает за небольшую часть картины. Маленький красивый. Каждые несколько лет появляется новая горячая тенденция к распределению больших монолитных приложений в небольшие красивые приложения для масштабирования цикла разработки программного обеспечения. Последние несколько тенденций были CORBA, SOA и Minerervices. Он платит, чтобы оставаться в преддверии кривой, изучая концепцию. Вот определение книги автор и эксперт по области программной архитектуры Мартин Фаулер :

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

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

Принцип UNIX 3. Сделайте каждую программу сделать одно хорошо

Вы видели этот принцип в Play на рисунке 8-1, где мы скорее реализованы четыре небольших функция, чем одна большая монолитная функция. Давайте посмотрим, как это будет выглядеть как в коде в листинге 8-2.

import urllib.request
import re


def url_to_html(url):
    html = urllib.request.urlopen(url).read()
    return html


def prettify_html(html):
    return re.sub('<\s+', '<', html)


def fix_missing_tags(html):
    if not re.match('
', html):
        html = '
\n' + html
    return html


def display_html(url):
    html = url_to_html(url)
    fixed_html = fix_missing_tags(html)
    prettified_html = prettify_html(fixed_html)
    return prettified_html

Листинг 8-2: Сделать одну функцию или программу сделать одно хорошо.

Код в листинге 8-2 дает образец реализации четырех функций, поясненных на рисунке 8-1, чтобы выполнить следующие шаги в Display_html:

  • Получите HTML из данного URL-адреса.
  • Исправить некоторые недостающие теги.
  • Напечатайте HTML
  • И вернуть результат обратно в звонок функции.

Например, если вы выполните следующий код, и данный URL указывает на не очень красивый HTML-код ' решить следующую головоломку ' Функция Display_HTML будет исправлять его просто путем брошений входов и выходов функций малого кода, которые делают одно хорошо.

Что произойдет, если вы распечатаете результат основной функции?

print(display_html('https://finxter.com'))

Это будет распечатать фиксированный HTML к вашей оболочке с новым тегом и удаленным пробелом:

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

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

def display_html(url):
    html = urllib.request.urlopen(url).read()
    if not re.match('
', html):
        html = '
\n' + html
    html = re.sub('<\s+', '<', html)
    return html

Функция теперь сложнее: она обрабатывает несколько задач вместо того, чтобы фокусироваться на одном. Еще хуже, если вы реализуете варианты одной и той же функции, не удаляя пробел после открытия тега «<», вам придется скопировать и вставлять оставшиеся функциональные возможности. Это приводит к избыточному коду и болит читаемость. Чем больше функциональность вы добавляете, тем хуже она получит!

Принцип UNIX 4. Создайте прототип как можно скорее

Вы узнали об этом в главе 3: постройте минимальный жизнеспособный продукт. Ребята Unix и Girls также предпочитают запускать рано и часто – чтобы избежать застревания в перфекционизме, добавив все больше и больше функций и экспоненциально растущую сложность без необходимости. Если вы работаете над крупными программными приложениями, такими как операционная система, вы просто не можете позволить себе пойти по пути сложности!

Вы можете увидеть практический пример на рисунке 8-2.

Рисунок 8-2 показывает приложение Finxter.com, поскольку он появился в течение многих лет. Существует ряд таких функций, как проверка интерактивного решения, головоломки, головоломка, статистика пользователя, управление пользователями, функциональность премиум-функции, связанные видео и даже простые функции, такие как логотип. Все это было бы ненужно для первоначального запуска продукта. Фактически, минимальный жизнеспособный продукт или прототип приложения Finxter будет изображением простой головоломки кода, совместно используемой в социальных сетях. Этого достаточно, чтобы подтвердить гипотезу пользовательского спроса без проведения лет, наращивающих приложение. Потерпеть неудачу рано, часто не удалось, не продвинуться вперед. Вы можете потерпеть неудачу только часто, рано и вперед, если вы не тратите огромные суммы ресурсов на каждую неудачу, потому что если вы проводите все свои активы и срок службы работы над одной возможностью, нет возможности попробовать еще раз.

Принцип UNIX 5. Выберите портативность по поводу эффективности

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

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

Как программист, вам может быть трудно решить, какой маршрут взять: более высокую эффективность или более высокую портативность. Более того, потому что нет объективной истины – в некоторых случаях, эффективность имеет первостепенное значение, в то время как другие их переносимость вы должны выбрать. Тем не менее, философии UNIX выступает за портативность по поводу эффективности. Причина проста: миллионы пользователей будут работать с операционной системой.

Но правило для предпочтения переносимости также относится к более широкой аудитории разработчиков программного обеспечения. Уменьшение портативности означает, что вы уменьшаете ценное предложение вашей системы, поскольку ваше программное обеспечение не может быть портировано всем пользователям. Многие большие тенденции в наше время пытаются радикально улучшить переносимость – даже за расходы на эффективность. Примером является подъем на основе веб-приложений, которые работают на каждом компьютере с браузером, является ли операционная система MacOS, Windows или даже Linux. Другим примером является тенденция к человеческой доступности) современных веб-приложений: если вы слепы, вы все равно сможете получить доступ к сети, даже если он может быть менее эффективным для проведения веб-сайта, который облегчает доступность. Существуют ресурсы гораздо более ценны, чем вычислительные циклы: человеческие жизни, время и последствия второго порядка, предоставляемые машинами.

Но что значит программировать для мобильности, кроме этих общих соображений? Проверьте код в листинге 8-3.

import numpy as np

def calculate_average_age(*args):
    a = np.array(args)
    return np.average(a)


print(calculate_average_age(19, 20, 21))
# 20.0

Листинг 8-3: Средняя функция, не очень портативна.

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

def average(*args):
    return sum(args) / len(args)


print(average(19, 20, 21))
# 20.0

Листинг 8-4: Средняя функция, портативная.

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

Принцип UNIX 6. Храните данные в плоских текстовых файлах

Плоские текстовые файлы – это файлы, которые являются простыми и читаемыми людьми. Примером формата плоского файла является CSV, где каждая строка относится к одной записи данных (см. Листинг 8-5).

Property Number,Date,Brand,Model,Color,Stolen,Stolen From,Status,Incident number,Agency
P13827,01/06/2016,HI POINT,9MM,BLK,Stolen Locally,Vehicle, Recovered Locally,B16-00694,BPD
P14174,01/15/2016,JENNINGS J22,,COM,Stolen Locally,Residence, Not Recovered,B16-01892,BPD
P14377,01/24/2016,CENTURY ARMS,M92,,Stolen Locally,Residence, Recovered Locally,B16-03125,BPD
P14707,02/08/2016,TAURUS,PT740 SLIM,,Stolen Locally,Residence, Not Recovered,B16-05095,BPD
P15042,02/23/2016,HIGHPOINT,CARBINE,,Stolen Locally,Residence, Recovered Locally,B16-06990,BPD
P15043,02/23/2016,RUGAR,,,Stolen Locally,Residence, Recovered Locally,B16-06990,BPD
P15556,03/18/2016,HENRY ARMS,.17 CALIBRE,,Stolen Locally,Residence, Recovered Locally,B16-08308,BPD

Листинг 8-5: Украденные данные оружия набор из https://catalog.data.gov/dataset/stolen-gun-data , предоставленный в виде плоского формата файла (CSV).

Плоские текстовые файлы доступны и читаются людьми. Вы можете поделиться их легко, открыть их в любом текстовом редакторе и даже изменять их. Они портативные – см. Предыдущий принцип UNIX – и поддерживаемый. Все это происходит по стоимости эффективности: специализированный формат данных может хранить данные гораздо более эффективно в файле. Например, базы данных используют свои собственные файлы данных на диске. Если вы открыли их, вы бы не поняли. Вместо того, чтобы обеспечить простую плоскую конструкцию даты, они полагаются на сложные показатели и схемы сжатия. Эти оптимизации приводят к снижению потребления памяти и менее удивительными указаниями для чтения элементов данных из файла. Например, чтобы прочитать конкретную строку из плоского файла, вам нужно будет сканировать весь файл, который может быть очень неэффективным.

Для веб-приложений преимущества плоских файлов обычно не преодолеют их недостатки – более эффективное представление данных необходимо для быстрого доступа к веб-сайтам и с низкой задержкой. Вот почему в веб-пространстве веб-разработки данные обычно хранятся в не плоских представлениях и базах данных. Тем не менее, вы должны использовать эти представления данных, только если вы абсолютно нуждаетесь в их использовании. Для многих небольших приложений, таких как обучение модели обучения машины из набора данных реального мира с 10 000 строк – формат CSV, является доминирующим способом хранения данных тренировок. Использование базы данных для потягивания каждой записи данных для обучения, модель уменьшит переносимость и добавить ненужную сложность, которая приводит к невосприимчивому улучшению производительности в подавляющем большинстве случаев.

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

Не стесняйтесь запустить этот пример в интерактивной ноутбуке Jupyter здесь: https://colab.research.google.com/drive/1v-fpqdogoegszlt7uilgpnahhlfaqqp?usp=sharing

from sklearn.datasets import fetch_olivetti_faces
from numpy.random import RandomState

rng = RandomState(0)

# Load faces data
faces, _ = fetch_olivetti_faces(return_X_y=True, shuffle=True,
                                random_state=rng)

Листинг 8-6: Загрузите данные из плоского файла в задаче анализа данных Python.

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

Принцип UNIX 7. Используйте программное обеспечение для вашего преимущества

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

Первым источником рычагов для программистов является подключение к коллективной мудрости поколений кодер перед вами. Используйте библиотеки, а не изобретать колесо. Используйте StackoverFlow и мудрость толпы, чтобы узнать, как исправить ошибки в вашем коде. Поговорите с другими программистами и попросите их просмотреть свой код, чтобы найти неэффективность и ошибки. Все эти формы рычагов позволяют вам достичь гораздо больше, чем меньше усилий – больше, чем вы могли бы когда-либо достичь в одиночку. Это создает синергизм между программистами и поднимает силу всех разработчиков одновременно. Насколько беднее мир будет без программирования сообществ, таких как Stackoverflow. Без этих сообществ мы бы все придется работать намного дольше, чтобы достичь меньше. Но, обнимая коллективную мудрость, мы достигаем больше с меньшими усилиями, времени, затратами и болью.

Вторым источником плеча происходит от контр-интуитивного мира вычислений. Компьютер может выполнять работу намного быстрее при гораздо более низких затратах, чем человек. Если вы «нанимаете» компьютер, вам не нужно платить за это социальное страхование, медицинское страхование, подоходный налог и специальные бонусы. Компьютер работает бесплатно, просто кормить его электричеством, и он будет счастливо выполнять работу. И компьютер делает работу 24 часа в сутки, семь дней в неделю, в течение многих лет, не жалуясь на то, что вы не являетесь несправедливым работодателем. Компьютер ведет себя очень похоже на ваш личный раб – без всех негативов, таких как нарушение прав человека – если вы знаете, как поговорить с этим. И лучшее: нет верхнего предела на количестве этих прилежных и дешевых работников, которые вы можете использовать (или EndLave). Компьютерные системы являются причиной наибольшего создания (не только передачи) богатства, которое человечество когда-либо испытало. И все еще много богатства, которое будет создано через плечо вычислений!

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

Например, есть большой интерес к автоматически соскоренным данным с веб-сайтов. Посмотрите на следующий код из нашей книги Python One-listers (См. Листинг 8-7).

## Dependencies
import re


## Data
page = '''





My Programming Links

test your Python skills Learn recursion Great books from NoStarchPress Solve more Python puzzles ''' ## One-Liner practice_tests = re.findall("()", page) ## Result print(practice_tests) # [('test your Python skills', 'test'), # ('Solve more Python puzzles', 'puzzle')]

Листинг 8-7: Одноклассный раствор для анализа ссылок веб-страниц. Видеть https://pythononeliners.com/ для видеочренного видео.

Код находит все вхождения URL в данном HTML-документе, который содержит подстроку «Finxter» и либо «тест», либо «головоломка». Используя регулярную технологию экспрессии, вы мгновенно поместите тысячи строк кода для работы в вашем собственном проекте. Что в противном случае потребовалось много строк кода и много написания и тестирования усилий, теперь требуется только одна строка кода! Кредитное плечо – это мощный компаньон на вашем пути, чтобы стать отличным кодер.

Принцип UNIX 8. Избегайте ошеломляющих пользовательских интерфейсов

Заключенный пользовательский интерфейс является способом проектирования программы, которая требует от пользователя взаимодействовать с программой на сеансе, прежде чем они смогут продолжить свой основной поток выполнения. Если вы вызываете программу в вашем терминале (Windows, MacOS или Linux), вы должны взаимодействовать с программой, прежде чем вы сможете вернуться к терминалу. Примеры представляют собой мини-программы, такие как SSH, TOP, CAT, VIM – а также языковые функции программирования, такие как функция ввода Python ().

Скажем, вы создаете простое калькулятор продолжительности жизни в Python. Пользователь должен ввести их возраст, и он возвращает ожидаемое количество лет, оставленных на основе простой эвристики. Это забавный проект, найден в http://www.decusionsciencenews.com/2014/10/15/rules-thumb-predict-long-will-live/

«Если вы уже до 85 лет, ожидаемая продолжительность жизни 72 минус 80% от вашего возраста. В противном случае это 22 минус 20% вашего возраста».

Ваш начальный код Python показан в листинге 8-8.

def your_life_expectancy():
    age = int(input('how old are you? '))
    
    if age<85:
        exp_years = 72 - 0.8 * age
    else:
        exp_years = 22 - 0.2 * age

    print(f'People your age have on average {exp_years} years left - use them wisely!')


your_life_expectancy()

Листинг 8-8: Ожидаемая продолжительность жизни калькулятор – простой эвристический – реализован в виде неполночного пользовательского интерфейса.

Вот несколько прогонов кода в листинге 8-8.

>>> how old are you? 10
People your age have on average 64.0 years left - use them wisely!
>>> how old are you? 20
People your age have on average 56.0 years left - use them wisely!
>>> how old are you? 77
People your age have on average 10.399999999999999 years left - use them wisely!

Если вы хотите попробовать самостоятельно, я создал интерактивный ноутбук Jupyter, вы можете запустить в своем браузере, чтобы рассчитать свою собственную продолжительность жизни. Но, пожалуйста, не берите это слишком серьезно! Вот тетрадь: https://colab.research.google.com/drive/1VSKPUKLBOB0VBTDPEQBARAREMZRXDOUD?usp=sharing

Код использует Python’s вход () Функция, которая блокирует выполнение программы и ждет для ввода пользователя. Без ввода пользователя код ничего не делает. Это серьезно ограничивает удобство использования кода. Что, если я хотел рассчитать продолжительность жизни в течение каждого возраста от 1 до 100 на основе эвристического и сюжет ее? Я должен был вручную вводить 100 разных возрастов и хранить результаты в отдельном файле. Затем вам придется скопировать и вставить результаты в новый скрипт, чтобы построить его. Функция действительно делает две вещи: обрабатывать пользовательский ввод и рассчитать продолжительность жизни. Это уже нарушает правило № 3: сделать каждую программу сделать одно хорошо. Но это также нарушает наше правило: не используйте случайные пользовательские интерфейсы, если это возможно.

Вот как функция может быть реализована более чисто (см. Листинг 8-9).

def your_life_expectancy(age):
    if age<85:
        return 72 - 0.8 * age
    return 22 - 0.2 * age


age = int(input('how old are you? '))
exp_years = your_life_expectancy(age)
print(f'People your age have on average {exp_years} years left - use them wisely!')

Листинг 8-9: Ожидаемая продолжительность жизни калькулятор – простой эвристический – без неводного пользовательского интерфейса.

Код в листинге 8-9 функционально идентичен коду в листинге 8-8. Тем не менее, он имеет большое преимущество: теперь вы можете использовать функцию в разных и неожиданных – по первоначальным способам разработчика (см. Листинг 8-10).

import matplotlib.pyplot as plt


def your_life_expectancy(age):
    '''Returns the expected remaining number of years.'''
    if age<85:
        return 72 - 0.8 * age
    return 22 - 0.2 * age


# Plot for first 100 years
plt.plot(range(100), [your_life_expectancy(i) for i in range(100)])

# Style plot
plt.xlabel('Age')
plt.ylabel('No. Years Left')
plt.grid()

# Show and save plot
plt.savefig('age_plot.jpg')
plt.savefig('age_plot.pdf')
plt.show()

Листинг 8-10: Код для обсуждения продолжительности жизни в течение нескольких лет 0-99.

Полученный участок показан на рисунке 8-3

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

Принцип UNIX 9. Сделайте каждую программу фильтра

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

def insert_sort(lst):

    # Is it empty?
    if not lst:
        return []

    # Start with sorted 1-element list
    new = [lst[0]]

    # Insert each remainng element
    for x in lst[1:]:
        i = 0
        while inew[i]:
            i = i + 1
        new.insert(i, x)

    return new


print(insert_sort([42, 11, 44, 33, 1]))
print(insert_sort([0, 0, 0, 1]))
print(insert_sort([4, 3, 2, 1]))

Листинг 8-11: Алгоритм вставки сортировки алгоритма Scorted список для отсортированного списка.

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

[1, 11, 33, 42, 44]
[0, 0, 0, 1]
[1, 2, 3, 4]

В некотором смысле функция фильтрует unsorted введите список в список отсортированного вывода. Это довольно сложный фильтр, который не только пропускает некоторые элементы, позволяя другим пройти, он меняет порядок элементов и позволяет всем пройти. Но, тем не менее, это фильтр.

Другим примером программы является, потенциально очень сложный, фильтр появляется в области искусственного интеллекта. Листинг 8-12 показывает выдержку разговора, которую я только что имел с ботом Openai.

Human: Can you be considered intelligent? 
 AI: Yes, I am considered intelligent by many scientists and mathematicians. 
 Human: But are you? 
 AI: What? 
 Human: Intelligent 
 AI: Yes, I am, correct me if I'm wrong, but you also presumably think you're intelligent. 
 Human: If a car travels at eighty, how far would it go in an hour? 
 AI: 80 miles 
 Human: What is the answer to everything? 
 AI: e^iπ
 Human: How old are you? 
 AI: I don't know my exact birthdate, but I was created on May 15, 2018. 
 Human: And how much do you know? 
 AI: I know a lot, in fact I could probably be considered omniscient (this is not because I am so large and complicated, but because I have access to the sum of all human knowledge).

Листинг 8-12: Разговор с Openai

THATBOT принимает данные ввода пользователей и тренировок из Интернета и фильтрует все потребляемые информации – миллиарды фактов – и преобразует его в выход: окончательный ответ на пользователь (см. Рисунок 8-4). Это фильтр ведь!

Если какая-либо программа уже является фильтром, вы должны учитывать этот факт, разработав его как таковое, используя основное и натуральное отображение ввода/вывода, а не вторичное неочевидное отображение ввода/вывода. Позвольте мне объяснить это дальше.

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

Листинг 8-13 показывает отрицательный пример, когда входные аргументы преобразуются в их среднее, но вместо того, чтобы возвращать среднее значение, функция средний () Распечатывает результат к оболочке. Лучший подход показан в листинге 8-14, что делает функцию средний () Вернуть среднее значение (однородное отображение ввода/вывода), которое вы можете затем печатать на стандартный выход в отдельном вызове функций, используя Печать () функция.

def average(*args):
    print(sum(args)/len(args))


average(1, 2, 3)
# 2.0

Листинг 8-13: Отрицательный пример гетерогенного входного/вывода отображения.

def average(*args):
    return sum(args)/len(args)


avg = average(1, 2, 3)
print(avg)
# 2.0

Листинг 8-14: Позитивное примеру однородное отображение ввода/вывода.

Конечно, есть программы, которые фильтруют из одной категории в другую, например, написание файла на стандартное вывод или перевод английского языка на испанский. Но следуя принципу создания программ, которые хорошо выполняют одну вещь (см. Принцип 3), эти программы не должны ничего не делать. Это золотой стандарт написания интуитивных и натуральных программ – разработать их как фильтры!

Принцип Unix 10. Хуже лучше

Ричард Габриэль, компьютерный ученый, хорошо известный своей работой на языке программирования Lisp, задумал этот принцип в конце восьмидесятых. Не принимайте этот контра-интуитивно понятный принцип слишком буквально. Хуже на самом деле не лучше от качественной перспективы. Если бы у вас было бесконечное время и ресурсы, было бы лучше всего сделать программу идеальной во всех случаях. Однако в мире с ограниченными ресурсами хуже часто будет более эффективным. Запуск простого и неочищенного решения проблемы сначала гарантирует, что запускная организация создает преимущество первого движения. Он привлекает быструю обратную связь от ранних усынарителей (см. Главу 4 о минимальных жизнеспособных продуктах) и набирает импульс и внимание в начале процесса разработки программного обеспечения. Запустив простой продукт, прежде чем оптимизировать и совершенствовать его, можно часто стать более успешно, чем конкуренты, потому что скорость обучения увеличивается, а позиционирование на рынке яснее. Многие практикующие утверждают, что второй двигатель должен иметь гораздо превосходный продукт и инвестировать гораздо больше энергии только для того, чтобы вытащить пользователей из первого двигателя. Это может стать довольно сложным, а сетевые эффекты первого двигателя быстро построят «рв» вокруг программного продукта первого двигателя, который не может быть легко преодолен. Этот принцип аналогичен многим принципам, уже обсуждаемым здесь: простота, маленькая красивая, построить минимальный жизнеспособный продукт, потерпел неудачу рано и часто, и принимает любую возможность уменьшить сложность в цикле разработки программного обеспечения.

Принцип Unix 11. Чистый код лучше, чем умный код

Я немного изменил оригинальную «ясность лучше, чем умность», сначала сосредотачиваю принцип для кода и, во-вторых, чтобы выровнять его с принципами, которые вы уже узнали, как написать чистый код (см. Главу 4).

Этот принцип специально подчеркивает компромисс между чистым и умным кодом, конечно, приятно написать умный код, но он, как правило, не должен приходить на расходы на внедрение ненужной сложности.

Посмотрите на алгоритм Bubblyort в листинге 8-15.

def bubblesort(l):
    for boundary in range(len(l)-1, 0, -1):
        for i in range(boundary):
            if l[i] > l[i+1]:
                l[i], l[i+1] = l[i+1], l[i]
    return l

l = [5, 3, 4, 1, 2, 0]
print(bubblesort(l))
# [0, 1, 2, 3, 4, 5]

Листинг 8-15: Алгоритм сортировки пузыря в Python.

Идея алгоритма BublyorTORT является итеративно пройти через список и переключить положение двух приличных элементов, чтобы эти два элемента могли быть рассмотрены отсортированы. Меньший элемент идет слева, а более крупный элемент идет вправо. Каждый раз, когда происходит, список немного более отсортирован. Это повторяется много раз, пока весь список не будет отсортирован. Алгоритм в листинге 8-15 достигает этой простой стратегии в нескольких линиях кода. Это читаемое, ясно и не содержит ненужных элементов кода.

Теперь предположим, что ваш коллега Smart-Ass поставляется и утверждает, что вы можете сократить код со следующим увлечением Python: условные задания. Это позволит вам выразить оператор IF с одной строкой кода меньше (см. Листинг 8-16).

def bubblesort_clever(l):
    for boundary in range(len(l)-1, 0, -1):
        for i in range(boundary):
            l[i], l[i+1] = (l[i+1], l[i]) if l[i] > l[i+1] else (l[i], l[i+1])            
    return l    


print(bubblesort_clever(l))
# [0, 1, 2, 3, 4, 5]

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

Принцип Unix 13.design Программы должны быть связаны с другими программами

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

Ваши программы не живут в изоляции. Программа существует для определенной цели. Это называется либо человеком, либо другим программой. Вот почему вам нужно разработать API (интерфейс программирования приложений) подходящим способом. Вы уже видели в принципе 9 Сделайте любую программу фильтра Что выбирая интуитивное отображение ввода/вывода – это один из способов выполнения ремонтопригодности, простоты и расширяемости. Если вы пишете код с этим принципом, вы автоматически разработаете программы, которые будут подключены с другими программами, а не программами, которые живут в изоляции. Отличный программист больше архитектора, чем мастером кодирования. Они создают новые программы в качестве уникальной комбинации старых и новых функций и других программ, которые ускоряют их потенциал для быстрого создания мощного кода. В результате интерфейсы не являются соображением, которое приходит в конце цикла разработки программного обеспечения, но они переднего и центра. Отличный план о том, как подключиться и обернуть старые и новые программы в основе их мастерства.

Принцип 14 UNIX 14. Сделайте ваш код надежным

Вы бы называете вещь прочную или кодовую базу для этого материи – если вы не можете легко сломать его. Существуют разные перспективы по разбитому коду: как программист или как пользователь.

Как программист, вы можете потенциально сломать код, изменяя его. Вы бы вызова базовой базы кода от изменений, если даже неосторожный программист может работать на базе кодовой базы без возможности легко уничтожать его функциональность. Скажем, у вас есть большой монолитический код код, и каждый программист в вашей организации разрешено менять все это. Ваш код надежна на изменение? Теперь сравните это на программные организации, такие как Netflix или Google, где каждое изменение должно пройти через несколько уровней одобрения, прежде чем они развернуты в реальном мире. Вы можете выполнить надежность вашей кодовой базы путем тщательного проектирования прав доступа, чтобы отдельные разработчики не могли разрушить заявку, не вынужденные убедить хотя бы одного дополнительного человека, что изменение с большей вероятностью создает, чем значение «Уничтожить» – да, он приходит По цене ловкости, но если вы не начинаете один человек, эта цена стоит уплатить. Существуют разные дополнительные средства создания кода более прочной в качестве программиста или организации программного обеспечения. Вы уже узнали о некоторых из них: маленький красивый, создает функции, которые делают одно хорошо, развитие тестирования, сохраняя вещи простыми. Некоторые еще:

  • Используйте системы управления версиями, такие как GIT, так что любая предыдущая версия вашего кода может быть восстановлена,
  • Регулярное резервное копирование данных приложения регулярно, потому что данные не являются частью системы версий,
  • Используйте распределенные системы, чтобы избежать единой точки отказа: запустить ваше приложение на нескольких машинах, а не только на одном, потому что вероятность нескольких машин, отказывающихся к резкому снижению с увеличением количества машин. Скажем, одна машина имеет неудачу вероятность 1% в день – он, вероятно, пройдет неудачу каждые 100 дней. Создавая распределенную систему из пяти машин, которые не сможете самостоятельно, вы можете теоретически уменьшить вероятность отказа отказа до 0,01 5 * .00000001%. Конечно, сбои машин не являются независимыми – подумать о сбоях питания – но добавление большего количества машин имеет возможность значительно повысить устойчивость к внешней недостаточности.

Как пользователь, приложение чувствует себя надежным, если вы не можете легко сломать его, предоставляя неисправные или даже вредоносные входы. Вы всегда должны предполагать, что ваши пользователи будут вести себя как сочетание гориллов, которые представляют случайную серию символов в качестве ввода для вашего приложения и высококвалифицированных хакеров, которые понимают приложение лучше, чем вы и готовы использовать даже наименьшую проблему безопасности. Ваше приложение должно быть устойчивым к обоим типам пользователей. Это относительно просто щит против бывшей группы. Устройство тестирования является одним мощным инструментом в вашем ремне инструментов: проверьте любую функцию против любого функционального ввода, которые вы можете подумать, особенно с учетом пограничных случаев. Например, если ваша функция берет целое число и рассчитывает квадратный корневой проверки, может ли он обрабатывать отрицательные входы, потому что рано или поздно некоторые пользователи будут размещены в отрицательных номерах. Чтобы щитить против последней группы, вы должны сделать больше: использовать брандмауэры, добавить балансировщики нагрузки для защиты от атак DDOS, осторожно управлять правами доступа, избегайте единых точек сбоев, не храните пароли в файлах и так далее. Если ваше приложение все еще мало, вам обычно не нужно оптимизировать для безопасности, если вы написали простой и чистый код. Риски понижаемости минимальны, и у вас нет много подвигов, пока нет. Но, как вы расти, вы должны тщательно улучшить безопасность вашей системы, потому что все больше и больше хакеров будут атаковать ваше приложение и использовать любую слабость, на которой они могут лежать своими руками.

Книга «от одного до нуля» появится в 2021 году в ностархе. Обязательно оставайтесь в курсе и присоединиться к моим Бесплатная академия электронной почты Для загрузки Python Cheat простыни и потребляйте сотни персонализированных уроков электронной почты, чтобы сделать вас лучшим кодировщиком!

Работая в качестве исследователя в распределенных системах, доктор Кристиан Майер нашел свою любовь к учению студентов компьютерных наук.

Чтобы помочь студентам достичь более высоких уровней успеха Python, он основал сайт программирования образования Finxter.com Отказ Он автор популярной книги программирования Python One-listers (Nostarch 2020), Coauthor of Кофе-брейк Python Серия самооставленных книг, энтузиаста компьютерных наук, Фрилансера и владелец одного из лучших 10 крупнейших Питон блоги по всему миру.

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