IPython sihirli ifadeler

 Jupyter Jupyter olmadan önce (yani birçok farklı dil çekirdeğiyle uyumlu bir arayüz haline gelmeden önce) IPython Notebook olarak biliniyordu. IPython bir Python yorumlayıcısı, ama özellikle etkileşimli sayısal hesaplamalar gözetilerek hazırlanmış bir yorumlayıcı. Başta sadece terminalde çalışıyordu, daha sonra Web teknolojileriyle birleştirilerek tarayıcı içinde kullanılabilen bir defter yapısına kavuştu.

Geçmiş bir yazıda bahsettiğimiz Jupyter arayüzünün özellikleri doğrudan doğruya IPython‘dan alınmış, ve yorumlanabilir herhangi bir dille çalışabilecek şekilde genelleştirilmiştir. Jupyter‘in devraldığı IPython özelliklerinden biri de sihirli ifadeler (line magics/cell magics) denen bazı kolaylaştırıcı, özelleşmiş komutlardır. Bu komutlar !, % veya %% ile başlarlar. Sihirli ifadeler Python yorumlayıcısına aktarılmadan IPython tarafından işlenir.

Sihirli ifadeler IPython çekirdeğine özgü oldukları için sadece Python ile çalışırlar. Jupyter’in desteklediği diğer diller (R, Julia, vd.) şimdilik bu özelliğe sahip değiller.

Sihirli ifadelerle ilgili tam referans için resmi belgelere bakabilirsiniz. Bu yazıda bazı en yaygın kullanılan komutlara göz atacağız.

Sistem komutu çalıştırmak

İşletim sisteminin komut yorumlayıcısına doğrudan erişmek için ! sihrini kullanırız. Bu komutların cevabı ekrana yazılır. (Dikkat: Aşağıdaki örnekler bir Linux sisteminde çalışır. Windows veya MacOS’da çalışıyorsanız, sisteminizdeki kabuğa uygun komutlar denemelisiniz.)

Tarih ve saat:

In [1]:
!date
Pzt Kas 20 19:58:15 +03 2017

ls ile \bin dizininde b ile başlayan dosyaları görelim.

In [2]:
!ls /bin/b*
/bin/bash     /bin/bzcat   /bin/bzegrep  /bin/bzgrep	    /bin/bzless
/bin/bunzip2  /bin/bzcmp   /bin/bzexe	 /bin/bzip2	    /bin/bzmore
/bin/busybox  /bin/bzdiff  /bin/bzfgrep  /bin/bzip2recover

Bu komutların çıktılarını, daha sonra kullanmak için bir değişkene atayabiliriz. Bu şekilde, komut satırında kolayca yapılabilecek bir iş için kod yazmak zorunda kalmayız.

In [3]:
bindosyalar = !ls /bin/b*
bindosyalar
Out[3]:
['/bin/bash',
 '/bin/bunzip2',
 '/bin/busybox',
 '/bin/bzcat',
 '/bin/bzcmp',
 '/bin/bzdiff',
 '/bin/bzegrep',
 '/bin/bzexe',
 '/bin/bzfgrep',
 '/bin/bzgrep',
 '/bin/bzip2',
 '/bin/bzip2recover',
 '/bin/bzless',
 '/bin/bzmore']

Yardım almak

Jupyter’in çevrimiçi yardımını hücre sihirleriyle de kullanabilirsiniz. Sihirli kelimeyi yazıp Shift-Tab bastığınızda bir yardım balonu çıkar.

Kullanabileceğiniz bütün sihirli kelimelerin listesini %lsmagic sihriyle görebilirsiniz.

In [4]:
%lsmagic
Out[4]:
Available line magics:
%alias  %alias_magic  %autocall  %automagic  %autosave  %bookmark  %cat  %cd  %clear  %colors  %config  %connect_info  %cp  %debug  %dhist  %dirs  %doctest_mode  %ed  %edit  %env  %gui  %hist  %history  %killbgscripts  %ldir  %less  %lf  %lk  %ll  %load  %load_ext  %loadpy  %logoff  %logon  %logstart  %logstate  %logstop  %ls  %lsmagic  %lx  %macro  %magic  %man  %matplotlib  %mkdir  %more  %mv  %notebook  %page  %pastebin  %pdb  %pdef  %pdoc  %pfile  %pinfo  %pinfo2  %popd  %pprint  %precision  %profile  %prun  %psearch  %psource  %pushd  %pwd  %pycat  %pylab  %qtconsole  %quickref  %recall  %rehashx  %reload_ext  %rep  %rerun  %reset  %reset_selective  %rm  %rmdir  %run  %save  %sc  %set_env  %store  %sx  %system  %tb  %time  %timeit  %unalias  %unload_ext  %who  %who_ls  %whos  %xdel  %xmode

Available cell magics:
%%!  %%HTML  %%SVG  %%bash  %%capture  %%debug  %%file  %%html  %%javascript  %%js  %%latex  %%markdown  %%perl  %%prun  %%pypy  %%python  %%python2  %%python3  %%ruby  %%script  %%sh  %%svg  %%sx  %%system  %%time  %%timeit  %%writefile

Automagic is ON, % prefix IS NOT needed for line magics.

Sihirli ifadelerin kullanımının özeti ve her bir komutun kısa açıklaması için %quickref komutunu kullanabilirsiniz.

In [5]:
%quickref  # Jupyter ekranında ayrı bir alt pencere açar.

Bütün sihirli ifadelerin tam ve kapsamlı bir referansı için %magic komutunu kullanabilirsiniz.

In [6]:
%magic # Jupyter ekranında ayrı bir alt pencere açar.

Satır sihirleri bir tek % işaretiyle başlar, ve tek satırda bulunurlar. Hücrenin geri kalanında Python kodu bulunabilir. Hücre sihirleri ise çift %% işaretiyle başlarlar. Hücrenin tamamı bu sihrin etkisinde kalır.

%time, %timeit: Süre ölçme

Bir komutun işletilmesinin ne kadar zaman aldığını ölçmek için %time ve %timeit sihirlerini kullanabiliriz. Bunlar standart kütüphanedeki time ve timeit modüllerini kullanır.

In [7]:
%time sum(range(1000))
CPU times: user 40 µs, sys: 4 µs, total: 44 µs
Wall time: 49.6 µs
Out[7]:
499500

%timeit komutu, ardından gelen Python komutunu bir döngü içinde birçok defa çalıştırır, sonra ortalama süreyi bulur. Bunu birkaç defa tekrarlar ve elde ettiği sonucu ortalama ve standart sapma olarak verir. Bu şekilde bilgisayar sistemi içindeki çeşitli rastgele gecikmeleri kısmen bertaraf etmek mümkün olur.

In [8]:
%timeit sum(range(1000))
19 µs ± 2.15 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Döngü sayısı açıkça verilmediyse, otomatik olarak ayarlanır. Döngü sayısı, toplam çalışma süresi 0.2 saniyenin üstünde olacak şekilde 10’un kuvvetleri olarak belirlenir. Döngü sayısı ve tekrar sayısı istendiği gibi değiştirilebilir.

In [9]:
%timeit -n 250 -r 4 sum(range(1000))
21.2 µs ± 726 ns per loop (mean ± std. dev. of 4 runs, 250 loops each)

Bazen süresini tutmak istediğimiz işlem birkaç satıra yayılmış olabilir. O zaman bütün hücrenin işleyiş süresini tutmak için, çift yüzde işaretiyle, %%timeit hücre sihiri kullanırız.

Örnek olarak, bir listeyi append ile genişletmek ve liste kurma arasındaki zaman farkına bakalım.

In [10]:
%%timeit -r 10
L = []
for i in range(1000):
    L.append(i**2)
326 µs ± 5.88 µs per loop (mean ± std. dev. of 10 runs, 1000 loops each)
In [11]:
%timeit -r 10 [i**2 for i in range(1000)]
282 µs ± 21.7 µs per loop (mean ± std. dev. of 10 runs, 1000 loops each)

Dizin işlemleri

Yeni bir dizin yaratalım ve o dizine geçelim.

In [12]:
!mkdir deneme
%cd deneme
/home/kaan/deneme

Yeni dizinde bir dosya yaratalım.

In [13]:
!touch dosya1
!ls
dosya1

Üst dizine dönelim.

In [14]:
%cd ..
/home/kaan

Yarattığımız dizini silelim.

In [15]:
!rm -r deneme/

Neden bütün işlemleri ! işleciyle yaparken, dizin değiştirmeyi %cd ile yaptık? Eğer komutu !cd deneme olarak verseydik, kabuk yorumlayıcı bunu işletir, ama hemen sonra kapanırdı. Sonraki her bir komut yeni bir kabuk yorumlayıcıyla yapılacağı için dizin değiştirme işlemi kalıcı olmazdı. IPython’un %cd komutu dizinlerin çalıştığımız ortamda kalıcı olarak değiştirilmesini sağlar.

Örnek olarak, aşağıdaki komutlar sonucunda, /deneme dizinine geçmiş olmuyoruz.

In [16]:
!mkdir deneme
!cd deneme
!pwd
/home/kaan

Doğrusunu yaparak %cd kullanırsak istediğimiz değişiklik geçerli olur.

In [17]:
%cd deneme
!pwd
/home/kaan/deneme
/home/kaan/deneme

Üst dizine geri çıkıp /deneme dizinini silelim.

In [18]:
%cd ..
!rm -r deneme/
/home/kaan

%%writefile: Bir metin dosyası yaratmak

Diyelim elle yazacağınız kısa bir metni bir dosyaya kaydetmek istiyorsunuz. Bunun için ayrı bir pencerede bir editör açabilirsiniz, veya Python’un dosya açma komutlarını kullanabilirsiniz. %%writefile hücre sihri ise zahmetsiz kestirme bir yol sağlar.

deneme isimli bir dosyaya iki telefon numarası yazalım:

In [19]:
%%writefile deneme
Kaan (111)-1234567
Meral (124)-9283759
Writing deneme

%cat ile dosyanın içeriğini ekrana dökerek istediğimizi yaptığını teyit edebiliriz.

In [20]:
%cat deneme
Kaan (111)-1234567
Meral (124)-9283759

%%writefile -a ile mevcut dosyanın altına ekleme yaparız. Yeni satırla başlamak için, satır başı vermemiz gerekir.

In [21]:
%%writefile -a deneme

Ziya (234)-8087955
Appending to deneme
In [22]:
%cat deneme
Kaan (111)-1234567
Meral (124)-9283759
Ziya (234)-8087955
In [23]:
%rm deneme

%run: Python programı çalıştırmak

Ayrı bir dosyada bulunan Python kodunu çalıştırmak için %run komutu kullanılır.

Basit bir Python programı hazırlayıp merhaba.py ismiyle kaydedelim.

In [24]:
%%writefile merhaba.py
isim = input("Adınız?")
print("Merhaba",isim)
Overwriting merhaba.py
In [25]:
%run merhaba.py
Adınız?kaan
Merhaba kaan

Çağırılan program mevcut yorumlayıcı tarafından işlendiği için, o program içinde yaratılan değişken isimleri kalıcı olur.

In [26]:
isim
Out[26]:
'kaan'

%load: Bir dosyanın içeriğini yüklemek

%load komutu, %run gibi, bir Python dosyasındaki komutları okuyup çalıştırmaya yarar. Farkı, kodu önce mevcut hücreye kopyalaması, ama biz tekrar talep etmedikçe çalıştırmamasıdır.

In [ ]:
%load merhaba.py

Yukarıdaki hücre çalıştırıldığında sihirli kelime yorum haline getirilir, dosyadaki kod aynı hücreye kopyalanır, ama çalıştırılmaz.

In [ ]:
# %load merhaba.py
isim = input("Adınız?")
print("Merhaba",isim)

Hücrede tekrar Shift-Enter’e basıldığında kod çalışır.

In [29]:
# %load merhaba.py
isim = input("Adınız?")
print("Merhaba",isim)
Adınız?kaan
Merhaba kaan

%qtconsole: Yan terminal açmak

Defterinizin akışına müdahale etmeden bazı yan işlemler yapmak istediğinizde, ayrı bir pencerede bir IPython penceresi açabilirsiniz. (Bu komut her işletim sisteminde bulunmayabilir.)

In [30]:
%qtconsole

Her iki arayüz de aynı çekirdeğe bağlıdır. Birbirlerinin tanımlarını görebilirler. Konsol penceresini kapatmak, onu başlatan defteri etkilemez.