О-о-о, эта глава будет очень большой. Дело все в том, что строки – это крайне мощный инструмент. И неудивительно: довольно большую часть времени программисты так или иначе взаимодействуют с текстом. Если в полной мере освоить этот инструмент, то можно делать воистину сложные вещи. Фан-факт: некоторые игры хранят данные об игроке, состоянии игры и даже целые карты в обычных текстовых файлах, а значит, как простой текст. А чтобы потом получить из этого текста данные для команд в игре, программисты пишут специальные парсеры, которые позволяют разобрать строки по кускам и дальше что-то с ними делать.
Так что научиться работать с текстом - жизненно важно программисту :)
В одной из начальных глав вы узнали, что строки (или тип str) — это базовый тип данных, который существует в Python (а вообще, в любом языке программирования). Так как с текстом программисты работают очень часто (если не постоянно), стоит рассмотреть работу со строками подробнее и четко обозначить, какие особенности есть при работе с ними.
По сути, строка — это последовательность символов. Причем эта последовательность может состоять из чего угодно: букв, цифр, знаков и других печатных элементов.
Строка является простым типом данных, то есть элемент хранится в памяти в одной ячейке, как число (это мы помним из главы про списки). Но в отличие от чисел или булевых типов, строка, равно как и список, является последовательностью. А значит, у каждого символа, также как и у списков, есть свой индекс.
Возможно, вы уже начали догадываться, что взаимодействие со строкой будет очень похожим на то, как мы работали со списками :)
И это действительно так! Длина, индексация, подсчет количества элементов — эти и некоторые другие операции действительно одинаковы как для строк, так и для списков.
Это объясняется полиморфизмом методов: так как по смыслу они выполняют одинаковые функции, названия у них также совпадают.
Однако, конечно, существуют и отличия.
Строка — это неизменяемый тип данных. Несмотря на наличие индексов, строки нельзя изменять по индексу, как это возможно в списках. Такие последовательности называются немутируемыми, то есть их нельзя изменять после создания.
Можно ошибочно подумать, что строка изменяется, когда мы соединяем две строки с помощью оператора сложения (+.) Однако на самом деле при этом создаётся новая строка, которая хранится в другой ячейке памяти.
Доказать это можно, проверив идентификаторы объектов в памяти с помощью функции id(). Таким образом можно увидеть, что после конкатенации строки переменная ссылается на новый объект.
Интересно, что операция конкатенации работает не только для строк, но и для списков. При этом, как и в случае со строками, итоговый объект будет новым. Конкатенация не изменяет исходные списки, в отличие от метода append(), который модифицирует существующий объект.
Интересный момент: строки можно “умножать” на числа! Такая возможность есть не во всех языках программирования, но Python это поддерживает.
По аналогии с конкатенацией строк, умножение действует как многократное сложение строки. Например, выражение 'str' * N просто повторяет строку N раз. Это позволяет получать интересные результаты при использовании данной операции.
Попробуйте переписать эту программу и изучите, как она работает
Создайте файл "strength_password.py"
Напишите программу, которая проверяет сложность пароля пользователя. Пользователь вводит некоторый пароль, который хочет использовать в почте. Нужно проверить, насколько он соответствует требованиям:
Длина не меньше 8 символов
Только латинские символы
Есть по крайней мере одна строчная и одна прописная буква
Есть по крайней мере 1 цифра и 1 спецсимвол (из группы !@#$%^&*()"№)
Пароль не должен содержать следующие последовательности: qwerty, 12345, 1234, или abcd1234.
Внимание! Эта задача чуть дальше в главе будет улучшена минимум дважды :)
Подсказка: вы можете спокойно сравнивать элементы строки посредством операторов. Например 'A' <= 'H' <=' Z' – это вполне себе допустимое выражение.
У строк довольно много методов. Некоторые вы уже знаете: split и join (создающие строку из списка и наоборот, делающие список из строки).
Конечно, это не единственные методы, которые есть у строк. Вообще строки - это довольно мощный по своей структуре объект, и обрабатывать информацию в нем можно множеством способов.
– И мне всё это надо выучить??
– Нуу, не всё, конечно. На самом деле, многие из этих команд можно запомнить по мере выполнения задач и практики на python. Основное, что точно понадобится – это поиск, методы для списков, преобразование в большие/маленькие символы, проверку на число/строку и замена символа. Это те команды, что часто встречаются на практике.
Создайте файл strength_password_methods.py.
Напишите программу, которая проверяет сложность пароля пользователя. Пользователь вводит некоторый пароль, который хочет использовать в почте. Программа должна проверить, насколько пароль соответствует следующим требованиям из предыдущей задачи.
Выведите также пользователю, какие требования НЕ были выполнены.
Подсказка: используйте следующие методы строк (не обязательно все!) для выполнения этого упражнения:
isalpha()
isdigit()
islower()
isupper()
find()
В Python существуют специальные литералы для строк, которые называются escape-последовательностями. Эти последовательности используются для представления специальных символов, которые не могут быть напрямую введены в строку или не являются “видимыми” при обычном вводе. Они начинаются с обратной косой черты (\), которая сообщает Python, что следующий символ имеет особое значение.
Ниже будет табличка с примерами литералов и их использованием
– Так, я не могу понять, что еще за каретка и забой?
– Эти термины пришли к нам из времен, когда использовались пишущие машинки и ранние текстовые терминалы. Сейчас объясню :)
Каретка — это элемент старых пишущих машинок, который передвигался влево после набора каждой буквы. Когда каретка доходила до конца строки, её нужно было вернуть в начало для печати следующей строки. Возврат каретки — это перемещение печатающего элемента в начало строки без перехода на следующую строку.
В программировании литерал \r (возврат каретки) используется для перемещения курсора в начало текущей строки. При этом то, что уже напечатано на строке, может быть перезаписано новыми символами.
Забой — это действие удаления символа, которое происходит как при нажатии клавиши “Backspace” на клавиатуре. В программировании литерал \b обозначает удаление предыдущего символа (забой).
Когда используется литерал \b, он удаляет один символ слева от текущего курсора.
Есть ситуации, когда вы не сможете увидеть полноценную работу некоторых кареток, в частности, забоя. Эта поблема может возникать в тех ситуациях, когда терминал не поддерживает полный набор управляющих символов, или есть буферизация из-за IDE.
Чтобы наверняка увидеть работу этих кареток, вам понадобится запускать вашу программу через терминал (запускайте программу двойным щелчком мыши, а не через IDLE или через консоль).
В Windows все довольно просто, вы можете открыть файл с программой двойным щелчком левой кнопки мыши. Только поставьте в конец input(), чтобы программа не закрывалась сразу после закрытия.
С MacOS все не так просто. Вам нужно полноценно запустить его из консоли.
Узнайте точный путь до вашего файла. Правой кнопкой мыши (или тап двумя пальцами) откройте контекстное меню. Откройте "свойства"
Выделите и скопируйте путь из строки "Где" или "Where"
Откройте программу Терминал
Введите в терминале cd <ваш путь без скобок>
После чего запустите программу командой python3 <имя_файла>.py , так вы запустите программу через консоль
Периодически возникает ситуация, когда нужна сырая строка. Сырая строка – это когда escape-последовательности, вроде \n, \t и другие не будут обрабатываться, а будут восприниматься буквально. Для этого перед строкой ставится буква r (буквально от raw – сырой).
Сырые строки часто используются, когда вам нужно работать с путями файлов, регулярными выражениями или текстом, содержащим много обратных косых черт, где обработка escape-последовательностей может создать проблемы.
Создайте файл flow_word.py.
Напишите программу, которая будет делать имитацию движения слова. Реализуйте задачу поэтапно.
Сначала определите текст в переменную, который будет "бежать" по экрану. Это может быть строка, которую введет пользователь
Сделайте переменную, которая будет содержать "длину экрана". Например, 40 или 200, это будет что-то вроде ширины консоли
Напишите цикл на количество кругов длины экрана
В цикле опишите строку по формату f"\r{' ' * i}{text}", в этом выражении:
{' ' * i} — это создание строки, состоящей из пробелов. Количество пробелов увеличивается на каждом шаге цикла, что сдвигает текст вправо.
\r — возврат каретки. Он перемещает курсор в начало строки, позволяя перезаписывать строку на каждом шаге цикла, создавая эффект движения.
Выведите эту строку через print, а в параметре end задайте пустую строку, чтобы каретка заменяла именно пустую строку
Добавьте с помощью библиотеки time задержку на 0.1 секунду, чтобы это не происходило моментально
* Если разобрались, как это работает, попробуйте сделать так, чтобы слово двигалось и в обратную сторону тоже.
ASCII (American Standard Code for Information Interchange) — это стандарт кодирования, который представляет символы в виде числовых значений. Впервые создан в 1960-х годах, ASCII стал основой для большинства систем кодирования текстов в компьютерах. Он представляет буквы английского алфавита, цифры, знаки препинания и управляющие символы, такие как пробел или символ новой строки. Каждый символ ASCII имеет числовое представление от 0 до 127.
Каждый символ в ASCII — это просто число. Например:
A — это 65
a — это 97
0 — это 48
Этот стандарт позволяет компьютерам интерпретировать символы как данные, и их легко обрабатывать, передавать или хранить.
В Python взаимодействие с кодировкой ASCII и символами осуществляется с помощью встроенных функций ord() и chr().
ord() — принимает символ и возвращает его числовой код в ASCII.
chr() — принимает число и возвращает соответствующий ему символ.
Таким образом, Python позволяет вам напрямую преобразовывать символы в их числовые коды и обратно.
Кодировка ASCII позволяет легко работать с символами на уровне их числовых представлений. Это особенно полезно при работе с шифрами (например, шифр Цезаря), сортировкой строк и других операций, которые требуют преобразования символов в числа и наоборот.
Особенности:
Простота
ASCII включает только английский алфавит, цифры и основные символы. Это делает его лёгким и быстрым для обработки, но ограниченным для работы с текстами на других языках.
Управляющие символы
Помимо букв и цифр, ASCII включает управляющие символы, такие как \n (новая строка) и \t (табуляция). Эти символы не отображаются на экране как буквы, но они контролируют форматирование текста.
Расширенный набор символов
Для работы с символами других языков используют расширенные стандарты, такие как Unicode. В Python 3 по умолчанию используется Unicode, который поддерживает гораздо больше символов (в том числе символы из других языков).
Допустим, вы хотите сдвинуть букву в алфавите на несколько позиций, как в шифре Цезаря. Вы можете сделать это с помощью ord() и chr():
Создайте файл caesar.py.
В этом уражнении вы напишете примитивный шифр Цезаря. Суть его заключается в следующем: каждый символ исходного сообщения сдвигается влево или вправо на N количество. Например, если сдвиг вправо на 4 то A станет E, E станет I, Y станет C и так далее.
Напишите программу, которая принимает строку от пользователя и число, на которое будут позиии сдвинуты вправо в алфавите с использованием кодов ASCII. Символы, которые не являются буквами (например, пробелы или знаки препинания), не должны изменяться.
Программа должна работать только с буквами (как заглавными, так и строчными).
Символы, которые идут после z или Z, должны “заворачиваться” обратно на a или A.
Все остальные символы остаются без изменений.
Введите строку: Hello, World!
Введите сдвиг: 2
Зашифрованная строка: Jgnnq, Yqtnf!
Создайте файл hack_password.py.
Напишите программу, которая принимает строку (пароль) от пользователя. Затем программа начинает “взламывать” пароль, перебирая символы один за другим, и в конце находит правильный пароль, показывая это в виде анимации.
Пользователь вводит пароль.
Программа имитирует процесс подбора пароля, постепенно изменяя символы.
Для каждого символа программа использует случайные символы из ASCII, пока не найдет правильный.
Анимация продолжается до тех пор, пока все символы не будут “угаданы” правильно.
Ввод пароля
Пользователь вводит пароль, который программа будет пытаться “взломать”.
Генерация случайных символов
Программа использует функцию random.randint(), которая выбирает случайный символ из диапазона ASCII (от символа ! до ~).
На каждом шаге программа перебирает символы для каждой позиции пароля, пока не найдёт правильный символ.
Анимация взлома
Программа постепенно “угадывает” каждый символ пароля.
На каждом шаге текущий символ обновляется на случайный и выводится на экран.
Как только программа находит правильный символ, она переходит к следующему символу в строке.
time.sleep(0.05) создаёт задержку, чтобы имитировать процесс подбора символов.
Завершение
Когда все символы подобраны правильно, программа выводит сообщение о том, что пароль найден.
На этом,конечно, еще не все. За "скобками" осталась тема метода format и регулярных выражений, но это будет в более подробном курсе по python.