Zadania z funkcji biblioteki standardowej

1. Napisz funkcję, która sprawdzi czy plik o podanej nazwie znajduje się w katalogu o podanej nazwie

Funkcja otrzymuje dwa argumenty: pliku oraz nazwę katalogu. Funkcja działa względem katalogu bierzącego. W przypadku znalezienia pliku zwraca True, w przeciwnym razie zwraca False w przypadku, gdy podany katalog nie istnieje funkcja wywołuje wyjątek, że podana nazwa nie jest katalogiem.

Funkcja będzie potrzebowała funkcje z biblioteki os: os.path.join w celu zbudowania ścieżki dostępu oraz funkcje os.path.isfile i os.path.isdirectory do sprawdzenia statusu pliku

In [1]:
import os
def isindir(file,dir):
    if os.path.isdir(dir):
        filepath = os.path.join(dir,file)
        if os.path.isfile(filepath):
            return True
        else:
            return False
    else:
        try:
            raise Exception("{0} is not directory".format(dir))
        except: 
            print("{0} is not directory".format(dir))

isindir("doc1.txt","katalog")
Out[1]:
True

2. Napisz funkcję, która zwraca listę plików z katalogu z określonym rozszerzeniem.

Domyślnie jest to bierzący katalog, a brak rozszerzenie wymusza wyświetlenie wszystkich plików. Nowe funkcje niezbędne do rozwiązania zadania to: os.listdir wyświetlająca zwarartość katalogu, oraz os.path.splitext do wyodrębnienia rozszerzenia

In [2]:
def listdir(dir=".",ext=None):
    if ext:
        if ext[0] is not ".": ext = "."+ext
    
    content = os.listdir(dir)
    for file in content:
        f = os.path.join(dir,file)
        if os.path.isfile(f):
            if ext:
                _,extension = os.path.splitext(f)
                if ext == extension:
                    print(file)
            else:
                print(file)
listdir("katalog","txt")             
doc2.txt
doc1.txt

Wykonaj kopię zapasową plików w bierzącym katalogu, z określonym rozszerzeniem w katalogu zapasowym o podanej nazwie **

Funkcja wymaga zastosowania biblioteki shutil, w której znajduje się funkcja kopiująca pliki. Funkcja wymaga określenia:

  1. Które obiekty z katalogu są plikami
  2. Czy plik ma prawidłowe rozszerzenie
  3. Musi sprawdzić czy katalog do zrobienia kopii zapasowej istnieje
In [3]:
import shutil
def backup(ext=None,dir=".",backupdir="backup"):
    try:
        os.mkdir(backupdir)
    except FileExistsError:
        print("Warning: Directory backup exists")
    if ext:
        if ext[0] is not ".": ext = "."+ext
    
    content = os.listdir(dir)
    print(content)
    files_to_backup = []
    for file in content:
        if os.path.isfile(file):
            if ext: 
                _,extension = os.path.splitext(file)
                print(ext,extension)
                if ext == extension:
                    files_to_backup.append(file)
                    print(files_to_backup)
            else:
                files_to_backup.append(file)
            
    print(files_to_backup)
    for file in files_to_backup:
        shutil.copy(file,os.path.join(backupdir,file))
        
os.chdir("/home/jarekj/Dropbox/dydaktyka/programowanie1/katalog")
backup(ext="txt")
os.chdir("/home/jarekj/Dropbox/dydaktyka/programowanie1/")
Warning: Directory backup exists
['backup', 'doc2.txt', 'doc1.txt']
.txt .txt
['doc2.txt']
.txt .txt
['doc2.txt', 'doc1.txt']
['doc2.txt', 'doc1.txt']

4. Napisz funkcję, która usunie z katalogu wszystkie pliki z danym rozszerzeniem. **

Jest to przykład funkcji niebezpiecznej, tj takiej, której stosowanie przynosi nieodwracalne skutki. Dobrą praktyką, zwłaszcza w środowiskach interaktywnych jest wyposażenie funkcji w dodatkowy parametr potwierdzajacy wykoanie usunięcia. Brak takiego parametru, powoduje jedynie wykonanie symulacji - tj zbudowanie listy plików do usunięcia.

Dochodzi tylko jedna nowa funkcja: os.remove. Trudność z zadaniem polega na tym, że wymaga ono zastosowania wskaźników do funkcji, tj przypisania do zmiennej funkcji, która będzie wywoływana w zależności od wyniku testu logicznego.

In [4]:
def cleandir(dir=".",ext=None,confirm=False):
    if ext:
        if ext[0] is not ".": ext = "."+ext
    
    if confirm:
        dowithfile = os.remove
    else:
        dowithfile = print
        print("files to remove:\n")
    content = os.listdir(dir)
    for file in content:
        f = os.path.join(dir,file)
        if os.path.isfile(f):
            if ext:
                _,extension = os.path.splitext(f)
                if ext == extension:
                    dowithfile(f)
            else:
                dowithfile(f)
                    

cleandir(ext="txt",confirm=False)
files to remove:

./dane.txt
./wynik.txt
./wynik2.txt
./plik.txt

5. Funkcja wyznaczająca wierzchołki dowolnego wielokąta foremnego

Funkcja używa wzoru na współrzędne wierzchołków wieloboku foremnego (i okręgu). W zależności od tego czy wielobok jest zamknięty czy nie ostatni wierzchołek pokrywa się ze środkowym lub nie. Zakładamy że promień domyślny to 1, a środek wieloboku = 1.

In [5]:
from math import sin, cos, pi

def wielobok(n,r=1,center=(0,0),close=True):
    w=[]
    for i in range(n+close):
        x = r*cos(i*2*pi/n)+center[0]
        y = r*sin(i*2*pi/n)+center[1]
        w.append((x,y))
    return w
    
wielobok(3,close=False)
Out[5]:
[(1.0, 0.0),
 (-0.4999999999999998, 0.8660254037844387),
 (-0.5000000000000004, -0.8660254037844384)]

6. Napisz funkcje która obliczy różnicę czasu pomiędzy chwilą obecną a jakąś datą w przeszłości

Funkcja jako argumenty przyjmuje datę i czas, z tym że czas jest opcjonalny. Następnie sprawdza prawidłowść formatu i wylicza tzw deltę czasową, z której pobiera sekundy.

In [6]:
from datetime import datetime

def uplywCzasu(data,godzina=None):
    '''
    data: data w formacie: d/m/Y 
    godzina czas w formacie: H:M
    '''
    date_format = "%d/%m/%Y"
    try:
        _ = datetime.strptime(data, date_format)
    except ValueError:
        print("Niepoprawny format daty")
        
    if not godzina:
        godzina = "00:00"
        
    time_format = "%H:%M"
    try: 
        _ = datetime.strptime(godzina,time_format)
    except ValueError:
        print("Niepoprawny format czasu")
    
    data_godzina = data +" "+ godzina
    date_time_format = date_format + " "+time_format
    time = datetime.strptime(data_godzina,date_time_format)
    teraz = datetime.now()
    delta = teraz - time
    return delta.seconds
    

uplywCzasu("28/07/1968","23:05")
Out[6]:
54210

7 Funkcja prezentująca podsumowanie listy: min, rednia-odch, srednia, srednia+odch, max

Wylicza podstawowe statystyki i wyświetla w postaci tekstowego porównania

In [7]:
from statistics import mean, stdev

def summary(*values):
    try: 
        mean_value = mean(values)
    except TypeError: 
        print("Cannot calculate from given list")
        return None
    min_value = min(values)
    mean_value = mean(values)
    std_value = stdev(values)
    max_value = max(values)
    txt = "min: " + str(round(min_value,2)) + " from: " + str(round(mean_value-std_value,2)) + \
    " - by: " + str(round(mean_value,2)) + " - to: " + str(round(mean_value+std_value,2)) + \
    " max: " + str(round(max_value,2))
    print(txt)
lst = [1,32,46,12,19,132,11,9,0,21]
summary(*lst)    
min: 0 from: -10.72 - by: 28.3 - to: 67.32 max: 132

8. Funkcja symulująca losowanie totolotka

Funkcja używa biblioteki random oraz zbiorów (nie omawiany wcześniej typ danych). Zbiory są używane z powodu konieczności zachowania unikalnych wartości wyników losowania jak i przekazywanych zakładów (po 6 unikalnych liczb z 49). Losowanie polega na wyborze 6 losowych liczb i porównaniu z przekazanym zakładem

In [8]:
import random

def zagraj(*liczby):
    population=range(1,49)
    if len(liczby) > len(set(liczby)) and len(liczby) !=6:
        print("liczb ma być 6 i muszą byc unikalne")
        return
    if set(liczby) > set(population):
        print("liczby muszą byc w przedziale 1 do 49")
        return
    losowanie = set(random.sample(population, 6))
    return(set(liczby) & losowanie)

#%%        
for i in range(1000):
    d = zagraj(1,5,6,9,11,33)
    if(len(d)>3):
        print("wygrales! "+ str(i))
wygrales! 100
wygrales! 112