<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Custom geek materials</title><subtitle>Some random IT information</subtitle><author><name>Custom geek materials</name></author><id>https://teletype.in/atom/customgeekmaterials</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/customgeekmaterials?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/customgeekmaterials?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-22T18:53:12.198Z</updated><entry><id>customgeekmaterials:floating-point</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/floating-point?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>Почему у программирования поплыла запятая?</title><published>2022-10-12T08:46:41.909Z</published><updated>2022-10-12T08:46:41.909Z</updated><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/c3/71/c3712d54-cec4-4fc1-84b3-eed029f673dd.png&quot;&gt;Числа с плавающей запятой в англоязычной литературе называются числа с плавающей точкой (от англ. floating point). Такое различие связано с тем, что в русскоязычной литературе принято отделять дробную часть числа запятой, а в европейской и американской - точкой.</summary><content type="html">
  &lt;p id=&quot;7cUn&quot;&gt;Числа с плавающей запятой в англоязычной литературе называются числа с плавающей точкой (от англ. floating point). Такое различие связано с тем, что в русскоязычной литературе принято отделять дробную часть числа запятой, а в европейской и американской - точкой.&lt;/p&gt;
  &lt;p id=&quot;hxzy&quot;&gt;Хранение чисел с плавающей запятой работает по стандарту IEEE 754 (1985 г). Для работы с числами с плавающей запятой на аппаратурном уровне к обычному процессору добавляют математический сопроцессор (FPU, floating point unit).&lt;/p&gt;
  &lt;figure id=&quot;Tm7o&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c3/71/c3712d54-cec4-4fc1-84b3-eed029f673dd.png&quot; width=&quot;1846&quot; /&gt;
    &lt;figcaption&gt;Типы с плавающей запятой&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;OXiJ&quot;&gt;Рисунок демонстрирует, как распределяются биты в числах с плавающей запятой разных разрядностей, где &lt;/p&gt;
  &lt;ul id=&quot;f2Lq&quot;&gt;
    &lt;li id=&quot;lPX4&quot;&gt;S - Sign (знак);&lt;/li&gt;
    &lt;li id=&quot;YHBX&quot;&gt;E - Exponent (8(11) разрядов поля порядка, экспонента);&lt;/li&gt;
    &lt;li id=&quot;nJw9&quot;&gt;M - Mantissa (23(52) бита мантиссы, дробная часть числа).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;gPzp&quot;&gt;Также на рисунке показана так называемая, мнимая единица, она всегда есть в самом старшем разряде мантиссы, поэтому её всегда подразумевают, но в явном виде не хранят, экономя один бит информации.&lt;/p&gt;
  &lt;p id=&quot;u40P&quot;&gt;Если попытаться уложить весь стандарт в два предложения, то получится примерно следующее: получить число в соответствующих разрядностях возможно по формулам:&lt;/p&gt;
  &lt;figure id=&quot;ECWR&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/82/08/8208a763-b7f5-4d22-874f-49e8c3ce609e.png&quot; width=&quot;788&quot; /&gt;
    &lt;figcaption&gt;Формулы расчёта значения числа с плавающей запятой&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;gwMD&quot;&gt;Например: +0,5 = 2 в -1й степени поэтому, число будет записано как&lt;/p&gt;
  &lt;pre id=&quot;PWhm&quot;&gt;  0_01111110_00000000000000000000000,&lt;/pre&gt;
  &lt;p id=&quot;Y2ci&quot;&gt; то есть знак равен 0, мантисса равна 0, порядок равен 127 - 1 = 126, чтобы получить следующие результаты вычислений:&lt;/p&gt;
  &lt;ul id=&quot;5Vng&quot;&gt;
    &lt;li id=&quot;98za&quot;&gt;-1 в нулевой степени - положительный знак;&lt;/li&gt;
    &lt;li id=&quot;4RVX&quot;&gt; умножить на порядок 2 в степени 126-127, то есть в -1й = 0,5;&lt;/li&gt;
    &lt;li id=&quot;KnZ5&quot;&gt;и умножить на мантиссу 1 + 0. &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;pPGZ&quot;&gt;То есть, &lt;code&gt;1 * 0,5 * (1 + 0) = 0,5.&lt;/code&gt; Отсюда становится очевидно, что чем сложнее мантисса и чем меньше порядок, тем более точные и интересные числа мы можем получить.&lt;/p&gt;
  &lt;h2 id=&quot;1REf&quot;&gt;А запятая-то куда поплыла?&lt;/h2&gt;
  &lt;p id=&quot;Bmpu&quot;&gt;Возьмём для примера число &lt;code&gt;-0,15625&lt;/code&gt;, чтобы понять как его записывать, откинем знак, это будет единица в разряде, отвечающем за знак, и посчитаем мантиссу с порядком. Представим число как положительное и будем от него последовательно отнимать числа, являющиеся отрицательными степенями двойки, чтобы получить максимально близкое к нулю значение.&lt;/p&gt;
  &lt;figure id=&quot;QZ8E&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/23/25/2325f920-3050-4c37-937a-6c9b01327f71.png&quot; width=&quot;200&quot; /&gt;
    &lt;figcaption&gt;Значения степеней двойки&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6LKl&quot;&gt;Очевидно, что -1 и -2 степени отнять не получится, поскольку мы явно уходим за границу нуля, а вот -3 прекрасно отнимается, значит порядок будет 127 - 3 = 124, осталось понять, что получится в мантиссе. Видим, что оставшееся после первого вычитания (0,15625 - 0,125) число - это 2 в -5й степени. Значит в мантиссе пишем &lt;code&gt;01&lt;/code&gt; и остальные нули, то есть слева направо указываем, какие степени после -3 будут нужны, а именно, -4 не нужна, ставим 0, а -5 нужна, ставим 1. Довольно очевидно, что при подсчёте других чисел нам так не повезёт, поэтому точность представления может страдать, мы будем отнимать степени двойки пока не получим 0 или пока не закончится мантисса. &lt;/p&gt;
  &lt;blockquote id=&quot;LZbX&quot;&gt;Отсюда и &amp;quot;уплывание&amp;quot; точности, отсюда же и разделение на float/double, чем больше битов есть для хранения значения, тем более высокую точность можно записать.&lt;/blockquote&gt;
  &lt;p id=&quot;JOAp&quot;&gt;Для полноты картины, приведу пару математических выкладок, по только что описанному алгоритму&lt;/p&gt;
  &lt;figure id=&quot;8wPY&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/81/69/81698731-5e9d-4905-a51b-656e37f566bf.png&quot; width=&quot;1474&quot; /&gt;
    &lt;figcaption&gt;Алгоритм вычисления значений с плавающей запятой&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Mh4p&quot;&gt;и по формуле, представленной в самом начале&lt;/p&gt;
  &lt;figure id=&quot;Z0Yj&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/72/43/72432af5-1c1c-4425-9ad6-518dbd230d9a.png&quot; width=&quot;1028&quot; /&gt;
    &lt;figcaption&gt;Формула вычисления значения с плавающей запятой&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;XZoO&quot;&gt;чтобы можно было самостоятельно посчитать на калькуляторе и убедиться в тождественности выражений. Так, число с плавающей запятой возможно посчитать двумя способами: по приведённой формуле, или последовательно складывая разряды мантиссы умноженные на двойку в степени порядка, уменьшая порядок на каждом шагу.&lt;/p&gt;
  &lt;h2 id=&quot;6AyU&quot;&gt;Может, есть какие-то особенности?&lt;/h2&gt;
  &lt;p id=&quot;ZnKx&quot;&gt;Конечно, куда же без них. Посмотрим на диапазон возможных значений чисел с плавающей запятой и отметим некоторые особенности:&lt;/p&gt;
  &lt;figure id=&quot;awd8&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bd/4e/bd4e932e-0ae4-4dd2-b744-4a9e17fb5413.png&quot; width=&quot;1738&quot; /&gt;
    &lt;figcaption&gt;Значения чисел с плавающей запятой&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;vD8q&quot;&gt;
    &lt;li id=&quot;w6SU&quot;&gt;возможен как положительный, так и отрицательный ноль (в целых числах ноль всегда положительный);&lt;/li&gt;
    &lt;li id=&quot;ocbB&quot;&gt;есть огромная зона, отмеченная на рисунке, которая являет собой непредставимые числа, слишком большие для хранения внутри такой переменной или настолько маленькие, что мнимая единица в мантиссе отсутствует;&lt;/li&gt;
    &lt;li id=&quot;ESJU&quot;&gt;в таком числе можно хранить значения положительной и отрицательной бесконечности;&lt;/li&gt;
    &lt;li id=&quot;ycIp&quot;&gt;при работе с такими числами появляется понятие не-числа, при этом важно помнить, что &lt;code&gt;NaN&lt;/code&gt; не равен &lt;code&gt;NaN&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>customgeekmaterials:4ODwFGBKtR7</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/4ODwFGBKtR7?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>LaTeX: базовое форматирование</title><published>2022-04-13T06:26:22.907Z</published><updated>2022-09-14T07:08:52.378Z</updated><summary type="html">LaTeX используется во всем мире для научных публикаций, документации, книг и во многих других формах публикации. Он не только позволяет создавать корректно оформленные документы, но и позволяет пользователям быстро справляться с сложными аспектами вёрстки текста, такими как ввод математических данных, создание оглавлений, ссылок и библиографий, а также согласованная компоновка текста во всех разделах документа. Благодаря огромному количеству доступных пакетов с открытым исходным кодом (подробнее об этом позже) возможности LaTeX почти безграничны. Эти пакеты позволяют пользователям значительно расширить возможности LaTeX, например создавать сноски, рисовать схемы и диаграммы, создавать таблицы. Также возможно создавать презентации...</summary><content type="html">
  &lt;p id=&quot;lbhD&quot;&gt;LaTeX используется во всем мире для научных публикаций, документации, книг и во многих других формах публикации. Он не только позволяет создавать корректно оформленные документы, но и позволяет пользователям быстро справляться с сложными аспектами вёрстки текста, такими как ввод математических данных, создание оглавлений, ссылок и библиографий, а также согласованная компоновка текста во всех разделах документа. Благодаря огромному количеству доступных пакетов с открытым исходным кодом (подробнее об этом позже) возможности LaTeX почти безграничны. Эти пакеты позволяют пользователям значительно расширить возможности LaTeX, например создавать сноски, рисовать схемы и диаграммы, создавать таблицы. Также возможно создавать презентации и подключать модули для работы с таблицами, например язык анализа данных R.&lt;/p&gt;
  &lt;p id=&quot;P10v&quot;&gt;Одна из наиболее важных причин по которым люди используют LaTeX, заключается в том, что он отделяет содержимое от стиля. Это означает, что как только вы напишите свой документ, мы с легкостью сможем изменить его внешний вид. Аналогичным образом, вы можете создать один стиль документа который можно использовать для стандартизации внешнего вида множества различных документов.&lt;/p&gt;
  &lt;p id=&quot;RyEQ&quot;&gt;Первый шаг - создать новый проект LaTeX. Вы можете сделать это на своем компьютере, создав новый файл &lt;strong&gt;.tex&lt;/strong&gt;, или же вы можете начать новый проект в Overleaf (онлайн редактор LaTeX документов. Автор предлагает в первую очередь освоить и использовать именно его). &lt;/p&gt;
  &lt;pre id=&quot;hXGe&quot;&gt;\documentclass{article}

\begin{document}
First document. This is a simple example, with no 
extra parameters or packages included.
\end{document}&lt;/pre&gt;
  &lt;p id=&quot;AAg8&quot;&gt;В первой строке кода объявляется тип документа, известный как класс. Класс управляет внешним видом документа. Для разных типов документов потребуются разные классы, т.е. для резюме  потребуется не такой класс, как для научной статьи. В данном случае классом является article, статья, самый простой и распространенный класс LaTeX. Принципиальной разницы между простыми текстовыми классами нет, в отчёте добавляется ещё одна ступень иерархии заголовков относительно статьи - часть, а в книге ещё одна ступень относительно отчёта - глава. Соответственно этому незначительно меняются стандартные отступы и колонтитулы, которые в документах, создаваемых не в учебных целях всё равно изменяются на собственные. Принципиально отличается только класс Beamer, позволяющий создавать презентации.&lt;/p&gt;
  &lt;h2 id=&quot;vIyZ&quot;&gt;Преамбула документа&lt;/h2&gt;
  &lt;p id=&quot;wK3I&quot;&gt;В предыдущем примере текст был введен после команды &lt;code&gt;\begin{document}&lt;/code&gt;. Все, что находится в файле &lt;strong&gt;.tex&lt;/strong&gt; до этого момента, называется преамбулой. В преамбуле определяется тип документа, язык, пакеты (подробнее об этом позже), и несколько других элементов. Например, обычная преамбула простого документа будет выглядеть следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;3fSH&quot;&gt;\documentclass[12pt, a4paper]{article}
\usepackage{cmap}
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}&lt;/pre&gt;
  &lt;p id=&quot;AA9K&quot;&gt;Или, как мы выяснили в прошлый раз, при использовании более современного компилятора&lt;/p&gt;
  &lt;pre id=&quot;RUJ3&quot;&gt;\documentclass[12pt, a4paper]{article}
\usepackage[russian]{babel}
\babelfont{rm}{PT Astra Serif}
\babelfont{sf}{PT Astra Serif}
\babelfont{tt}{Courier}&lt;/pre&gt;
  &lt;h2 id=&quot;JyvG&quot;&gt;Полужирный, курсив и подчеркивание&lt;/h2&gt;
  &lt;p id=&quot;5A0X&quot;&gt;Очень часто в тексте документа нужно выполнить выделение полужирным, курсивом или подчёркиванием. Эти частые операции осуществляются написанием выделяемой части текста в соответствующем тэге:&lt;/p&gt;
  &lt;ul id=&quot;7O9U&quot;&gt;
    &lt;li id=&quot;gpKo&quot;&gt;Жирный шрифт: &lt;code&gt;\textbf{...}&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;gHM3&quot;&gt;Курсив: &lt;code&gt;\textit{...}&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;cHJX&quot;&gt;Подчеркивание: &lt;code&gt;\underline{...}&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;43dW&quot;&gt;Добавление изображений&lt;/h2&gt;
  &lt;p id=&quot;BrwK&quot;&gt;Теперь рассмотрим, как добавлять изображения в документ LaTeX. Ниже приведен пример того, как включить изображение.&lt;/p&gt;
  &lt;pre id=&quot;GutA&quot;&gt;\documentclass{article}
\usepackage{graphicx}
\graphicspath{ {images/} }

\begin{document}
The universe is immense and it seems to be homogeneous, in a large scale, everywhere we look at.

\includegraphics{universe}
There&amp;#x27;s a picture of a galaxy above&lt;/pre&gt;
  &lt;p id=&quot;sgtw&quot;&gt;LaTeX не может работать с изображениями сам по себе, поэтому вам нужно будет использовать &lt;em&gt;пакет&lt;/em&gt;. Помните, мы упоминали пакеты выше, и даже использовали несколько для написания текста кириллицей?&lt;br /&gt;Если взглянуть в мир LaTeX чуть глубже, для пакетов есть онлайн архив CTAN, у каждого пакета есть очень подробная документация, а для пакетов, создающих, например, ГОСТ стили ещё и на русском.&lt;br /&gt;Пакеты можно использовать для изменения внешнего вида вашего документа по умолчанию или для расширения функциональных возможностей. В данном конкретном случае необходимо включить изображение в документ, поэтому следует использовать пакет &lt;strong&gt;graphicx&lt;/strong&gt;. Этот пакет предоставляет команды &lt;code&gt;\includegraphics{...}&lt;/code&gt; и &lt;code&gt;\graphicspath{...}&lt;/code&gt;. Чтобы использовать пакет, необходимо включить в преамбулу строку &lt;code&gt;\usepackage{graphicx}&lt;/code&gt;.&lt;/p&gt;
  &lt;ul id=&quot;h3Bl&quot;&gt;
    &lt;li id=&quot;9GKE&quot;&gt;Команда &lt;code&gt;\graphicspath{ {images/} }&lt;/code&gt; сообщает LaTeX, что изображения хранятся в папке с именем &lt;code&gt;images&lt;/code&gt; в текущем каталоге (относительно файла &lt;strong&gt;.tex&lt;/strong&gt;, в котором ведётся работа).&lt;/li&gt;
    &lt;li id=&quot;Y02G&quot;&gt;Команда &lt;code&gt;\includegraphics{universe}&lt;/code&gt; - включает изображение в документ. Здесь universe - это имя файла, содержащего изображение без расширения, поэтому &lt;strong&gt;universe.png&lt;/strong&gt; становится &lt;code&gt;universe&lt;/code&gt;. Имя файла изображения не должно содержать пробелов или нескольких точек.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;RwFc&quot;&gt;Примечание: Если расширение файла опущено, LaTeX попробует выполнить поиск по всем поддерживаемым форматам. Также обычно рекомендуется использовать строчные буквы для расширения файла при загрузке файлов изображений. &lt;/p&gt;
  &lt;h2 id=&quot;sZMA&quot;&gt;Подписи, ярлыки и ссылки&lt;/h2&gt;
  &lt;p id=&quot;TDA2&quot;&gt;Изображения могут быть подписаны, помечены и снабжены ссылками с функцией &lt;code&gt;figure&lt;/code&gt;, как показано ниже:&lt;/p&gt;
  &lt;pre id=&quot;H1RD&quot;&gt;\begin{figure}[h]
    \centering
    \includegraphics[width=0.25\textwidth]{mesh}
    \caption{a nice plot}
    \label{fig:mesh1}
\end{figure}

As you can see in the figure \ref{fig:mesh1}, the
function grows near 0. Also, in the page \pageref{fig:mesh1}
is the same example.&lt;/pre&gt;
  &lt;p id=&quot;n5hz&quot;&gt;В примере приведенном выше есть три важные команды:&lt;/p&gt;
  &lt;pre id=&quot;UpkJ&quot;&gt;\caption{a nice plot}
\label{fig:mesh1}
\ref{fig:mesh1}&lt;/pre&gt;
  &lt;p id=&quot;eIuy&quot;&gt;При размещении изображений в документе LaTeX рекомендуется помещать их в среду &lt;code&gt;figure&lt;/code&gt; или аналогичную среду, чтобы LaTeX расположил изображение таким образом, чтобы оно соответствовало остальной части вашего текста. Среды выступают как полноценные и самостоятельные единицы. Сами эти окружения часто располагаются по правилам, а внутри них действуют собственные правила размещения. Например, оператор &lt;code&gt;centering&lt;/code&gt; в &lt;code&gt;figure&lt;/code&gt; отцентрирует его содержимое, а сама &lt;code&gt;figure&lt;/code&gt; будет стремиться расположиться на одной странице, то есть является неразрывной. Так в &lt;code&gt;figure&lt;/code&gt; нельзя помещать длинные таблицы, потому что LaTeX не сможет вставить в длинную таблицу разрыв страницы и мы просто-напросто не увидим то, что выходит за пределы листа А4.&lt;/p&gt;
  &lt;h2 id=&quot;IuZ9&quot;&gt;Создание списков в LaTeX&lt;/h2&gt;
  &lt;p id=&quot;SZih&quot;&gt;Создавать списки в LaTeX очень просто. Вы можете создавать списки, используя различные среды списков. Ещё раз: среды - это разделы нашего документа, которые вы хотите представить иначе, чем остальную часть документа. Они начинаются с &lt;code&gt;\begin{...}&lt;/code&gt; и заканчиваются на &lt;code&gt;\end{...}&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;pbs2&quot;&gt;Существует два основных типа списков: упорядоченные списки и неупорядоченные списки. Каждый из них будет использовать разную среду.&lt;/p&gt;
  &lt;h3 id=&quot;ukfR&quot;&gt;Неупорядоченные списки&lt;/h3&gt;
  &lt;p id=&quot;gNBW&quot;&gt;Неупорядоченные списки создаются средой &lt;code&gt;itemize&lt;/code&gt;. Каждой записи должна предшествовать управляющая последовательность &lt;code&gt;\item&lt;/code&gt;, как показано ниже.&lt;/p&gt;
  &lt;pre id=&quot;bGkb&quot;&gt;\begin{itemize}
\item The individual entries are indicated with a black dot, a so-called bullet.
\item The text in the entries may be of any length.
\end{itemize}&lt;/pre&gt;
  &lt;p id=&quot;PqBf&quot;&gt;По-умолчанию отдельные записи обозначаются черной точкой, так называемой маркировкой. Текст в записях может быть любой длины. Чтобы изменить маркер списка необходимо в преамбуле документа обновить значение для команды &lt;code&gt;\item&lt;/code&gt;. В примере ниже используется длинное тире, шириной в одну букву M используемого вами шрифта.&lt;/p&gt;
  &lt;pre id=&quot;uCfT&quot;&gt;\renewcommand\labelitemi{\emdash}&lt;/pre&gt;
  &lt;h3 id=&quot;ntdF&quot;&gt;Упорядоченные списки&lt;/h3&gt;
  &lt;p id=&quot;IngK&quot;&gt;Упорядоченный список имеет тот же синтаксис в другой среде. Мы создаем упорядоченные списки, используя среду &lt;code&gt;enumerate&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;rm4s&quot;&gt;\begin{enumerate}
\item This is the first entry in our list
\item The list numbers increase with each entry we add
\end{enumerate}&lt;/pre&gt;
  &lt;p id=&quot;p5Vx&quot;&gt;Как и в случае с неупорядоченными списками, каждой записи должна предшествовать управляющая последовательность &lt;code&gt;\item&lt;/code&gt;, которая автоматически сгенерирует номер, обозначающий элемент. Из-за такой автоматизации удобно перемещать элементы списка между собой, не заботясь о нумерации. Перечисляемые метки состоят из последовательных номеров, начинающихся с единицы. Это поведение также возможно изменить, добавив соответствующую строку в преамбуле, но для примера, изменим перечисляемые метки для одного списка:&lt;/p&gt;
  &lt;pre id=&quot;x7tI&quot;&gt;\begin{enumerate}[label=\asbuk*),ref=\asbuk*]&lt;/pre&gt;
  &lt;p id=&quot;Wt4H&quot;&gt;Такой набор опций создаст список из меток &lt;code&gt;а) б) в) ...&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;INpc&quot;&gt;Вместо выводов&lt;/h2&gt;
  &lt;p id=&quot;xhb7&quot;&gt;В этой статье я постарался описать самые часто используемые инструменты базового редактирования текста. Для оформления подавляющего большинства текстов этого будет достаточно. Осталось описать таблицы, псевдографику, множественные источники данных и автоматизации, но часто это причисляют к нетривиальным механизмам, поэтому пока возьмём небольшую паузу. Думаю, важно будет сказать, что использование LaTeX - это дело привычки. Например, однажды сформировав преамбулу для своих документов (например, по внутреннему, корпоративному стандарту) перестаёшь думать о стилях и вёрстке, а думаешь уже только о содержательной составляющей. &lt;/p&gt;

</content></entry><entry><id>customgeekmaterials:latex-motivation</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/latex-motivation?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>LaTeX: мотивация.</title><published>2022-03-14T11:07:45.898Z</published><updated>2022-09-14T07:01:20.816Z</updated><summary type="html">&quot;Даже путь в тысячу ли начинается с первого шага.&quot; — Лао-цзы. Глава 64, строка 12 книги Дао дэ цзин</summary><content type="html">
  &lt;p id=&quot;qM2c&quot;&gt;&lt;strong&gt;&amp;quot;Даже путь в тысячу ли начинается с первого шага.&amp;quot;&lt;/strong&gt; — Лао-цзы. Глава 64, строка 12 книги Дао дэ цзин&lt;/p&gt;
  &lt;h2 id=&quot;THuV&quot;&gt;TL;DR.&lt;/h2&gt;
  &lt;p id=&quot;psJ1&quot;&gt;Устав от необходимости вникать в тонкости вёрстки документов, автор открыл для себя и хочет открыть для других дивный новый мир компьютерной вёрстки документов.&lt;/p&gt;
  &lt;h2 id=&quot;b0vA&quot;&gt;Проблемы&lt;/h2&gt;
  &lt;p id=&quot;w9QM&quot;&gt;Рано или поздно каждый сталкивается с необходимостью создать текстовый документ, который должен отвечать некоторым требованиям форматирования и/или мультимедийности. У многих людей с созданием таких документов связана значительная часть работы, а для некоторых - это основная деятельность. Я, как и многие другие люди, не задумывался об используемом инструментарии и &amp;quot;как и все&amp;quot; просто открывал первый попавшийся MS Word, MS WordPad, Apple Pages, LibreOffice Writer (давайте я дальше буду их для краткости называть &amp;quot;офисом&amp;quot;), писал то, что мне было нужно, закрывал и забывал. &lt;/p&gt;
  &lt;p id=&quot;fVL7&quot;&gt;Всё было хорошо, пока я не обнаружил себя копирующим-вставляющим очередные пять страниц текста в новый файл, чтобы изменить в нём пару-тройку десятков слов. Это привело меня к первой, главной для ленивого человека, проблеме: автоматизация рутинных операций, обозначим её как &amp;quot;проблему номер один&amp;quot;.&lt;/p&gt;
  &lt;p id=&quot;HtK4&quot;&gt;Смена деятельности на основной работе (необходимость создавать ещё больше документации) показала пример нерадивости некоторых коллег: отправив очередной большой документ, страниц на 400-500, на доработку в ответ я получил этот же самый документ с обновлённой меткой &amp;quot;последних изменений&amp;quot;. То есть, чтобы понять, что именно изменилось (или не изменилось), мне пришлось заново вычитывать несколько сотен страниц. Это позволило сформулировать проблему ленивого человека, которую мы можем назвать &amp;quot;проблема номер два&amp;quot;: из рук вон плохие или полностью отсутствующие версионирование и контроль контента.&lt;/p&gt;
  &lt;p id=&quot;UPau&quot;&gt;В процессе работы, документ-с-комментариями (тот самый, из предыдущего пункта) разросся до полутора тысяч страниц, а работать над ним начали несколько человек, что помогло сформулировать ещё две проблемы, соответственно, &amp;quot;номер три&amp;quot; и &amp;quot;номер четыре&amp;quot;: отсутствие возможности совместной (командной) разработки, чрезвычайно долгое или вовсе невозможное открытие и редактирование больших документов, особенно на &amp;quot;слабых&amp;quot; компьютерах.&lt;/p&gt;
  &lt;p id=&quot;zbTm&quot;&gt;Как постскриптум к подразделу &amp;quot;проблем&amp;quot; хочу напомнить о боли, которую испытывали, кажется, все пользователи офиса - попытки переместить вставленное изображение куда-то выше или ниже по тексту мышкой. Передаю привет поехавшим абзацам, картинке, уходящей за пределы страницы и многочасовым попыткам сверстать документ &amp;quot;как задумано&amp;quot;.&lt;/p&gt;
  &lt;h2 id=&quot;eVOU&quot;&gt;Поиски решения&lt;/h2&gt;
  &lt;p id=&quot;tYTh&quot;&gt;Быстрый поиск решений первой проблемы, той, которая про автоматизацию, не увенчался успехом. Были созданы некоторые &amp;quot;эталонные шаблоны&amp;quot;, которые открывались, редактировались, &amp;quot;сохранялись как&amp;quot; в новый файл, иногда просто сохранялись и найти человека, который не сохранил себе копию, а вписал данные в шаблон, было невозможно. В общем, автоматизация рутины средствами существующих программ провалилась.&lt;/p&gt;
  &lt;p id=&quot;Zyln&quot;&gt;Быстрый поиск решения проблемы контроля контента не решился, хотя в новых версиях офисных пакетов, кажется, появился функционал версионирования, но работает он не слишком очевидно, и требует включения в каждом конкретном документе. Но поиск привёл к необходимости оставлять комментарии по тексту, и это даже показалось сравнительно удобным, хотя, как оказалось, не все умеют включать отображение комментариев и использовать их по назначению. &lt;/p&gt;
  &lt;p id=&quot;dAEo&quot;&gt;Решить проблему командной работы не удалось вовсе. Даже гуру офисной работы, создавая документ признают, что просто копипастят фрагменты документа в один, и тратят несколько часов на увлекательное приведение к единому формату, например, по ГОСТ. &lt;/p&gt;
  &lt;p id=&quot;IU6X&quot;&gt;К слову о попытках решения обозначенных четырёх проблем нельзя не упомянуть современные легковесные форматы текста, вроде Markdown, которые позволяют с минимальными усилиями создавать аккуратные одинаково выглядящие документы, заметки, инструкции и описания. И, кажется, &lt;code&gt;.md&lt;/code&gt; всем хорош, но только лишь для &amp;quot;внутреннего использования&amp;quot;, то есть, в нём довольно затруднительно сменить шрифт, создать, например, оглавление, создать документ, разбитый на  страницы, изменить колонтитулы, отступы, пронумеровать заголовки, и многое другое.&lt;/p&gt;
  &lt;h2 id=&quot;y9Y2&quot;&gt;Возможное решение&lt;/h2&gt;
  &lt;p id=&quot;g3Cf&quot;&gt;Устав от попыток решить эти скучные проблемы я решил подумать головой. Этот непривычный процесс привёл к поразительному результату: мои проблемы возникали в разное время не у меня одного, и люди уже давно придумали решение. Конечно, решение не без оговорок, именно поэтому я озаглавил его как возможное. Системы компьютерной вёрстки. &lt;/p&gt;
  &lt;blockquote id=&quot;twTV&quot;&gt;Согласно википедии, &lt;strong&gt;LaTeX&lt;/strong&gt; — наиболее популярный набор расширений системы компьютерной &lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%92%D1%91%D1%80%D1%81%D1%82%D0%BA%D0%B0&quot; target=&quot;_blank&quot;&gt;вёрстки&lt;/a&gt; &lt;a href=&quot;https://ru.wikipedia.org/wiki/TeX&quot; target=&quot;_blank&quot;&gt;TeX&lt;/a&gt;, который облегчает набор сложных документов. Важно заметить, что ни один из макропакетов для TeX’а не может расширить возможностей TeX (всё, что можно сделать в LaTeX’е, можно сделать и в TeX’е без расширений), но, благодаря различным упрощениям, использование макропакетов зачастую позволяет избежать весьма изощрённого программирования. Пакет позволяет автоматизировать многие задачи набора текста и подготовки статей, включая набор текста на нескольких языках, нумерацию разделов и формул, перекрёстные ссылки, размещение иллюстраций и таблиц на странице, ведение библиографии и др. Кроме базового набора существует множество пакетов расширения LaTeX. Общий внешний вид документа в LaTeX определяется &lt;em&gt;стилевым файлом&lt;/em&gt;. Существует несколько стандартных стилевых файлов для статей, книг, писем и т. д., кроме того, многие издательства и журналы предоставляют свои собственные стилевые файлы, что позволяет быстро оформить публикацию, соответствующую стандартам издания.&lt;/blockquote&gt;
  &lt;p id=&quot;gnk3&quot;&gt;Выражаясь проще, это некоторый набор специальных команд, написанных прямо посреди обычного текста (того, который можно написать прямо в блокноте и сохранить с расширением &lt;code&gt;.txt&lt;/code&gt;) и, не особо думая о вёрстке, получить в результате ровный, опрятный, строго шаблонизированный документ. &lt;/p&gt;
  &lt;p id=&quot;ozeE&quot;&gt;В процессе работы с LaTeX нам всё равно придётся ввести понятие компиляции, поэтому предлагаю не откладывать в долгий ящик. &lt;strong&gt;Компиляция &lt;/strong&gt;- это создание некоторого &amp;quot;фиксированного образа&amp;quot; (запускаемый файл программы для программирования, готовый документ для LaTeX, набор песен на компакт-диске), доступного только для чтения, из некоторого &amp;quot;исходного текста&amp;quot;. То есть, это подход, отличающийся от привычного в офисе - писать прямо в документе, который потом и отправится на печать. LaTeX компилирует документы по строго определённым правилам, что порождает как плюсы, так и минусы. Самый большой плюс в том, что нам (почти) не нужно думать о вёрстке (отступах, размерах, стилях, шрифтах), а самый большой минус в том, что мы не видим результат нашей работы сию секунду, поскольку то, что мы пишем - не скомпилировано.&lt;/p&gt;
  &lt;p id=&quot;wF7d&quot;&gt;Поскольку это работа с простым текстом (а не с хорошо завуалированным архивом и xml документом, как это происходит в случае с офисом), то сразу отпадает проблема версионирования, ведь любой простой текст можно отслеживать в git. Проблема открытия гигантских документов тоже отходит на второй план, прямо сейчас я пишу эту заметку в текстовом файле, который использую как личный цифровой блокнот, который насчитывает более двадцати тысяч строк текста. Как решать первую и третью проблемы (автоматизация и командная работа) попробуем поговорить в следующей статье, поскольку это выходит за пределы рассуждений о мотивации.&lt;/p&gt;
  &lt;h2 id=&quot;FdvC&quot;&gt;Первый документ&lt;/h2&gt;
  &lt;p id=&quot;7cVo&quot;&gt;Как и везде, в изучении нового инструмента есть два пути, сложный и простой. Мы, для начала, пойдём простым. Только лишь потому, что в LaTeX и без того достаточно много вещей, которые могут отпугнуть простого пользователя, не будем добавлять к ним ещё и вопросы настроек инструментария. Спасибо создателям сервиса &lt;a href=&quot;https://www.overleaf.com/&quot; target=&quot;_blank&quot;&gt;https://www.overleaf.com/&lt;/a&gt; за их труд, они действительно, как это заявлено на стартовой странице, LaTeX,Evolved: The easy to use, online, collaborative LaTeX editor. То есть, улучшили процесс редактирования LaTeX документов настолько, насколько это вообще было возможно. Пройдя несложную регистрацию, мы видим (пока что) пустой список наших проектов. Создадим новый проект и Overleaf создаст для нас шаблон пустого документа, в котором будут прописаны минималистичные настройки. То есть, документ уже как-то выглядит и если к нему не предъявляются дополнительные требования, может быть отредактирован и отправлен куда нужно, для этого мы нажимаем кнопку &amp;quot;Download PDF&amp;quot; и наслаждаемся полученным документом.&lt;/p&gt;
  &lt;p id=&quot;Z4L2&quot;&gt;Но внимательный читатель (привет тебе, зануда, на таких как ты держится земля), который сразу пошёл проверять, так ли это, заметил проблему. Не отображается кириллица. Всё в документе есть, а кириллических символов нет. Раз и навсегда решим эту проблему в два шага: &lt;br /&gt;1. &lt;code&gt;Menu &lt;/code&gt;- &lt;code&gt;Settings &lt;/code&gt;- &lt;code&gt;Compiler &lt;/code&gt;- &lt;code&gt;XeLaTeX&lt;/code&gt;;&lt;br /&gt;2. вторую строку &lt;code&gt;\usepackage[utf8]{inputenc}&lt;/code&gt; нужно стереть и заменить на четыре:&lt;/p&gt;
  &lt;pre id=&quot;2wuf&quot;&gt;\usepackage[russian]{babel}
\babelfont{rm}{PT Astra Serif}
\babelfont{sf}{PT Astra Serif}
\babelfont{tt}{Courier}&lt;/pre&gt;
  &lt;p id=&quot;B0oG&quot;&gt;где вместо &lt;code&gt;PT Astra Serif&lt;/code&gt; и &lt;code&gt;Courier&lt;/code&gt; нужно вставить названия любых шрифтов, которые Вы считаете хорошими. Мелким шрифтом, стоит оговорить, что всеми любимый &lt;code&gt;Times New Roman&lt;/code&gt; является запрещённым на территории России шрифтом, а &lt;code&gt;Astra Serif&lt;/code&gt; является его легальным бесплатным аналогом. Но, если очень сильно хочется именно его, то можно решить проблему (в том числе) так:&lt;/p&gt;
  &lt;pre id=&quot;m4OR&quot;&gt;\usepackage{fontspec} 
\setmainfont{Times New Roman}&lt;/pre&gt;
  &lt;p id=&quot;4FCW&quot;&gt;Эти строки заменяют те сложные четыре из второго пункта. Решать задачи можно по-разному, и это прекрасно. &lt;/p&gt;
  &lt;h2 id=&quot;1cXi&quot;&gt;Что дальше?&lt;/h2&gt;
  &lt;p id=&quot;Izgv&quot;&gt;Простейший документ получен. Неплохой результат. Кстати, внимательный читатель мог заметить, что мы использовали некоторую &amp;quot;управляющую&amp;quot; конструкцию &lt;code&gt;\usepackage&lt;/code&gt;, которая добавила нашему документу функциональности, например, возможность менять шрифт со стандартного. Именно такие управляющие конструкции будут нашими лучшими друзьями при дальнейшем, в том числе сложном, редактировании документов.&lt;/p&gt;

</content></entry><entry><id>customgeekmaterials:basic-principles</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/basic-principles?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>Базовые принципы</title><published>2021-01-03T19:26:26.493Z</published><updated>2021-01-03T19:26:26.493Z</updated><summary type="html">Собеседования. Все мы, так или иначе, рано или поздно их проходим. Сегодня я хочу поговорить о часто задаваемых вопросах на собеседованиях. И технических мы коснёмся только в самом конце нашей беседы. Я убеждён, что все принципы, описанные для использования в сфере информационных технологиях подходят и для обычной, повседневной, жизни. Я буду называть принципы и примеры, а додумать применимость в жизни я оставлю читателю. </summary><content type="html">
  &lt;h2&gt;(в основном, программирования)&lt;/h2&gt;
  &lt;p&gt;Собеседования. Все мы, так или иначе, рано или поздно их проходим. Сегодня я хочу поговорить о часто задаваемых вопросах на собеседованиях. И технических мы коснёмся только в самом конце нашей беседы. Я убеждён, что все принципы, описанные для использования в сфере информационных технологиях подходят и для обычной, повседневной, жизни. Я буду называть принципы и примеры, а додумать применимость в жизни я оставлю читателю. &lt;/p&gt;
  &lt;h3&gt;DRY&lt;/h3&gt;
  &lt;p&gt;&lt;em&gt;Don&amp;#x27;t repeat yourself&lt;/em&gt;. Акроним dry (англ. сухой, чистый). &lt;strong&gt;Не повторяйся&lt;/strong&gt;. Любой код, который программист вынужден повторять можно убрать в цикл, метод, класс, подпрограмму, модуль, сервис. Если в Вашей программе есть повторяющийся (скопипастченный) код - это не очень хорошая программа, потому что если и когда Вам нужно будет её исправлять - Вы потратите вагон времени только на поиск всех мест, содержащих  нужную копипасту. Программы и компьютеры, их же придумали как раз для того, чтобы не нужно было самому выполнять повторяющиеся действия. Поэтому, не повторяй себя. Двигайтесь вперёд. Антагонист этого принципа - &lt;strong&gt;WET&lt;/strong&gt;. &lt;em&gt;Write everything twice&lt;/em&gt;. Акроним wet (англ. влажный). &lt;strong&gt;Пиши всё дважды&lt;/strong&gt;. Экономьте собственное время, не пишите по два раза.&lt;/p&gt;
  &lt;h3&gt;KISS&lt;/h3&gt;
  &lt;p&gt;Keep it simple, stupid. Сохрани это простым, до глупости. Это не призыв быть глупым, как могло показаться на первый взгляд. Это призыв оставаться понятным и простым в рассуждениях, объяснениях и описании кода. Никто не любит тех, кто умничает по поводу и без него. Если есть возможность решить задачу просто и быстро - нужно воспользоваться ей. Если же совсем никак не получается без сложного и неочевидного решения: обильно прокомментируйте его. Известно, что если вы не можете объяснить своё занятие или свои действия пятилетнему - вы слишком мудрите. Или занимаетесь ерундой, выбирайте сами. Всегда думайте, что ваш код будет читать живой человек, который не может залезть к вам в голову и магически понять &amp;quot;что имел ввиду автор&amp;quot;. Да и старую поговорку &amp;quot;будь проще и люди к тебе потянутся&amp;quot; тоже никто пока что не отменил.       &lt;/p&gt;
  &lt;h3&gt;YAGNI&lt;/h3&gt;
  &lt;p&gt;&lt;em&gt;You ain&amp;#x27;t gonna need it&lt;/em&gt;. &lt;strong&gt;Вам это не понадобится&lt;/strong&gt;. Здесь возможны две трактовки, но обе сводятся к одному: не делай лишнего. Да, всегда нужно думать немного наперёд, бесспорно. Но всегда эта мысль должна опираться на здравый смысл: настанет ли момент когда это может пригодиться. И да, всегда нужно стараться сделать чуть больше и чуть лучше, чем требуется, но нужно думать: не затрачу ли я на это вообще все свои ресурсы без остатка? Поэтому: делайте лучше, делайте больше, делайте наперёд, но только если это для вас ничего не стоит. Иначе, поберегите силы.&lt;/p&gt;
  &lt;h3&gt;SOLID&lt;/h3&gt;
  &lt;p&gt;Ну и немного действительно полезной информации, такое любят спрашивать на джуниорских собеседованиях. Это акроним, &lt;em&gt;solid&lt;/em&gt; - &lt;strong&gt;надёжный, цельный&lt;/strong&gt;. Состоит этот акроним из целых пяти понятий, каждое из которых так или иначе делает ваш код лучше, надёжнее, понятнее. &lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Single responsibility principle&lt;/em&gt; - &lt;strong&gt;принцип единственной ответственности&lt;/strong&gt;, атомарности. Любой объект, будь то класс, экземпляр или функция должны выполнять одно дело, но делать это полностью и хорошо. Если Ваш объект занимается больше, чем одним делом - это плохой объект. Этот принцип можно перефразировать пословицей &amp;quot;за двумя зайцами погонишься - ни одного не поймаешь&amp;quot;. &lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Open/close principle&lt;/em&gt; - &lt;strong&gt;принцип открытости/закрытости&lt;/strong&gt;, описываемые Вами объекты (да, тут про объектно-ориентированное программирование) должны быть открыты для расширения и закрыты для модификации. То есть поведение объекта должно быть максимально инкапсулировано, но чем больше у объекта потенциал к расширению (применению наследования и полиморфизма) тем лучше. Это позволяет, помимо прочего, следовать принципу &lt;strong&gt;DRY&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Liskov substitution principle&lt;/em&gt; - &lt;strong&gt;Принцип подстановки Барбары Лисков&lt;/strong&gt;. Используемые и описываемые вами объекты должны быть заменяемы на свои подтипы без изменения правильности работы. Этот принцип тесно связан с предыдущим и согласно ему котики и пёсики должны уметь делать всё, что умеет делать животное, но не обязательно котик должен уметь делать то, что умеет пёсик. Наследование и полиморфизм.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Interface segregation&lt;/em&gt; - &lt;strong&gt;Принцип разделения интерфейсов&lt;/strong&gt;. Много разных интерфейсов всегда лучше одного общего. Звучит знакомо? Да, конечно, это же &lt;em&gt;Single responsibility&lt;/em&gt;, естественно, это касается и интерфейсов и сложного ООП. В конце концов, Вам жалко что ли насоздавать интерфейсов на каждый чих? Это гораздо более гибко, чем иметь один God-Interface через который будут работать вообще все объекты в программе.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Dependency inversion&lt;/em&gt; - &lt;strong&gt;Инверсия зависимостей&lt;/strong&gt;. Все зависимости должны быть абстрактны. Не стоит вписывать в свою программу зависимость от какого-то конкретного класса, если есть возможность зависеть от интерфейса. Ваш код таким образом становится гораздо более расширяем и его можно гораздо проще переиспользовать в других проектах, поскольку у Вас не будет зависимостей от конкретных классов, и вы не будете связаны наследованием.&lt;/p&gt;
  &lt;p&gt;Описанные принципы, несмотря на свою кажущуюся технологичность, подходят и для жизни: &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;S&lt;/strong&gt; - не пытайтесь делать несколько дел одновременно;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;O&lt;/strong&gt; - постарайтесь сделать так, чтобы не пришлось переделывать;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;L&lt;/strong&gt; - используйте заменяемые объекты (чтобы сидеть, используйте стул, а не шкаф);&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;I&lt;/strong&gt; - лучше использовать несколько простых инструментов, чем сто-в-одном;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;D&lt;/strong&gt; - делайте так, чтобы результатом вашего труда мог воспользоваться кто угодно, а вы не зависели от специфичных решений, больше абстрагируйте.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;И напоследок&lt;/h3&gt;
  &lt;p&gt;Принцип, который чаще всего помогает в работе лично мне, потому я дал себе труд его сформулировать: &lt;em&gt;При работе всегда надо стараться пользоваться не новыми технологиями, а головой.&lt;/em&gt;(с) Иван Овчинников, 2018г. &lt;/p&gt;

</content></entry><entry><id>customgeekmaterials:bit-ops</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/bit-ops?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>Двоичные операции</title><published>2020-12-11T21:07:56.796Z</published><updated>2020-12-13T08:31:25.583Z</updated><summary type="html">&lt;img src=&quot;https://teletype.in/files/98/ce/98ce477b-ee8f-41d4-a9cc-89b608aa1433.png&quot;&gt;В современных реалиях мегамощных компьютеров (давайте я буду называть их исполнителями, потому что имеются ввиду вообще все устройства, способные выполнять программу, а это и компьютеры и ноутбуки и телефоны и прочие содержащие электронную слаботочную начинку утюги) вряд ли кто-то задумывается об оптимизации скорости выполнения программы или экономии занимаемой памяти. Но всё меняется, когда программист впервые принимает сложное решение: запрограммировать микроконтроллер или другой «интернет вещей». Там в вашем распоряжении жалкие пара мегабайт памяти, если очень повезёт, в которые нужно не только как-то впихнуть текст программы и исполняемый бинарный код, но и какие-то промежуточные, пользовательские и другие данные, буферы обмена...</summary><content type="html">
  &lt;p&gt;В современных реалиях мегамощных компьютеров (давайте я буду называть их исполнителями, потому что имеются ввиду вообще все устройства, способные выполнять программу, а это и компьютеры и ноутбуки и телефоны и прочие содержащие электронную слаботочную начинку утюги) вряд ли кто-то задумывается об оптимизации скорости выполнения программы или экономии занимаемой памяти. Но всё меняется, когда программист впервые принимает сложное решение: запрограммировать микроконтроллер или другой «интернет вещей». Там в вашем распоряжении жалкие пара мегабайт памяти, если очень повезёт, в которые нужно не только как-то впихнуть текст программы и исполняемый бинарный код, но и какие-то промежуточные, пользовательские и другие данные, буферы обмена и обработки. Другая ситуация, в которой нужно начинать «думать о занимаемом пространстве» это разработка протоколов передачи данных, чтобы протокол был быстрый, не гонял по сети сумасшедшие килобайты данных и быстро преобразовывался (сериализовался/десериализовался). На помощь приходит натуральная (если можно так выразиться) для информатики система счисления, двоичная. И правда, если нам нужно передать по сети, например, поле для игры в морской бой, размером 10х10, каждая клетка которого может находиться как минимум в трёх состояниях (закрыта, пуста, занята) нам для такой передачи явно будет недостаточно булева типа, но и самый маленький тип в java - &lt;code&gt;byte&lt;/code&gt; с его диапазоном &lt;code&gt;-128...127&lt;/code&gt; будет чрезвычайно избыточен. Если не использовать никаких оптимизаций то одна посылка будет занимать сто байт. Мы же можем придумать такой протокол, который сможет уместить поле 10х10 в 200 бит, то есть в 25 байт. В четыре раза компактнее, а значит и быстрее. Как это сделать?&lt;/p&gt;
  &lt;h2&gt;&lt;strong&gt;Лирическое отступление: &lt;/strong&gt;&lt;/h2&gt;
  &lt;h3&gt;&lt;strong&gt;Системы счисления&lt;/strong&gt;&lt;/h3&gt;
  &lt;p&gt;Числа не существуют сами по себе, они связаны определёнными в математической науке законами и полностью подчиняются ей. Программирование, как один из аспектов жизни тоже полностью подчинено математике (называется сложным словосочетанием «математическая доказательность»), но не такой математике, которой пугают людей, а базовой, на уровне «прочитать число», «записать число», произвести сложение, вычитание, умножение. Запись чисел осуществляется поразрядно, то есть одно число может содержать несколько цифр, стоящих друг за другом. Разряды в записи чисел увеличивают свой вес справа налево, то есть самая правая цифра - самая маленькая. В любой системе счисления более значимый разряд всегда находится левее и увеличивается на единицу, если менее значимый разряд «переполняется». Мы можем это увидеть в привычной нам десятичной системе счисления, когда разряд единиц достигает цифры девять, на единицу увеличивается разряд десятков, а разряд единиц «сбрасывается в ноль». Просто потому, что такое основание, можно сказать, что «так исторически сложилось» или «других цифр не придумали» (кстати, для шестнадцатеричной системы счисления, в итоге придумали)&lt;/p&gt;
  &lt;h3&gt;&lt;strong&gt;Двоичная система счисления&lt;/strong&gt;&lt;/h3&gt;
  &lt;p&gt;Представляет особенный интерес для области информационных технологий, поскольку вся электроника работает по принципу «есть напряжение или нет напряжения», единица или ноль. Все числа из любых систем счисления в результате преобразуются в двоичную и представляются в виде набора единиц и нулей. Так для записи десятичного числа ​&lt;code&gt;116​&lt;/code&gt; используется двоичная запись ​&lt;code&gt;1110100&lt;/code&gt;.​ Преобразование из системы счисления с бОльшим основанием в систему счисления с меньшим основанием производится последовательным делением исходного числа на основание системы счисления и записи остатков такого деления в младшие разряды. Например:&lt;/p&gt;
  &lt;pre&gt;116​/​2​= ​58​(​0​) /​2​= ​29​(​0​) /​2​= ​14(​​1​) /​2​= ​7​(​0​) /​2​= ​3​(​1​) /​2​= ​1​(​1​) /​2​= ​1​&amp;lt; ​2&lt;/pre&gt;
  &lt;p&gt;В этом примере полученные остатки от деления записаны в скобках и можно обратить внимание на то, что они полностью повторяют запись числа 116 показанную ранее в зеркальном отражении. Обратное преобразование - это последовательное умножение разрядов числа на величину каждого разряда с их аккумулированием к общему результату:&lt;/p&gt;
  &lt;pre&gt;1110100​= ​0​*​1​+ ​0​*​2​+ ​1​*​4​+ ​0​*​8​+ 1​​*​16​+ ​1​*​32​+ ​1​*​64​= ​4​+ ​16​+ 3​2​+ ​64​= ​116&lt;/pre&gt;
  &lt;p&gt;В программах двоичный числовой литерал записывается с префиксом ​0b,​то есть для нашего примера ​&lt;code&gt;0b1110100&lt;/code&gt;.​ Поскольку двоичная система счисления является основной для компьютерной техники, помнить, например, значения степеней двойки - обычно, хорошее подспорье в работе.&lt;/p&gt;
  &lt;h2&gt;&lt;strong&gt;Вернёмся к нашему полю 10х10. &lt;/strong&gt;&lt;/h2&gt;
  &lt;h3&gt;&lt;strong&gt;Представления чисел.&lt;/strong&gt;&lt;/h3&gt;
  &lt;p&gt;Для того, чтобы записать три состояния нам нужны двоичные числа &lt;code&gt;0(00)&lt;/code&gt;, &lt;code&gt;1(01)&lt;/code&gt; и &lt;code&gt;2(10)&lt;/code&gt;. Что, очевидно, занимает два разряда двоичной записи и даже ещё остаётся место для четвёртого (третьего) состояния &lt;code&gt;11&lt;/code&gt;. То есть четыре ячейки поля могут быть записаны в 2х4 разрядах, в одном стандартном восьмибитном байте. Давайте разбираться, как это сделать, и что нам это даёт. Итак мы можем равноправно считать как в десятичной, так и в двоичной системах счисления, значение числа останется прежним, как его ни записывай. Поэтому мы можем сказать, что один байт, состоящий из восьми бит может сохранить для нас четыре клетки нашего поля по четыре состояния каждая, для этого его надо разделить на пары битов &lt;code&gt;00_00_00_00&lt;/code&gt;. Каждая пара будет в состоянии сохранить значение &lt;code&gt;0(00)&lt;/code&gt;, &lt;code&gt;1(01)&lt;/code&gt;, &lt;code&gt;2(10)&lt;/code&gt; или &lt;code&gt;3(11)&lt;/code&gt;. В этом случае нам становится неудобно записывать наши данные в десятичной системе счисления, ведь не сразу очевидно, какое именно число скрывается за двоичным кодом, например, &lt;code&gt;01_10_00_10&lt;/code&gt;. Далее, для удобства восприятия я буду разделять запись байта на такие пары.&lt;/p&gt;
  &lt;h3&gt;&lt;strong&gt;Маски и битовые сдвиги&lt;/strong&gt;&lt;/h3&gt;
  &lt;p&gt;Чтобы записать число в переменную мы используем привычный оператор присваивания и пишем &lt;code&gt;byte a = 3;&lt;/code&gt; Исполнитель в этом случае превратит некоторую область памяти из &lt;code&gt;00_00_00_00&lt;/code&gt; в &lt;code&gt;00_00_00_11&lt;/code&gt;. Мы можем попросить исполнителя сместить записанные биты влево или вправо на нужное количество разрядов используя оператор &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; или &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; соответственно. Например, &lt;code&gt;byte a = 3 &amp;lt;&amp;lt; 2;&lt;/code&gt; В этом случае переменная будет иметь вид &lt;code&gt;00_00_11_00&lt;/code&gt;, что равно двенадцати. Внимательный читатель мог заметить, что &lt;code&gt;сдвинуть на 2&lt;/code&gt; это тоже самое, что &lt;code&gt;умножить на 4&lt;/code&gt;. Если развивать эту мысль, то можно однозначно сказать, что &lt;u&gt;сдвиг числа влево на N разрядов эквивалентен умножению этого числа на 2 в степени N&lt;/u&gt;. Можем ли мы как-то удобно получить нужное значение из конкретных битов без необходимости двигать их туда-обратно? Конечно, для этого придумали маски.&lt;/p&gt;
  &lt;p&gt;Например, я хочу узнать, какое значение имеет самый младший бит (признак чётности) в записанном значении &lt;code&gt;byte a = 3;&lt;/code&gt; Я применяю к этому числу так называемую маску: говорю, что остальные биты мне не важны, и я хочу увидеть состояние именно этого. На помощь спешит операция побитового И. В некоторых источниках её ещё называют арифметическим И. Записывается она в виде амперсанда (&lt;code&gt;&amp;amp;&lt;/code&gt;) и возвращает для разряда единицу только если в обоих операндах в соответствующих разрядах единицы. То есть: &lt;/p&gt;
  &lt;pre&gt;3(00_00_00_11) &amp;amp; 1(00_00_00_01) = 1(00_00_00_01); 
4(00_00_01_00) &amp;amp; 1(00_00_00_01) = 0(00_00_00_00). &lt;/pre&gt;
  &lt;p&gt;Как видно, мы получили в результате цифру, обозначающую чётность исходного числа. Накладывать такие маски можно не только на один разряд, но на любое их количество. Маска для двух разрядов это &lt;code&gt;&amp;amp;3&lt;/code&gt;, для трёх &lt;code&gt;&amp;amp;7&lt;/code&gt;, для четырёх &lt;code&gt;&amp;amp;15&lt;/code&gt; и так далее &lt;code&gt;&amp;amp;31&lt;/code&gt;, &lt;code&gt;&amp;amp;63&lt;/code&gt;. Эти числа неожиданно сильно напоминают степени двойки, не правда ли? Маски также можно сдвигать относительно проверяемого числа, например, проверить старшие два разряда нашего замученного байта можно так: &lt;code&gt;byte result = a &amp;amp; (3 &amp;lt;&amp;lt; 6);&lt;/code&gt; здесь мы двухбитную маску &lt;code&gt;3(11)&lt;/code&gt; сдвигаем на шесть разрядов (&lt;code&gt;11_00_00_00&lt;/code&gt;) и накладываем на число &lt;code&gt;a&lt;/code&gt; (&lt;code&gt;xx_xx_xx_xx &amp;amp; 11_00_00_00&lt;/code&gt;) таким образом нам вернётся состояния именно этих двух битов, остальные биты этого числа мы игнорируем (маскируем) они станут нулями. И нам, кстати, совершенно нет дела до того, какое будет у байта десятичное представление. А чтобы получить не просто значение маскированной переменной, а именно этих двух старших битов, нужно полученное маскированное значение сдвинуть обратно вправо на количество битов, на которое изначально сдвигали влево. То есть если мы изначально &lt;code&gt;xx&lt;/code&gt; сдвинули на шесть разрядов влево, теперь маскированное значение нужно сдвинуть на шесть разрядов вправо.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/98/ce/98ce477b-ee8f-41d4-a9cc-89b608aa1433.png&quot; width=&quot;1774&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2&gt;&lt;strong&gt;Заключение&lt;/strong&gt;&lt;/h2&gt;
  &lt;p&gt;Тема битовых операций постепенно теряет свою актуальность в связи с развитием технологий, скоростей, объёмов. Скорее всего, битовые операции в ближайшем будущем перейдут в разряд узкоспециальных знаний и будут применяться только при программировании микроконтроллеров. И правда, зачем такие сложные вещи в условном JavaScript/HTML5, где основная задача - это быстро и красиво для разработчика и пользователя, и можно не особо считать потраченные килобайты.&lt;/p&gt;
  &lt;h2&gt;&lt;strong&gt;Постскриптум&lt;/strong&gt;&lt;/h2&gt;
  &lt;p&gt;&lt;code&gt;N &amp;lt;&amp;lt; K&lt;/code&gt; = N * 2 в степени K&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;N &amp;gt;&amp;gt; K&lt;/code&gt; = N / 2 в степени K&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;x &amp;amp; y&lt;/code&gt; = битовая. 1 если оба &lt;code&gt;x == 1&lt;/code&gt; и &lt;code&gt;y == 1&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;X &amp;amp;&amp;amp; Y&lt;/code&gt; = литеральная.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;x | y&lt;/code&gt; = битовая. 1 если хотя бы один из &lt;code&gt;x == 1&lt;/code&gt; или &lt;code&gt;y == 1&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;X || Y&lt;/code&gt; = литеральная&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;x ^ y&lt;/code&gt; = битовая. 1 если &lt;code&gt;x&lt;/code&gt; отличается от &lt;code&gt;y&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;~x&lt;/code&gt; = битовая. 1 если &lt;code&gt;x == 0&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;!X&lt;/code&gt; = литеральная&lt;/p&gt;
  &lt;p&gt;Литеральные операции применяются ко всему числовому литералу целиком, а не к каждому отдельному биту. Здесь особенность в том, как язык программирования интерпретирует числа. В Java, например, в таких операциях может участвовать только тип &lt;code&gt;boolean&lt;/code&gt;, а C++ воспринимает любой ненулевой числовой литерал как истину, а нулевой, соответственно, как ложь. Логика формирования значения при этом остаётся такой же, как и при битовых операциях.&lt;/p&gt;

</content></entry><entry><id>customgeekmaterials:print-formatted</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/print-formatted?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>Форматированный вывод</title><published>2020-12-07T12:43:40.435Z</published><updated>2021-05-13T20:07:57.269Z</updated><summary type="html">Подавляющее большинство мануалов по тем или иным языкам программирования показывают прекрасный пример того, как начинающему программисту написать свой первый &quot;Hello, world!&quot; и это прекрасно! Давайте разбираться, почему этого недостаточно и как сделать жизнь программиста чуть лучше. Да, по форматированному выводу написано также огромное количество мануалов, в том числе в стандартных документациях к языкам, но почему бы не сделать попытку отказаться от казённого языка больших компаний и не рассказать своими словами?</summary><content type="html">
  &lt;p&gt;Подавляющее большинство мануалов по тем или иным языкам программирования показывают прекрасный пример того, как начинающему программисту написать свой первый &lt;em&gt;&amp;quot;Hello, world!&amp;quot;&lt;/em&gt; и это прекрасно! Давайте разбираться, почему этого недостаточно и как сделать жизнь программиста чуть лучше. Да, по форматированному выводу написано также огромное количество мануалов, в том числе в стандартных документациях к языкам, но почему бы не сделать попытку отказаться от казённого языка больших компаний и не рассказать своими словами?&lt;/p&gt;
  &lt;h3&gt;Немного истории&lt;br /&gt;&lt;/h3&gt;
  &lt;p&gt;Современные языки программирования, так или иначе, но берут своё начало в C.&lt;/p&gt;
  &lt;p&gt;...&lt;/p&gt;
  &lt;p&gt;...&lt;/p&gt;
  &lt;p&gt;...&lt;/p&gt;
  &lt;p&gt;Так, мы подождали, когда нас покинут эксперты в области истории программирования и можем спокойно продолжать. Подавляющее большинство так называемых &amp;quot;языков высокого уровня&amp;quot; содержат отличную стандартную библиотеку функций (классов и методов), в которой описана функция &lt;code&gt;print()&lt;/code&gt; она обычно либо лежит в системном классе, либо в другом очень удобном и доступном месте. Все люди ей радостно пользуются, и если нужно, например, собрать строчку из нескольких составляющих просто применяют конкатенацию строк, получая что-то вроде &lt;code&gt;print(&amp;quot;Hello, I&amp;#x27;m &amp;quot; + &amp;quot;Ivan &amp;quot; + 35 + &amp;quot; years of age&amp;quot;);&lt;/code&gt;. Всё очень хорошо и понятно. но можно лучше. Разработчики языков программирования придумали, как избавиться от конкатенации и удобно форматировать строки. Нужно написать параметризированный шаблон и подставлять в него значения. Всего навсего.&lt;/p&gt;
  &lt;h3&gt;Понятие форматирования&lt;br /&gt;&lt;/h3&gt;
  &lt;p&gt;Всё началось в K&amp;amp;R C, где функция &lt;code&gt;print();&lt;/code&gt; не была описана вовсе. Это было для меня камнем преткновения изучения C в школе, где на уроках информатики нам преподавали QBasic. Я использовал директиву &lt;code&gt;print(); &lt;/code&gt;а компилятор упорно утверждал, что не знает такой. Удивительно, что простой вывод осуществлялся функцией &lt;code&gt;printf(); &lt;/code&gt;что расшифровывалось как &lt;em&gt;print formatted&lt;/em&gt;. Форматированный вывод подразумевал как раз создание шаблона строки и заполнения его параметрами, хотя и простой &lt;em&gt;&amp;quot;Hello, world&amp;quot;&lt;/em&gt; с его помощью вывести можно. Что представляет собой форматирование? Это отличается от того, к чему мы привыкли при форматировании текста в HTML или MS Word, где под этим словом подразумевается создание отступов, интервалов и прочих украшательств. В программировании форматирование - это создание таких мест в строке, которые будут заполнены значениями, так или иначе переданными шаблону. Места, которые будут заполнены значениями отмечаются в шаблоне специальной последовательностью, которая называется &lt;strong&gt;placeholder&lt;/strong&gt; (англ. - держатель места, заполнитель). То есть, если мы опишем вызов шаблона &lt;code&gt;&amp;quot;Hello, %s&amp;quot;&lt;/code&gt; и передадим в него литерал &amp;quot;&lt;code&gt;world&amp;quot; &lt;/code&gt;вся строка в шаблоне выведется &amp;quot;как есть&amp;quot;, а заполнитель заменится на переданный литерал. Заполнитель представляет собой символ &lt;code&gt;%&lt;/code&gt; и некоторую последовательность, означающую, собственно, формат принимаемого в заполнитель значения. Самые популярные заполнители - это:&lt;br /&gt; - &lt;code&gt;%s&lt;/code&gt; - string, обычный строковый литерал. Представляется &amp;quot;как есть&amp;quot;, не дополняется никакими символами и не обрезается.&lt;br /&gt; - &lt;code&gt;%d&lt;/code&gt;, &lt;code&gt;%i&lt;/code&gt; - decimal, integer - целое число в десятичной системе счисления. Разницы в использовании &lt;code&gt;%d&lt;/code&gt; и &lt;code&gt;%i &lt;/code&gt;нет&lt;br /&gt; - &lt;code&gt;%x&lt;/code&gt;, &lt;code&gt;%X&lt;/code&gt; - hexadecimal - целое число в шестнадцатиричном представлении. Разница между &lt;code&gt;%x&lt;/code&gt; и &lt;code&gt;%X&lt;/code&gt; в том, что в итоговой строке будут использованы строчные или заглавные буквы &lt;em&gt;A-F&lt;/em&gt; для представления чисел &lt;em&gt;10-15&lt;br /&gt;&lt;/em&gt; - &lt;code&gt;%f&lt;/code&gt; - float - числа с плавающей точкой (дробные числа)&lt;br /&gt; - &lt;code&gt;%c&lt;/code&gt; - character - символ.&lt;br /&gt; - &lt;code&gt;%%&lt;/code&gt; - собственно, символ процента. Поскольку с него начинается специальная последовательность, чтобы вывести символ &amp;quot;как есть&amp;quot; нужно было положить его внутрь последовательности. Выкрутились.&lt;/p&gt;
  &lt;p&gt;Параметры, передаваемые заполнителям, передаются в ту же функцию форматирования &lt;em&gt;после строки шаблона через запятую&lt;/em&gt; (функции форматирования всегда принимают аргумент переменной длины). Параметры всегда присваиваются заполнителям в том порядке, в котором переданы, то есть первый заполнитель всегда держит место для первого параметра, второй для второго и так далее.&lt;/p&gt;
  &lt;p&gt;Некоторые заполнители могут дополняться параметрами, так, например, &lt;code&gt;%5d&lt;/code&gt; будет означать, что переданное целое число будет помещено в пространство из не менее, чем пяти символов (слева будут дописаны пробелы, если число занимает меньше символов). Используя же &lt;code&gt;%05d&lt;/code&gt; мы будем минимальное выделенное пространство заполнять не пробелами, а нулями. Или, к примеру, в случае &lt;code&gt;%.2f&lt;/code&gt; мы указываем, что дробную часть числа при отображении следует обрезать до двух символов, и число &lt;em&gt;1.23456&lt;/em&gt; будет отображено как &lt;em&gt;1.23&lt;/em&gt;.&lt;/p&gt;
  &lt;h3&gt;C/C++&lt;/h3&gt;
  &lt;p&gt;&lt;br /&gt;Функция &lt;code&gt;printf();&lt;/code&gt; это весьма удобная альтернатива простому выводу в поток вывода в C++. Оператор &lt;code&gt;std::cout&lt;/code&gt; не предоставляет возможности к форматированию строк и поэтому, несмотря на свою популярность, не может считаться равноценной заменой классическому &lt;code&gt;printf();&lt;/code&gt; Более того в языке присутствует функция &lt;code&gt;sprintf();&lt;/code&gt; позволяющая осуществлять форматированный вывод не в консоль, но в другой строковый литерал.&lt;/p&gt;
  &lt;pre&gt;char fmt[20];
sprintf(fmt, &amp;quot;shift |%%%dd|, 7);
// no output, but fmt == &amp;quot;shift |%7d|&amp;quot;
printf(fmt, 10);
printf(&amp;quot;preformatted with zeros %07d&amp;quot;, 10);
// shift |     10|
// preformatted with zeros 0000010&lt;/pre&gt;
  &lt;h3&gt;Java&lt;/h3&gt;
  &lt;p&gt;&lt;br /&gt;В Java классические форматтеры представлены методами &lt;code&gt;System.out.printf();&lt;/code&gt; (а если быть совсем точным, то &lt;code&gt;PrintStream#printf();&lt;/code&gt;) и &lt;code&gt;String#format();&lt;/code&gt; первый осуществляет вывод форматированной строки в поток, второй в строку.&lt;/p&gt;
  &lt;pre&gt;System.out.printf(&amp;quot;%s loves string formatting\n&amp;quot;, &amp;quot;Everyone&amp;quot;);
System.out.println(String.format(&amp;quot;Sadly, %.2f%% of programmers use it&amp;quot;, 50f));
// Everyone loves string formatting
// Sadly, 50.00% of programmers use it&lt;/pre&gt;
  &lt;h3&gt;Python&lt;/h3&gt;
  &lt;p&gt;&lt;br /&gt;Здесь форматирование осуществляется всегда для строки и может использоваться внутри функции &lt;code&gt;print()&lt;/code&gt;, например, для заполнения значением конкретной переменной&lt;/p&gt;
  &lt;pre&gt;customstring = &amp;quot;String formatting&amp;quot;
print(f&amp;quot;{customstring} is powerful&amp;quot;)
# String formatting is powerful&lt;/pre&gt;
  &lt;p&gt;или близким к классическому способом&lt;br /&gt;&lt;/p&gt;
  &lt;pre&gt;print(&amp;quot;Machine learning provides {} the ability to learn {}&amp;quot;.format(&amp;quot;systems&amp;quot;, &amp;quot;automatically&amp;quot;))
# Machine learning provides systems the ability to learn automatically&lt;/pre&gt;
  &lt;p&gt;Вообще, python в части форматирования строк &amp;quot;пошёл&amp;quot; дальше всех, потому что предоставляет механизмы для именованного заполнения, повторного заполнения держателей и использования.&lt;br /&gt;&lt;/p&gt;
  &lt;pre&gt;print(&amp;quot;{2} has a friend called {0} and a sister called {1}&amp;quot;. format(&amp;quot;Betty&amp;quot;, &amp;quot;Linda&amp;quot;, &amp;quot;Daisy&amp;quot;))
# Daisy has a friend called Betty and a sister called Linda

tool=&amp;quot;Unsupervised algorithms&amp;quot;
goal=&amp;quot;patterns&amp;quot;
print(&amp;quot;{title} try to find {aim} in the dataset&amp;quot;.format(title=tool, aim=goal))
# Unsupervised algorithms try to find patterns in the dataset&lt;/pre&gt;
  &lt;h3&gt;Выводы&lt;/h3&gt;
  &lt;p&gt;Естественно, каждый может найти как десяток доводов продолжать использовать форматирование строк, так и десяток доводов продолжать их не использовать. В этой статье я постарался ответить на вопрос &amp;quot;а что это у Вас за странный вызов на печать такой&amp;quot;, а не дать читателю завет &amp;quot;всегда пользуйся только вот этим&amp;quot;. Поиск доводов &amp;quot;за&amp;quot; и &amp;quot;против&amp;quot; автор всегда оставляет читателю.&lt;/p&gt;

</content></entry><entry><id>customgeekmaterials:code-practice-makes-perfect</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/code-practice-makes-perfect?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>Ресурсы, чтобы &quot;набить руку&quot;</title><published>2020-11-29T20:25:06.237Z</published><updated>2020-11-29T20:25:39.211Z</updated><summary type="html">Естественно, список не полон и состоит только из тех ресурсов, которые я в разное время посещал лично, оценочная сложность задач также весьма субъективна (по пятибалльной шкале). Данная статья ни в коем случае не является рекламой ни одного из нижеперечисленных ресурсов и содержит только моё личное субъективное мнение. Список ниже создан исключительно с целью ответа на один из самых часто задаваемых студентами вопросов: есть ли какой то хороший ресурс, где можно попрактиковаться в решении простых и не очень задач.</summary><content type="html">
  &lt;p&gt;Естественно, список не полон и состоит только из тех ресурсов, которые я в разное время посещал лично, оценочная сложность задач также весьма субъективна (по пятибалльной шкале). Данная статья ни в коем случае не является рекламой ни одного из нижеперечисленных ресурсов и содержит только моё личное субъективное мнение. Список ниже создан исключительно с целью ответа на один из самых часто задаваемых студентами вопросов: есть ли какой то хороший ресурс, где можно попрактиковаться в решении простых и не очень задач.&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&quot;https://codingbat.com/java&quot; target=&quot;_blank&quot;&gt;https://codingbat.com/java&lt;br /&gt;&lt;/a&gt;Визуально - не самый красивый сайт, но очень хорошо показывает, какие тесты прошёл Ваш код, а какие нет, что позволяет сориентироваться, в каком направлении думать дальше. Лучшая подборка простейших задач.&lt;br /&gt;&lt;strong&gt;Язык интерфейса:&lt;/strong&gt; только английский&lt;br /&gt;&lt;strong&gt;Задачи:&lt;/strong&gt; Java, Python&lt;br /&gt;&lt;strong&gt;Сложность задач:&lt;/strong&gt; 0 - 4&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://hackerrank.com&quot; target=&quot;_blank&quot;&gt;https://hackerrank.com&lt;br /&gt;&lt;/a&gt;Портал, который позиционирует себя как объединяющий компании и исполнителей на основе решения проблем в разных областях знаний. Лучшая подборка задач на алгоритмы и математику.&lt;br /&gt;&lt;strong&gt;Язык интерфейса:&lt;/strong&gt; пишет, что есть русский, но мне не удалось включить&lt;br /&gt;&lt;strong&gt;Задачи:&lt;/strong&gt; Algorithms, Data Structures, Mathematics, C, C++, Java, Python, Ruby, Linux Shell, Functional Programming, AI, SQL, Databases, Regex&lt;br /&gt;&lt;strong&gt;Сложность задач:&lt;/strong&gt; 1 - 4&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://leetcode.com&quot; target=&quot;_blank&quot;&gt;https://leetcode.com&lt;br /&gt;&lt;/a&gt;На мой взгляд немного сложноватая навигация, но симпатично сделанный портал, нацеленный на обучение. Хорошие фильтры для задач, но даже с применением фильтров - задачи не отсортированы по нарастанию сложности. Есть подсказки и секция &amp;quot;похожие вопросы&amp;quot;.&lt;br /&gt;&lt;strong&gt;Язык интерфейса:&lt;/strong&gt; не нашёл, где можно поменять&lt;br /&gt;&lt;strong&gt;Задачи:&lt;/strong&gt; C, C++, C#, Java, Python, Python3, JavaScript, Ruby, Swift, Go, Scala, Kotlin, Rust, PHP&lt;br /&gt;&lt;strong&gt;Сложность задач:&lt;/strong&gt; 1 - 5&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.codewars.com&quot; target=&quot;_blank&quot;&gt;https://www.codewars.com&lt;br /&gt;&lt;/a&gt;Хорошая навигация и усложнение задач по мере прохождения. После решения показывает не только правильный вариант, но и то, как решили другие участники. Лучший редактор кода.&lt;br /&gt;&lt;strong&gt;Язык интерфейса:&lt;/strong&gt; только английский&lt;br /&gt;&lt;strong&gt;Задачи:&lt;/strong&gt; C, C++, C#, Go, Haskell, Java, JavaScript, PHP, Python, Ruby, Rust, Shell, SQL, Swift и ОЧЕНЬ много других, в том числе экзотических, вроде Brainfuck&lt;br /&gt;&lt;strong&gt;Сложность задач:&lt;/strong&gt; 1 - 5&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.codingame.com&quot; target=&quot;_blank&quot;&gt;https://www.codingame.com&lt;br /&gt;&lt;/a&gt;Пожалуй, самый красивый портал из этого списка. И с самой интересной идеей. Идеально подойдёт тем, кто хочет дальше писать игры. Все задачи завязаны на игровой процесс и шикарно визуализированы.&lt;br /&gt;&lt;strong&gt;Язык интерфейса:&lt;/strong&gt; только английский&lt;br /&gt;&lt;strong&gt;Задачи:&lt;/strong&gt; C, C++, C#, Java, Python3, JavaScript, Bash, Ruby, Swift, Go, Groovy, Scala, Perl&lt;br /&gt;&lt;strong&gt;Сложность задач:&lt;/strong&gt; 2 - 5&lt;/li&gt;
  &lt;/ol&gt;

</content></entry><entry><id>customgeekmaterials:git-bash-made-easy</id><link rel="alternate" type="text/html" href="https://teletype.in/@customgeekmaterials/git-bash-made-easy?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=customgeekmaterials"></link><title>От пустого места до пулл-реквеста 2.0</title><published>2020-11-29T20:03:50.838Z</published><updated>2020-11-29T20:26:10.831Z</updated><summary type="html">В продолжение предыдущей статьи о Git, которая по объективным причинам может понравиться не всем. В этом кратком руководстве не будет ничего о теории git, о состояниях файлов и прочей, без сомнения полезной для дальнейшей работы информации. Пошаговая инструкция по внесению правок в проект и предложению своих изменений к ревью, посредством механизма pull-request. С небольшими комментариями к каждому шагу.</summary><content type="html">
  &lt;h1&gt;Или повесть о настоящем терминале&lt;/h1&gt;
  &lt;p&gt;В продолжение &lt;a href=&quot;https://teletype.in/@wayneshephard/fifteen-steps-to-git&quot; target=&quot;_blank&quot;&gt;предыдущей статьи о Git&lt;/a&gt;, которая по объективным причинам может понравиться не всем. В этом кратком руководстве не будет ничего о теории &lt;strong&gt;git&lt;/strong&gt;, о состояниях файлов и прочей, без сомнения полезной для дальнейшей работы информации. Пошаговая инструкция по внесению правок в проект и предложению своих изменений к ревью, посредством механизма &lt;em&gt;pull-request&lt;/em&gt;. С небольшими комментариями к каждому шагу.&lt;/p&gt;
  &lt;p&gt;Естественно, что любой графический клиент для &lt;strong&gt;git&lt;/strong&gt; - это ни что иное, как набор нарисованных кнопок и полей, выполняющих те или иные терминальные команды приложения &lt;strong&gt;git&lt;/strong&gt;. Также естественно, что зачастую есть необходимость работать с системами контроля версий не только в удобном графическом интерфейсе, но и в терминале, например, на серверах, где разворачивается инфраструктура или приложение. Помимо этого в терминале, естественно, можно осуществлять и разработку приложения.&lt;/p&gt;
  &lt;p&gt;О том, какие команды нужно выполнить, чтобы начать разрабатывать приложение в безоконной среде и поговорим. Сразу оговорюсь, что в треугольных скобках будет указан аргумент, или часть аргумента, который нужно изменить, чтобы инструкция подходила именно для Вас, например, если написано, что нужно выполнить &lt;code&gt;git commit -m &amp;quot;&amp;lt;your-comment&amp;gt;&amp;quot;&lt;/code&gt;, то нужно будет выполнить в терминале команду &lt;strong&gt;git&lt;/strong&gt; с аргументом commit и ключом &lt;strong&gt;&lt;code&gt;-m&lt;/code&gt;&lt;/strong&gt; после которого &lt;em&gt;в кавычках&lt;/em&gt; нужно будет написать &lt;em&gt;Ваш комментарий&lt;/em&gt;. Итак, к делу, по пунктам:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Создаём &lt;em&gt;новый&lt;/em&gt; проект, или берём существующий, который нужно версионировать. В терминале в папку проекта можно перейти, выполнив команду &lt;code&gt;cd &amp;lt;absolute-path-to-project-directory&amp;gt;&lt;/code&gt;, где абсолютный - означает путь от корня файловой системы&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Инициализируем&lt;/em&gt; в папке новый локальный гит репозиторий командой &lt;code&gt;git init&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Добавляем&lt;/em&gt; в папку проекта новый файл &lt;strong&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; (на UNIX-подобных операционных системах, командой &lt;strong&gt;&lt;code&gt;touch .gitignore&lt;/code&gt;&lt;/strong&gt;) и открываем его на редактирование любым текстовым редактором (например, &lt;strong&gt;&lt;code&gt;nano .gitignore&lt;/code&gt;&lt;/strong&gt;)&lt;/li&gt;
    &lt;li&gt;В файл игнорирования &lt;em&gt;нужно вписать&lt;/em&gt; все файлы и папки, которые не должны попасть во внешний (удалённый) репозиторий. Их нужно перечислить на отдельных строках. Например, для проекта, написанного в IntelliJ IDEA это должны быть папки &lt;code&gt;.idea/&lt;/code&gt; и&lt;strong&gt;&lt;code&gt; out/&lt;/code&gt;&lt;/strong&gt; а также файл проекта &lt;code&gt;*.iml&lt;/code&gt;и таким образом в файле &lt;code&gt;.gitignore&lt;/code&gt; можно быть три строки. Сохраняем файл игнорирования.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;На сайте github.com создаём&lt;/em&gt; новый репозиторий. Это не повторение уже проделанной работы, а создание именованного места хранения Вашего репозитория. &lt;em&gt;Важно помнить&lt;/em&gt;, что удалённый репозиторий, созданный на Github&amp;#x27;e всегда следует считать основным. После создания у этого репозитория появится свой адрес вида https://github.com/&lt;strong&gt;&amp;lt;your-account-name&amp;gt;/&amp;lt;your-repository-name&amp;gt;.git &lt;/strong&gt;именно этот адрес нам понадобится для дальнейшей работы, скопируем его в буфер обмена.&lt;/li&gt;
    &lt;li&gt;Нам необходимо &lt;em&gt;добавить&lt;/em&gt; в наш локальный репозиторий информацию о том, что его копия будет храниться удалённо, для этого нужно выполнить команду &lt;code&gt;git remote add origin &amp;lt;remote-repository-address&amp;gt;&lt;/code&gt; которая добавит удалённый репозиторий под именем &lt;code&gt;origin&lt;/code&gt;. Удалённых копий репозитория может быть несколько, главное, чтобы их имена не повторялись.&lt;/li&gt;
    &lt;li&gt;Мы &lt;em&gt;находимся&lt;/em&gt; в локальной ветке &lt;code&gt;master&lt;/code&gt; и нам необходимо зафиксировать (сделать коммит) все текущие изменения (те, что уже были в папке на момент инициализации репозитория). Для этого нужно выполнить две команды &lt;br /&gt;&lt;code&gt;&lt;strong&gt;git add . &lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;git commit -a -m &amp;quot;initial commit&amp;quot;&lt;/strong&gt;&lt;/code&gt;&lt;br /&gt;Особенное внимание следует обратить на то, что в первой команде на конце стоит точка, и это означает, что нужно добавить к версионированию вообще все файлы (кроме игнорируемых) из текущей директории и всех её поддиректорий. Вторая команда может содержать любой текст в сообщении коммита, но обычно пишут, что это начальный, инициализирующий коммит.&lt;/li&gt;
    &lt;li&gt;Для &lt;em&gt;отправки&lt;/em&gt; локального репозитория в удалённый (создания общедоступной копии) необходимо выполнить команду &lt;code&gt;&lt;strong&gt;git push -u origin&lt;/strong&gt; &lt;strong&gt;master&lt;/strong&gt;&lt;/code&gt;. То есть указать действие, куда и что нужно &amp;quot;запушить&amp;quot;. Ключ &lt;strong&gt;&lt;code&gt;-u&lt;/code&gt;&lt;/strong&gt; означает, что в удалённом репозитории на момент выполнения команды &lt;strong&gt;&lt;code&gt;push&lt;/code&gt;&lt;/strong&gt; нет ветки с названием &lt;strong&gt;&lt;code&gt;master&lt;/code&gt;&lt;/strong&gt;, и мы хотим не только её создать, но и явно указать, что это полная копия нашей локальной ветки &lt;strong&gt;&lt;code&gt;master&lt;/code&gt;&lt;/strong&gt;. Установить связь этих веток.&lt;/li&gt;
    &lt;li&gt;Мы &lt;em&gt;готовы&lt;/em&gt; вносить правки. Это принято делать в отдельных ветках, чтобы ненароком не сломать ничего в основной (мастер) ветке. Чтобы создать ветку и переключиться в неё нужно выполнить команды&lt;br /&gt;&lt;code&gt;&lt;strong&gt;git branch &amp;lt;branch-name&amp;gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;git checkout &amp;lt;branch-name&amp;gt;&lt;/strong&gt;&lt;/code&gt;&lt;br /&gt;Для навигации по веткам можно использовать &lt;strong&gt;&lt;code&gt;git branch -a&lt;/code&gt;&lt;/strong&gt; - команду, которая выведет на экран список всех существующих локально веток проекта, и &lt;strong&gt;&lt;code&gt;git checkout &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/strong&gt; - команду, которая переключает ветки.&lt;/li&gt;
    &lt;li&gt;Здесь, в новой ветке, &lt;em&gt;можно&lt;/em&gt; вносить правки в проект без опасения нанести вред основному проекту. Важно помнить, что пока пользователь не зафиксирует свои изменения - они не появятся в &lt;strong&gt;git&lt;/strong&gt;, и пока пользователь сам, явно, ничего из &lt;strong&gt;git&lt;/strong&gt; не удалит - оно никуда не пропадёт. Чем чаще мы будем делать фиксации (коммиты) при работе - тем лучше, таким образом мы сможем точнее отследить момент, например, когда всё перестало работать или сможем случайно удалить меньшее количество данных.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;После внесения&lt;/em&gt; правок в проект, мы готовы сливать изменения из текущей ветки с основной веткой проекта. В простых проектах, которые обычно пишутся &amp;quot;для себя&amp;quot; это делается командой &lt;strong&gt;&lt;code&gt;git merge&lt;/code&gt;&lt;/strong&gt; с указанием веток, которые необходимо слить. В нашем случае, мы хотим, чтобы слияние произошло после ревью изменений другим человеком, для этого нужно опубликовать внесённые изменения. Это делается уже знакомой нам командой &lt;code&gt;&lt;strong&gt;git push -u origin &lt;/strong&gt;&amp;lt;your-branch-name&amp;gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;На сайте github.com создаём&lt;/em&gt; новый &lt;strong&gt;pull-request&lt;/strong&gt; для нашего репозитория. В нём указываем источник изменений - нашу ветку, и назначение изменений - ветку &lt;strong&gt;&lt;code&gt;master&lt;/code&gt;&lt;/strong&gt;. В создаваемом запросе на слияние появится несколько вкладок, демонстрирующих какие именно изменения предлагается внести, сколько коммитов понадобилось для написания этих правок и так далее. С точки зрения ревью наиболее интересная вкладка &lt;strong&gt;Files&lt;/strong&gt;, на ней отображаются конкретные изменения конкретных файлов с возможностью комментирования каждой строки.&lt;/li&gt;
    &lt;li&gt;Важно помнить, что запросы на слияние создаются для веток, а не для конкретных коммитов, поэтому для внесения дополнительных правок после ревью можно осуществлять в уже существующей ветке, и эти правки будут сразу видны в пулл-реквесте. Но у этой особенности есть и обратная сторона - если закрыть пулл-реквест, но не слить ветки проекта - следующий запрос на слияние будет содержать правки всех предыдущих. Поэтому, по завершении работы над веткой, её нужно слить с основной веткой проекта (&lt;strong&gt;github&lt;/strong&gt; позволяет сделать это нажатием кнопки &lt;strong&gt;merge&lt;/strong&gt;) и удалить локально. Новые правки должны вноситься только в новой ветке, см. п. 9.&lt;/li&gt;
    &lt;li&gt;Для того, чтобы обновить состояние локального репозитория необходимо выполнить команду &lt;strong&gt;&lt;code&gt;git pull -a&lt;/code&gt;&lt;/strong&gt; которая скачает из удалённого репозитория текущую версию проекта. Ключ &lt;strong&gt;&lt;code&gt;-а&lt;/code&gt; &lt;/strong&gt;означает, что нужно скачать все ветки.&lt;/li&gt;
    &lt;li&gt;Если по какой то причине локальная ветка с изменениями не слилась с основной веткой репозитория, следует удостовериться, что Вы находитесь в ветке &lt;strong&gt;&lt;code&gt;master&lt;/code&gt;&lt;/strong&gt;, и выполнить команду &lt;strong&gt;&lt;code&gt;git merge &amp;lt;your-branch-name&amp;gt;&lt;/code&gt;&lt;/strong&gt;. Если все предыдущие пункты были выполнены именно так, как описаны, конфликтов слияния возникнуть не должно&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Как мог заметить внимательный читатель, мы поговорили не только о запросах на слияние, но и том, что делать после того, как запрос был удовлетворён (или отклонён). Спасибо за внимание.&lt;/p&gt;

</content></entry></feed>