# Отчет по теме 6 ***Цель работы: Научиться работать с файловым устройством в качестве накопителя или источника данных для проведения расчетов.*** Терехов Фёдор Валерьевич, А-01-23 ## 1. Вывод данных на экран дисплея. ### 1.1. Вывод с использованием функции print. >Этот способ можно применять и в командной строке, и в функциях, поэтому привыкайте использовать только его! По умолчанию вывод будет осуществляться на экран, но, как увидим дальше, пункт назначения выводимых данных можно переопределить. ```python fff=234.5;gg='Значение температуры = ' print(gg, fff) ``` Ответ программы: ```shell Значение температуры = 234.5 ``` *По умолчанию выводимые объекты разделяются одним пробелом. Если нужен другой разделитель его можно указать в отдельном аргументе sep.* ```python fff=234.5;gg='Значение температуры = ' print(gg, fff) print(gg, fff, sep='/') ``` Ответ программы: ```shell Значение температуры = 234.5 Значение температуры = /234.5 ``` *После вывода автоматически осуществляется переход на другую строку. Если курсор надо оставить в той же строке, то следует использовать еще один аргумент.* ```python fff=234.5;gg='Значение температуры = ' print(gg, fff) print(gg, fff, sep='/') print(gg, fff,sep='/',end='***'); print('____') ``` Ответ программы: ```shell Значение температуры = 234.5 Значение температуры = /234.5 Значение температуры = /234.5***____ ``` *После end= надо указать какими символами должна закончиться выводимая строка или указать пустую строку. Наоборот, если в какой-то момент требуется просто перейти на новую строку, можно использовать такое обращение к функции.* ```python print() ``` *Наконец, оператор вывода может располагаться на нескольких строках с использованием тройных кавычек.* ```python print(""" Здесь может выводиться большой текст, занимающий несколько строк""") print("Здесь может выводиться", "большой текст,", "занимающий несколько строк") ``` Ответ программы: ```shell Здесь может выводиться большой текст, занимающий несколько строк Здесь может выводиться большой текст, занимающий несколько строк ``` ### 1.2. Вывод с использованием метода write объекта sys.stdout. *Объект stdout представляет собой поток стандартного вывода – объект, в который программы выводят символьное представление данных. Обычно это – экран дисплея. Объект находится в модуле sys, который надо импортировать.* ```python import sys sys.stdout.write('Функция write') ``` Ответ программы: ```shell Функция write% ``` *Обратите внимание, что этот метод после вывода строки не осуществляет переход на новую строку. Если это требуется, то следует в конце строки добавить один или несколько символов “\n”:* ```python import sys sys.stdout.write('Функция write\n') ``` Ответ программы: ```shell Функция write ``` ## 2. Ввод данных с клавиатуры. ### 2.1. Для ввода используйте уже знакомую функцию input. ```python psw=input('Введите пароль:') print(psw) print(type(psw)) ``` Ответ программы: ```shell Введите пароль:123 123 ``` ### 2.2. Ввод с контролем значения. *Пусть вводится число, которое должно находиться в интервале значений от 17.5 до 23.8.* ```python while True: znach=float(input('Задайте коэф.усиления = ')) if znach<17.5 or znach>23.8: print('Ошибка!') else: break ``` Ответ программы: ```shell Задайте коэф.усиления = 15.4 Ошибка! Задайте коэф.усиления = 21.6 ``` ### 2.3. Ввод и обработка выражения, подлежащего расчету. ```python import math print(eval(input('введите выражение для расчета = '))) ``` Ответ программы: ```shell введите выражение для расчета = math.log10(23/(1+math.exp(-3.24))) 1.34504378689765 ``` ## 3. Ввод-вывод при работе с файлами. ***Работа с файлом требует указания источника данных - полного имени файла с путем доступа к его расположению. Обычно наибольшие затруднения вызывает корректная локализация этого пути.*** ### 3.1. Функции для работы с путем к файлу. >Эти функции собраны в модуле os. Поэтому при работе с файлами надо импортировать этот модуль командой.Эти функции собраны в модуле os. Поэтому при работе с файлами надо импортировать этот модуль командой import os Как и в других системах, в среде Python в любой момент времени подразумевается некоторый рабочий каталог. Какой рабочий каталог установлен в текущий момент времени? Это можно узнать с помощью функции os.getcwd (cwd = current working directory). os.getcwd() Сохраните этот путь в переменной с именем, совпадающим с вашей фамилией в латинской транскрипции. Отобразите её значение с помощью функции print. ```python import os TerekhovFV=os.getcwd() print(TerekhovFV) ``` Ответ программы: ```shell /Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs ``` *Изменить расположение рабочего каталога можно обращением к уже многократно применявшейся функции os.chdir, аргументом которой будет символьная строка с указанием пути к каталогу, назначаемому в качестве рабочего.* ```python import os TerekhovFV=os.getcwd() print(TerekhovFV) os.chdir('/Users/fedorterekhov/Library') print(os.getcwd()) ``` Ответ программы: ```shell /Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs /Users/fedorterekhov/Library ``` *Фунция os.mkdir(path) - создает новую директорию:* ```python import os os.mkdir('TEMA6/test_directory') ``` Ответ программы: ![Создана директория test_directory](images/3.1.2.png) *Фунция os.rmdir(path) - удаляет пустую директорию:* ```python import os os.rmdir('TEMA6/test_directory') ``` Ответ программы: ![Удалена директория test_directory](images/3.1.3.png) **rmdir работает только с пустыми директориями! Для удаления непустых директорий нужно использовать shutil.rmtree().** *Фунция os.listdir(path) - возвращает список файлов и директорий:* ```python import os print(os.listdir()) print(type(os.listdir())) ``` Ответ программы: ```shell ['TEMA4', 'TEMA3', 'TEMA2', 'TEMA5', 'README.md', '.gitignore', 'TEMA9', 'TEMA0', 'TEMA7', 'TEMA6', 'TEMA1', 'TEMA8', '.git'] ``` *Фунция os.path.isdir(path) - проверяет, является ли путь директорией:* ```python import os print(os.path.isdir('TEMA6/test_directory')) print(os.path.isdir('TEMA6/images')) print(type(os.path.isdir('TEMA6/test_directory'))) ``` Ответ программы: ```shell False True ``` *С помощью функции os.path.abspath можно получить символьную строку, содержащую имя файла вместе с полным путем доступа к нему:* ```python import os fil=os.path.abspath("report.md") print(fil) ``` Ответ программы: ```shell /Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs/report.md ``` *Выделить путь доступа к файлу из строки, содержащей и этот путь, и имя файла можно с помощью функции os.path.dirname:* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) print(drkt) ``` Ответ программы: ```shell /Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs/python-labs ``` *Выделить имя файла/конечной директории из этой строки с отбрасыванием пути можно с помощью функции os.path.basename:* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) print(os.path.basename(drkt)) ``` Ответ программы: ```shell python-labs ``` *Функция os.path.split разделяет путь к файлу или директории на корневую часть пути и имя файла или имя директории. Возвращает кортеж, содержащий два элемента:* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) print(os.path.split(drkt)) print(type(os.path.split(drkt))) ``` Ответ программы: ```shell ('/Users/fedorterekhov/Library/Mobile Documents/com~apple~CloudDocs/Учёба/3 курс/POAS_labs', 'python-labs') ``` *С помощью функции os.path.exists можно проверить существует ли путь, заданный в символьной строке – аргументе функции. Возвращаемое значение: True или False.* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) print(os.path.exists(drkt + "/TEMA6")) print(os.path.exists(drkt + "/TEMA66")) ``` Ответ программы: ```shell True False ``` *Проверьте наличие файла с известным расположением с помощью функции os.path.isfile, аргументом которой должна быть символьная строка с путем и именем интересующего файла. Возвращаемое значение: True или False.* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) print(os.path.isfile(drkt + "/TEMA6/report.md")) print(os.path.isfile(drkt + "/TEMA6/report1.md")) ``` Ответ программы: ```shell True False ``` ## 4. Общая схема работы с файлом. *Для обмена данными с файлом необходимо выполнить следующие операции:* * Открытие файла с указанием его имени и цели (чтение, запись, добавление данных); * Выполнение одной или нескольких операций обмена данными с файлом; * Закрытие файла. ### 4.1. Открытие файла для записи или чтения данных – функция open. *При открытии файла необходимо указать имя файлы (с путем, если он не в рабочем каталоге) и цель работы с ним. Для открытия используется функция open.* ```python help(open) ``` Ответ программы: ```shell Help on built-in function open in module io: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) Open file and return a stream. Raise OSError upon failure. file is either a text or byte string giving the name (and the path if the file isn't in the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped. (If a file descriptor is given, it is closed when the returned I/O object is closed, unless closefd is set to False.) mode is an optional string that specifies the mode in which the file is opened. It defaults to 'r' which means open for reading in text mode. Other common values are 'w' for writing (truncating the file if it already exists), 'x' for creating and writing to a new file, and 'a' for appending (which on some Unix systems, means that all writes append to the end of the file regardless of the current seek position). In text mode, if encoding is not specified the encoding used is platform dependent: locale.getpreferredencoding(False) is called to get the current locale encoding. (For reading and writing raw bytes use binary mode and leave encoding unspecified.) The available modes are: ========= =============================================================== Character Meaning --------- --------------------------------------------------------------- 'r' open for reading (default) 'w' open for writing, truncating the file first 'x' create a new file and open it for writing 'a' open for writing, appending to the end of the file if it exists 'b' binary mode 't' text mode (default) '+' open a disk file for updating (reading and writing) 'U' universal newline mode (deprecated) ========= =============================================================== The default mode is 'rt' (open for reading text). For binary random access, the mode 'w+b' opens and truncates the file to 0 bytes, while 'r+b' opens the file without truncation. The 'x' mode implies 'w' and raises an `FileExistsError` if the file already exists. ``` *Откройте файл zapis1.txt для записи данных с помощью инструкции* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) fp=open(file=drkt+'/TEMA6/zapis1.txt',mode='w') ``` Ответ программы: ![Создан файл zapis1.txt](images/4.1.2.png) *Здесь fp – это файловый объект, который в других языках программирования обычно называют файловой переменной. Он сохраняет ссылку на открываемый файл и позволяет в дальнейшем ссылаться на файл, не указывая путь и имя открытого файла. В аргументе функции с именем file указывается путь и имя открываемого файла, а в аргументе с именем mode – предполагаемая цель его использования (w=write – для записи).* *Если путь в переменной drkt совпадает с рабочим каталогом, то его можно опустить, оставив только имя открываемого файла:* ```python fp=open('zapis1.txt','w') ``` *Тип и список атрибутов переменной fp:* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) fp=open(file=drkt+'/TEMA6/zapis1.txt',mode='w') print(type(fp)) print(dir(fp)) ``` Ответ программы: ```shell ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines'] ``` Если требуются другие операции с открываемым файлом, то для второго аргумента «mode=…» могут быть заданы следующие значения: w – запись с созданием нового файла или перезапись существующего файла, w+ - чтение и запись/перезапись файла, r – только чтение (это значение - по умолчанию), r+ - чтение и/или запись в существующий файл, a – запись в конец существующего файла или, если его нет, запись с созданием файла, a+ - то же, что и в «a», но с возможностью чтения из файла. В зависимости от значения этого аргумента тип создаваемой файловой переменной может быть разным. *Создаваемые и читаемые файлы могут быть бинарными или символьными. При открытии бинарного файла к указанным выше буквам в аргументе-цели надо добавить символ «b».* ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) fp1=open(drkt+'/TEMA6/zapis2.bin',mode='wb+') ``` Ответ программы: ![Создан файл zapis2.bin](images/4.1.4.png) ***В бинарный файл можно без преобразования записывать объекты любого типа.*** *Если файл – символьный, то его тип обозначается «t», но это – значение по умолчанию и его можно не указывать. В символьный файл можно записывать только объекты типа str. Объекты других типов надо перед записью преобразовать к этому типу.* ### 4.2. Закрытие файла. *Сразу после завершения работы с файлом его следует закрыть для обеспечения сохранности его содержимого. Это делается с помощью метода close, применяемого к объекту – файловой переменной.* ```python fp.close() ``` ### 4.3. Запись информации в файл с помощью метода write. ***Метод write относится к объекту – файловой переменной.*** ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) sps=list(range(1,13)) fp=open(file=drkt+'/TEMA6/zapis3.txt',mode='w') fp.write(str(sps[:4])+'\n') fp.write(str(sps[4:8])+'\n') fp.write(str(sps[8:])+'\n') fp.close() ``` Файл zapis3.txt: ``` [1, 2, 3, 4] [5, 6, 7, 8] [9, 10, 11, 12] ``` ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) sps3=[['Иванов И.',1],['Петров П.',2],['Сидоров С.',3]] fp3=open(drkt + '/TEMA6/zapis4.txt','w') for i in range(len(sps3)): stroka4=sps3[i][0]+' '+str(sps3[i][1]) fp3.write(stroka4) fp3.close() ``` Файл zapis4.txt: ``` Иванов И. 1Петров П. 2Сидоров С. 3 ``` ```python import os fil=os.path.abspath("report.md") drkt=os.path.dirname(fil) sps3=[['Иванов И.',1],['Петров П.',2],['Сидоров С.',3]] gh=open(drkt+'/TEMA6/zapis5.txt','w') for r in sps3: gh.write(r[0]+' '+str(r[1])+'\n') gh.close() ``` Файл zapis5.txt: ``` Иванов И. 1 Петров П. 2 Сидоров С. 3 ``` ## 5. Способы чтения информации. *Информация в текстовом файле размещена последовательно, по строкам, с завершением каждой строки символом ‘\n’ (конец строки). При чтении из файла из него извлекается часть информации, начиная с некоторого символа. Обычно, для удобства, считают, что перед этим символом стоит невидимый маркер (указатель), который при открытии файла устанавливается перед первым символом. После чтения части информации маркер перемещается и ставится перед символом, следующим за прочитанной частью информации.* ### 5.1. Первый способ чтения. ```python import os sps1=[] dirr=os.path.dirname(os.path.abspath("report.md")) fp=open(dirr + '/TEMA6/zapis3.txt') for stroka in fp: stroka=stroka.rstrip('\n') stroka=stroka.replace('[','') stroka=stroka.replace(']','') sps1=sps1+stroka.split(',') fp.close() print(sps1) ``` Ответ программы: ```shell ['1', ' 2', ' 3', ' 4', '5', ' 6', ' 7', ' 8', '9', ' 10', ' 11', ' 12'] ``` *В функции открытия файла использован только один аргумент, остальные – со значениями «по умолчанию».* *Перед занесением строки в список с помощью метода rstrip, из неё удаляется символ конца строки, а с помощью метода replace – скобки.* *Подумайте, как сделать так, чтобы список, полученный при чтении из файла, совпал с исходным.* ```python import os sps1=[] dirr=os.path.dirname(os.path.abspath("report.md")) fp=open(dirr + '/TEMA6/zapis3.txt') for stroka in fp: stroka=stroka.rstrip('\n') stroka=stroka.replace('[','') stroka=stroka.replace(' ','') stroka=stroka.replace(']','') sps1=sps1+stroka.split(',') fp.close() print(sps1) ``` Ответ программы: ```shell ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] ``` ### 5.2. Чтение информации из файла с помощью метода read. *Метод read, как и write, относится к объекту – файловой переменной. В качестве аргумента этого метода может задаваться целое число – количество символов или, если открыт бинарный файл, - количество байт, которое должно быть прочитано, соответственно, из текстового или бинарного файла, начиная с текущего положения маркера. Если указанное число превышает количество оставшихся символов (байт) в файле, то считываются все оставшиеся символы (байты). Если это число не указано, то считываются вся информация от маркера до конца файла. Метод возвращает строку с символами или совокупность байт, прочитанных из файла.* ```python import os dirr=os.path.dirname(os.path.abspath("report.md")) fp=open(dirr + '/TEMA6/zapis3.txt') stroka1=fp.read(12) stroka2=fp.read() fp.close() print(stroka1) print(stroka2) ``` Ответ программы: ```shell 1, 2, 3, 4] [5, 6, 7, 8] [9, 10, 11, 12] ``` ### 5.3. Чтение информации с помощью методов readline и readlines. *Эти методы позволяют прочитать из файла, начиная с текущего положения маркера, соответственно, одну строку символов (совокупность байт) или все строки (все байты).* ```python import os dirr=os.path.dirname(os.path.abspath("report.md")) fp=open(dirr + '/TEMA6/zapis3.txt') stroka1=fp.readline() stroka2=fp.readlines() fp.close() print(stroka1) print(stroka2) ``` Ответ программы: ```shell [1, 2, 3, 4] ['[5, 6, 7, 8]\n', '[9, 10, 11, 12]\n'] ``` ## 6. Ввод-вывод объектов с использованием функций из модуля pickle. *В модуле pickle содержатся функции для работы с бинарными файлами, в которые могут последовательно записываться или считываться целиком один или несколько объектов из оперативной памяти.* ### 6.1. Запись. ```python import os import pickle mnoz1={'pen','book','pen','iPhone','table','book'} #Объект типа «множество» fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis6.mnz','wb') # Бинарный файл – на запись pickle.dump(mnoz1,fp) #dump – метод записи объекта в файл fp.close() ``` Ответ программы: ![Создан файл zapis6.mnz](images/6.1.png) ### 6.2. Чтение. ```python import os import pickle fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis6.mnz','rb') mnoz2=pickle.load(fp) #load – метод чтения объекта из бинарного файла fp.close() print(mnoz2) ``` Ответ программы: ```shell {'iPhone', 'table', 'pen', 'book'} ``` **Объясните, почему он не совпадает с тем, что было задано при создании mnoz1. Инструкцией проверьте два объекта: mnoz1 и mnoz2 на совпадение.** ```python import os import pickle mnoz1={'pen','book','pen','iPhone','table','book'} #Объект типа «множество» fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis6.mnz','wb') # Бинарный файл – на запись pickle.dump(mnoz1,fp) #dump – метод записи объекта в файл fp.close() print(mnoz1) fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis6.mnz','rb') mnoz2=pickle.load(fp) #load – метод чтения объекта из бинарного файла fp.close() print(mnoz2, '\n') print(mnoz1==mnoz2) print(mnoz1 is mnoz2) ``` Ответ программы: ```shell {'book', 'iPhone', 'table', 'pen'} {'book', 'iPhone', 'table', 'pen'} True False ``` **Почему порядок элементов отличается от исходного?** * Множество (set) в Python - неупорядоченная коллекция * Элементы хранятся в порядке, оптимизированном для быстрого поиска * Порядок зависит от хэш-значений элементов и может меняться между запусками * Исходный порядок {'pen','book','iPhone','table'} не сохраняется **Почему удалились дубликаты?** * Множество автоматически удаляет повторяющиеся элементы * Исходно было: {'pen','book','pen','iPhone','table','book'} * Стало: {'pen','book','iPhone','table'} (4 элемента вместо 6) **Проверка совпадения:** * mnoz1 == mnoz2: True - объекты содержат одинаковые элементы * mnoz1 is mnoz2: False - это разные объекты в памяти ### 6.3. Запись и чтение. *Теперь с использованием тех же функций запишите в файл, а затем прочитайте два объекта разных типов: то же множество mnoz1 и ранее созданный список sps3. При считывании объекты извлекаются из файла в той же последовательности, в которой они в него записывались.* ```python import os import pickle mnoz1={'pen','book','pen','iPhone','table','book'} sps3=[['Иванов И.',1],['Петров П.',2],['Сидоров С.',3]] fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis6.mnz','rb') fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis7.2ob','wb') pickle.dump(mnoz1,fp) pickle.dump(sps3,fp) fp.close() fp=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/zapis7.2ob','rb') obj1=pickle.load(fp) #Первое обращение к load читает первый объект obj2=pickle.load(fp) #Второе – читает второй fp.close() print(obj1) print(obj2) ``` Ответ программы: ```shell {'book', 'pen', 'iPhone', 'table'} [['Иванов И.', 1], ['Петров П.', 2], ['Сидоров С.', 3]] ``` ## 7. Перенаправление потоков ввода и вывода данных. ```python import os import sys vr_out=sys.stdout #Запоминаем текущий поток вывода fc=open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/Stroka.txt','w') #Откроем файл вывода sys.stdout=fc #Перенацеливаем стандартный поток вывода на файл print('запись строки в файл') #Вывод теперь будет не на экран, а в файл sys.stdout=vr_out #Восстановление текущего потока print('запись строки на экран') #Убеждаемся, что вывод на экран восстановился fc.close() ``` Ответ программы: ![Создан файл Stroka.txt со строкой](images/7.1.png) Также на экран выведено сообщение: ```shell запись строки на экран ``` *Точно также можно перенаправить поток ввода – sys.stdin – вместо клавиатуры – из файла.* ```python import os import sys tmp_in = sys.stdin #Запоминаем текущий поток ввода fd = open(os.path.dirname(os.path.abspath("report.md")) + '/TEMA6/Stroka.txt', "r") #Открываем файл для ввода (чтения) sys.stdin = fd #Перенацеливаем ввод на файл вместо клавиатуры while True: try: line = input () #Считываем из файла строку print(line) # Отображаем считанное except EOFError: break ``` Ответ программы: ```shell запись строки в файл ```