Jupyter / IPython sihirli ifadeler

Jupyter
Author

Kaan Öztürk

Published

November 28, 2017

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 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:

!date
Cum 17 Kas 2023 15:23:08 +03

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

!ls /bin/z*
/bin/zcat    /bin/zfgrep      /bin/zipgrep    /bin/zmore     /bin/zstdless
/bin/zcmp    /bin/zforce      /bin/zipinfo    /bin/znew      /bin/zstdmt
/bin/zdiff   /bin/zgrep       /bin/zipnote    /bin/zoom
/bin/zdump   /bin/zip         /bin/zipsplit   /bin/zstd
/bin/zegrep  /bin/zipcloak    /bin/zjsdecode  /bin/zstdcat
/bin/zenity  /bin/zipdetails  /bin/zless      /bin/zstdgrep

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.

bindosyalar = !ls /bin/z*
bindosyalar
['/bin/zcat',
 '/bin/zcmp',
 '/bin/zdiff',
 '/bin/zdump',
 '/bin/zegrep',
 '/bin/zenity',
 '/bin/zfgrep',
 '/bin/zforce',
 '/bin/zgrep',
 '/bin/zip',
 '/bin/zipcloak',
 '/bin/zipdetails',
 '/bin/zipgrep',
 '/bin/zipinfo',
 '/bin/zipnote',
 '/bin/zipsplit',
 '/bin/zjsdecode',
 '/bin/zless',
 '/bin/zmore',
 '/bin/znew',
 '/bin/zoom',
 '/bin/zstd',
 '/bin/zstdcat',
 '/bin/zstdgrep',
 '/bin/zstdless',
 '/bin/zstdmt']

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.

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

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.

%time sum(range(1000))
CPU times: user 27 µs, sys: 4 µs, total: 31 µs
Wall time: 35.5 µs
499500

Ancak, bilgisayar sistemi bazı anlarda başka işlerle meşgul olabildiği için bir tek süre ölçümü yanıltıcı olabilir. %timeit, komutu bir döngü içinde birçok defa çalıştırır, bunların ortalama süresini bulur. Bunu birkaç defa tekrarlar ve elde ettiği sonuçların ortalama ve standart sapma olarak verir.

%timeit sum(range(1000))
15.6 µs ± 482 ns per loop (mean ± std. dev. of 7 runs, 100,000 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.

%timeit -n 250 -r 4 sum(range(1000))
20.2 µs ± 795 ns per loop (mean ± std. dev. of 4 runs, 250 loops each)

Süresini tutmak istediğimiz işlem birkaç satıra yayılmış olabilir. O zaman bütün hücrenin işleyiş süresini ölçmek 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.

%%timeit -r 10
L = []
for i in range(1000):
    L.append(i**2)
239 µs ± 2.34 µs per loop (mean ± std. dev. of 10 runs, 1,000 loops each)
%timeit -r 10 [i**2 for i in range(1000)]
210 µs ± 1.53 µs per loop (mean ± std. dev. of 10 runs, 1,000 loops each)

Dizin işlemleri

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

!mkdir deneme
%cd deneme
/home/kaan/veridefteri.com/posts/IPython_sihirli_ifadeler/deneme

Yeni dizinde bir dosya yaratalım.

!touch dosya1
!ls
dosya1

Üst dizine dönelim.

%cd ..
/home/kaan/veridefteri.com/posts/IPython_sihirli_ifadeler

Yarattığımız dizini silelim.

!rm -r deneme/

Neden bütün işlemleri ! operatörüyle yaparken, dizin değiştirmeyi %cd ile yaptık? Eğer komutu !cd deneme olarak verseydik, kabuk yorumlayıcı bunu işletir ve hemen sonra kapanırdı. Sonraki komutlar 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.

!mkdir deneme
!cd deneme
!pwd
/home/kaan/veridefteri.com/posts/IPython_sihirli_ifadeler

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

%cd deneme
!pwd
/home/kaan/veridefteri.com/posts/IPython_sihirli_ifadeler/deneme
/home/kaan/veridefteri.com/posts/IPython_sihirli_ifadeler/deneme

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

%cd ..
!rm -r deneme/
/home/kaan/veridefteri.com/posts/IPython_sihirli_ifadeler

%%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:

%%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.

%cat deneme
Kaan (111)-1234567
Meral (124)-9283759

%%writefile -a ile mevcut dosyanın altına ekleme yaparız.

%%writefile -a deneme
Ziya (234)-8087955
Appending to deneme
%cat deneme
Kaan (111)-1234567
Meral (124)-9283759
Ziya (234)-8087955
%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.

%%writefile merhaba.py
isim = "Kaan Öztürk"
print("Merhaba",isim)
Writing merhaba.py

Şimdi bu programı çalıştıralım

%run merhaba.py
Merhaba Kaan Öztürk

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

isim
'Kaan Öztürk'

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.

%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.

```{python}
# %load merhaba.py
isim = input("Adınız?")
print("Merhaba",isim)
```

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

# %load merhaba.py
isim = "Kaan Öztürk"
print("Merhaba",isim)
Merhaba Kaan Öztürk

%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.)

%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.

%pastebin: Kod parçası paylaşmak

%pastebin sihri, bir dosyayı, veya mevcut oturumdan seçtiğiniz satırları dpaste.com sitesinde herkese açık olarak yayınlar ve URL’sini döndürür.

Bu defterdeki In[1]-In[11] arası komutları Gist’e yüklemek için:

%pastebin -d "Deneme yüklemesi" 1-11
'https://dpaste.com/D73XU7CMS'

merhaba.py dosyasını Gist’e yüklemek için:

%pastebin -d "Deneme yüklemesi" merhaba.py
'https://dpaste.com/GDS5QF5WM'

%who: Oturumda tanımlanmış değişkenler

Mevcut oturumda tanımlanmış değişken isimlerini gösterir.

%who
isim     

Değişken isimlerini bir liste olarak almak isterseniz %who_ls kullanabilirsiniz.

%who_ls
['isim']

%reset: Değişkenleri topluca silmek

Mevcut oturumda kullanıcı tarafından tanımlanmış değişkenleri siler. Modüllerde tanımlanmış isimlere dokunmaz.

x = 1
s = "asdfg"
%who
isim     s   x   
%reset
Nothing done.
%who
isim     

Parametreler: * %reset -f : Teyit istemeden sıfırlar. * %reset -s : Yumuşak sıfırlama: Komut geçmişi silinmez, sadece isim alanı temizlenir. * %reset in : Komut geçmişini sıfırlar. * %reset out : Çıktı geçmişini sıfırlar. * %reset dhist : Dizin geçmişini sıfırlar. * %reset array : Sadece NumPy dizi (array) değişkenlerini siler.

%macro: İşlemleri otomatik olarak tekrar etmek

Arka arkaya yazdığınız birkaç komutu daha sonra tekrar tekrar işletmek için bir kenara yazmak istediğinizde %macro sihri işinize yarayacaktır. Bu işlem,de daha önce verdiğimiz komutları giriş sayılarını vererek bir seferde çalıştırabiliriz.

from random import randint
zar1 = randint(1,6)
zar2 = randint(1,6)
zar3 = randint(1,6)
a = 5
print(zar1 + zar2)
8
print(zar1, zar2, zar3, zar1+zar2+zar3)
5 3 3 11

Bu komutları kullanarak bir makro hazırlayalım. Girdi numaralarını hücrelerin yanından okuyabileceğimiz gibi, %hist -n sihiriyle de görebiliriz.

%hist -n

… 40: from random import randint 41: zar1 = randint(1,6) 42: zar2 = randint(1,6) 43: zar3 = randint(1,6) 44: a = 5 45: print(zar1 + zar2) 46: print(zar1, zar2, zar3, zar1+zar2+zar3) 47: %hist -n

%macro sihirli kelimesinden sonra, makroya vereceğiniz isim ve komut numarası aralıkları gelmelidir. Aralıklar n1-n2 n3-n4 n5 şeklinde verilebilir. Aralıkların başı ve sonu dahil edilir. Araya virgül koyulmaz.

%macro zar_at 40-43 46
Macro `zar_at` created. To execute, type its name (without quotes).
=== Macro contents: ===
from random import randint
zar1 = randint(1,6)
zar2 = randint(1,6)
zar3 = randint(1,6)
print(zar1, zar2, zar3, zar1+zar2+zar3)
 
zar_at
4 6 4 14

%save: Komutları kaydet

Hazırladığınız bir makroyu veya girdi satırlarının bir kısmını sonraki bir oturumda kullanmak için sabit diske yazmak isterseniz %save sihrini kullanabilirsiniz. Parametre olarak satır numaraları aralıkları veya numara listesi verilebilir.

%save deneme 40-43 46
The following commands were written to file `deneme.py`:
from random import randint
zar1 = randint(1,6)
zar2 = randint(1,6)
zar3 = randint(1,6)
print(zar1, zar2, zar3, zar1+zar2+zar3)

Satır numaraları yerine daha önce hazırladığınız bir makronun ismini de verebilirsiniz.

%save deneme zar_at
The following commands were written to file `deneme.py`:
from random import randint
zar1 = randint(1,6)
zar2 = randint(1,6)
zar3 = randint(1,6)
print(zar1, zar2, zar3, zar1+zar2+zar3)

%store: Değişkenleri sabit diske kaydet

Hesabınız sırasında ürettiğiniz bazı değişkenleri sonraki oturumlarda kullanmak için kaydetmek istediğinizde bu sihri kullanabilirsiniz.

L = [i*2 for i in range(10)]
%store L
Stored 'L' (list)

Değişkenleri silelim:

%reset -f

Artık L listesini kaybettik.

print(L)
NameError: name 'L' is not defined

L değişkenini kaydedilen yerden geri yükleyelim.

%store -r L
print(L)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
%store L >kareler.txt
Writing 'L' (list) to file 'kareler.txt'.
%cat kareler.txt
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
!rm kareler.txt

matplotlib arayüzünü ayarlamak

matplotlib Python’un gayrıresmi görselleştirme kütüphanesidir. Özel %matplotlib sihriyle, hangi arka yüzü kullanmak istediğinizi belirleyebilirsiniz.

%matplotlib -l
Available matplotlib backends: ['tk', 'gtk', 'gtk3', 'gtk4', 'wx', 'qt4', 'qt5', 'qt6', 'qt', 'osx', 'nbagg', 'webagg', 'notebook', 'agg', 'svg', 'pdf', 'ps', 'inline', 'ipympl', 'widget']

Bu arka yüzlerin hepsi her işletim sisteminde bulunmayabilir.

Birçok Jupyter defter kullanıcısı, defterin başında %matplotlib inline komutunu vermeyi tercih eder. Bu sayede ürettiğiniz matplotlib grafikleri defterin içine gömülür ve tam bir belge oluşturmanızı sağlar.

%matplotlib inline
import matplotlib.pylab as plt
x = plt.linspace(-20,20,100)
y = plt.sin(x)/x
plt.plot(x,y)

Bunun yerine notebook arka yüzü kullanmayı tercih ederseniz, fareyle etkileşebileceğiniz, kaydırıp zumlayabileceğiniz dinamik bir formda gösterilir.

Dikkat: matplotlib arka yüzünü bir oturum içinde sadece bir kere belirleyebilirsiniz. Aşağıdaki komutlar için çekirdeği tekrar başlatmanız gerekecektir. Çekirdeği, menü çubuğunda Kernel -> Kernel Restart seçerek, veya iki kere sıfıra basarak tekrar başlatabilirsiniz.

%matplotlib notebook
import matplotlib.pylab as plt
x = plt.linspace(-20,20,100)
y = plt.sin(x)/x
plt.plot(x,y)

Deftere gömülü olarak bir etkileşimli grafik arayüzü elde ederiz.

Grafiğin ayrı bir pencerede gösterilmesini istiyorsanız gtk, qt, agg, ve türevlerini kullanabilirsiniz. O zaman en sonda matplotlib’in show() komutunu vermelisiniz.

%matplotlib qt5
import matplotlib.pylab as plt
x = plt.linspace(-20,20,100)
y = plt.sin(x)/x
plt.plot(x,y)
plt.show()

Bu komutlardan sonra grafik şöyle bir pencerede gösterilir.

%%script: Herhangi bir yorumlayıcıyı çalıştır

Başka dillere ait yorumlayıcıları kullanmaya ne dersiniz? Belki bir sürü veri dosyasını hızlıca işlemek için birkaç kabuk komutu vereceksiniz. Belki Awk, Perl, ya da Ruby ile hızlı bir işlem yapmak istiyorsunuz. Sisteminize kurulu herhangi bir yorumlayıcıyı çalıştırıp ona komutlar vermek için %%script hücre sihrini kullanabilirsiniz.

Hücrenin başına %%script’in ardından yorumlayıcı programın adını, ve gerekiyorsa bazı parametreleri yazın. Hücredeki alt satırlar yorumlayıcıya gönderilip işlenecek, gelen cevap ekrana basılacak.

%%script bash
for i in 1 2 3; do
echo $i
done
1
2
3

%%html: HTML yorumlayıcı

Bulunduğu hücredeki HTML kodunu işler ve HTML belgesini ekrana verir.

%%html
<html>
<head>
<style>
table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    widtd: 100%;
}

th, td {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #dddddd;
}
</style>
</head>
<body>
<h1> Çevrimiçi alışveriş veri kayıtları </h1>
<table class="table table-bordered table-hover table-condensed">
<thead><tr><th title="Field #1">InvoiceNo</th>
<th title="Field #2">StockCode</th>
<th title="Field #3">Description</th>
<th title="Field #4">Quantity</th>
<th title="Field #6">UnitPrice</th>
</tr></thead>
<tbody><tr>
<td align="right">536365</td>
<td>85123A</td>
<td>WHITE HANGING HEART T-LIGHT HOLDER</td>
<td align="right">6</td>
<td align="right">2.55</td>
</tr>
<tr>
<td align="right">536365</td>
<td>71053</td>
<td>WHITE METAL LANTERN</td>
<td align="right">6</td>
<td align="right">3.39</td>
</tr>
<tr>
<td align="right">536365</td>
<td>84406B</td>
<td>CREAM CUPID HEARTS COAT HANGER</td>
<td align="right">8</td>
<td align="right">2.75</td>
</tr>
</tbody></table>

</body>
</html>

Çevrimiçi alışveriş veri kayıtları

InvoiceNo StockCode Description Quantity UnitPrice
536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2.55
536365 71053 WHITE METAL LANTERN 6 3.39
536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2.75