lab

ЛАБОРАТОРНАЯ РАБОТА №4

Тема: Кортежи. Диапазоны. Двоичные последовательности

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

ОГЛАВЛЕНИЕ

1 Кортежи
1.1 Создание кортежей
1.2 Модуль random
1.3 Создание игры "Анаграмма"
2 Диапазоны
3 Двоичные последовательности
3.1 Тип bytes
3.2 Тип bytearray
3.3 Операции над объектами типов bytes и bytearray
Индивидуальные задания

 Оглавление

1 Кортежи

Кортежи в языке Python имеют тип (класс) tuple и представляют собой неизменяемые последовательности элементов, значениями которых могут быть данные разных типов. По сути это списки, которые нельзя после создания изменять.

 Оглавление

1.1 Создание кортежей

Подобно другим рассмотренным типам кортежи могут быть созданы как в виде литералов, так и с помощью консруктора класса – встроенной функции tuple([iterable]) (см. подраздел 8.1 лаб. раб. №1).
При использовании литерала в круглые скобки помещают элементы кортежа, разделенные запятыми:

>>> a_tuple=(3.45, 'JS' , [1,2])
>>> a_tuple
(3.45, 'JS', [1, 2]).

Можно круглые скобки не указывать, перечисляя элементы кортежа через запятые. Результат будет тот же:

>>> a_tuple=3.45, 'JS' , [1,2]
>>> a_tuple
(3.45, 'JS', [1, 2]).

Выполняется и обратная операция – отдельным объектам присваиваются значения элементов кортежа:

>>> a,b,c=a_tuple
>>> a
3.45
>>> b
'JS'
>>> c
[1, 2].

При использовании функции tuple([iterable]) в качестве ее аргумента указывается итерабельный тип, из элементов которого будет создан кортеж:

>>> a_list=[0.01, 'Web' , 37, True ]
>>> b_tuple= tuple (a_list)
>>> b_tuple
(0.01, 'Web', 37, True).

При вызове конструктора без аргумента:

>>> tuple ()
()

создается пустой кортеж – (), который в логическом контексте соответствует False (любой другой кортеж – True).
Поскольку кортежи являются неизменяемыми последовательностями:

>>> from collections import Sequence, MutableSequence
>>> isinstance (a_tuple, Sequence)
True,
>>> isinstance (a_tuple, MutableSequence)
False,

они поддерживают все операции, свойственные этим типам объектов (см подраздел 1.4.2 лаб. раб. №3). Например, операцию добавления элемента к кортежу:

>>> a_tuple+= 'a' , 'b'
(3.45, 'JS', [1, 2], 'a', 'b').

Однако при добавлении одноэлементного кортежа:

>>> a_tuple+=(77)

возникает ошибка:

TypeError: can only concatenate tuple (not "int") to tuple,

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

>>> a_tuple+=(77,)
>>> a_tuple
(3.45, 'JS', [1, 2], 'a', 'b', 77).

Работа с кортежами выполняется быстрее, чем со списками. Поэтому, если имеется набор значений, который не будет меняться, его лучше реализовать как кортеж. Кортежи делают код безопаснее в том случае, если нужно защитить данные от записи.
Примером использования кортежей служит разработка игры "Анаграмма", рассмотренная в подразделе 1.3. Поскольку при этом возникает нобходимость получения случайных величин, рассмотрим методы их генерации, представленные в модуле random.

 Оглавление

1.2 Модуль random

Загрузим модуль random и определим с помощью встроенной функции dir() (см. подразделы 8.1 лаб. раб. №1 и 2.4 лаб. раб. №6 ) пространство имен этого модуля:

>>> import random
>>> dir (random)

['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI',
'_BuiltinMethodType', '_MethodType', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__',
'__doc__', '__file__', '__initializing__', '__loader__', '__name__', '__package__', '_acos',
'_ceil', '_cos', '_e', '_exp', '_inst', '_log', '_pi', '_random', '_sha512', '_sin', '_sqrt',
'_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'expovariate',
'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate',
'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']
;
Как видно из приведенного выше списка имен, модуль random содержит большое количество методов, связанных с генерацией случайных чисел (точнее, псевдослучайных чисел). Из них рассмотрим следующие:

Необходимо отметить, что модуль random не должен быть использован в приложениях, где требуется криптографическая безопастность генератора псевдослучайных чисел. Вместо него применяйте метод ssl.RAND_bytes() модуля ssl.

 Оглавление

1.3 Создание игры "Анаграмма"

Рассмотрим программу ana.py, которая предназначена для создания игры "Анаграмма" (анаграммы – это слова, образованные из исходного слова путем перестановки букв). Суть игры заключается в следующем: программа выбирает слово (из списка заранее приготовленных), переставляет в нем случайным образом буквы, формируя анаграмму, и предлагает ее пользователям. Их задачей является отгадать исходное слово:

# Создание анаграмм
import random
WORDS= 'компьютер' ,
'питон' ,
'сервер' ,
'клиент' ,
'браузер' ,
'протокол' ,
'программа' ,
'процессор' ,
'контекст'
word=random.choice(WORDS)
correct=word
ana= ''
while word:
pos=random.randrange( len (word))
ana+=word[pos]
word=word[:pos]+word[pos+1:]
print ( '''
<<Игра АНАГРАММА>>
Для выхода нажмите Enter ''' )
print ( 'Вот анаграмма: ' ,ana.upper())
ans= input ( 'Попробуй отгадать слово ' )
while ans != correct and ans != '' :
print 'Ответ неправильный' )
ans= input ( 'Попробуй еще раз ' )
if ans == correct:
print 'Молодец!' )
print 'Спасибо за игру' )
input ( ).

Поскольку при создании анаграмм выбор слова и перестановку букв в нем необходимо осуществлять случайным образом, программа начинается с подключения модуля random (см. подраздел 1.2), который содержит необходимые методы для выполнения случайного выбора.
Набор исходных слов, из которых будут формироваться анаграммы задается в виде кортежа, имя которого (WORDS) задано заглавными буквами. Это сделано для того, чтобы показать, что его значениями являются константы. Использование констант делает программу более понятной и легко читаемой.
Необходимо однако сказать, что правило задавать константы заглавными буквами в языке Python является прежде всего соглашением между программистами и интерпретатором не поддерживается, т.е. значения, имена которых заданы заглавными буквами можно изменить точно так, как значения, имена которых заданы строчными буквами. Но в силу указанных выше причин этого делать не следует.
Отметим, что в программе элементы кортежа при перечислении указываются с новой строки без использования символов обратного слэша, как это предусмотрено при задании длинных операторов (см. подраздел 6.1 лаб. раб. №1) и длинных строк (см. подраздел 2.1 лаб. раб. №2). Это допускается делать при перечислении элементов последовательностей, указанных в круглых "()", квадратных "[]" и фигурных "{}" скобках.
Для выбора одного из слов кортежа WORDS используется метод choice() модуля random (см. подраздел 1.2, который случайным образом выбирает один из элементов кортежа и сохраняет его в переменной word.
Затем начинается собственно процесс формирования анаграммы в переменной ana, которая вначале является пустой строкой. При этом в цикле, пока переменная word не примет значение '', что в логическом контексте означает False, будут выполняться следующие действия:

После выхода из цикла переменная word становится пустой строкой, а в переменной ana сформирована анаграмма.
Вторая часть программы связана с организацией игры с пользователем:

 Оглавление

2 Диапазоны

Диапазоны (англ. ranges), как новый тип последовательностей range, появились в языке Python, начиная с версий 3.x. До этого функция xrange(), которая в 3.x не используется, возвращала последовательность чисел класса list.
Для создания элементов класса range необходимо использовать конструктор – встроенную функцию range([start,] stop [, step]) (см. подраздел 8.1 лаб. раб. №1), которая возвращает неизменяемую виртуальную последовательность чисел от start до stop - 1 с шагом step. Значениями по умолчанию для необязательных аргументов start и step являются соответственно 0 и 1:

>>> r= range (10)
>>> r
range(0, 10)
>>> for _ in r:
print (_, end= ' ' )
0 1 2 3 4 5 6 7 8 9

>>> r= range (-5,6)
>>> r
range(-5, 6)
>>> for _ in r:
print (_, end= ' ' )
-5 -4 -3 -2 -1 0 1 2 3 4 5

>>> r= range (1,12,2)
>>> r
range(1,12,2)
>>> for _ in r:
print (_, end= ' ' )
1 3 5 7 9 11

Можно представить числа, формируемые функцией range(), в виде последовательности определенного типа, использовав соответствующий конструктор, например, в виде списка:

>>> list ( range (1,12,2))
[1, 3, 5, 7, 9, 11],

или в виде кортежа:

>>> tuple ( range (20,10,-3))
(20, 17, 14, 11).

Если stop не превышает start, то формируется пустая последовательность чисел, логическим значением которой является False:

>>> bool ( range (1,1))
False

Если step = 0 :

>>> r= range (1,5,0)
ValueError: range() arg 3 must not be zero,

возникает исключение: 3-й аргумент функции range() не может быть 0.
Будучи неизменяемой последовательностью:

>>> from collections import Sequence, MutableSequence
>>> isinstance (range(7), Sequence)
True,
>>> isinstance (range(7), MutableSequence)
False,

тип range, как и типы list и tuple, поддерживает все общие операции, свойственные неизменяемым последовательностям (см. подраздел 1.4.2 лаб. раб. №3), кроме операции конкатенации ("+"). Например, можно получить значение элемента последовательности по его индексу:

>>> range (7)[5]
5.

 Оглавление

3 Двоичные последовательности

Для работы с двоичными данными в языке Python имеются встроенные типы данных bytes и bytearray, которые поддерживаются типом memoryview, использующим буферный протокол (buffer protocol) для доступа к другим, находящимся в памяти, двоичным объектам без необходимости их копирования.

 Оглавление

3.1 Тип bytes

Объекты bytes являются неизменяемыми последовательностями одиночных байтов. Поскольку многие двоичные протоколы базируются на ASCII-кодировании текста, объкты bytes предлагают несколько методов, которые допускают работу только с ASCII-совместимыми данными и тесно связаны со строковыми объектами.
Во-первых, синтаксис литералов bytes во многом совпадает с синтаксисом строковых литералов, за исключением того, что добавляется префикс b:

Только ASCII-символы разрешается использовать в литералах объекта bytes (независимо от объявленного кодирования исходного кода):

>>> b'кириллица'
SyntaxError: bytes can only contain ASCII literal characters.

Поэтому любые значения литералов bytes, превыщающие 127, должны быть преобразованы в литералы bytes с использованием соответствующих ESC-последовательнвостей.
Так же как строковые литералы, литералы bytes могут использовать префикс r для экранирования ESC-последовательностей. Литералы и строк и объектов bytes в общем случае могут иметь следующие варианты префикса: r | R | b | B | br | Br | bR | BR.
Хотя литералы и представление объектов bytes базируются на ASCII-тексте, они на самом деле ведут себя как незменяемые последовательности целых чисел, значение каждого из которых x находится в пределах 0 <= x < 256. При попытках выйти за это органичение вызывет ошибку ValueError.
Помимо использования литеральной формы объекты bytes также можно создавать с помощью конструктора класса – встроенной функции bytes([source[, encoding[, errors]]]) (см. подраздел 8.1 лаб. раб. №1). Необязательный аргумент source используется для указания одного из нескольких вариантов создания объекта bytes:

Отметим, что для объекта b типа bytes b[0] будет целым числом, в то время как b[0:1] объектом bytes длины 1:

>>> b= bytes ( range (5))
>>> b[0]
0,
>>> b[0:1]
b'\x00'.

Этим объекты типа bytes отличаются от текстовых строк, где индексное значение и срез строки длиной 1 означают строку длины 1:

>>> s= "cat"
>>> s[0]
'c',
>>> s[0:1]
'c'.

 Оглавление

3.2 Тип bytearray

Объекты bytearray являются изменяемым вариантом объектов bytes, т.е. представляет собой изменяемую последовательность целых чисел x в диапазоне 0 <= x < 256.
Литеральные формы создания объектов типа bytearray не используются. Эти объекты могут быть созданы с помощью конструктора класса – встроенной функции bytearray([source[, encoding[, errors]]]) (см. подраздел 8.1 лаб. раб. №1). Необязательный аргумент source используется для указания нескольких вариантов создания объекта bytearray:

 Оглавление

3.3 Операции над объектами типов bytes и bytearray

Оба типа – и bytes, и bytearray, являясь последовательностями:

>>> from collections import Sequence
>>> isinstance (bytes(2), Sequence)
True,
>>> isinstance (bytearray(2), Sequence)
True,

поддерживают все операции, присущие базовым последовательностям (см. подраздел 1.4.2 лаб. раб. №3).
Благодаря общему использованиюю ASCII текста, как базиса для двоичного протокола, объекты типов bytes) и bytearray) используют почти все методы, присущие текстовым строкам (см. подраздел 2.6 лаб. работы №1), за исключением:

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

Экземпляры как типа bytes, так и типа bytearray поддерживают метод decode(encoding="utf-8", errors="strict"), который является обратным по отношению к методу str.encode() и возвращает строку, являющуюся результатом декодирования заданной последовательности байтов. По умолчанию кодировка имеет значение 'utf-8', обработка ошибки – "strict", что означает выработку исключения UnicodeError при обнаружении ошибки кодирования, другими возможными значениями являются: 'ignore', 'replace' и 'xmlcharrefreplace', а также любое другое имя, которое зарегистрировано в codecs.register_error. Приведем примеры использования методов encode() для строк и decode() для объектов bytes:

>>> 'cat' .encode(encoding= 'utf-8' )
b'cat',
>>> b'cat' .decode()
'cat',
>>> b= "питон" .encode()
>>> b
b'\xd0\xbf\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd',
>>> b.decode()
'питон'.

 Оглавление

Индивидуальные задания

1 Разработать программу на языке Python, которая выполняет следующее:

2. Разработать программу, которая:

Таблица 1 – Перечень индивидуальных заданий

Номер
п/п
Тип
элемента
ДиапазонВыводВариант
11,2,3,51,2511
22,3,5,62,32,222
33,4,5,6-10,1033
41,6,3,5-7,21,314
52,5,4,31125
61,2,3,51,60,531
72,3,5,620,0,-212
83,4,5,61,2523
91,6,3,52,32,234
102,5,4,3-10,1015
111,2,3,5-7,21,321
122,3,5,61132
133,4,5,61,60,513
141,6,3,520,0,-224
152,5,4,31,2535
161,2,3,52,32,211
172,3,5,6-10,1022
183,4,5,6-7,21,333
191,6,3,51114
202,5,4,31,60,525

 Оглавление