Введение в язык программирования семантика языка

Введение. в языки программирования

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

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

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

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

Вам уже известно, что алгоритм, записанный на языке программирования, называется программой. А что же мы понимаем под языком программирования?

Язык программирования— это совокупность набора символов (алфавит) системы, правил образования (синтаксис) и истолкования конструкций из символов (семантика) для задания алгоритмов с использованием символов естественного языка.

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

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

По этому критерию можно выделить следующие уровни языков программирования: машинные, машинно-ориентированные и машинно-независимые (языки высокого уровня).

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

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

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

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

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

Именно такие языки и ориентированы на описание алгоритмов. Поэтому их еще называют алгоритмическими языками.

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

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

Существуют два способа трансляции:

Разницу между компиляцией и интерпретацией можно выяснить с помощью аналогии. Фармацевты в аптеке приготовляют микстуру по старинному рецепту, написанному на латыни. Есть два пути: можно сначала перевести (скомпилировать) рецепт на родной язык и лишь затем готовить лекарство на родном языке. А можно, по мере чтения перевода рецепта, сразу готовить лекарство, но не записывать сам текст перевода (т.е. только интерпретировать). В последнем случае мы не получим текста рецепта на родном языке. А можно, по мере чтения перевода рецепта, сразу готовить лекарство, но не записывать сам текст перевода (т.е. только интерпретировать). В последнем случае мы не получим текста рецепта на родном языке, а сразу получим микстуру, правда, если лекарство нужно готовить несколько раз, рецепт придется переводить многократно.

Источник

Синтаксис и семантика языка программирования

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

Синтаксис языка — совокупность правил, определяющих допустимые конструкции (слова, предложения) языка, его форму.

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

Языки программирования относятся к группе формальных языков, для которых в отличие от естественных языков однозначно определены синтаксис и семантика. Описание синтаксиса языка включает определение алфавита и правил построения различных конструкций языка из символов алфавита и более простых конструкций. Для этого обычно используют форму Бэкуса-Наура (БНФ) или синтаксические диаграммы. Описание конструкции в БНФ состоит из символов алфавита языка, названий более простых конструкций и двух специальных знаков:

· «::=»— читается как «может быть заменено на»,

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

Пример БНФ

БНФ, могут выглядеть следующим образом:

::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

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

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

Алфавит языка программирования Borland Pascal 7.0 включает:

1. строчные, прописные буквы латинского алфавита (a..z, A..Z) и знак подчеркивания ( _ ), который также во многих случаях считается буквой (строчные и прописные буквы не различаются);

3. специальные знаки, состоящие из одного и двух символов:

4. служебные слова (эти сочетания считаются единым целым и их нельзя использовать в программе в другом качестве): (примеры)

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

В Borland Pascal идентификатор представляет собой последовательность букв латинского алфавита (включая символ подчеркивания) и цифр, которая обязательно начинается с буквы.

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

Структура программы

Программа на Borland Pascal состоит из трех частей: заголовка, раздела описаний и раздела операторов.

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

Write (‘Введите два натуральных числа:’);

if a>b then a:=a-b <если a>b, тогда a:=a-b>

Writeln(‘Hauбoльшuй общий делитель равен ’,a);

Программа названа «example». Раздел описаний в данном случае включает только описание переменных (см. параграф 2.3). Раздел операторов содержит операторы ввода исходных данных, вычислений и вывода результатов. Начнем рассмотрение особенностей программирования на языке Borland Pascal с проблемы описания данных.

Источник

Лекция на тему: «Введение в язык программирования»

ТЕМА: Введение в язык программирования. Основные типы данных

ОЦ: Рассмотреть понятие языка программирования, структура программы, типы данных.

РЦ: Развивать научное и логическое мышление, память, внимание, познавательный интерес к учебе в целом и конкретной дисциплине.

ВЦ: Воспитывать усидчивость, аккуратность, вежливость, настойчивость.

ТИП УРОКА: сообщение и усвоение новых знаний

ВИД ЗАНЯТИЯ: Лекция – беседа

ОБЕСПЕЧЕНИЕ ЗАНЯТИЯ: плакаты, ПК

1.Вводная часть. (5мин)

2. Основная часть – изучение нового материала (60мин)

3. Закрепление (20 мин)

Проверка домашнего задания.

Объяснение новой темы.

Организационный момент: приветствие, отсутствующие, цель.

Выражения и операции

Лекция в тетради читать.

Введение в язык программирования. Основные типы данных.

Основные сведения о языке Паскаль.

В языке Паскаль используются различные типы данных. Мы будем пользоваться некоторыми из так называемых стандартных типов данных:

Основные математические функции.

Структура программы на Паскале.

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

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

Далее следует описательная часть, которая может включать в себя несколько разделов.

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

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

Основные операторы Паскаля.

Ввод данных — это передача информации от внешних уст­ройств в оперативную память. Вводятся, как правило, исходные данные решаемой задачи.

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

Основными устройствами ввода-вывода у персонального ком­пьютера являются клавиатура и дисплей (экран монитора). Процедура ввода с клавиатуры имеет следующий формат:

где — это последовательность имен перемен­ных, разделенных запятыми.

Слово read переводится как читать. (Точнее говоря, Read — это оператор обращения к стандартной процедуре ввода.)

Набираем на клавиатуре:

253.98 100 G ( Enter )

Набираем на клавиатуре:

Другой вариант оператора ввода с клавиатуры имеет вид:

Здесь слово ReadLn означает read line читать строку. Этот оператор отличается от Read только тем, что после считывания последнего в списке значения для одного оператора ReadLn данные для следующего оператора будут считываться с начала новой строки.

то ввод значений будет происходить из двух строк

Оператор вывода на экран (обращение к стандартной процеду­ре вывода) имеет следующий формат:

Здесь элементами списка вывода могут быть выражения раз­личных типов (в частности, константы и переменные).

Второй вариант процедуры вывода на экран:

В результате выполнения writeln после вывода информации курсор переводится на следующую строку. Результатом выполнения write (1); writeln; write(-2,3); будет 1

Источник

Введение в понимание программирования 😉

В честь нового года решил сделать обзорную статью по программированию и языках программирования. Профессиональным программистам просьба не пинать т.к. пишется в стиле «не для специалистов».

Если будет непонятно – не расстраивайтесь. Очень многие профессиональные программисты так же ничего в этом не понимают (что не мешает им эффективно работать).

Итак, КО мог бы сказать, что язык программирования — формальная знаковая система, предназначенная для записи компьютерных программ. Для того чтобы понять что такое язык программирования нужно понять, что такое… Инструкция.

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

Рассмотрим простую инструкцию – она написана на каком-либо языке, содержит разделы, приложения и имеет определенную структуру и стиль.

Структура и стиль инструкции в программировании называется парадигмой.

Разделы инструкции в программировании называют функциями.

Язык инструкции – язык программирования.

Основные парадигмы программирования:

Класс декларативного программирования – это класс парадигм которые вместо алгоритма описывают результат который требуется получить. Представители класса:

Чисто декларативное программирование, кстати, не всеми программистами считается программированием. Это такие языки как SQL, HTML. Кто видел код тот поймет почему программисты так считают. «Код» не обладает всеми возможностями языка программирования и является простым описанием требуемого результата.

Читайте также:  Английский язык исчисляемые и неисчисляемые примеры

Логическое программирование – программирование на основе фактов и моделей связи между фактами. Единственный вменяемый представитель: Prolog

Функциональное программирование – для использования программирования используется стиль математических операций. Если не знакомы с дискретной математикой, то ничего не понятно от слова совсем. Представители этой парадигмы: LISP, Erlang, Scala, Miranda, Haskell.

Пример программы (Hello World) на LISP:

(format t «Hello, world!

Пример чуть сложнее:

and for b = 1 then (+ a b)

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

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

Пример программы (С++):

.» ПОЛОЖИТЕЛЬНОЕ ЧИСЛО» ELSE

.» ОТРИЦАТЕЛЬНОЕ ЧИСЛО» THEN

Объектно-ориентированное программирование (ООП) – как следует из названия программирование на основе объектов которые являются экземплярами классов. Является важной опцией языков программирвоания.

В ООП производятся операции со свойствами экземпляров классов путем выполнения методов. Методы – набор инструкций по изменению классов.

Основной концепцией ООП является система ООП на классах:

Чтобы понятно перевести это на русский давайте посмотрим на домашних животных. Возьмем кота Ваську и собаку Жучку.

Класс Млекопитающие, наследует класс Животные

Свойство: кормит молоком детенышей

Класс Собака, наследует класс Млекопитающие

Класс Кот, наследует класс Млекопитающие

Васька – экземпляр класса Кот

Жучка – экземпляр класса Собака

Жучка и Васька могут иметь свойства: живет (от Животных), кормить молоком (от Млекопитающих), а так же могут: питаться, размножатся, умирать.

Но Жучка может лаять и не может мурчать, а Васька может мурчать, но не может лаять поскольку их «фирменные» классы не содержат соответствующих свойств.

Помимо классов есть программирование основанное на прототипах. В этом случае отсутствует описание класса, оно выводится в момент написания программы. Язык программирования для примера: JavaScript.

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

Структурное программирование – оформление программы так чтобы она легко читалась и понималась другими программистами. То есть это простой и понятный стиль написание программы. Язык, который частично заставляет это делать, Python.

«Чистых» языков программирования (которые бы использовали только одну парадигму) не существует, каждый язык отражает в себе одну или несколько парадигм.

Если тема будет интересна то напишу обзоры для Perl, Python, C++, JavaScript, Prolog, SQL, HTML+CSS.

Всех с наступающим праздником! Счастья, здоровья, удачи!

Дубликаты не найдены

Никогда не понимал таких статей.

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

Все описано техническим языком, что хрен поймут обычные люди.

Что именно непонятно?

для кого эта статья?

Мне как программисту, ты не открыл словом ничего.

Дал коллеге прочитать, он сказал что не хрена не понял.

Он понял что есть языки программирования, и что они оказываются выглядят как инструкции.

Он понял что есть языки программирования, и что они оказываются выглядят как инструкции.

Наверно пользователям таки лучше по старинке;)

Да ладно вам, конечно людям, которые не связаны с IT сферой, это будет непонятно (по крайней мере после первого чтения), но для людей, которые только начинают разбираться в этом аде, статья может привнести порядок в мысли, что очень даже полезно 🙂

от программиста программистам

остальным не понятно чуть более чем полностью

Автор, вы или напейтесь, или протрезвейте.

1. Когда пытаешься что-то донести до потенциальной аудитории, то надо следовать простой цепочке действий:

— обозначить пути решения

— пройти по каждому из путей

— найти оптимальный (для вашей задачи не применимо, можно забить)

2. Что у вас за проблема? Никто не программирует? ИМХО, начинающих до фига или чуть больше. Качество кода соответствующее, причем авторы считают себя если не гениями, то где-то рядом. Причем мало кто в курсе, что такое стандарты написания кода.

3. Какие пути решения предлагаете к необозначенной проблеме? Писать код? Без понимания где он должен будет работать? В какой среде и кем он будет исполняться? Нативный ли это будет код для системы или интерпретируемый? Пофиг, пишем?

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

«Программирование на основе концепции классов и объектов» будет понятнее?

Лично я специально написал «формально» т.к. лично я считаю, что языки разметки (HTML, PostScript, TeX) должны быть выделены в отдельную категорию. Не данные, но и не программы.

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

А что, если я скажу, что парадигмой, а не прадигмой?

Ну, все теперь, укатал ты его.

пост хороший, но нихрена не понятно

Коротко.

Тыжпрограммист

В этот томный вечер хочу поделиться с вами умопомрачительной историей о своих связях с криминальным миром.

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

В этой истории фигурирует и преступная группировка, и команда исследователей, благодаря которым всё случилось, и ФБР, куда же без родимых. Украденные деньги почти полностью вернули обратно, участники отсидели несколько лет в американских тюрьмах. Общественность пребывала в ах*е, а личность Левина стала культовой — это всё вы почитайте сами в инторнетах, если возникнет желание (например, тут: https://darknetdiaries.com/transcript/23/ ).

А вот чего в инторнетах вы не прочитаете (ну разве что сейчас), так это историю о том, как я консультировалась у Левина. Насчёт создания сайта. На джумле.

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

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

Но меня нокаутировали ответом — это не важно. Почитай в интернете, как делать сайты, ну в самом деле. Изи-бризи же, ну. А если будет нужно, то и коллайдер соберёшь и неча ныть.

И вот тебе номер телефона моего хорошего знакомого Вовы Левина, он пособит советами, если что.

Кто такой Владимир Левин, я тогда не знала. У меня был спасительный номер и задание: сделать новостной сайт. Я перечитала тонну материалов, у меня кровоточили глаза от попыток разобраться в коде. В итоге, я наткнулась на конструкторы сайтов и выбрала джумлу. Молодёжь, внимание. Джумла — это вам не современная удобная тильдочка, где кодить вообще не нужно. Этот монстр требовал какого-никакого процесса и это было мучительно: маркетолог, искусствовед, гуманитарий, несчастная душа, влипшая в очередную передрягу. В общем, я разрыдалась, сдалась, собрала накопившиеся вопросы и позвонила своему спасителю.

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

Я не понимала. Но я сделала сайт и очень гордилась собой.

Спасибо вам за помощь, Владимир Леонидович! 🙂

Увидела пост про Паука-Программиста, и не смогла пройти мимо )

Мой паук получился примерно 8 см длиной без учета ножек. Связан из неизвестных х/б ниток, набит синтепухом. Глазки на безопасном креплении.

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

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

Помогите вспомнить цитату

Не могу вспомнить или найти цитату, как я думаю её автор Б. Шнайер в книге Прикладная криптография.
Смысл цитаты в том, что математика (криптографический алгоритм) идеальна, компьютеры уязвимы, а люди (операторы) и есть уязвимость.

И юзеры такие:

Новая незнакомая пряжа дала неожиданный результат. Мне хотелось купить хоть что-нибудь, лишь бы не YarnArt Dolce.

На глаза попалась Kartopu Elegance. Ниточка у нее тоньше: в потоке 100 гр. длина 180 м. Она оказалась менее пушистой на ощупь, но зато имеет очень красивый бархатистый блеск в изделии.

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

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

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

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

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

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

Надпись на паучьей жопе гласит «I see all bugs». Что логично, Паук же всё-таки.

Чуть позже по этой же схеме был связан Паук Саурон В общем, вязанные пауки крутые, будьте, как вязанные пауки: опасными, глазастыми, милыми и пушистыми!

*Плачущий ТС*

Новый тест TelegramTV бота

Доброго времени суток.

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

А именно доработкой своего TelegramTV бота: @t_tv_bot (текущая версия)

Что я сделал в новой версии на данный момент:

— Взял за основу базы каналов всем нам известный сервис iPTV, чье имя нельзя произносить в слух. Более 1000 каналов.

— Добавил возможность подгрузить весь список каналов по команде /playlist

— Добавил возможность посмотреть список доступных групп каналов по команде /groups

— Добавил возможность подгрузить список каналов только нужной группы

— Добавил поиск нужного канала в базе по названию

Ссылка на тестовый TelegramTV bot: @ttvdemo_bot

Приглашаю всех протестить мое творение и высказать свои мнения.

По ограничениям на данный момент.

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

Ссылки на потоки во время теста временные, поэтому копировать, воровать и прочее бесполезно. Не тратьте время.

С нетерпением жду комментарии

Бедный Тимми

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

Все нижеприведённые примеры являются строками в понимании питона:

s = ‘text’ # одинарные апострофы
s = «text» # одинарные двойные кавычки
s = »’text»’ # тройные апострофы
s = «»»text»»» # тройные двойные кавычки

Строкой является любой символ (или последовательность символов), заключённый в литералы строк, в т.ч. пробелы, цифры, знаки препинания.

Обратите внимание на последний пример. Он начинается и заканчивается пробелами. Эти пробелы так и будут выводиться на экран и сами собой никуда не денутся. Это важно, потому что пробел также является символом строки и элементом последовательности. В данном случае при принте первого и/или последнего элемента мы не увидим ничего на экране. Но тем не менее, эти пробелы там будут, потому что они включены в строку и являются её элементами, хоть и не имеют визуального отображения. Что с этим делать и как быть, мы обязательно поговорим во второй части.

Читайте также:  Как на чеченском языке будет мама

В чём разница одинарных и тройных литералов? Стандартно для объявления строк в коде мы используем одинарные кавычки или апострофы. И чаще всего такие строки являются короткими.

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

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

Сейчас внимательно следите за порядком слов «кавычки» и «апострофы». Если внутри самой строки должны содержаться апострофы или кавычки, то сама строка должна обрамляться соответственно кавычками или апострофами:

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

1. использовать тройные кавычки или апострофы (при чём без разницы, что вы из них выберете),

>>> «»»O’Reilly published D.Beazley’s book «Python Cookbook» in 2013″»»
‘O\’Reilly published D.Beazley\’s book «Python Cookbook» in 2013’

>>> ‘O\’Reilly published D.Beazley\’s «Python Cookbook» in 2013’
‘O\’Reilly published D.Beazley\’s «Python Cookbook» in 2013’
>>> «O’Reilly published D.Beazley’s \»Python Cookbook\» in 2013″
‘O\’Reilly published D.Beazley\’s «Python Cookbook» in 2013’

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

>>> s = «Мама мыла раму\nМила раму мыла»
>>> print(s) # только функция print понимает, что делать со спецсимволами
Мама мыла раму
Мила раму мыла
>>> s # в этом случае просто выводится содержимое переменной
‘Мама мыла раму\nМила раму мыла’

Achtung! Achtung! Приятные новости: в длинных строках всё это не нужно! =)

>>> s = «»»Эта очень длинная строка
. сама переносится, сама табулируется
. сама экранируется \.»»»
>>> print(s)
Эта очень длинная строка
сама переносится, сама табулируется
сама экранируется \.
>>> s
‘Эта очень длинная строка\nсама переносится, сама\tтабулируется\nсама экранируется \\.’

>>> s = «»»Но если вдруг вам будет очень нужно прописать здесь что-то вроде ‘\n’, то вам нужно воспользоваться экранированием, чтобы \\n не выполнялся»»»
>>> print(s)
Но если вдруг вам будет очень нужно прописать здесь что-то вроде ‘
‘, то вам нужно воспользоваться экранированием, чтобы \n не выполнялся

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

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

Лаконично, просто и понятно. Вот её сигнатура:

Она говорит нам о том, что:

Собственно, что это вдруг я её вспомнил? Посмотрите ещё раз внимательно. В числе её параметров присутствуют такие вещи как sep=’ ‘ и end=’\n’. Оба этих параметра принимают любые строковые символы, в том числе экранируемые. Зачем это нужно знать? Затем, чтобы иметь возможность оформлять вывод по своему желанию.

>>> a = «Мама»
>>> b = «мыла»
>>> c = «раму»
>>> print(a, b, c) # стандартный принт трёх переменных
Мама мыла раму
>>> print(a, b, c, sep=’\t’) # делаем разделителем табуляцию
Мама мыла раму
>>> print(a, b, c, sep=’\t’, end=’\n\n’) # добавляем лишнюю пустую строку по окончанию вывода
Мама мыла раму
>>> print(a, b, c, sep=’42’)
Мама42мыла42раму
>>> print(a, b, c, sep=’42’, end=’THE END’)
Мама42мыла42рамуTHE END

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

Но проще и лучше отформатировать строку заранее, чем пытаться подстроить под неё принт.

Кроме самих кавычек и апострофов в питоне существуют так называемые префиксы, которые определяют подвид строки. Их немного, я перечислю все, но остановлюсь только на тех, с которыми вы столкнётесь раньше всего и будете в последствии сталкиваться регулярно. Такими префиксами являются (в скобках указаны альтернативные виды написания:

Не знаю, как там у настоящих серьёзных программистов в свитерах из собственной бороды, но в простой мирской жизни вам понадобятся три вида строк: обычные, сырые и форматированные. Ну иногда и «сыроформатированные», но намного реже.

Префиксы указываются до литералов без пробелов, например:

>>> s = ‘\a\nМама’ # обычная строка
>>> print(s)
# в этом месте сработал символ переноса строки «\n»
Мама

Сырые строки можно использовать как минимум в трёх случаях:

— в регулярных выражениях,

— для хранения файловых путей Windows, поскольку в них содержатся обратные слэши;

— для хранения сложных математических формул в разметке LATEX.

Байтовыми строками являются строки, отражающие двоичную структуру любых данных, в том числе текста, картинок, музыки, видео и т.д. При работе с текстом такие строки возникают при кодировании строки методом encode():

Если к вам вдруг прилетела байтовая строка, то чаще всего её можно привести в человеческий вид при помощи обратного метода decode():

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

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

Итак, до версии 3.6 нужно было делать примерно так:

И всё это длинно, долго, муторно. А вот всё то же самое, только в f-строке:

>>> name = «Вася»
>>> surname = «Пупкин»
>>> age = 18
>>> s = f’Это . Его фамилия . Вчера ему исполнилось лет.’
>>> print(s)
Это Вася. Его фамилия Пупкин. Вчера ему исполнилось 18 лет.

Всё это, конечно же, дублируется в отдельном канале в телеге. По всем вопросам обращайтесь через Telegram.

P.S. Большое спасибо всем моим подписчикам за поддержку и активность! Без вас я, возможно, не решился бы продолжать.

Ссылки на предыдущие посты:

ПЕРВОЕ ЗНАКОМСТВО С PYTHON

Python (в русском языке распространено название пито́н или па́йтон) — кроссплатформенный высокоуровневый язык программирования общего назначения, ориентированный на повышение производительности разработчика и читаемости кода.

Эту фразу видели все, кто хоть раз в жизни открывал статью про Python на Википедии. Вроде бы всё просто и ясно, но как-то не очень. Уже здесь встречаются непонятные термины: кроссплатформенный, высокоуровневый… Дать ёмкое и понятное определение чему бы то ни было – это великое искусство. Поэтому, я думаю, стоит пояснить всё вышесказанное простыми словами. А простыми словами это выглядит примерно так: Пайтон – это язык программирования, который можно использовать на любой известной стандартной операционной системе (Windows, MacOs, Linux) и при помощи которого можно написать практически любую программу (от «Привет, мир!» до новой операционной системы или нового языка программирования). Звучит заманчиво, не так ли?

Пайтон был придуман в 1991 году голландцем Гвидо ван Россумом, также известным как «великодушный пожизненный диктатор». Именно он по сей день принимает окончательные решения о том, как именно будет развиваться язык. Кстати, последняя версия питона (3.9.0) вышла буквально на днях – 05.10.2020. Её главная особенность для новичков, на мой взгляд, в том, что для её установки требуется минимум Windows 10 (на семёрку она не инсталлируется). Всё, чему будут посвящены мои статьи, гарантированно будет актуальным для версий 3.6.0-3.9.0. Версии питона 2.Х здесь рассматриваться не будут, т.к. для разработки новых приложений они уже не используется, а те, кто всё ещё стоически поддерживает приложения, написанные на них, вряд ли будут всё это читать.

Этой командой мы узнаём адрес той ячейки памяти, где у нас лежит число 5 – это ячейка 1609562080 (у вас может быть другое значение – это неважно).

Следом выполним ещё пару команд:

То же самое?! Да, именно так. Переменная «b» ссылается всё на ту же самую пятёрку. Последняя проверка этой теории:

Возникает вопрос: а что же тогда такое знак «=» в данном случае? В питоне знак «=» не знак равенства, а оператор присваивания. Равенство в питоне выражается через оператор «==», который используется исключительно в булевой логике, т.е. для сравнения значений и/или содержимого разных объектов.

Итак, вывод: в питоне переменных нет, знак «=» не приравнивает значение к переменной и не записывает значение в переменную, а присваивает какому-либо объекту именную ссылку для удобства обращения.

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

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

Вот и всё, теперь переменная «а» ссылается уже не на целочисленный объект 5, а на строковый объект 5. Для наглядности я сразу запросил тип каждого из объектов, и оснований не верить результатам лично у меня нет: вначале пятёрка – это число, в конце – строка. Об этом говорит не только type(a), но и само значение, которое раньше было голой пятёркой, а теперь обрамлено кавычками.

Подобным образом тип любого объекта можно менять очень быстро в зависимости от нужд разработчика, и в этом прелесть. Почему это одновременно и боль? Потому что динамическая типизация к огромному сожалению отбирает большое количество ресурсов, что сказывается на производительности и быстродействии. Да, это какие-то там микросекунды, но они очень важны. Кроме того, неопытные разработчики очень любят использовать эту прелесть без особой нужды, что, во-первых, отъедает ресурсы, а во-вторых, даёт подчас внезапные неожиданные результаты. Например, вы бы хотели ожидать на выходе работы программы целое число, а получаете строку. Казалось бы, чего проще – ну переделай её обратно в число и живи счастливо? Но согласитесь, что это как минимум неудобно, когда вам нужно неожиданный результат потом как-то обрабатывать и приводить к нужному типу. Это дополнительный код, а значит дополнительное время на его написание, на его работу и на его поддержку. А время – деньги.

Стиль кодирования. PEP8

У каждого языка программирования, как и любого другого языка, есть свои законы, которым он подчинён. Если русском языке мы пишем названия месяцев со строчной буквы (9 мая, 8 марта), то в английском, например, месяцы всегда пишутся с прописной (January, 4th of July). Питон также имеет свою семантику, грамматику и свой синтаксис. Основным сводом законов, определяющих требования к красивому и качественному стилю кодирования определены в документе, который называется Python Enhancement Protocol 8 или PEP8. Основные правила на самом деле достаточно просты, но почему-то на каждом новом курсе я встречаю людей, упорно их игнорирующих.

Давайте начнём с того, что Python – язык международный. Это вам не 1С, на котором пишут в буквальном смысле по-русски. В питоне всё по-английски. Всё и всегда. Мне попадались 2 уникума, которые упорно именовали переменные по-русски. Объясняли они это тем, что «так понятнее». Нет, если вы не знаете английского, то вам, возможно, будет понятнее. Но нужно учитывать, что IT – это англоязычная среда, все программы, и 90% документации написаны именно на английском, и, в конце концов, ваш код могут читать (а большинство времени будет потрачено именно на его чтение, причём не только вами) люди, не знающие русского. Ну или давайте наоборот: вам прислали на проверку кусок кода, где половина на хинди или суахили. Как вам такое? Возьмите себя в руки и если вы не знаете или плохо знаете английский – начните его учить с нуля. Не брезгуйте онлайн-переводчиками и словарями для выбора имён переменных и функций – это не стыдно.

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

Не проще ли было сразу назвать эти переменные по-человечески (в прямом смысле)? Давайте попробуем:

Выхлоп не изменился, но мозгу становится понятнее, глазу приятнее. Осталось разобраться с «i».

В строке «for i in string» «i» является ничем иным как временной переменной. Её тоже нужно уметь красиво и понятно назвать. Как показывает моя собственная практика, иногда хорошее, грамотное название переменной снимает у студентов возникшие вопросы по дальнейшим действиям. Они внезапно начинают понимать, что делали не так и что нужно на самом деле делать и куда двигаться. Так давайте уже её переделаем и пойдём дальше:

>>> number = 5
>>> string = «mama»
>>> for letter in string:
. print(letter * number)
.
mmmmm
aaaaa
mmmmm
aaaaa

Именно это и описано в PEP8 – как писать качественный код, отвечающий требованиям и стилю Python, или как принято говорить – pythonic style или pythonic way. Многие из нас, кто ещё в школе пытался учиться программированию, помнят такой язык, как Basic или QBasic. Потом он перерос в VBA и до сих пор (к сожалению…) используется для написания макросов в офисных программах Microsoft. И в связи с этим у многих из нас при изучении питона всплывает Basic style – стиль кодирования на Basic. Pythonic style ушёл намного дальше. Читаемость кода за счёт простоты синтаксиса повысилась в разы. Вот для наглядности пример.

Задача: получите из входного потока число и напечатайте сумму его цифр.

Как бы эту задачу решило большинство в «Basic style»:

>>> number = input()
>>> summa = 0
>>> for dig in number:
… if dig in ‘0123456789’:
… summa = summa + int(dig)
>>> print(summa)

Как это решается в «Pythonic style»:

Возможно, вам сейчас ничего не понятно из того, что тут написано, но вам стоит оценить хотя бы то, сколько сил и времени сэкономлено за счёт сокращения количества строк. «Достаточно одной таблетки» (с). В данном случае – одной строки, а результат одинаковый.

Давайте тезисно определим основные правила синтаксиса:

— используя питон, мы пишем на английском языке;

— все названия переменных, функций, классов должны как можно полнее отражать их суть и содержание;

— названия переменных и функций принято писать в нижнем регистре, разделяя слова подчёркиванием (snake_case):

#НЕ правильно
MyNumber = 42
Mynumber = 42
MYNUMBER = 42
mynumber = 42
МоЙнОмЕр = 42
def MyFunction():
def Myfunction():
def MYFUNCTION():
def myfunction():

— названия классов принято писать в CamelCase – слова пишутся с заглавной буквы без разделителей между словами:

#НЕ правильно
все остальные варианты

— для названия переменных, функций и классов нельзя использовать зарезервированные слова (слова, которые зашиты в питоне в качестве операторов, имен встроенных функций, классов и их атрибутов и методов);

— конец строки является концом инструкции (никакие специальные знаки не требуются);

— вложенные инструкции объединяются в блоки по величине отступов. 1 отступ = 4 пробела;

— вложенные инструкции в Python записываются в соответствии с одним и тем же шаблоном: основная инструкция завершается двоеточием, вслед за которым располагается вложенный блок кода с отступом в 4 пробела под строкой основной инструкции.

if a == 1:
print(‘mama’ * 3) # 4 пробела после двоеточия

— в случае, если длина инструкции превышает 80 знаков, допустимо записывать одну инструкцию в нескольких строках. Достаточно ее заключить в пару круглых, квадратных или фигурных скобок:

if (a == 1 and b == 2 and
c == 3 and d == 4): # продолжение инструкции выравнивается по открывающей скобке
print(‘mama’ * 3) # 4 пробела после двоеточия

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

— технически возможно записать несколько инструкций в одной строке, разделяя их точкой с запятой (но такой способ не приветствуется, т.к. не соответствует стилю кодирования PEP8):

Это основные вещи, которые нужно выучить. Благо, что мы живём в 21 веке и рабочие среды уже давно умеют анализировать наш код на соответствие стилю, а также полно разнообразных сторонних линтеров. Поэтому, если вы переживаете, что вы не осилите этот момент – ваша IDE вам подскажет, где что поправить, и в большинстве случаев – сама же и поправит. Если она этого самостоятельно делать не умеет, то можно воспользоваться сторонними линтерами.

Что будет, если на всё это забить и писать как бог на душу положит? Да ничего. Просто вас проклянут до десятого колена те, кто будет это читать, а в остальном ничего.

Также у питона есть свой собственный сборник мантр, который также призван формировать хороший стиль у разработчиков. Выполним в консоли команду:

Перевод на русский конечно же существует:

Дзен Пайтон (составлен Тимом Питерсом)
Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложное лучше, чем запутанное.
Плоское лучше, чем вложенное.
Разреженное лучше, чем плотное.
Читаемость имеет значение.
Особые случаи не настолько особые, чтобы нарушать правила.
При этом практичность важнее безупречности.
Ошибки никогда не должны замалчиваться.
Если не замалчиваются явно.
Встретив двусмысленность, отбрось искушение угадать.
Должен существовать один — и, желательно, только один — очевидный способ сделать это.
Хотя он поначалу может быть и не очевиден, если вы не голландец (это такая шутливая отсылка к Гвидо).
Сейчас лучше, чем никогда.
Хотя никогда зачастую лучше, чем прямо сейчас.
Если реализацию сложно объяснить — идея плоха.
Если реализацию легко объяснить — идея, возможно, хороша.
Пространства имён — отличная вещь! Давайте будем делать их больше!

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

Можно написать в консоли print(), нажать Enter – программа отработает без ошибок, но ничего напечатано не будет. И это нормально, ведь мы не сказали функции, что именно ей нужно напечатать. Пока что мы просто заставили её сработать вхолостую, что она и сделала.

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

Текст в питоне – это тип данных «строка» (подробнее о них мы поговорим в следующий раз, и поверьте, там есть о чём). Строки должны быть заключены в кавычки.

Hello, world! – это не строка.

«Hello, world!» – а вот это уже строка.

Значит именно так мы и должны передать её в функцию print.

Отлично, мы сделали это! Но, можно ещё интереснее. Например, можно записать строку в переменную, передать в функцию эту переменную и распечатается та же строка:

Мне надоело здороваться со всем миром, я хочу разнообразия. Для этого я хочу сам говорить программе, с кем поздороваться. Для этого я вызову функцию ввода с клавиатуры «input».

На сегодня это всё, спасибо за внимание!

Всё это, конечно же, дублируется в отдельном канале в телеге. По всем вопросам обращайтесь через Telegram.

P.S. Большое спасибо всем моим подписчикам за поддержку и активность! Без вас я, возможно, не решился бы продолжать.

Ссылки на предыдущие посты:

Предлагаю помощь в освоении Питона

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

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

— материала много, и всё за один вебинар рассказать не удаётся (ограниченная подача информации),

— материал подаётся бессистемно и сбивчиво (неопытность лектора как преподавателя),

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

— а также многое другое.

Сразу хочется предупредить восклицание «да это просто студенты тупые». Отнюдь. Когда человек сам платит деньги за обучение – он обычно знает, чего хочет и зачем ему это нужно. То есть он готов и хочет учиться, но не может воспринять материал, вследствие чего в его голове возникает каша из бессистемных знаний. И всё это уже на базовом уровне, то есть именно там, где всё нужно не просто забить к себе в голову, а разложить по полкам и знать где и что лежит, чтобы в нужный момент это взять, даже если вас подняли посреди ночи. Дело не в зубрёжке. Дело в понимании. Если нет понимания процесса, то нет и возможности этот процесс реализовать.

Не ждите, что я вам скажу что-то принципиально новое. Всё, что я буду излагать, можно было бы легко найти в другом месте. Есть куча сайтов с бесплатным контентом и даже бесплатными курсами. Всё это легко гуглится. Я сам их использовал в своё время, да и сейчас иногда проще что-то быстро нагуглить, чем читать специальную литературу или официальную документацию. В то же время, могу сказать, что лично мне некоторых вещей очень не хватало на старте изучения Python. Прежде всего, не хватало объяснения под другим углом, с другими примерами, иногда очень хотелось повышенной многословности вместо сухих фраз или просто брошенных кусков кода («читай – там всё написано»).

Я рассчитываю, что эти статьи вам помогут начать писать свои собственные программы «для дома, для семьи». Мы не будем лезть в такие дебри, как например, асинхронность. Мы также не будем рассматривать такие библиотеки как NumPy, matplotlib. Только необходимый минимум, только база, никакого хардкора. Но мы будем это делать обстоятельно и поступательно, связывая одно с другим и обрастая нужной информацией углубляться дальше. В каждой теме будут присутствовать примеры в виде рабочих и понятных кусков кода (никаких бессмысленных foo-bar).

В первом приближении план таков:

План неокончательный ни по составу, ни по компоновке, но общий скелет и путь именно такой.

Надеюсь, что всё это поможет всем, кто ищет помощи, но не может её по каким-то причинам найти.

Ещё раз повторюсь: я не являюсь истиной в последней инстанции и не претендую на то, чтобы понравиться всем. Кому-то зайдёт, кому-то нет – это нормально, т.к. обучение – это всегда очень индивидуально, потому что субъективно.

Источник

Интересные факты из жизни