Języki skryptowe Python



Podobne dokumenty
Język Python (2) Język Python (2) 1/36

Python wprowadzenie. Warszawa, 24 marca PROGRAMOWANIE I SZKOLENIA

Python. Wprowadzenie. Jolanta Bachan

Programowanie w języku Python. Grażyna Koba

System operacyjny Linux

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach:

Podstawy Pythona. Krzysztof Gdawiec. Instytut Informatyki Uniwersytet Śląski

Podstawy bioinformatyki 2017/18

Język programowania zbiór reguł określających, które ciągi symboli tworzą program komputerowy oraz jakie obliczenia opisuje ten program.

Trochę o plikach wsadowych (Windows)

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Podstawy programowania w Pythonie

Język Python. Język Python 1/35

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Wstęp do Informatyki dla bioinformatyków

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Podstawy Programowania Podstawowa składnia języka C++

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

lekcja 8a Gry komputerowe MasterMind

Naukę zaczynamy od poznania interpretera. Interpreter uruchamiamy z konsoli poleceniem

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Biblioteka standardowa - operacje wejścia/wyjścia

Zmienne powłoki. Wywołanie wartości następuje poprzez umieszczenie przed nazwą zmiennej znaku dolara ($ZMIENNA), np. ZMIENNA=wartosc.

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

Zaawansowany kurs języka Python

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

Pliki. Informacje ogólne. Obsługa plików w języku C

Języki skryptowe w programie Plans

Administracja sieciowymi systemami operacyjnymi III Klasa - Linux

Kurs rozszerzony języka Python

Pisząc kod w Pythonie na pewno już nie raz coś poszło nie tak i Shell wypisał komunikat o błędzie podobny do poniższego:

Zmienne, stałe i operatory

Podstawy JavaScript ćwiczenia

PROGRAMOWANIE W PYTHONIE OD PIERWSZYCH KROKÓW

Wstęp do informatyki. stęp do informatyki Polecenia (cz.2)

Środowisko programisty

Spis treści. Funkcje. 1 Funkcje 1.1 Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie Zadanie 7

Podstawy programowania skrót z wykładów:

1 Przygotował: mgr inż. Maciej Lasota

Wstęp do programowania

Lekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists()

Wstęp do programowania

1 Podstawy c++ w pigułce.

Informatyka 2015/16 wykład 9. Pliki Sterowanie przebiegiem programu cz. 2. Dr inż. Witold Nocoń (p. 230)

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

Język skryptowy: Laboratorium 1. Wprowadzenie do języka Python

Wstęp do Programowania, laboratorium 02

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Bash - wprowadzenie. Bash - wprowadzenie 1/39

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Kurs języka Python Wykład 6. Pliki tekstowe Pliki rekordów Pliki CSV Strumienie

Metody numeryczne Laboratorium 2

Podstawy bioinformatyki 2017/18

Kurs rozszerzony języka Python

Python jest interpreterem poleceń. Mamy dwie możliwości wydawania owych poleceń:

Zaawansowany kurs języka Python

Podstawy programowania w Pythonie

Podstawy i języki programowania

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Kier. MTR Programowanie w MATLABie Laboratorium

4. Pliki Informacje ogólne o dostępie do plików w PHP Sprawdzanie istnienia pliku file_exists()

Podstawy programowania. Python wykład 6

Autor: dr inż. Katarzyna Rudnik

Typy danych, cd. Łańcuchy znaków

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Przykład 1: Funkcja jest obiektem, przypisanie funkcji o nazwie function() do zmiennej o nazwie funkcja1

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

Skrypty BASH a. Systemy Operacyjne 2. Mateusz Hołenko. 4 października 2012

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

Podstawy. Jan Koprowski Politechnika Gdańska, FTiMS Informatyka Stosowana

Politechnika Łódzka. Instytut Systemów Inżynierii Elektrycznej. Laboratorium cyfrowej techniki pomiarowej. Ćwiczenie 4

Podstawy Programowania ELEMENTY PROGRAMU i TYPY DANYCH

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Temat zajęć: Tworzenie skryptów powłoki systemu operacyjnego.

Serwer WWW Apache. Plik konfiguracyjny httpd.conf Definiujemy m.in.: Aktualne wersje 2.4.6, , zakończony projekt

Algorytmy i struktury danych

Ćwiczenie 1. Wprowadzenie do programu Octave

JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA. Marcin Lewandowski [ ]

1 Podstawy c++ w pigułce.

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

Programowanie 3 - Funkcje, pliki i klasy

Podstawy Programowania C++

Umieszczanie kodu. kod skryptu

Programowanie w językach wysokiego poziomu

Pliki. Informacje ogólne. Obsługa plików w języku C

Pliki. Operacje na plikach w Pascalu

WYDZIAŁ ELEKTROTECHNIKI, AUTOMATYKI I INFORMATYKI INSTYTUT AUTOMATYKI I INFORMATYKI KIERUNEK AUTOMATYKA I ROBOTYKA STUDIA STACJONARNE I STOPNIA

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Program wykonujący operację na plikach powinien zachować schemat działania zapewniający poprawną pracę:

System operacyjny Linux

Oczywiście plik musi mieć rozszerzenie *.php

Wykład VI. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Wykład 4. Tablice. Pliki

Transkrypt:

Języki skryptowe Python Wykład 6 Moduły i pliki Janusz Szwabiński Plan wykładu: Moduły i ich importowanie Tworzenie własnych modułów Pliki odczyt i zapis Manipulowanie plikami i katalogami

Moduły i ich importowanie skrypty w Pythonie lub kod skompilowany np. w C/C++ najczęściej zawierają definicje obiektów do wielokrotnego użycia definicje w nich zawarte mogą być w każdej chwili dostępne w interpreterze lub innym skrypcie do załadowania modułu służy instrukcja import dodatkowo wbudowana funkcja import pozwala na załadowanie modułu, którego nazwa została określona w trakcie wykonywania programu moduł można przeładować w locie (np. po dokonaniu w nim zmian) poleceniem reload moduły to przykłady obiektów typy singleton. tzn. tylko jedna instancja konkretnego modułu jest załadowana do pamięci, i jest ona globalnie dostępna moduły mają własne przestrzenie nazw Kilka słów o przestrzeniach nazw Przestrzeń nazw (nie tylko) w Pythonie to abstrakcyjna przestrzeń, w której dowolne słowo może być jednoznacznie przypisane do reprezentowanego przez nie obiektu (funkcji, zmiennej itp.): wskazanie obiektu poprzez nazwę większość przestrzeni nazw zaimplementowana w postaci słowników (może się zmienić w przyszłości) trzy ważne przestrzenie nazw: zbiór nazw wbudowanych nazwy lokalne (podczas wywołania funkcji) nazwy globalne nie istnieje związek pomiędzy nazwami z różnych przestrzeni nazw przestrzenie nazw tworzone są w różnych chwilach i są aktywne przez różny czas przestrzeń zawierająca nazwy wbudowane tworzona jest podczas pracy Pythona i nigdy nie jest usuwana przestrzeń nazw globalnych modułu tworzona jest podczas wczytywania jego definicji i jest aktywna do chwili zakończenia pracy interpretera instrukcje wykonywane przez szczytowe wywołania interpretera, zarówno czytane z pliku jak i wprowadzane interaktywnie, są częścią modułu o nazwie main nazwy wbudowane przechowywane są w module builtin przestrzeń nazw lokalnych funkcji tworzona jest w momencie jej wywołania i niszczona, gdy następuje powrót z funkcji (również przez nieobsłużony wyjątek) wywołanie rekurencyjne powoduje tworzenie za każdym razem nowej przestrzeni nazw lokalnych zasięg jest tekstowym obszarem programu, w którym przestrzeń nazw jest wprost osiągalna, tzn. niekwalifikowane odniesienia do nazwy znajdują ją w obowiązującej przestrzeni nazw. Dla przykładu, jeżeli w celu wyliczenia pierwiastka kwadratowego z liczby 10 muszę wykonać polecenie math.sqrt(10)to funkcja sqrtnie jest dostępna bezpośrednio, czyli znajduje się poza zasięgiem aktualnej przestrzeni nazw. w każdym momencie wykonania programu używa się trzech zagnieżdżonych zasięgów nazw: najbardziej zagnieżdżony, nazwy lokalne środkowy, zawiera aktualne nazwy globalne modułu zewnętrzny, jest zasięgiem nazw wbudowanych przypisanie zawsze zachodzi w najbardziej zagnieżdżonym zasięgu przypisania nie powodują kopiowania danych, przywiązują jedynie nazwy do obiektów

In [1]: print dir( builtin ) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseExcepti on', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFErro r', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingP ointerror', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportErro r', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'Non e', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowErr or', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'T ypeerror', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncode Error', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', ' IPYT HON ', ' IPYTHON active', ' debug ', ' doc ', ' import ', ' name ', ' package ', 'abs', 'all', 'any', 'apply', 'basestrin g', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'ch r', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyrigh t', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'dreload', 'enume rate', 'eval', 'execfile', 'file', 'filter', 'float', 'format', 'fro zenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'he lp', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclas s', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'ma x', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'po w', 'print', 'property', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 's taticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'uni code', 'vars', 'xrange', 'zip'] Importowanie modułów Do załadowania modułu służy funkcja import. Jego nazwa trafia wówczas do bieżącej tablicy symboli. Przez tę nazwę odnosimy się do elementów modułu: In [2]: import math print math.sqrt(2) 1.41421356237 Funkcja import umożliwia również zaimportowanie wybranych elementów do aktualnej tablicy symboli. Możliwe są wówczas niekwalifikowane odniesienia do ich nazw: In [3]: from math import sqrt as SQ print SQ(2) 1.41421356237 Istnieje również możliwość załadowania całego modułu do bieżącej tablicy symboli, jednak powinniśmy go unikać, ponieważ może to prowadzić do niekontrolowanego nadpisania niektórych funkcji:

In [4]: from math import * print sqrt(2) 1.41421356237 Jeżeli używamy jej w skrypcie albo innym module, w dobrym zwyczaju załadowanie wszystkich potrzebnym modułów na początku pliku źródłowego. Tworzenie własnych modułów Rozważmy najpierw dwie funkcje : In [5]: def fib(n): # wypisz na ekranie wyrazy szeregu Fibonacciego mniej sze od n a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): # zwróć listę wyrazów szeregu Fibonacciego mniejszych o d n result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result In [6]: fib(10) 1 1 2 3 5 8 In [7]: fib2(10) Out[7]: [1, 1, 2, 3, 5, 8] Ponieważ funkcje te mogą nam się jeszcze przydać, zapiszmy je do pliku fibo.py:

In [108]: %%writefile fibo.py def fib(n): a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result Writing fibo.py Ten plik to nic innego jak nasz pierwszy (dość prosty) moduł: In [8]: import fibo dir(fibo) Out[8]: [' builtins ', ' doc ', ' file ', ' name ', ' package ', 'fib', 'fib2'] In [9]: fibo.fib(10) 1 1 2 3 5 8 In [10]: fibo.fib2(10) Out[10]: [1, 1, 2, 3, 5, 8] Moduł ten możemy nieco "podrasować", dodając m.in. dokumentację:

In [117]: %%writefile fibo.py # -*- coding: utf-8 -*- """Funkcje generujące wyrazy szeregu Fibonacciego""" def fib(n): """Wyświetl wyrazy szeregu mniejsze od n na ekranie""" a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): """Zwróć listę wyrazów szeregu mniejszych od n""" result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result Overwriting fibo.py In [11]: reload(fibo) Out[11]: <module 'fibo' from 'fibo.pyc'> In [12]: help(fibo) Help on module fibo: NAME fibo - Funkcje generujące wyrazy szeregu Fibonacciego FILE /home/szwabin/dropbox/zajęcia/pythonintro/6_moduly_i_pliki/fib o.py FUNCTIONS fib(n) Wyświetl wyrazy szeregu Fibonacciego mniejsze od n fib2(n) Zwróć listę wyrazów szeregu Fibonacciego mniejszych od n Częstą praktyką jest dodawanie do modułu kodu, który zostanie wykonany w momencie uruchomienia modułu jako samodzielnego programu. Zrealizujemy to w następujący sposób (argument -aoznacza, że dodajemy do istniejącego pliku):

In [129]: %%writefile -a fibo.py def test(): """Funkcja testująca działanie modułu""" assert(fib2(4)[-1]==3) print "Test zakończony poprawnie" if name == ' main ': test() Appending to fibo.py Zmienna name zawiera z reguły nazwę modułu. Wyjątkiem jest sytuacja, w której moduł uruchomiony jest jako samodzielny program wówczas ta zmienna odnosi się do napisu main. Sprawdźmy, jak to działa. Po przeładowaniu modułu pojawiła się dodatkowa funkcja: In [13]: reload(fibo) Out[13]: <module 'fibo' from 'fibo.py'> In [14]: dir(fibo) Out[14]: [' builtins ', ' doc ', ' file ', ' name ', ' package ', 'fib', 'fib2', 'test'] Możemy ją oczywiście wywołać ręcznie: In [15]: fibo.test() Test zakończony poprawnie Przy uruchomieniu modułu jako skryptu, zostanie ona uruchomiona automatycznie: In [16]:!python fibo.py Test zakończony poprawnie Ścieżka wyszukiwania modułów gdy moduł fibojest importowany, interpreter Pythona poszukuje pliku fibo.pyw katalogu bieżącym, a następnie w katalogach określonych w zmiennej środowiskowej PYTHONPATH jeśli zmienna PYTHONPATHnie jest określona, lub modułu nie ma w katalogach zdefiniowanych w zmiennej, interpreter kontynuuje poszukiwanie w ścieżkach ustalonych w momencie instalacji (pod Linuksem najczęściej /usr/lib/pythonlub /usr/local/lib/python) na samym końcu przeszukiwane są katalogi umieszczone w zmiennej sys.path

In [17]: import sys print sys.path ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gn u', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/us r/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-package s', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-pac kages/pilcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/us r/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubunt u-sso-client', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2', '/us r/lib/python2.7/dist-packages/ipython/extensions'] In [18]:!echo $PYTHONPATH Rozszerzanie ścieżki wyszukiwania Pod Linuksem dodajemy do pliku.bashrcw naszym katalogu domowym następujący kod: PYTHONPATH=$PYTHONPATH:$HOME/MyPython export PYTHONPATH Ze wzgledu na legendarną przyjazność systemu operacyjnego dla użytkownika, użytkownicy Windowsa radzą sobie sami :) Pliki odczyt i zapis Wbudowana funkcja openotwiera plik i tworzy odpowiadający mu obiekt. Jej składnia jest następująca: open(nazwa_pliku,tryb) pierwszy argument to ciąg znaków będący nazwą pliku drugi argument to ciąg znaków sposób pracy z plikiem 'r' tylko do odczytu (wartość domyślna) 'w' tylko do zapisu (istniejący plik o podanej nazwie zostanie nadpisany!) 'a' dopisywanie do istniejącego pliku 'r+' do odczytu i zapisu 'rb' tylko do odczytu w trybie binarnym 'wb' tylko do zapisu w trybie binarnym 'r+b' do odczytu i zapisu w trybie binarnym In [19]: f = open('workfile','w') print f <open file 'workfile', mode 'w' at 0x7f7a9dec4420>

Pracując z obiektami plików, mamy do dyspozycji następujące metody: read() wczytuje całą zawartość pliku i przekształca ją w napis (uwaga na duże pliki!) read(n) wczytuje nbajtów z pliku readline() czyta pojedynczy wiersz z pliku readlines() zwraca listę, której elementami są łańcuchy znaków reprezentujące poszczególne wiersze z pliku (uwaga na duże pliki!) write(napis) zapisuje łańcuch znaków do pliku tell() bieżąca pozycja w pliku mierzona w bajtach seek(k,p) zmienia pozycję w pliku dodając kbajtów do punktu odniesienia p: p=0 początek pliku p=1 pozycja bieżąca p=2 koniec pliku close() zamknięcie pliku In [20]: f.close() print f <closed file 'workfile', mode 'w' at 0x7f7a9dec4420> Otwórzmy powyższy plik raz jeszcze, tym razem w trybie do odczytu i zapisu: In [21]: f = open("workfile",'r+') Sprawdzamy jego zawartość: In [22]: f.read() #powinien być pusty Out[22]: '' Wpisujemy coś do pliku: In [23]: f.write("0123456789abcdef") Odczytujemy pozycję w pliku: In [24]: f.tell() Out[24]: 16 Przechodzimy do 5 bajtu w pliku i odczytujemy kolejny jeden bajt: In [25]: f.seek(5) f.read(1) Out[25]: '5' Ponownie odczytujemy pozycję:

In [26]: f.tell() Out[26]: 6 Trzeci bajt od końca: In [27]: f.seek(-3,2) f.read(1) Out[27]: 'd' Wracamy na początek i odczytujemy dwa kolejne bajty: In [28]: f.seek(0) f.read(2) Out[28]: '01' Wczytujemy cały wiersz: In [29]: f.seek(0) f.readline() Out[29]: '0123456789abcdef' Próba odczytu po zamknięciu pliku spowoduje błąd: In [30]: f.close() f.readline() -------------------------------------------------------------------- ------- ValueError Traceback (most recent cal l last) <ipython-input-30-02a0f4f4da9c> in <module>() 1 f.close() ----> 2 f.readline() ValueError: I/O operation on closed file Z życia (naukowców) wzięte Rozważmy plik będący wynikiem numerycznego rozwiązania równań ruchu oscylatora harmonicznego z tłumieniem:

In [71]:!head -20 osc_rk4.dat #osc_rk4.dat #oscylator harmoniczny z tlumieniem #i sila wymuszajaca #czas(s) polozenie(m) predkosc(m/s) 0.251327 0.0247305 0.113945 0.502655 0.0652931 0.204403 0.753982 0.125012 0.265655 1.00531 0.196106 0.294634 1.25664 0.270357 0.290914 1.50796 0.339749 0.256465 1.75929 0.397015 0.195193 2.01062 0.436054 0.112386 2.26195 0.452214 0.0141906 2.51327 0.442452-0.092775 2.7646 0.405419-0.201675 3.01593 0.341495-0.305649 3.26726 0.252758-0.398059 3.51858 0.142889-0.472887 3.76991 0.0169508-0.52526 4.02124-0.118975-0.551995 Widzimy, że pierwsze 4 wiersze w pliku to komentarz, natomiast kolejne zawierają dane opisujące położenie i prędkość oscylatora w funkcji czasu, uporządkowane w 3 kolumnach. Naszym celem jest wczytanie tego pliku w Pythonie. Możliwość pierwsza lista wszystkich wierszy: In [73]: results = [] f = open("osc_rk4.dat","r") #wczytujemy wiersze, pomijamy komentarz lines = f.readlines()[4:] #zamykamy plik f.close() #wydobywamy dane z wczytanych ciągów znaków for line in lines: #dzielimy wiersz na pola fields = line.split() #zamieniamy napisy na liczby time = float(fields[0]) pos = float(fields[1]) vel = float(fields[2]) #dopisujemy do listy z wynikami all = (time,pos,vel) results.append(all) #sprawdzamy wynik for i in results[:5]: print i (0.251327, 0.0247305, 0.113945) (0.502655, 0.0652931, 0.204403) (0.753982, 0.125012, 0.265655) (1.00531, 0.196106, 0.294634) (1.25664, 0.270357, 0.290914)

W przypadku bardzo dużych plików rozwiązanie to mocno obciąża pamięć, ponieważ cały plik musi być załadowany do pamięci operacyjnej komputera. Dlatego lepiej jest iterować po wierszach w pliku: In [74]: results = [] f = open("osc_rk4.dat","r") #iteracja po wierszach - w każdym kroku wczytywany tylko jeden wiers z for line in f: #ignorujemy komentarz if line[0] == "#": continue #wydobycie danych tym razem bardziej "pythonowo" all = [float(val) for val in line.split()] results.append(all) #zamykamy plik f.close() #sprawdzamy wynik for i in results[:5]: print i [0.251327, 0.0247305, 0.113945] [0.502655, 0.0652931, 0.204403] [0.753982, 0.125012, 0.265655] [1.00531, 0.196106, 0.294634] [1.25664, 0.270357, 0.290914] Iterację po wierszach można również wykonać w wersji tylko dla wtajemniczonych: In [75]: results3 = [[float(val) for val in l.split()] for l in open("osc_rk4.dat","r") if l[0]!= "#"] for i in results3[:5]: print i [0.251327, 0.0247305, 0.113945] [0.502655, 0.0652931, 0.204403] [0.753982, 0.125012, 0.265655] [1.00531, 0.196106, 0.294634] [1.25664, 0.270357, 0.290914] Inna możliwość to pętla while:

In [76]: f = open("osc_rk4.dat","r") while 1: line = f.readline() if not line: break if line[0] == "#": print line f.close() #osc_rk4.dat #oscylator harmoniczny z tlumieniem #i sila wymuszajaca #czas(s) polozenie(m) predkosc(m/s) Do dobrych praktyk należy jednak używanie polecenia withprzy pracy z plikami. Jego zaletą jest to, że odczytywany plik zostanie poprawnie (automatycznie) zamknięty albo po zakończeniu odczytu, albo po wystąpieniu wyjątku: In [78]: with open('osc_rk4.dat') as f: results4 = [[float(val) for val in l.split()] for l in f i f l[0]!= "#"] for i in results4[:5]: print i [0.251327, 0.0247305, 0.113945] [0.502655, 0.0652931, 0.204403] [0.753982, 0.125012, 0.265655] [1.00531, 0.196106, 0.294634] [1.25664, 0.270357, 0.290914] Ponieważ plik zostaje otworzony w obrębie bloku rozpoczętego poleceniem with, należy do zasięgu lokalnego. Tuż przed wyjściem z tego bloku interpreter zwalnia zasoby zajęte przez zmienne lokalne, a zatem powinien zamknąć plik. Sprawdźmy, czy jest tak rzeczywiście: In [79]: print f <closed file 'osc_rk4.dat', mode 'r' at 0x7f9125511420> Zapisywanie do pliku

In [80]: #otwieramy plik do zapisu of = open("dane.dat","w") #dobrym zwyczajem jest wpisać do niego jakiś komentarz of.write("#dane.dat\n") of.write("#oscylator harmoniczny z tlumieniem i sila wym.\n") of.write("#czas polozenie predkosc\n") #zapisujemy wyniki z listy results for l in results: of.write("%5.2f %5.2f %5.2f\n"%(l[0],l[1],l[2])) #zamykamy plik of.close() Sprawdźmy zawartość pliku dane.dat(w konsoli uniksowej): In [81]:!head -10 dane.dat #dane.dat #oscylator harmoniczny z tlumieniem i sila wym. #czas polozenie predkosc 0.25 0.02 0.11 0.50 0.07 0.20 0.75 0.13 0.27 1.01 0.20 0.29 1.26 0.27 0.29 1.51 0.34 0.26 1.76 0.40 0.20

Zauważmy, że writew pętli forw powyższym przykładzie zapisuje do pliku cały wiersz z danymi na raz. Wiersz ten utworzony jest z szablonu, czyli łancucha znaków zawierającego pewne symbole. W ich miejsce wstawiane są przy pomocy operatora %dane liczbowe z krotki będącej prawym argumentem tego operatora. Możliwe jest następujące formatowanie: %d liczba całkowita %5d liczba całkowita w polu o szerokosci 5 znaków %-5d j.w, ale wyrównana do lewej %05d j.w., ale uzupełniona zerami od lewej (np. 00041) %g liczba zmiennoprzecinkowa w formacie %f lub %e %e liczba zmiennoprzecinkowa w formacie naukowym (np. 1.100000e + 00) %E j.w., ale wykładnik oddzielony litera E %G liczba zmiennoprzecinkowa w formacie %f lub %E %11.3e liczba zmiennoprzecinkowa w formacie %e z trzema cyframi dziesiętnymi w polu o szerokości 11 znaków %.3e liczba zmiennoprzecinkowa w formacie %e z trzema cyframi dziesiętnymi w polu o najmniejszej możliwej szerokości %5.1f liczba zmiennoprzecinkowa zapisana w notacji dziesiętnej z jedną cyfrą dziesiętną w polu o szerokości 5 znaków %.3f j.w., ale z trzema liczbami dziesiętnymi w polu o możliwie najmniejszej szerokości %s ciąg znaków %-20s ciąg znaków wyrównany do lewej w polu o szerokości 20 znaków Nowszy sposób formatowania łańcuchów znaków Powyższy sposób formatowania łańcuchów znaków jest bardzo popularny, ponieważ przypomina on styl używany przez funkcję sprintfw języku C. Jednak uważany jest on za nieco przestarzały i obecnie zaleca się stosowanie metody formatobiektu str. W porównaniu ze starą składnią, tutaj pojawiają się nawiasy klamrowe i zamiast znaku %używany jest znak :. Np. '%03.2f'zostanie zastąpione przez '{:03.2f}'. Nowy sposób formatowania oferuje jednak szereg nowych możliwości: In [82]: print '{0}, {1}, {2}'.format('a', 'b', 'c') #wstawianie argumentów n a podstawie ich pozycji print '{}, {}, {}'.format('a', 'b', 'c') print '{2}, {1}, {0}'.format('a', 'b', 'c') a, b, c a, b, c c, b, a In [84]: print '{2},{1},{0}'.format(*'abc') ożna rozpakować print '{0}{1}{0}'.format('abra', 'cad') powtarzać # sekwencję w argumencie m # indeksy argumentów można c,b,a abracadabra

In [87]: #wartości wstawiane po kluczach print 'Współrzędne: {latitude}, {longitude}'.format(latitude='37.24 N', longitude='-115.81w') coord = {'latitude': '37.24N', 'longitude': '-115.81W'} print 'Współrzędne: {latitude}, {longitude}'.format(**coord) Współrzędne: 37.24N, -115.81W Współrzędne: 37.24N, -115.81W In [92]: #justowanie tekstu print '{:<30}'.format('left aligned') print '{:>30}'.format('right aligned') print '{:^30}'.format('centered') #jak wyżej, tylko z '*' jako znakiem wypełniającym print '{:*^30}'.format('centered') left aligned right aligned centered ***********centered*********** In [89]: print '{:+f}; {:+f}'.format(3.14, -3.14) #znak pojawia się zawsze print '{: f}; {: f}'.format(3.14, -3.14) #spacja w przypadku liczb dodatnich print '{:-f}; {:-f}'.format(3.14, -3.14) #pokazuje tylko minus +3.140000; -3.140000 3.140000; -3.140000 3.140000; -3.140000 In [90]: # możliwa jest konwersja w 'locie' print "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42) int: 42; hex: 2a; oct: 52; bin: 101010 In [2]: '{:,}'.format(1234567890) #przecinek jako separator między tysiącami Out[2]: '1,234,567,890' Więcej na temat metody format pod adresem https://docs.python.org/2/library/string.html#formatstrings (https://docs.python.org/2/library/string.html#formatstrings) Marynowanie danych czyli moduł cpickle napisy łatwo zapisuje się do i odczytuje z pliku liczby wymagają trochę pracy przy konwersji z i na łańcuch znaków jeszcze trudniej jest zapisać i odczytać złożone typy danych moduł cpicklepotrafi przekształcić prawie każdy złożony typ danych w napis ("marynowanie") taki napis można zapisać do pliku, przesłać przez sieć itp. można go również "odmarynować", czyli wydobyć z niego oryginalny obiekt standardowy sposób na uczynienie obiektów Pythona trwałymi warto dbać o to, aby tworzone typy danych dawały się łatwo "marynować"

In [93]: import cpickle as pickle In [94]: dir(pickle) Out[94]: ['BadPickleGet', 'HIGHEST_PROTOCOL', 'PickleError', 'Pickler', 'PicklingError', 'UnpickleableError', 'Unpickler', 'UnpicklingError', ' builtins ', ' doc ', ' name ', ' package ', ' version ', 'compatible_formats', 'dump', 'dumps', 'format_version', 'load', 'loads'] In [95]: help(pickle.dump) Help on built-in function dump in module cpickle: dump(...) dump(obj, file, protocol=0) -- Write an object in pickle format to the given file. See the Pickler docstring for the meaning of optional argument p roto. Przygotujmy jakieś dane do zapisania: In [96]: tel = {'Yoda' : 1111, 'Chewie' : 2222, 'Luke' : 3333} lis = range(5) l = 123 Zapisujemy je do pliku: In [97]: of = open("marynata","w") pickle.dump(tel,of) pickle.dump(lis,of) pickle.dump(l,of) of.close() Podglądnijmy zapisany plik:

In [98]:!cat marynata (dp1 S'Chewie' p2 I2222 ss'yoda' p3 I1111 ss'luke' p4 I3333 s.(lp1 I0 ai1 ai2 ai3 ai4 a.i123. Dane z pliku ładujemy w kolejności zapisania: In [99]: f = open("marynata","r") telefony = pickle.load(f) zakres = pickle.load(f) liczba = pickle.load(f) f.close() In [100]: print telefony print zakres print liczba {'Chewie': 2222, 'Yoda': 1111, 'Luke': 3333} [0, 1, 2, 3, 4] 123 Manipulowanie plikami i katalogami Funkcje potrzebne do operacji na plikach znajdziemy w module os: większość funkcji zaimplementowana w modułach specyficznych dla danej platformy (np. posix, nt) podczas ładowania oswybierany jest odpowiedni z nich operacje na plikach (zmiana nazwy i atrybutów, usuwanie) operacje na katalogach operacje na procesach In [1]: import os

Usuwanie plików Tworzymy najpierw jakiś plik do usunięcia: In [2]: f = open("testos.txt","w") f.write("jakiś test") f.close() Usunięcie pliku jest proste: In [3]: os.remove("testos.txt") Powtórzenie usunięcie wygeneruje znany już wyjątek: In [4]: os.remove("testos.txt") -------------------------------------------------------------------- ------- OSError Traceback (most recent cal l last) <ipython-input-4-a342e4040f74> in <module>() ----> 1 os.remove("testos.txt") OSError: [Errno 2] No such file or directory: 'testos.txt' Podczas pracy interaktywnej w interpreterze Pythona taki błąd nie stanowi oczywiście wielkiego problemu, ponieważ programista może na niego natychmiast zareagować. Jeśli jednak wyjątek pojawi się podczas wykonywania dłuższego skryptu, przerwie on jego działanie. Jest to oczywiście sytuacja niepożądana, dlatego do dobrych praktyk należy wyłapywanie wyjątków. Zagadnieniu temu poświęcony będzie część jednego z kolejnych wykładów. Natomiast teraz powinien wystarczyć przykład, jak radzić sobie w tym konkretnym przypadku: In [5]: try: os.remove("testos.txt") except os.error: print "Operacja nie powiodła się" Operacja nie powiodła się Zmiana nazwy pliku Stwórzmy najpierw jakis plik roboczy: In [6]: name1 = "plik.txt" fi = open(name1,'w') fi.write("to jest plik roboczy o nazwie %s."%name1) fi.close()

Sprawdźmy, czy plik taki rzeczywiście powstał, i co zawiera: In [7]: %%bash ls -l plik.txt -rw-rw-r-- 1 szwabin szwabin 39 lis 10 18:10 plik.txt In [8]: %%bash cat plik.txt To jest plik roboczy o nazwie plik.txt. Dygresja Polecenie %%bash to przykład polecenia magicznego IPythona. W tym konkretnym przypadku pozwala on korzystać z funkcjonalności powłoki systemowej bez wychodzenia z notatnika. Zmiany nazwy pliku dokonamy przy pomocy polecenia os.rename: In [9]: name2 = "file.txt" os.rename(name1,name2) Sprawdźmy wynik działania tego polecenia: In [10]: fi = open(name1) -------------------------------------------------------------------- ------- IOError Traceback (most recent cal l last) <ipython-input-10-296f70111754> in <module>() ----> 1 fi = open(name1) IOError: [Errno 2] No such file or directory: 'plik.txt' In [12]: fi = open(name2) fi.read() Out[12]: 'To jest plik roboczy o nazwie plik.txt.' In [13]: fi.close() Informacje o pliku In [14]: os.stat(name2) Out[14]: posix.stat_result(st_mode=33204, st_ino=10092891, st_dev=2051, st_nl ink=1, st_uid=1000, st_gid=1000, st_size=39, st_atime=1447175813, s t_mtime=1447175435, st_ctime=1447175741) Jak widać, wynik działania polecenia os.statnie jest szczególnie czytelny. Możemy jednak to zmienić:

In [16]: import time def dump(st): mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime = st print "- rozmiar:", size, "bajtów" print "- właściciel:", uid, gid print "- utworzony:", time.ctime(ctime) print "- ostatni dostęp:", time.ctime(atime) print "- ostatnia modyfikacja:", time.ctime(mtime) st = os.stat(name2) dump(st) - rozmiar: 39 bajtów - właściciel: 1000 1000 - utworzony: Tue Nov 10 18:15:41 2015 - ostatni dostęp: Tue Nov 10 18:16:53 2015 - ostatnia modyfikacja: Tue Nov 10 18:10:35 2015 Dygresja! Gdybyśmy planowali stworzyć własny moduł z przydatnymi funkcjami do pracy na plikach, funkcja dumpbyłaby bardzo dobrą kandydatką na element tego modułu. Podstawowe operacje na katalogach Sprawdźmy bieżący katalog: In [17]: os.getcwd() Out[17]: '/home/szwabin/dropbox/zaj\xc4\x99cia/pythonintro/6_moduly_i_pliki' Jego zawartość wyświetlimy przy pomocy funkcji os.listdir: In [18]: print os.listdir(os.getcwd()) ['5-intro.pdf.gz', 'calc.py', 'modutils.py', 'Chapter8_Modules.ipyn b', '3-intro_utf.pdf', '6_moduly_i_pliki.ipynb', 'box.jpg', 'SciPyth on5.ipynb', '.ipynb_checkpoints', 'SciPython4.ipynb', '4-intro.pdf', 'file.txt', 'bpyfd_diags6.png', 'SciPython3.ipynb'] Można również tak:

In [19]: for item in os.listdir(os.getcwd()): print item 5-intro.pdf.gz calc.py modutils.py Chapter8_Modules.ipynb 3-intro_utf.pdf 6_moduly_i_pliki.ipynb box.jpg SciPython5.ipynb.ipynb_checkpoints SciPython4.ipynb 4-intro.pdf file.txt bpyfd_diags6.png SciPython3.ipynb Przy podawaniu ścieżki do katalogów można korzystać z typowych skrótów: In [20]: print "Zawartość katalogu bieżącego:\n" print os.listdir('.') print "\n\nzawartość katalogu nadrzędnego:\n" print os.listdir('..') Zawartość katalogu bieżącego: ['5-intro.pdf.gz', 'calc.py', 'modutils.py', 'Chapter8_Modules.ipyn b', '3-intro_utf.pdf', '6_moduly_i_pliki.ipynb', 'box.jpg', 'SciPyth on5.ipynb', '.ipynb_checkpoints', 'SciPython4.ipynb', '4-intro.pdf', 'file.txt', 'bpyfd_diags6.png', 'SciPython3.ipynb'] Zawartość katalogu nadrzędnego: ['Przyk\xc5\x82ady', '1_Intro', 'ricardoduarte-python-for-developer s-88df06e', 'thinkpython.pdf', '5_Funkcje', '2_Pierwsze_kroki', '3_Z mienne_wyrazenia_instrukcje', '6_Moduly_i_pliki', '4_Zlozone_typy_da nych'] Przejście do innego katalogu roboczego: In [22]: os.chdir("/home/szwabin/mypython") os.getcwd() Out[22]: '/home/szwabin/mypython' Tworzenie katalogów: In [23]: os.listdir('.') Out[23]: []

In [24]: os.mkdir('test') os.listdir('.') Out[24]: ['Test'] Jeśli katalog już istnieje: In [25]: os.mkdir('test') -------------------------------------------------------------------- ------- OSError Traceback (most recent cal l last) <ipython-input-25-f2fde2339d88> in <module>() ----> 1 os.mkdir('test') OSError: [Errno 17] File exists: 'Test' Możemy tworzyć kilka poziomów na raz: In [26]: os.makedirs('test2/poziom1/poziom2') os.listdir('.') Out[26]: ['Test', 'Test2'] In [27]: print os.listdir('test2') print os.listdir('test2/poziom1') ['Poziom1'] ['Poziom2'] Pojedynczy katalog usuniemy w następujący sposób: In [28]: os.rmdir("test") os.listdir('.') Out[28]: ['Test2'] Możliwe jest również usunięcie całej ścieżki na raz: In [29]: os.removedirs('test2/poziom1/poziom2') os.listdir('.') Out[29]: [] Uwaga! Usuwany katalog musi być pusty: In [30]: os.mkdir('test') f = open('test/plik.txt','w') f.write('bla bla bla') f.close()

In [31]: os.rmdir('test') -------------------------------------------------------------------- ------- OSError Traceback (most recent cal l last) <ipython-input-31-9d11237dd07e> in <module>() ----> 1 os.rmdir('test') OSError: [Errno 39] Directory not empty: 'Test' In [32]: os.remove('test/plik.txt') os.rmdir('test') In [33]: os.listdir('.') Out[33]: [] Ścieżki dostępu do plików In [34]: plik = "/home/szwabin/books/programming.collective.intelligence.pdf" Pełną ścieżkę do pliku możemy rozbić na nazwę pliku i katalog, w którym plik się znajduje: In [35]: os.path.split(plik) Out[35]: ('/home/szwabin/books', 'Programming.Collective.Intelligence.pdf') Nazwę katalogu i pliku możemy też odczytać specjalnymi funkcjami: In [36]: kat = os.path.dirname(plik) print kat pl = os.path.basename(plik) print pl #nazwa katalogu #nazwa pliku /home/szwabin/books Programming.Collective.Intelligence.pdf Dysponując nazwą katalogu i pliku, możemy je oczywiście połączyć w jedną ścieżkę dostępu: In [37]: os.path.join(kat,pl) Out[37]: '/home/szwabin/books/programming.collective.intelligence.pdf' Przeszukiwanie drzewa katalogów

In [47]: for root, dirs, files in os.walk("/home/szwabin/dropbox/zajęcia/pyth onintro/3_zmienne_wyrazenia_instrukcje/", topdown=false): print root print dirs print files print '-'*20 kcje/.ipynb_checkpoints [] ['3_Zmienne_wyrazenia_instrukcje-checkpoint.ipynb', 'Untitled0-check point.ipynb'] -------------------- kcje/preview/3_zmienne_wyrazenia_instrukcje_files [] ['require.min.js', 'MathJax.js', 'jquery.min.js'] -------------------- kcje/preview ['3_Zmienne_wyrazenia_instrukcje_files'] ['state_diagram.png', '3_Zmienne_wyrazenia_instrukcje.html', '3_Zmie nne_wyrazenia_instrukcje.html~'] -------------------- kcje/ ['.ipynb_checkpoints', 'Preview'] ['state_diagram.svg', 'Untitled0.ipynb', 'state_diagram.png', '3_Zmi enne_wyrazenia_instrukcje.ipynb', '3_zmienne_wyrazenia_instrukcje.pd f'] -------------------- In [48]: for root, dirs, files in os.walk("/home/szwabin/dropbox/zajęcia/pyth onintro/3_zmienne_wyrazenia_instrukcje/", topdown=false): for name in files: print os.path.join(root, name) for name in dirs: print os.path.join(root, name)

kcje/.ipynb_checkpoints/3_zmienne_wyrazenia_instrukcje-checkpoint.ip ynb kcje/.ipynb_checkpoints/untitled0-checkpoint.ipynb kcje/preview/3_zmienne_wyrazenia_instrukcje_files/require.min.js kcje/preview/3_zmienne_wyrazenia_instrukcje_files/mathjax.js kcje/preview/3_zmienne_wyrazenia_instrukcje_files/jquery.min.js kcje/preview/state_diagram.png kcje/preview/3_zmienne_wyrazenia_instrukcje.html kcje/preview/3_zmienne_wyrazenia_instrukcje.html~ kcje/preview/3_zmienne_wyrazenia_instrukcje_files kcje/state_diagram.svg kcje/untitled0.ipynb kcje/state_diagram.png kcje/3_zmienne_wyrazenia_instrukcje.ipynb kcje/3_zmienne_wyrazenia_instrukcje.pdf kcje/.ipynb_checkpoints kcje/preview Jeszcze o przeszukiwaniu katalogów Bardzo przydatnym modułem jest znajdujący się w bibliotece standardowej glob. Pozwala on na używanie dzikich kart w nazwach plikow na zasadach podobnych do powłoki uniksowej: *zastępuje zero lub więcej znaków?zastępuje dokładnie jeden znak nawiasy kwadratowe definiują zakresy, np. [1-9]oznacza dowolną cyfrę między 1 a 9 In [51]: import glob os.chdir('/home/szwabin/dropbox/zaj\xc4\x99cia/pythonintro/6_modul y_i_pliki') Wszystkie pliki o rozszerzeniu ipynb:

In [52]: print glob.glob('*.ipynb') ['Chapter8_Modules.ipynb', '6_moduly_i_pliki.ipynb', 'SciPython5.ipy nb', 'SciPython4.ipynb', 'SciPython3.ipynb'] Wszystkie pliki w aktualnym katalogu: In [53]: print glob.glob('*.*') ['5-intro.pdf.gz', 'calc.py', 'modutils.py', 'Chapter8_Modules.ipyn b', '3-intro_utf.pdf', '6_moduly_i_pliki.ipynb', 'box.jpg', 'SciPyth on5.ipynb', 'SciPython4.ipynb', '4-intro.pdf', 'file.txt', 'bpyfd_di ags6.png', 'SciPython3.ipynb'] Pliki o rozszerzeniu składającym się z 3 liter: In [54]: print glob.glob("*.???") ['3-intro_utf.pdf', 'box.jpg', '4-intro.pdf', 'file.txt', 'bpyfd_dia gs6.png'] Pliki o rozszerzeniu składającym się z 3 liter, przy czym pierwszą literą rozszerzenia jest plub t: In [56]: print glob.glob("*.[pt]??") ['3-intro_utf.pdf', '4-intro.pdf', 'file.txt', 'bpyfd_diags6.png']