Урок 3. Кортежі. Словники.

Основи Python и Django. -> Bash та віртуальне оточення Python

Bash та віртуальне оточення Python.

Інтерпретатор BASH допомагає автоматизувати багато рутинних дій.

Наприклад, активування віртуального оточення.

Ця операція відбувається досить часто і іноді розробник забуває про неї.

Зробимо так, щоб процес активації відбувався без нашої участі.

Створимо bash скрипт auto.sh із командою активації віртуального оточення.

chmod +x auto.sh
chmod +x auto.sh

Тепер для того, щоб при зміні директорії автоматично запускався наш Скрипт необхідно переписати функцію CD.

Зробимо це у файлі .bashrc cd () { builtin cd ${1:+”$@”} if [ -f “auto.sh” ] then . ./auto.sh fi
}

У цій функції ми насамперед викликаємо оригінальну (вбудовану) функцію cd. builtin cd ${1:+”$@”}

Потім перевіряємо існування файлу і якщо він є запускаємо його.

    if [ -f "env.sh" ]
    then
     . ./auto.sh
    fi
Основи Python и Django. -> Віртуальне оточення. Інсталятор PIP.

Встановлювач pip. Віртуальне оточення.

При розробці програм на Python часто виникає потреба в установці сторонніх бібліотек (пакетів), що не входять до постачання Python.

Після встановлення з’являється можливість їх імпорту та використання.

Встановити пакет python можна вручну, розпакувавши архів у потрібне місце.

Насамперед Python намагається знайти імпортовану бібліотеку в поточному каталозі.

Це можна перевірити, створивши файл бібліотеки mylib.py. print(‘Importing mylib’)

І в іншому файлі спробувати його імпортувати.

import mylib

Висновок.

shell>python imp.py 
Importing mymodule
shell>

Якщо файл покласти в каталог lib, наприклад, то імпорт буде наступним:

import lib.mylib

При цьому необхідно не забути створити в каталозі спеціальний файл init.py, який позначить цей каталог як пакет і уможливить імпорт із нього.

Установник pip полегшує завдання встановлення пакетів.

Він оперує репозиторієм пакетів на сайті https://pypi.org та тягне їх від туди.

Встановити їх у систему можна командою.

apt install python-pip

Після цього використання буде в такому форматі. Pislya tsʹoho vykorystannya bude v takomu formati.

pip install package_name1 package_name2

Ми можемо створити список усіх необхідних бібліотек у файлі requirements.txt (наприклад), перерахувавши їх у стовпчик.

packege_name1
package_name2

І потім скористатися ключем -r для передачі файлу-списку в інсталятор pip. pip install -r requirements.txt
Де ще Python шукає бібліотеки під час імпорту? Де ще Python шукає бібліотеки під час імпорту? Переглянути всі шляхи якими проходить пошук можна в змінній PYTHONPATH, використовуючи модуль sys.

Цей модуль безпосередньо взаємодіє з інтерпретатором Python.

import sys
print(sys.path)

Можна запустити однією командою прямо з консолі bash.

python -c "import sys; print('\n'.join(sys.path))"

Вывод

/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/home/zdimon/.local/lib/python2.7/site-packages
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages/PILcompat
/usr/lib/python2.7/dist-packages/gtk-2.0
/usr/lib/python2.7/dist-packages/ubuntu-sso-client
/usr/lib/python2.7/dist-packages/wx-3.0-gtk2

Як бачимо майже всі шляхи є системними та прав на запис у них має лише привелигеровані користувачі.

Тому при спробі просто встановити якийсь пакет запустивши, наприклад,

pip install markdown

Ви отримаєте помилку прав доступу, оскільки поточний користувач не може писати в /usr/local/lib/python2.7/dist-packages.

ERROR: Could not install packages due to an EnvironmentError: 
[Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/markdown

Вихід із цієї ситуації - це змінити змінну оточення інтерпретатора sys.path, вказавши у ньому шлях нашого проекту замість системних шляхів.

Це забезпечує таку програму як virtualenv.

Установка

apt install virtualenv

Створення віртуального оточення.

virtualenv venv # python 2

virtualenv -p python3 venv  # python 3

При цьому venv - довільне ім’я папки, яка створюється в поточній директорії.

Зазвичай її створюють поруч із директорією проекту, чи всередині неї.

Після створення цієї директорії необхідно запустити bash скрипт activate із каталогу venv/bin.

Саме він і змінюватиме шляхи в sys.path до наших залежностей.

Після активації ми побачимо префікс (venv) у командному рядку консолі, що означає те, що тепер під час використання pip установника він ставитиме пакети не в системні каталоги, а всередину нашого віртуального оточення. Це каталог venv/lib/python3.5/site-packages/.

Основи Python и Django. -> Бібліотека beautifulsoup.

Бібліотека BeatifulSoup.

Встановлення.

pip install bs4

приклад html документа

html_document = '''    
<html>
    <head>
        <title>Головна сторінка</title>
    </head>
    <body>
        <h1> Посилання H1  </h1>
        <a href="http://google.com">Посилання 1 </a>
        <a href="http://yandex.ru"> Посилання 2 </a>
        <div id="block_id">
            Блоковий елемент
        </div>
        <p class="p_class"> Параграф 1 </p>
        <p class="p_class"> Параграф 2 </p>
        <p class="p_class"> Параграф 3 </p>
        <table>
            <tr> 
                <td valign="top"> Ячейка 1 </td>
                <td valign="top"> Ячейка 1 </td>
                <td valign="top"> Ячейка 3 </td>    
            </tr>
            <tr> 
                <td valign="top"> Комірка1 </td>
                <td valign="top"> Комірка 1 </td>
                <td valign="top">Комірка 3 </td>    
            </tr>
        </table>
    </body>
</html>    
'''

Читання DOM.

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')

Заголовок документа.

soup.title.string

Пошук одного та групи елементів.

el = soup.find('h1')

Знайдемо усі посилання на сторінці.

soup.findAll('a')

Доступ до тексту та атрибутів тега.

link.get('href')
link.text

Прохід по масиву

for link in soup.findAll('a'):
    print(link.get('href'))

Пошук одного елемента по id.

el = soup.find('h1',{'id': 'my-header'})

Пошук багатьох елементів на ім’я класу.

els = soup.findAll('div',{'class': 'class_name'})

за кількома класами

show = soup.find('div', class_='action-link showPhonesLink')
show = soup.find('div', attrs={'class': 'action-link showPhonesLink'})

Пошук за css атрибутами.

els = soup.findAll('div',attrs={'id': '123'})

Метод select

results = soup.select('td[valign="top"]')
  • повертає масив

Мережі

Основи Python и Django. -> Библиотека requests.

Бібліотека requests.

дока

Встановлення.

pip install requests

Використання.

import requests

Запит із передачею хедерів.

r=requests.get(url, headers={"key":"val"})
print(t.text)

POST запрос

url = 'https://webmonstr.com/ru/login/'
data = {"username": "test", "password": "test"}
r = requests.post(url,data=data)
print(r.text)

Словники.

Перераховані структури даних, що визначаються у вигляді пар ключ - значення всередині фігурних дужок через двокрапку та розділених комою.

Доступ до значень елементів словника за ключем.

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

print dict['Name']

Ключ може бути числом.

dict = {1: 'one', 2: 'two'}
print dict[1]
print dict[3]

Traceback (most recent call last):
  File "dict_ex.py", line 3, in <module>
    print dict[3]
KeyError: 3

Безпечне вилучення.

print dict.get(3,'no')

Зміна словника

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School"; # Add new entry

Видалення елементів із словника.

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

del dict['Name']; # remove entry with key 'Name'
dict.clear();     # remove all entries in dict
del dict ;        # delete entire dictionary

Ключ має бути незмінним об’єктом.

dict = {['Name']: 'Zara', 'Age': 7}


Traceback (most recent call last):
   File "test.py", line 3, in <module>
      dict = {['Name']: 'Zara', 'Age': 7};
TypeError: list objects are unhashable

Вбудовані функції роботи зі словником..

Створення словника.

md = dict(name='Vova', age=23)

print(md)

Довжина словника.

len(dict)

Строкове уявлення.

str(dict)
type(variable)

Створення словника з 2 списків функцією zip.

d1 = ['one', 'two', 'three']
d2 = [1, 2, 3]
d3 = dict(zip(d1,d2))
print(d3

>> {'three': 3, 'two': 2, 'one': 1}

Вбудовані методи словників.

dict.clear() # очистить
dict.copy() # склонировать (сделать копию)




dict.fromkeys(seq[, value])

Create a new dictionary with keys from seq and values set to value.

seq = ('name', 'age', 'sex')
val = (10,20,30)
dict = dict.fromkeys(seq,val)
print dict
>> {'age': (10, 20, 30), 'name': (10, 20, 30), 'sex': (10, 20, 30)}

dict.get(key, default=None)

Проверка на существование ключа.

dict.has_key(key)  # only for Python 2!

if 'key' in md:
    print('Yes')
else:
    print('No')

Отримання всіх ключів словника.

print(dict.keys())

>> dict_items([('two', [1, 2, 3]), ('one', [1, 2, 3]), ('three', [1, 2, 3])]) # python 3
>> [('three', [1, 2, 3]), ('two', [1, 2, 3]), ('one', [1, 2, 3])] # python 2

Отримання всіх значень словника.

print(dict.values())
>> dict_values([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) # python 3
>> [[1, 2, 3], [1, 2, 3], [1, 2, 3]] # python 2

Отримання всіх ключів значень словника.

print(dict.items())

>> dict_items([('two', [1, 2, 3]), ('one', [1, 2, 3]), ('three', [1, 2, 3])]) # python 3
>> [('three', [1, 2, 3]), ('two', [1, 2, 3]), ('one', [1, 2, 3])] # python 2

Обхід словника у циклі.

for key, value in d.iteritems(): # For Python 2.x

for key, value in d.items(): $ for Python 3.x

Альтернативний спосіб обходу за ключами dict.keys().

for key in d3.keys():
    print(d3[key])

Масове оновлення словника словника.

dict.update(dict2)

Функція НЕ повертає, а змінює словник.

Перетворення словника на рядок json.

import json

json.dumps({"one": 1, "two": '2'})

Запишем в файл.

# write into file
f = open('tst.txt','w+')
f.write(s1)
f.close()

Для запису рядка її потрібно перетворювати з об’єкта словника на рядок функцією dumps.

Вважаємо з файлу.

# read from file
f = open('tst.txt','r')
st = f.read()
f.close()
st_dict = json.loads(st)
print(st_dict['two'])

Для роботи зі словником його необхідно перетворювати з рядка на об’єкт ф-цією loads.

Основи Python и Django. -> Домашнє завдання. Гра "очко".

Домашнє завдання

#! /usr/bin/env python
# -*- coding: utf-8 -*-

questions = [ 
        {
            "question": "Оператор виведення на екран?", 
            "answers": [
                {"text": "1 echo", "is_true": False},
                {"text": "2 print", "is_true": True},
                {"text": "3 output", "is_true": False}
            ] 
        },

        {
            "question": "Оператор циклу?",
            "answers": [
                {"text": "1 for", "is_true": True},
                {"text": "2 if", "is_true": False},
                {"text": "3 loop", "is_true": False}
            ]
        },

    ]

for i in questions:
    print("\x1b[34;47m" + i["question"] + "\x1b[0m")
    for j in i["answers"]:
        print("\x1b[34;47m" + j["text"] + "\x1b[0m")

    value = input("Укажите правильный номер: ")
    value = int(value)
    print("---------------------")
    if i["answers"][value - 1]["is_true"] == True:
        print('\x1b[30;42m' + 'Верно!' + '\x1b[0m')
    else:
        print('\x1b[30;41m' + 'Не верно!' + '\x1b[0m')
    print("---------------------")

Написати гру в “очко”.

Суть гри.

Гравцеві пропонується брати карти по одній, набираючи очки. При наборі 21 очка гравець виграє, при більшому значенні – програє.

koloda = [6,7,8,9,10,2,3,4,11] * 4

import random
random.shuffle(koloda)

print('Пограємо в очко?')
count = 0

while True:
    choice = input('Братимете карту? y/n\n')
    if choice == 'y':
        current = koloda.pop()
        print('Вам трапилася карта гідністю %d' %current)
        count += current
        if count > 21:
            print(''Вибачте, але ви програли')
            break
        elif count == 21:
            print('Вітаю, ви набрали 21!')
            break
        else:
            print('У вас %d очков.' %count)
    elif choice == 'n':
        print('У вас %d очок і ви закінчили гру.' %count)
        break

print('До нової зустрічі!')