10/06/2013

Rzadko wykorzystywane typy danych

Wstęp

Przy codziennej pracy z pythonem często korzystasz z takich typów danych jak słownik, lista, krotka czy zbiór. Ale warto pamiętać, że istnieją również inne typy danych, które często mogą Ci się przydać, a o których niekoniecznie słyszałeś. Przedstawię kilka z nich, które moim zdaniem są warte uwagi.

Counter

Typ ten przydaje się wtedy gdy chcesz np. sprawdzić ile razy występuje dany obiekt w zbiorze i dodatkowo chcesz to trzymać jako słownik. Przykład:


deque

Obiekt deque idealnie nadaje się do stosu lub kolejki. Dodawanie oraz pobieranie elementu jest zbliżone do O(1); nie ważne czy pobierasz z końca czy z początku. Jeżeli jednak chcesz dostać się do elementów po indeksach lepiej jest skorzystać z listy, która jest do tego przystosowana, więc siłą rzeczy jest szybsza. Poniżej, krótkie porównanie:


defaultdict

defaultdict przydaje się tam, gdzie chcesz stworzyć słownik w którym przy dostępie ma już mieć zdefiniowaną domyślną wartość. Zamiast martwić się sprawdzaniem czy czasem dany klucz ma zdefiniowaną wartość, sam ustawiasz jaki to ma być typ.


namedtuple

Ten typ danych jest często wykorzystywany przy pobieraniu danych z bazy lub np. z pliku csv. Ja napisałem prosty przykład jak szybko przemienić otrzymanego JSON'a w namedtuple i mieć dostęp do wartości nie po kluczu, a po atrybucie.

heapq

heapq przyda się wtedy, gdy chcesz stworzyć kopiec (kolejka priorytetowa). Przykład użycia:


bisect

Wykorzystanie modułu bisect nadaje się wtedy, gdy masz wystarczająco dużą listę, w której sortowanie jej za każdym razem nie wchodzi w grę, ale w jakiś sposób chcesz otrzymać wartość, która znajdowała by się pod indeksem 42, gdyby lista była posortowana. Prosty przykład wraz z porównaniem:

9/28/2013

Pylibmc, ultramemcache i python-memcached

Wstęp

W ubiegłym roku pisałem o ultrajsonie, który wypadł bardzo dobrze. Przedwczoraj natrafiłem na bibliotekę ultramemcache, którą również postanowiłem przetestować i sprawdzić czy jest ultra.

Do porównania wykorzystam biblioteki python-memcached oraz pylibmc. Pierwszy test odbył się standardowo poprzez odpalenie jednego procesu. Drugi natomiast z wykorzystaniem czterech procesów co znacznie przyspieszyło działanie.

Jeden proces:


python-memcached


ultramemcache


pylibmc


Cztery procesy:


python-memcached


ultramemcache


pylibmc


Wyniki

Testy wykonałem kilka razy dla każdego ze skryptów i wybrałem najlepsze wyniki dla danej biblioteki.

Był to bardzo prosty test, ale da się zauważyć spore różnice w szybkości działania tych bibliotek. W przypadku jednego procesu ultramemcache poradził sobie najlepiej, chociaż pylibmc jest tuż tuż... Jeżeli chodzi o cztery procesy to pylibmc jest zdecydowanym zwycięzcą.

Zachęcam do robienia swoich testów. Do sporządzenia wykresu skorzystałem z infogr.am. Jedno z lepszych narzędzi do sporządzania infografik z jakich korzystałem.

Update: dodałem testy dla pylibmc.

8/14/2013

Dodiff

Ostatnio często muszę robić diffy w gicie i zapisywać je do plików. Przykładowa nazwa pliku z diffem wygląda tak: {branch}-{branch/commit}.diff

Diffy pomiędzy poszczególnymi commitami nie są mi potrzebne. Aby otrzymać takiego diffa można wykonać komendę git diff {branch/commit} > ~/diffs/{branch}-{branch/commit}.diff.
Przykłady:
git diff develop > ~/diffs/develop-master.diff
git diff 66666 > ~/diffs/66666-develop.diff
git diff 18361 > ~/diffs/18361-develop.diff
git diff 47529 > ~/diffs/47529-0dbf4fa.diff
Jak widać jest trochę pisania.
  •  po co za każdym razem wpisywać katalog w którym ma zostać stworzony plik
  • po co podawać nazwę brancha na której właśnie jesteś (i to dwa razy!) ;)
  • pracuj na gałęziach, których nazwy składają się wyłącznie z cyfr to oczopląsu dostaniesz po kilkunastu takich komendach
Dlatego też postanowiłem napisać do tego prostą funkcję w bashu. Założenie było proste, mam podać nazwę funkcji i jako pierwszy parametr przekazać nazwę brancha/commita między którym chcę zobaczyć różnice.

Skrypt ma sam sprawdzić czy jest już katalog diffs w moim katalogu użytkownika, jak nie ma, to niech go tworzy i dodatkowo, niech sam pobiera informację na temat nazwy brancha na którym aktualnie jestem.

Tak powstała funkcja dodiff (ja ją wrzuciłem standardowo do ~/.bash_aliases):
dodiff() {
    if [ ! -d ~/diffs ]; then
        mkdir -p ~/diffs
    fi

    branch=`git rev-parse --abbrev-ref HEAD`
    git diff $1 > ~/diffs/$branch-$1.diff
}
Przykład użycia: showterm.

8/04/2013

bumpversion

bumpversion to ciekawa paczka do automatycznego podbijania wersji twojej paczki ;).

(screencast)

 Jedną komendą jesteś w stanie podbić wersję w swojej paczce w kilku miejscach (oczywiście, najlepiej informację o wersji trzymać w jednym miejscu, ale czasami jesteś zmuszony, aby zrobić to w kilku plikach).

Przykładowo, twoja aktualna wersja to 0.1.10, zrobiłeś małego fixa i chcesz podbić wersję do 0.1.11. Dodatkowo informacje na temat wersji trzymasz w pliku setup.py oraz w random_words/__init__.py. Zapomniałem dodać; jak chcesz to zajrzyj do paczki RandomWords, bo to na niej jest przykład.

Teraz wystarczy odpalić:
bumpversion --current-version 0.1.10 patch setup.py random_words/__init__.py
i gotowe. Skrypt podbił wersję w pliku setup.py oraz w random_words/__init__.py


Dokumentację i więcej przykładów użycia znajdziesz na githubie.

P.S. Screena musiałem zrobić lokówką bo ubuntu odmówiło przed chwilą posłuszeństwa, a nie chce mi się resetować systemu.

5/25/2013

Travis CI oraz PyPI badges

Jeżeli korzystasz z Travis-CI do testowania swojego repozytorium na githubie oraz trzymasz paczkę na pypi, możesz w łatwy i prosty sposób dodać informacje na temat statusu do pliku README. Dzięki temu userzy będą widzieć czy wszystkie testy przeszły pomyślnie, jaka jest aktualna wersja paczki oraz jaka jest ilość ściągnięć. U mnie dla repo RandomWords wygląda to tak:

Travis-CI

W dokumentacji travis-ci znajdziesz informacje o tym co musisz umiejscowić w odpowiednim pliku.

PyPI

Osobiście korzystam z dwóch formatów. Markdown dla github oraz reStructuredText dla PyPI.

Markdown:
[![PyPi version](https://pypip.in/v/$REPO-NAME/badge.png)](https://crate.io/packages/$REPO-NAME/)
[![PyPi downloads](https://pypip.in/d/$REPO-NAME/badge.png)](https://crate.io/packages/$REPO-NAME/)
reStructuredText:
.. image:: https://pypip.in/v/$REPO-NAME/badge.png
    :target: https://crate.io/packages/$REPO-NAME/
    :alt: Latest PyPI version

.. image:: https://pypip.in/d/$REPO-NAME/badge.png
    :target: https://crate.io/packages/$REPO-NAME/
    :alt: Number of PyPI downloads
Przykład dla markdown znajdziesz tutaj, a dla reStructuredText tutaj. Zachęcam do używania.

RandomWords 0.1.8

Wrzuciłem przed chwilą poprawkę do biblioteki RandomWords. Od dzisiaj działa pod pythonem 2.6, 2.7, 3.2 oraz 3.3. Można to sprawdzić tutaj.

5/22/2013

gift

Stworzyłem skrypt do pobierania obrazków z tumblera, znajdziesz go w repo gift (get images from tumblr). Pobieranie informacji na temat danego bloga opiera się o tumblerowe API, więc musisz mieć swoją appkę. Tutaj możesz ją szybko założyć. Obrazki są zapisywane w katalogu images/nazwa-bloga.

Instalacja

Repo ściągasz poleceniem:
git clone https://github.com/tomislater/gift.git
Wchodzisz do katalogu gift i instalujesz zależności:
pip install -r requirements.txt

Jak używać

Po założeniu aplikacji w pliku config.cfg podajesz swój consumer key:
[tumblr]
consumer_key = your_consumer_key
Jak korzystać ze skryptu najlepiej dowiesz się wpisując w konsoli:
python gift.py -h

Poniżej kilka screenów:
python gift.py perfectboard

python gift.py joeyxbadass

./gift skate--n--surf -l 100

5/17/2013

TFDPronunciation nowa wersja (progressbar)

Dodałem dzisiaj do skryptu TFDProunciation progressbar. Czasami strasznie mi muli net i fajnie mniej więcej wiedzieć kiedy skrypt skończy się wykonywać.



bpython i dzielenie się kodem

Przy codziennej pracy z pythonem moimi ulubionymi konsolami są bpython (szybkość) i IPython (kombajn). Dzisiaj będzie krótko na temat jednej z funkcji jaką oferuje bpython, a chodzi tutaj o wrzucenie kodu z konsoli do internetu ;)

bpaste

Aby wysłać kod z konsoli bpython wystarczy wcisnąć F8 i potwierdzić to klawiszem y. Domyślnie kod jest wysyłany na bpaste i z poziomu konsoli wygląda to mniej więcej tak:
http://bpaste.net/show/cVuvrhTrBZB8ZSM9DVxP/
I to tyle jeśli chodzi o wrzucanie na bpaste.

gist

Ale co jeśli, chcę szybko umieścić kod na gist? Oczywiście da się, lecz trzeba poczynić kilka kroków. Pierwsze co musisz zrobić to stworzyć plik konfiguracyjny dla bpythona w którym zamieścisz informację, jakiego skryptu ma używać do wypychania kodu. Jeśli nie masz pliku ~/.config/bpython/config to go stwórz i dodaj w sekcji general linijkę: pastebin_helper = do_gist_json. Przykładowo u mnie wygląda to tak:
Nazwa do_gist_json to oczywiście nazwa skryptu, który będzie miał się wykonać po wciśnięciu F8 (domyślnie jest to pastebinit, dlatego też leci na bpaste). Czas na napisanie skryptu. Zaraz! Jak pisać?! Spokojnie, poniżej zamieszczam kod; musisz tylko podmienić dane user i pass na swoje jeśli chcesz, aby kod wrzucał się na twoje konto. Jeśli nie chcesz, możesz usunąć argument auth:
#!/usr/bin/env python

import sys
import json
import requests


def do_gist_json(s):
    gist_url = 'https://api.github.com/gists'

    data = {'description': "Gist from BPython",
            'public': True,
            'files': {
                'sample.py': {'content': None}
            }}
    data['files']['sample.py']['content'] = s

    res = requests.post(gist_url,
                        data=json.dumps(data),
                        auth=("user", "pass"))

    return res.json()["html_url"]

if __name__ == "__main__":
    s = sys.stdin.read()
    print do_gist_json(s)
Domyślnie wysyłany kod jest publiczny, jeśli tego nie chcesz to już pewnie zauważyłeś, którą linijkę musisz zmienić :). Plik do pobrania jest tutaj. Ściągnij/skopiuj gdzieś na dysk i nazwij go tak jak podałeś w pliku ~/.config/bpython/config. Następnie musisz nadać skryptowi prawa do wykonywania, czyli wpisujesz w konsoli:
chmod +x do_gist_json
i kopiujesz do /usr/bin/
sudo cp do_gist_json /usr/bin/
I już, teraz po odpaleniu bpythona i wciśnięciu klawisza F8 program będzie wiedział, że kod ma wysłać na gist, a nie na bpaste.
https://gist.github.com/tomislater/5595417
EDIT:
Skrypt korzysta z biblioteki requests, więc musisz ją mieć u siebie (sudo pip install requests).

4/28/2013

i3 i nowe aliasy

Jakiś czas temu jeden z moich znajomych zaproponował mi wypróbowanie xmonad do pracy. Pobawiłem się nim jakieś półtora dnia i nie przypadł mi bardzo mocno do gustu. Może inaczej, był fajny, ale myślałem, że będzie lepszy ;) (chociaż, na początku byłem pod wielkim wrażeniem). Postanowiłem więc poszukać alternatywy dla xmonad i znalazłem i3. Spędziłem trochę czasu na konfiguracji środowiska i jestem z niego bardzo zadowolony. Postanowiłem póki co wykorzystywać go do codziennej pracy, jak nie będzie mnie zbytnio irytował to zacznę go używać w pracy.

Przy okazji uaktualniania repo dotfiles, dodałem trzy nowe aliasy. Zamieszczam je poniżej:

Bezpieczny rm:
alias rm='rm -I'

Największy plik/katalog w danym katalogu
alias ds='du -ks *|sort -n'

Aktualna pogoda dla miasta Szczecin (ICM)
alias szczecin='display "http://www.meteo.pl/um/metco/mgram_pict.php?ntype=0u&row=370&col=142&lang=pl"'

4/21/2013

Python test framework - splinter

Trafiłem dzisiaj na framework splinter, który służy do testowania webowych aplikacji. Po przeczytaniu dokumentacji i przejrzeniu krótkiego tutoriala postanowiłem sprawdzić czy może mi się przydać. Framework poznałem u siebie lokalnie, wykonując testy na jednej z moich appek do testów, ale tutaj przedstawię to na istniejącej witrynie w sieci. Na początek garść informacji.

Możliwości

  • wykonywanie skryptów javascript
  • bardzo proste api
  • multi webdrivers (chrome, firefox, phantomjs, zopetestbrowser, remote)
  • wsparcie dla xpath i css
  • działające iframe i alerty
  • działający ajax oraz asynchroniczny javascript

 

 Instalacja

pip install splinter
Po jakże trudnej instalacji możesz wziąć się za testowanie web aplikacji.

Poniżej znajduje się lista, które przetestuję na stronie sonyvegas:
  • skorzystanie z wyszukiwarki
  • próba skorzystania z kalendarza
  • próba zalogowania na nieistniejące konto
Pierwsze co musisz zrobić to stworzyć instancję przeglądarki, a robisz to tak:
from splinter import Browser
browser = Browser('firefox')
Następnie należy podać adres pod jaki zamierzasz się udać. Jak wyżej zaznaczyłem zacznę od testowania wyszukiwarki:
browser.visit('http://sonyvegas.info/search.php')

input = browser.find_by_xpath(
    '//td[@class="trow1"]/table/tbody/tr/td/input[@class="textbox"]')
input.first.fill("rendering")

button = browser.find_by_name("submit")
button.first.click()

assert browser.is_text_present("Wyniki") is True
assert len(browser.find_by_xpath('//a[@class=" subject_old"]')) == 20
Co wykonał ten test? Wszedł pod wskazany adres. Wyszukał inputa (za pomocą xpath) w którego wprowadził wyrażenie "rendering", następnie odszukał przycisk służący do zaakceptowania szukania i kliknął go. Po tej akcji sprawdził czy na stronie znalazł się tekst "Wyniki" oraz czy na stronie jest 20 linków z wynikami.

Teraz sprawdzę czy user na pewno nie ma dostępu do kalendarza:
browser.visit("http://sonyvegas.info/calendar.php")
assert browser.is_text_present(
    u"Kalendarz został wyłączony przez administratora.")
Jak widać test jest bardzo prosty. Udaje się pod wskazany internetowy adres :) i sprawdza czy wyświetla nam się odpowiedni komunikat na stronie.

Ostatnim testem będzie próba zalogowania się na nieistniejące konto:
browser.visit("http://sonyvegas.info/member.php?action=login")
browser.fill("username", "testuser")
browser.fill("password", "userpassword")
browser.check("remember")
browser.find_by_name("submit").first.click()
assert browser.is_text_present(
    u"Wprowadzono nieprawidłowy login i/lub hasło.")
Jak widzisz tutaj też nie ma zbyt dużo filozofii. Udajesz się pod adres logowania, wprowadzasz username, password oraz zaznaczasz, że chcesz być zapamiętanym i klikasz w submit, tyle. Następnie sprawdzasz, czy user się nie zalogował.

Użyłem tutaj bardzo prostych przykładów, lecz nie powinieneś mieć problemów z używaniem splintera. Framework ma naprawdę dobrą dokumentację, naprawdę mi się spodobał.

Zapomniałbym! Na koniec oczywiście zamknij przeglądarkę ;)
browser.quit()

4/14/2013

Nowa wersja TFDPronunciation

Dodałem małą poprawkę do repo TFDPronunciation. Informacje o tym czy plik został znaleziony czy też nie są wyświetlane w kolorze. Dzięki temu szybciej wiesz co się stało. Poniżej przykładowy screen:


P.S. Kilka dni temu powróciłem do Sublime Text po zmianie komputera na lepszy i muszę powiedzieć, że jest całkiem spoko, tylko nie mogę poprawnie skonfigurować SublimeCodeIntel. Linux x64, Ubuntu 12.04. Jak ktoś by rozwiązał ten problem to niech da mi znać :) Dokładnie chodzi o to, że po pewnym czasie pracy (mniej niż minuta?) plugin zaczyna zżerać 100% procka....

3/23/2013

Vim tagbar

Tagbar pomaga wtedy gdy w module masz dużo kodu i jest ci trudno ogarnąć, co gdzie jest (np. po wcześniejszej osobie, która pisała kod).

Jeżeli korzystasz z pathogen to instalacja jak się domyślasz jest banalna:
cd ~/.vim/bundle
git clone https://github.com/majutsushi/tagbar.git
Dodatkowo musisz mieć w systemie Exuberant Ctags. Szybka instalacja pod Ubuntu:
sudo apt-get install ctags
W pliku .vimrc możesz jeszcze dodać:
nmap <F8> :TagbarToggle<CR>
Umożliwi ci to na szybki dostęp do Tagbar wciskając F8.

Tak to wygląda dla kodu pythona:
Tagbar vim
 Kilka przydatnych skrótów klawiszowych:
  • enter/double click - przenosi Cię do taga, na który wskazałeś kursorem (na screenie widać, że przeniosło mnie do metody route)
  • s - sortowanie tagów według kolejności występowania lub według nazwy (domyślnie jest według kolejności występowania)
  • p - przenosi do danego tagu, lecz kursor pozostaje w tagbarze
  • -/+ - zwija/rozwija tagi, np. importy czy klasy
  • =/* - zwija/rozwija wszystkie tagi
  • ctrl+n/ctrl+p - skakanie po top-level tagach (następny, poprzedni)
  • F8 ;)

3/09/2013

Vim i gitgutter

Kilka dni temu trafiłem na plugin vim-gitgutter i postanowiłem go wypróbować. W wielkim skrócie plugin odpowiada za pokazywanie w którym miejscu w pliku dokonałeś zmian, coś jak git diff.


Korzystam z pathogen, więc aby zainstalować plugin wklepałem:
cd ~/.vim/bundle
git clone git://github.com/airblade/vim-gitgutter.git
I już można się bawić. Posiedziałem nad nim chwilę i naprawdę mi się spodobał, lecz musiałem wprowadzić kilka swoich poprawek :)

Po pierwsze, wyłączyłem domyślne pokazywanie różnic, a zbindowałem sobie komendę GitGutterToggle pod <leader>gr. Dzięki temu jak chcę zobaczyć różnicę to wciskam ,gr (klawisz <leader> mam zbindowany pod ","), a jak chcę wyłączyć to wciskam znów to samo. Dodatkowo zbindowałem sobie komendy GitGutterNextHunk i GitGutterPrevHunk odpowiednio pod <leader>d oraz <leader>s. Mogę przez to w łatwy i szybki sposób poruszać się po pliku skacząc z jednej zmiany na drugą.

Tak to wygląda w pliku .vimrc:
let g:gitgutter_enabled = 0
nmap <leader>gr :GitGutterToggle<CR>
nmap <leader>s :GitGutterPrevHunk<CR>
nmap <leader>d :GitGutterNextHunk<CR>
Plugin oferuje jeszcze kilka innych ciekawych rozwiązań takich jak np. podświetlanie danej linii ze zmianami, ale mi osobiście to bardziej przeszkadza niż pomaga. Jak zawsze zapraszam do repo dotfiles. Jak masz coś fajnego, też się podziel :)

3/06/2013

Anki i volume

Ostatnio nie wiadomo z jakich przyczyn (najprawdopodobniej jakiś program nadpisał mi configa .mplayer/config) anki nagle zaczęło odtwarzać wszystkie pliki audio bardzo cicho. Anki do odtwarzania audio korzysta z mplayera, więc od razu było wiadomo gdzie muszę szukać przyczyny.

Pierwsze co znalazłem na ten temat w man mplayer to informacja o tym, aby pobawić się głośnością. Dodałem więc do configa linijkę:
af=volume=10:0
Dzięki temu, każdy plik otwierany przez mplayer był wzmocniony o 10dB. Warto pamiętać, że jest to skala logarytmiczna, jak podasz 100 to wcale nie będzie głośniejsze sto razy, tylko dziesięć miliardów. Zadziałało, ale gdy podaje się zbyt dużą głośność to filtr ją przycina, aby do karty muzycznej nie przesyłać danych spoza akceptowalnego zakresu, co dla nas objawia się tym, że dźwięk jest zniekształcony.

Zmniejszyłem więc do 5dB (i do mniejszych wartości), ale dalej to samo. Dźwięk w niektórych momentach zostaje zniekształcony i po jednym odtworzeniu pliku, drugi raz nie chce już się tego robić ;) Nie mogłem tego zaakceptować, więc szukam dalej. Odtworzyłem pierwszy lepszy plik audio za pomocą mplayer i okazało się, że korzysta on nie ze sterownika alsa, lecz z pulse i problem został rozwiązany.

W configu umieściłem więc informacje o tym z jakiego sterownika mplayer ma korzystać i wszystko wróciło do normy. Oczywiście nie musiałem już podbijać głośności o te kilka decybeli, więc z configu mam teraz tylko:
ao="alsa"

2/28/2013

VimFx - skróty z vima w ff

VimFx oferuje możliwość używania skrótów z vima w przeglądarce firefox. Co mnie skusiło, aby go wypróbować? Mnogość opcji na którą składają się:
  1. szybkie wyłączenie dodatku na danej stronie ;)
  2. łatwe dodawanie stron za pomocą wyrażeń regularnych do blacklisty
  3. włączenie/wyłączenie każdego skrótu
  4. szybki help (wciskasz ?)
  5. szukanie via Vim
  6. skakanie po tabach
  7. nawigacja po stronie
Repo projektu na githubie: VimFx - znajdziesz tu od razu skróty klawiszowe.

2/21/2013

Vim Commands dla Anki

Znalazłem ciekawy deck (flashcard?) dla Anki. Ukrywa się pod nazwą Vim Commands. Codziennie po 5 nowych komend nikomu nie zaszkodzi. Gość ma jeszcze repo na githubie, więc zawsze można dodawać coś od siebie i dzielić się ze światem. Na start jest 239 komend. Jeżeli ustawisz sobie po 5 nowych komend dziennie, to po dwóch miesiącach powinieneś już sprawnie nimi operować.

2/14/2013

Update wszystkich submodułów w GIT

Jeżeli w swoim repozytorium gita korzystasz z kilku/kilkunastu repozytoriów to po dłuższej chwili zacznie cię mocno irytować taka rutyna:
  1. wchodzę w submoduł
  2. sprawdzam gałąź, czy jest na master
  3. odpalam git pull
  4. wychodzę z submodułu
Jest na to łatwy sposób. Wystraczy wklepać w konsoli:
git submodule foreach git pull
Ale uwaga, tutaj niespodzianka ;) Jeżeli dopiero co zassałeś swoje repozytorium w którym masz submoduły, to aby działały musisz najpierw odpalić:
git submodule init
git submodule update --recursive
wszystko się oczywiście wykona, ale submoduły zostaną zaktualizowane do konkretnego commita, którego ustawiłeś wykonując wcześniej git push. Co implikuje to, że nie będziesz miał ustawionej gałęzi w żadnym z submodułów. Submoduł będzie wskazywał na konkretnego commita, a nie na gałąź.

git submodule update --recursive
Jest to oczywiście normalne i tak powinno to działać! Taka jest idea submodułów. Odwołują się do commita, którego im przypisałeś, a nie do konkretnej gałęzi.

Gdy dopiero co budujesz swoje repozytorium i dodajesz submoduły do swojego repo, mają one gałąź i jest to normalne, lecz w momencie gdy je wypychasz i ktoś je sklonuje (albo, ty sam to zrobisz do innego katalogu), to po aktualizacji submodułów będą one wskazywały właśnie na commit, a nie na gałąź. Dlatego też, gdy sklonujesz sobie repozytorium i chcesz wprowadzić jakieś zmiany, np. aktualizacja submodułu do najnowszej wersji warto wykonać:
git submodule init
git submodule update --recursive
A następnie jedno z dwóch poleceń:

Gdy nie masz ustawionych gałęzi, czyli najczęściej zaraz po sklonowaniu (pobierze gałąź master lub jakąkolwiek inną jaką wskażesz):
git submodule foreach git pull origin master
git submodule foreach git checkout master
Gdy masz ustawione gałęzie we wszystkich submodułach (pobierze gałąź na której aktualnie się znajduje, czyli tą na którą wskazuje HEAD):
git submodule foreach git pull
I to chyba tyle, jest jeszcze problem, gdy prawie wszystkie twoje submoduły opierają się o gałąź master, a jeden np. o gałąź develop, ale wskoczyć do tego jednego i odpalić git pull to już chyba nie problem.

2/10/2013

Vim-snipmate i python

Trafiłem ostatnio na dość ciekawy plugin do vima, a mianowicie na vim-snipmate. Jest to fork z repo snipmate.vim, które autor przestał rozwijać jakieś 3-4 lata temu.

vim-snipmate

Czym jest snipmate? Jest to plugin, który pomaga dopełniać pisany przez ciebie kod. Przykładowo, wpisujesz def lub cl, wciskasz <tab> i plugin sam dalej tworzy funkcję czy klasę. Postanowiłem, że stworzę video i pokażę jak plugin się sprawdza przy pisaniu w pythonie. Bardzo mocno go polecam. Tym bardziej, że wspiera praktycznie każdy popularniejszy format.

Video

Instalacja

Zakładam, że używasz pathogen. Jeżeli nie, zajrzyj tutaj. Przy okazji polecam ten post, w którym opisuję praktycznie krok po kroku jak zrobić sobie Python IDE.
cd ~/.vim/bundle
git clone git://github.com/garbas/vim-snipmate.git
git clone https://github.com/tomtom/tlib_vim.git
git clone https://github.com/MarcWeber/vim-addon-mw-utils.git
git clone https://github.com/honza/snipmate-snippets.git
I tyle, jeżeli chodzi o instalację, jak używać vim-snipmate możesz zobaczyć na filmiku wyżej.

2/05/2013

Cron i zc.lockfile

Musiałem dzisiaj napisać skrypt, który odpalał się co minutę poprzez crona i mogło się zdarzyć, że będzie wykonywał się trochę dłużej niż jedna minuta. Dlatego też, trzeba było wymyślić jakiś mechanizm, który by mnie uchronił przed odpaleniem skryptu kolejny raz, gdy ten jeszcze się nie wykonał.

Z pomocą przyszedł mi moduł zc.lockfile. Instalujesz go normalnie poprzez pipa:
pip install zc.lockfile

Jak działa zc.lockfile? Krótki opis:
The zc.lockfile package provides a basic portable implementation of interprocess locks using lock files. The purpose if not specifically to lock files, but to simply provide locks with an implementation based on file-locking primitives. Of course, these locks could be used to mediate access to other files. For example, the ZODB file storage implementation uses file locks to mediate access to file-storage database files. The database files and lock file files are separate files.

Ja go użyłem w następujący sposób, w skrypcie zdefiniowałem odpowiednią funkcję, a pod jego koniec dodałem: 
import zc.lockfile

def moja_uber_funkcja():
    pass

if __name__ == '__main__':

    try:
        lock = zc.lockfile.LockFile('moj_super_cron_skrypt')
    except zc.lockfile.LockError:
        sys.exit(1)
    
    moja_uber_funkcja()

    lock.close()
Dzięki temu, dopóki metoda close na obiekcie lock się nie wykona, skrypt będzie rzucał pięknym exceptionem zc.lockfile.LockError i mam pewność, że nic dalej się nie wykona ;)

2/02/2013

Powerline-bash, vim-powerline - zmiany

Powerline-shell

W listopadzie napisałem posta na temat powerline-bash. Warto wiedzieć, że repo zmieniło nazwę i jest teraz dostępne pod adresem powerline-shell. Całą dyskusję na temat zmiany nazwy można zobaczyć tutaj.

Powerline

Drugą dość ciekawą informacją jest to, iż prace na rozwojem vim-powerline zostały porzucone. Ale nie bój się! Plugin jest nadal dostępny, nie mniej jednak polecam przesiadkę na powerline. Oferuje to samo co vim-powerline, dodatkowo ma możliwość podpięcia również pod konsolę oraz co jest oczywiste będzie dalej rozwijany.

Poniżej zamieszczam dwa screeny z obu skryptów. Najlepiej samemu przetestować i wybrać ten który najbardziej się spodoba. Osobiście korzystam z powerline-shell w konsoli, a z powerline w vimie. Jakoś powerline-shell jest dla mnie bardziej przejrzysty ;)

powerline

powerline-shell

1/31/2013

Vim cheat sheet

Jakiś czas temu natknąłem się w necie na dwie dość ciekawe ściągawki do vima. Warto by się z nimi zapoznać lub mieć niedaleko siebie podczas pracy. Kilka razy już mi się przydały. Tak się zastanawiam czy sobie jakiegoś własnego cheat sheet nie zrobić w formie plakatu i walnąć za monitorem ;).

Klik w obrazek po więcej.


1/27/2013

Submoduły na github.com

Submoduły

Submoduły, czyli co zrobić, żeby np. na githubie w jednym repo umieścić inne repozytoria, aby wyglądało to tak jak poniżej, a nie tak jak na przykład tutaj.


Do czego się w ogóle przydają submoduły i dlaczego powinieneś je stosować? Wyobraź sobie, że tworzysz swoje repozytorium, które do poprawnej pracy wymaga innych, konkretnych repozytoriów gita. I tutaj z pomocą przychodzą submoduły. Dzięki nim twoje repozytorium będzie posiadało informacje o tym, gdzie dany submoduł się znajduje (jego adres) oraz jego ostatnie commit ID.

Dzięki takiemu zabiegowi, inni developerzy, którzy sklonują twoje repo (które wykorzystuje inne repozytoria), nie będą musieli się martwić, czy wszystko będzie działało tak jak powinno. Unikniesz przez to czasami dziwnych błędów. Np. ktoś dociągnie zbyt stare repozytorium lub zbyt nowe, albo całkowicie inną gałąź, niż tą które wykorzystuje twoje repo ;)

Osobiście póki co, użyłem submodułów w moim repo dotfiles.

Dodawanie submodułów

Załóżmy, że chcesz dodać jako submoduł repozytorium hubble, wystarczy wykonać komendę:
git submodule add https://github.com/jaymedavis/hubble.git
I to tyle, jeśli chodzi o dodawanie submodułów.

Klonowanie repozytorium z submodułami

Powiedzmy, że chcesz sklonować moje repozytorium ;) dotfiles, które posiada kilka submodułów. Repo klonujesz normalnie, jak każde inne. Po sklonowaniu jednak submoduły są puste, nic w nich nie ma, nie panikuj! Wystarczy wpisać dwie poniższe komendy:
git submodule init
git submodule update
W ten sposób git dociągnie wszystkie wymagane submoduły. Jeżeli autor repozytorium, które sklonowałeś, ustawił, że dany submoduł ma być w danej wersji, git sobie z tym poradzi i dociągnie dokładnie tą wersję. Jeżeli autor nie użył by submodułów mógłbyś mieć problem, bo skąd masz wiedzieć, jaką wersję danego repo masz sklonować?

Usuwanie submodułów

Z usuwaniem może być czasami trochę problemów. Najlepiej jest to zrobić w ten sposób:
  1. Usuwasz odpowiednią sekcję z pliku .gitmodules oraz .git/config
  2. Wykonujesz komendę git rm --cached ścieżka_do_submodułu (bez ukośników)
  3. Commitujesz i usuwasz nieśledzony już moduł
I to tyle ile wystarczy wiedzieć o submodułach na początek. Więcej informacji znajdziesz w dokumentacji.

1/21/2013

Zen Coding w vimie

Zdarza się, że muszę zajrzeć do szablonu z HaTeeMeLem i coś na szybko dorobić, zmienić czy wyrzucić. I tutaj przychodzi z pomocą Zen Coding. Nie będę się o tym mocno rozpisywał, ponieważ w necie jest już mnóstwo postów/artykułów na ten temat. Zamiast tego obejrzyj sobie to sześciominutowe video:



Okej, spodobało Ci się? Chcesz mieć to samo w vimie? Proszę bardzo, najpierw musisz zainstalować zencoding-vim:
cd ~/.vim/bundle
git clone https://github.com/mattn/zencoding-vim.git

Zakładam oczywiście, że korzystasz z vim-pathogen (pisałem o tym tutaj). I to tyle, nic więcej nie musisz konfigurować. Pod tym linkiem znajdziesz prosty tutorial pochodzący z tego repo z githuba. Natomiast tutaj są opisane selectory i aliasy. Jak chcesz już teraz zobaczyć, czy spodoba cię się Zen Coding to tutaj jest proste demo.

Oczywiście, nie zawsze jest to jakoś mega wydajne, czasami lepiej skopiować podobny szablon i zmienić parę rzeczy, mimo to warto się z nim zaznajomić, ponieważ oszczędzi Ci on mnóstwo czasu.

1/20/2013

Skrypt instalacyjny dla dotfiles

Postanowiłem dodać skrypt instalacyjny dla mojego repo dotfiles. Ustawiłem cztery opcje instalowania:
  • wszystkie pliki
  • tylko vim
  • tylko bash
  • tylko czcionki
# instalacja wszystkich plików
./install.sh # (-f, --force)

# tylko vim
./install.sh vim

# tylko bash
./install.sh bash

# tylko czcionki
./install.sh fonts

O vima i acka musisz już sam zadbać. To samo się tyczy jeżeli chcesz używać jako colorscheme solarized (dark) w gnome-terminal. Ale wszystko opisałem w pliku README.md, więc nie masz czym się martwić.

1/19/2013

Kilka przydatnych aliasów (bash)

Aliasy

Codziennie korzystam z dobrodziejstw konsoli. Wpisuję komendy, zapamiętuję, wpisuję nowe, zapamiętuję nowe, itd. Jeśli korzystam z jakiejś komendy dość często robię sobie z niej alias i wrzucam do pliku .bash_aliases w katalogu użytkownika.

Przedstawię aliasy z których korzystam na co dzień i które znacznie ułatwiają mi pracę. Aliasy będę przedstawiał najpierw w formie kodu, później krótki opis i na końcu obrazek jeżeli będzie to konieczne. Uwaga, zaczynam.

Katalogi/pliki

alias lr='ls -R | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/   /'\'' -e '\''s/-/|/'\'''
W przyjemny dla oka sposób, wyświetla strukturę katalogów (rekurencyjnie).



alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'
alias ......='cd ../../../../..'
Zamiast wpisywać "cd ..", wpisujesz "..". Jak raz użyjesz to nie ma odwrotu!

b() {
    str=""
    count=0
    while [ "$count" -lt "$1" ];
    do
        str=$str"../"
        let count=count+1
    done
    cd $str
}
Służy do tego samego co powyższy alias, z tym, że używasz go w sposób "b <liczba>".

alias l.='ls -d .* --color=auto'
Wyświetla tylko ukryte pliki.

alias lf='ls -Gl | grep ^d'
alias lsd='ls -Gal | grep ^d'
Oba listują wyłącznie katalogi. Drugi pokazuje również ukryte katalogi.

function mcd() {
  mkdir -p "$1" && cd "$1";
}
Tworzy katalog i od razu do niego wchodzi.

Terminal

alias c='clear'
Zamiast wpisywać clear, wpisujesz c.

alias freq='cut -f1 -d" " ~/.bash_history | sort | uniq -c | sort -nr | head -n 30'
Listuje 30 najczęściej wywoływanych przez ciebie poleceń basha.

Ubuntu

alias upgrade='sudo apt-get update && sudo apt-get upgrade && sudo apt-get clean'
Szybki upgrade.

I na koniec

extract () {
    if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2)   tar xjf $1     ;;
        *.tar.gz)    tar xzf $1     ;;
        *.bz2)       bunzip2 $1     ;;
        *.rar)       unrar e $1     ;;
        *.gz)        gunzip $1      ;;
        *.tar)       tar xf $1      ;;
        *.tbz2)      tar xjf $1     ;;
        *.tgz)       tar xzf $1     ;;
        *.zip)       unzip $1       ;;
        *.Z)         uncompress $1  ;;
        *.7z)        7z x $1        ;;
        *)     echo "'$1' cannot be extracted via extract()" ;;
         esac
     else
         echo "'$1' is not a valid file"
     fi
}
Rozpakowywuje najpopularniejsze archiwa, "extract <nazwapliku>"

Więcej aliasów znajdziesz w moim repo na githubie dotfiles. Polecam jeszcze stronę alias.sh, na której nie ma co prawda jeszcze dużej ilości aliasów, ale można znaleźć kilka ciekawych. Oczywiście jak masz własne aliasy to warto się nimi dzielić.

1/17/2013

Vim jako Python IDE

Wstęp

Trochę mi zajęło zabranie się za napisanie tego posta, ale oto jest. Mam nadzieję, że Ci się przyda. Post pisany trochę po to by utrwalić wiedzę, trochę po to, aby pomóc innym, którzy chcą spróbować Vima i trochę po to, by mieć coś ciekawego na tym blogu.

Zacznę od tego dlaczego nie inne edytory. Wypróbowałem naprawdę mnóstwo różnych IDE do Pythona, zaczynając od Eclipse, poprzez PyCharm, Komodo, erci5, Sublime Text 2 i wiele wiele innych, na Wingware kończąc. Wszystko z czego korzystałem po pewnym czasie albo i na początku "muliło", miało mnóstwo opcji z których nie skorzystałem i pewnie nie skorzystam nigdy w życiu, zaśmiecało mi system, dużo ważyło, etc. A odpalenie kilku instancji programu, tak aby można było porobić coś jeszcze na komputerze? Zapomnij.

Dlatego zacząłem szukać czegoś lekkiego, czegoś co będę mógł szybko odpalić z terminala i od razu pracować, czegoś co będę mógł w łatwy sposób odpalić na innej maszynie, czegoś co jest darmowe, czegoś co daje mi ogromne możliwość dzięki swojej modularności, czyli czegoś co teraz nazywam Vim Python IDE. Wspomnę tylko, że najbardziej do gustu ze wszystkich edytorów jakie testowałem przypadł mi Sublime Text 2, ale i on po pewnym czasie zaczął mnie irytować. Mimo to, bardzo mocno go polecam, bo jest naprawdę dobry.

Jeżeli nie miałeś nigdy styczności z vimem, to polecam ci skorzystanie z vimtutora (taki nauczyciel vima). Odpalisz go komendą vimtutor w wierszu poleceń. Nie jest Ci to niezbędne, aby przestudiować tego posta, ale warto się z tym zapoznać albo chociaż gdzieś zapisać i poświęcić kiedyś trochę czasu na naukę.

Wszystko co jest tutaj opisane wypróbowałem jedynie na systemie Ubuntu, a moją podstawową konsolą jest gnome-terminal.

TL;DR

Jeśli nie chce ci się czytać/przepisywać/konfigurować to na końcu posta umieściłem link do repo na którym znajdziesz wszystkie pliki konfiguracyjne, z których ja korzystam i które tutaj opisałem. Zaczynamy!

Czas zacząć

Na początek kilka zrzutów ekranu, aby pokazać, że vim nie jest taki straszny (no dobra, trochę; ale tylko na początku).





Instalacja

Jeżeli masz już zainstalowanego vima (a najprawdopodobniej masz) to sprawdź czy masz ustawioną flagę xterm_clipboard (polecenie vim --version). Dzięki niej będziesz mógł w wygodny sposób korzystać ze schowka. Jeżeli nie masz to kiedyś napisałem posta co należy zrobić, aby ją uaktywnić (opis dla Ubuntu).

Jeśli nie masz zainstalowanego vima, to wykonaj polecenie sudo apt-get install vim-gnome. Dzięki temu nie będziesz musiał przejmować się niektórymi problemami, np. takimi jak brak ustawionej flagi xterm_clipboard.
I już możesz zacząć korzystać, chociaż wątpię w to, aby komukolwiek w dzisiejszych czasach odpowiadała praca w vimie bez pluginów, bo to one są tym co tak naprawdę czyni ten edytor tak wspaniałym.

Pluginy

Opiszę tutaj, krótko każdy z pluginów z których korzystam. O konfiguracji/instalacji/skrótach klawiszowych dowiesz się później, przy konfigurowaniu pliku .vimrc.
  • vim-pathogen - w wielkim skrócie, plugin do zarządzania pluginami
  • ctrlp.vim - szukanie plików, otwieranie pliku w konkretnej linii, otwieranie kilku plików, szybkie tworzenie pliku
  • python-mode - praktycznie wszystko co jest Tobie potrzebne do przyjemnego pisania kodu w Pythonie; szybki podgląd dokumentacji, wykonywanie kodu, rope autocomplete, łatwe skakanie po metodach/klasach, łatwe zaznaczanie całych metod/klas, etc.
  • nerdtree - drzewko plików (przydaje się)
  • nerdcommenter - komentowanie kodu na kilka ciekawych sposobów
  • ack.vim - używa ack (grep dla programistów) w vimie
  • powerline - w terminalu korzystam z powerline-bashtutaj o tym pisałem (uwaga, zmieniła się nazwa repo, po więcej zapraszam tutaj). Zamierzam również wykorzystać plugin powerline w bashu, ponieważ oferuje taką możliwość. Ale to temat na osobnego posta

Konfiguracja

vim-pathogen

Pierwsze co musisz zrobić to zainstalować vim-pathogen. Najlepiej wykonać dwie poniższe komendy:
mkdir -p ~/.vim/autoload ~/.vim/bundle
curl -so ~/.vim/autoload/pathogen.vim https://raw.github.com/tpope/vim-pathogen/HEAD/autoload/pathogen.vim
Od teraz będziesz mógł dodawać pluginy do katalogu ~/.vim/bundle/nazwa-pluginu/. Dodaj jeszcze w pierwszej linijce w pliku .vimrc w swoim katalogu użytkownika tą linię:
call pathogen#infect()

.vimrc

Po kolei będę wklejał bloki kodu, które należy umieścić w pliku .vimrc oraz będę je krótko opisywał do czego się przydają.

autocmd! bufwritepost .vimrc source %
Automatycznie przeładowywuje plik .vimrc.

set pastetoggle=<F2>
set clipboard=unnamed
Lepsze kopiowanie/wklejanie, jeżeli masz do wklejenia jakiś duży blok tekstu. Przechodzisz do trybu insert, wciskasz <F2> i wklejasz tekst.

set bs=2
set mouse=a
Ustawia normalną obsługę backspace oraz włącza obsługę myszki.

let mapleader = ","
Binduje <Leader> do klawisza "," . Później zobaczysz do czego może się przydać.

noremap <C-n> :nohl<CR>
vnoremap <C-n> :nohl<CR>
inoremap <C-n> :nohl<CR>
Jeżeli wyszukałeś jakąś frazę, to vim ją podkreślił, jeśli chcesz pozbyć się podświetlenia wciśnij CTRL+n.

noremap <C-Z> :update<CR>
vnoremap <C-Z> <C-C>:update<CR>
inoremap <C-Z> <C-O>:update<CR>
Szybki zapis pliku, CTRL+z.

noremap <Leader>e :quit<CR>
noremap <Leader>E :qa!<CR>
Szybkie zamknięcie pliku/plików. Już widzisz do czego przydaje się <Leader>. Po wciśnięciu ",e" vim zamknie plik nad którym aktualnie pracujesz. Jeżeli użyjesz ",E" to zostanie zamknięty cały vim. Skrótów z <Leader> możesz używać podobnie jak tych z CTRL lub wciskać jeden po drugim. Czyli w tym przypadku wciskając klawisz "e" nie musisz trzymać klawisza ",". Analogicznie będzie w kolejnych skrótach z wykorzystaniem <Leader>.

map <c-j> <c-w>j
map <c-k> <c-w>k
map <c-l> <c-w>l
map <c-h> <c-w>h
Służy do wygodniejszego poruszania się po okienkach. Zamiast wciskania CTRL+w, a później h/j/k/l, wciskasz sobie CTRL+h/j/k/l.

map <Leader>n <esc>:tabprevious<CR>
map <Leader>m <esc>:tabnext<CR>
Wygodniejsze przemieszczanie się po zakładkach. ",n" (wcześniejsza), ",m" (następna).

vnoremap < <gv
vnoremap > >gv
Wygodne przemieszczanie bloków kodu. Zaznaczasz tekst i wybierasz w którym kierunku ma być przesunięty. "<" (lewo), ">" (prawo).

autocmd ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red
au InsertLeave * match ExtraWhitespace /\s\+$/
Podświetla na czerwono niepotrzebne białe znaki (taby/spacje). Jak korzystasz z dobrodziejstw codereview to prędzej czy później będziesz tego szukał.

filetype off
filetype plugin indent on
syntax on
Włącza rozpoznawanie plików oraz podświetlanie składni.

set number
set tw=79
set nowrap
set fo-=t
set colorcolumn=80
highlight ColorColumn ctermbg=233
Pierwsza komenda wyświetla numer wiersza w którym się znajdujesz po lewej stronie. Przedostatnia i ostatnia odpowiadają za wyświetlanie się kolumny, która jest pomocna przy kodowaniu, jeżeli ustaliliście razem z zespołem jakąś konwencję. Natomiast druga, trzecia i czwarta komenda odpowiada za brak zawijania tekstu. Dodatkowo, jeżeli jest ci naprawdę potrzebne zawinięcie jakiegoś tekstu możesz go zaznaczyć i wcisnąć "gq". Program ci go zawinie do 79 kolumny i zacznie wypełniać wiersz poniżej, również do 79 kolumny i tak w kółko. Szczerze, bardzo rzadko z tego korzystam, ale przydaje się jak wrzucasz jakieś dłuższe teksy do szablonu/kodu.



set history=700
set undolevels=700
Nie trzeba tłumaczyć.

set tabstop=4
set softtabstop=4
set shiftwidth=4
set shiftround
set expandtab
W wielkim skrócie, używa tylko i wyłącznie spacji, zero tabów. Jak gdzieś użyjesz taba to ci go zamieni na cztery spacje, dziękuję.

set hlsearch
set incsearch
set ignorecase
set smartcase
Podświetla znalezioną frazę podczas szukania i rozróżnia znaki ("oink" to nie to samo co "OinK").

set nobackup
set nowritebackup
set noswapfile
Wyłącza pliki backup oraz swap. Nie są Ci do niczego potrzebne, a jak pracujesz z gitem czy mercurialem to tym bardziej.

powerline (https://github.com/Lokaltog/powerline)

Instalacja:
cd ~/.vim/bundle
git clone git://github.com/Lokaltog/powerline.git

W pliku .vimrc wklej:
set guifont=Source\ Code\ Pro\ for\ Powerline\ for\ Powerline
set laststatus=2
source ~/.vim/bundle/powerline/powerline/ext/vim/source_plugin.vim

Zmienną guifont oczywiście musisz zmienić na swoją czcionkę. Jest to potrzebne do gvima. Jeżeli z niego nie korzystasz, możesz tą linijkę usunąć albo zakomentować. Jeżeli powerline dziwnie się wyświetla musisz spatchować swoją czcionkę, jak to zrobić jest opisane tutaj. Ja osobiście korzystam z czcionki SourceCodePro (musiałem spatchować). Ustawienie zmiennej laststatus na wartość 2 zapewni wyświetlanie się linii na dole okna.

Oprócz powerline do vima, korzystam jeszcze z powerline-bash. Pisałem o nim w tym poście. Ludzie mają problemy z skonfigurowaniem tak czcionki, aby była wyświetlana poprawnie i w pluginie vima jak i w konsoli. Jeżeli będziesz używał tylko plugina powerline do vima to nie masz czym się przejmować. Jednak, jeśli zapragniesz korzystać z powerline oraz z powerline-bash to może być Ci ciężko je pogodzić. Jeżeli używasz czcionki SourceCodePro to pod koniec posta zamieściłem linki do mojego repo na githubie. Tam znajdziesz katalog .fonts. Wystarczy, że skopiujesz go do swojego katalogu domowego i w gnome-terminal ustawisz czcionkę na Source Code Pro for Powerline for Powerline.

vim-colors-solarized (https://github.com/altercation/vim-colors-solarized)

Instalacja:
cd ~./vim/bundle/
git clone https://github.com/altercation/vim-colors-solarized

Korzystam z tego colorscheme ponieważ najbardziej mi odpowiada. Ciekawym jest jeszcze wombat256mod.vim, z którego korzystałem dopóki nie natknąłem się na solarized (dark).

Do pliku .vimrc wklej to:
set t_Co=16
set background=dark
let g:solarized_termcolors=16
colorscheme solarized

Jeżeli chcesz mieć również takie kolory w terminalu (gnome-terminal) to wklej w terminalu te komendy:
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_background" --type bool false
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_colors" --type bool false
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/palette" --type string "#070736364242:#D3D301010202:#858599990000:#B5B589890000:#26268B8BD2D2:#D3D336368282:#2A2AA1A19898:#EEEEE8E8D5D5:#00002B2B3636:#CBCB4B4B1616:#58586E6E7575:#65657B7B8383:#838394949696:#6C6C7171C4C4:#9393A1A1A1A1:#FDFDF6F6E3E3"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/background_color" --type string "#00002B2B3636"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/foreground_color" --type string "#65657B7B8383"

ctrlp.vim (https://github.com/kien/ctrlp.vim)

Instalacja:
cd ~/.vim/bundle
git clone https://github.com/kien/ctrlp.vim.git

Plik .vimrc
let g:ctrlp_max_height = 30
set wildignore+=*.pyc
set wildignore+=*build/*
set wildignore+=*dist/*
set wildignore+=*.egg-info/*
set wildignore+=*/coverage/*

Pierwsza komenda ustala maksymalną ilość wierszy jakie mogą się wyświetlić przy wyszukiwaniu pliku. A reszta ustawia jakie pliki/katalogi mają się Tobie nie wyświetlać podczas wyszukiwania. Aby wyświetlić CtrlP wciśnij CTRL+p (w trybie normal). Tak to mniej więcej wygląda:




Po liście, która się wyświetla poruszasz się klawiszami CTRL+j, CTRL+k, zatwierdzasz enterem albo jak chcesz w nowym tabie otworzyć CTRL+t. Dodatkowo gdy po wpisanej frazie dodasz ":<liczba>" to przeniesie Cię do zaznaczonego/zaznaczonych plików do konkretnej linijki (bardzo pomocne gdy Python wypluwa ci informacje o tym w którym pliku i w której linijce jest błąd).

A teraz, kilka najważniejszych skrótów klawiszowych odnoszących się do tego pluginu. Wszystkie oczywiście działają gdy masz otwartego CtrlP:

  • F5 - odświeżanie listy, jak usunąłeś/dodałeś jakiś plik
  • CTRL+f, CTRL+b - przełączanie się między trybami files, buffor, mru files (pliki, bufor, najczęściej otwierane pliki)
  • CTRL+d - ustawiasz czy ma szukać po ścieżce czy po pliku
  • CTRL+r - regex mode, nie raz pewnie za to podziękujesz
  • CTRL+z - gdy się poruszasz po oknie i wciśniesz ten właśnie skrót to zaznaczy/odznaczy Ci plik. Jak sobie już zaznaczyć wciskasz CTRL+o, aby je otworzyć (w tym samym oknie wszystkie pliki) albo CTRL+t, aby każdy otworzyć w osobnym tabie
  • CTRL+p, CTRL+n - wcześniejsza/następna fraza jaką wpisywałeś
  • gdy zaznaczysz kilka plików (maksymalnie cztery) i wpiszesz ":diffthis", a później wciśniesz CTRL+o to ładnie te pliki do siebie porówna i pokaże Ci gdzie się różnią
  • jak wpiszesz ścieżkę do pliku czy sam plik, który nie istnieje i użyjesz skrótu CTRL+y to CtrlP stworzy Ci ten plik

python-mode (https://github.com/klen/python-mode)

Instalacja:
cd ~/.vim/bundle
git clone https://github.com/klen/python-mode

Plik .vimrc
map <Leader>g :call RopeGotoDefinition()<CR>
let ropevim_enable_shortcuts = 1
let g:pymode_rope_goto_def_newwin = "vnew"
let g:pymode_rope_extended_complete = 1
let g:pymode_breakpoint = 0
let g:pymode_syntax = 1
let g:pymode_virtualenv = 1

Pierwsza linijka ustawia pod skrótem ",g" wywołanie RopeGotoDefinition... Jeżeli zapomniałeś czegoś na temat danego obiektu albo chcesz się dowiedzieć czegoś nowego na jego temat to wskazujesz na niego, wciskasz ",g" i przenosi cię do pliku w którym jest zaimplementowany.
Druga włącza obsługę skrótów.
W trzeciej przekazujesz w jaki sposób ma się wyświetlać okno, po znalezieniu pliku w którym obiekt jest zaimplementowany. W tym przypadku dzieli ekran pionową kreską, przykład:


Kursor miałem na stringu LoremIpsum i wcisnąłęm ",g".

Reszta w skrócie zapewnia ci wsparcie dla virtualenv, ustawia ładne podświetlanie składni oraz rozszerza podpowiadanie składni. Właśnie, czas na przydatne skróty.

  • K - wywołane na jakimś module, wyświetla okno na dole z dokumentacją danego modułu
  • ,r - odpala kod
  • CTRL+spacja - używa Rope autocomplete (poniżej jest opis jak sobie wygodnie zbindować skróty, żeby się po nim szybko poruszać)
  • [M, ]M - skakanie po metodach poprzednia/następna
  • aC - zaznaczenie całej klasy, ale! W zależności co podasz przed literą a, vim różnie się zachowa i tak oto, vaC (zaznacza całą klasę), daC albo dC (usuwa całą klasę), yaC lub yC (kopiuje całą klasę), caC albo cC (usuwa całą klasę i od razu zmienia tryb na insert)
  • iC - analogicznie jak powyżej z tym, że nie odnosi się do całej klasy, tylko do jej wnętrza
  • aM - j.w tyle, że dla metod 
  • iM - j.w tyle, że dla metod
Teraz wróć znów do pliku .vimrc i dodaj takie coś:
set completeopt=longest,menuone
function! OmniPopup(action)
    if pumvisible()
        if a:action == 'j'
            return "\<C-N>"
        elseif a:action == 'k'
            return "\<C-P>"
        endif
    endif
    return a:action
endfunction

inoremap <silent><C-j> <C-R>=OmniPopup('j')<CR>
inoremap <silent><C-k> <C-R>=OmniPopup('k')<CR>

Zapewni Ci to poruszanie się po OmniPopupie (CTRL+spacja) za pomocą CTRL+j, CTRL+k. Tak to wygląda:


nerdtree (https://github.com/scrooloose/nerdtree)

Instalacja:
" cd ~/.vim/bundle
" git clone https://github.com/scrooloose/nerdtree.git

Plik .vimrc
nmap <leader>t :NERDTree<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif

Powyższe ustawienia bindują Ci otwieranie nerdtree pod skrótem ",t" oraz gdy zamykasz ostatnie okno w vimie i zostanie tylko nerdtree, to automatycznie się zamknie. Opis wszystkich skrótów znajdziesz tutaj. Ja najczęściej korzystam z tych:
  • o - otwarcie pliku
  • go - otwarcie pliku, ale pozostanie w oknie z nerdtree
  • t - otwarcie pliku w nowym tabie
  • T - j.w. tyle, że nie przenosi do nowego taba
  • enter, dwuklik myszką (jak to brzmi) - to samo co "o"

nerdcommenter (https://github.com/scrooloose/nerdcommenter)

Instalacja:
cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdcommenter.git

Zasada działania pluginu jest bardzo prosta. Zaznaczasz jakiś fragment kodu i wciskasz odpowiednią kombinację klawiszy, aby zakomentować kod. Tutaj, żadnej konfiguracji nie trzeba podawać. Poniżej znajdziesz skróty z których najczęściej korzystam; dołączę również obrazki, żebyś lepiej się orientował jak dany skrót działa. Za pomocą skrótu ",cu", odkomentowujesz kod. Całą dokumentację znajdziesz tutaj.

Wszystkie skróty będę odpalał z takiej pozycji:


",cc"

",c+spacja"

",cb"

ack.vim (https://github.com/mileszs/ack.vim)

Instalacja:
sudo apt-get install ack-grep
cd ~/.vim/bundle
git clone https://github.com/mileszs/ack.vim.git

O ack.vim pomyśl jak o grepie dla programistów, i tyle. W pliku .vimrc dodaj:
nmap <leader>a <Esc>:Ack!

Aby go użyć wciskasz ",a" i wpisujesz wyrażenie. Przykład dla zapytania "setUp":


Skróty klawiszowe są podobne jak w przypadku nerdtree, więc nie powinieneś mieć z tym problemu.

Koniec

To byłoby na tyle, jeżeli chodzi o vima i pythona. Jeżeli nie chce Ci się tego wszystkie wprowadzać samemu ręcznie możesz zawitać na mój profil na githubie i zajrzeć na moje repo z dotfiles do czego mocno zachęcam bo sam pewnie bym nie chciał tego wszystkiego wklepywać.

To był jeden zbiorczy post dotyczący tego jak sobie ułatwić życie w vimie, jeżeli programujesz w tym czasie w Pythonie. Mam nadzieję, że przyda Ci się to, co tutaj opisałem. Zamierzam na bieżąco opisywać jakieś ciekawe pluginy do vima. Jeżeli sam znasz coś, na co warto zwrócić uwagę to daj mi znać czy to przez maila (tomislater <taki_internetowy_znaczek> gmail.com), g+, githuba czy zostawiając tutaj komentarz.

A teraz w nagrodę za wytrwałość, śmieszny obrazek:


1/13/2013

TDFPronunciation - nowa wersja

Dodałem w skrypcie korzystanie z wątków, dzięki temu długość oczekiwania na zakończenie skryptu dla np. sześciu słów spadło z 5.4 sekund do 1.3 sekundy. Link do nowej wersji: TDFPronunciation.



1/09/2013

RandomWords 0.1.7

Puściłem przed chwilą na githuba i pypi nową wersję RandomWords 0.1.7. Główna zmiana to porzucenie modułu pickle i zastąpienie go modułem ujson, o którym ostatnio pisałem. Zrobiłem testy i jasno wyszło, że o wiele szybciej będę wczytywał dane za pomocą ujsona. Poniżej zamieściłem wykresy z testów. Każdy był przeprowadzony sto razy.

Wykres szybkości wczytywania danych dla nowej wersji RandomWords.
We wszystkich klasach widać wyraźny wzrost prędkości ładowania danych przy tworzeniu instancji.

1/05/2013

Pobieranie słów z The Free Dictionary


Do nauki języka i nie tylko, korzystam z programu Anki. Przy okazji bardzo go polecam.

Problem na jaki dzisiaj natrafiłem był taki, iż w większości decków stworzonych przez userów nie ma dźwięków i obrazków. O ile brak obrazka jeszcze przejdzie, to brak przykładu wymowy danego słowa już nie za bardzo. Jak się domyślasz znudziło mnie ciągłe przełączanie się między Anki i Google Translate czy The Free Dictionary w celu usłyszenia poprawnej wymowy danego słowa, więc postanowiłem napisać skrypt, który będzie za mnie szukał danego słowa, pobierał go w formacie mp3 i zapisywał do katalogu sounds, po czym ręcznie będę go mógł dodać gdzie zechcę, np. do Anki ;)

Skrypt wrzuciłem na githuba: TDFPronunciation. Jak z niego korzystać znajdziesz w pliku README.md.

Po pobraniu słowa, skrypt zapisze go w katalogu TDFPronunciation/sounds/. Możesz sam utworzyć katalog sounds po sklonowaniu repo, jednak nic się nie stanie gdy go nie będziesz miał, skrypt to wykryje i sam go stworzy. Przed każdym wysłaniem żądania, skrypt sprawdzi, czy czasem dane słowo nie zostało już pobrane wcześniej. Jeżeli tak, to nie będzie go znów pobierał. Dorzucam kilka screenów:





Nie wszystkie rzeczy jeszcze są dokończone, ale to co ma robić wykonuje. Jeżeli ci się podoba to zachęcam do korzystania. Jak znajdziesz jakiś błąd to daj mi znać, czy to przez githuba, maila czy poprzez komentarz na blogu.