Monday, September 24, 2018

Android Uzerinde Linux - Termux

Android işletim sisteminin temeli Linux işletim sistemidir, en azından çekirdek seviyesinde bu böyle. Peki madem böyle niye Ubuntu'da, ya da diğer Debian bazlı sistemlerde olduğu gibi apt-get, python, ruby, komutlari ile ya da Flask gibi uygulamalari kurup, geliştirmeyi direk Android telefonu üzerinde yapamıyoruz? Hatta cep telefonları artık iyice kuvvetlendi, dizüstü bilgisayarı atsak, sadece cep telefonu üzerinde geliştirme yapsak?

Bunların yapılamamasının sebebi Linux temelli olsa da Android'de her şeyi Java bazlı işletebilmek için katman üzerine katman koyarak Linux baz sisteminden uzaklaşılmış olması. Fakat bazıları bayağı uğrarak Linux temelli geliştirmeyi Android'e taşımışlar. Google Play'den indirilebilecek bir uygulama Termux.

Termux'a bir "app" demek basit kaçar aslında, daha çok bir başlangıç kabuğu denebilir, Termux bize telefon içinde bir komut satırı verir, bu satırda apt install ya da pkg install ile ek uygulamaları Ubuntu'da olduğu gibi kurarız. Mesela apt-install python gibi. Termux'u yazanlar bir sürü Linux bazlı programı bu şekilde Android için hazır hale getirmişler. Liste tüm programları kapsamıyor, ama şaşırtıcı derecede faydalı programlar var. C++ icin clang, ya da Tex icin texlive hatta emacs! Tabii cep telefonu üzerinde emacs kullanmak acaip olur, planlanan Samsung'un DevX sistemi ile / gibi dışarıdan bir Bluetooth klavyesi bağlayıp görüntüyü bir büyük ekrana yansıtacak türden kullanım herhalde. Ki bu tür kullanım başta değindiğimiz pür cep telefon bazlı geliştirmedir.

Python sistemi daha once bahsedildigi gibi hazır, pkg install python3 ardından, pip install virtualenv deriz, ve python3 için bir sanal ortam yaratabiliriz. Cep telefonu üzerinde virtualenv'e girmek bazılarımızı şaşırtabilir. Fakat işliyor.



Sanal ortama girince burada pip install ile ipython, numpy, scipy kurabiliriz. Bazı paketlerde sorun çıkabilir, mesela zmq için bizde bir sorun çıktı ki bu sorun jupyter ile de yasanabilir, once pgk install libzmq libzmq-dev python-dev libcrypt-dev kurulur. Ardından, eğer zmq import edilmesi problem veriyorsa, komut satırına çıkıp ana dizinde bir .bash_profile dosyası yaratıp onun içine alttakini yazarız,

export LD_PRELOAD=$LD_PRELOAD:"/data/data/com.termux/files/usr/lib/libzmq.so"

exit ile Termux'dan çıkıp tekrar girersek, artık zmq çalışıyor olacak.

Paketler pandas, matplotlib icin ek bazi kurma islemleri

pkg install clang freetype-dev libpng-dev python2-dev

Matpotlib icin $HOME/.config/matplotlib/matplotlibrc icinde backend : TkAgg yazmak lazim, komut satirindan cikip tekrar girin, sonra

LDFLAGS=" -lm -lcompiler_rt -lpython" pip install cython pandas matplotlib

Eger Python 2 ortami icin kurulum yapiliyorsa ustteki  -lpython2.7 yapilabilir.

"Dışarısı" ile Dosya Paylaşmak

Termux kendi izole alanında işliyor. Eğer Android ana dizinlerine Termux komut satırından erişmek istersek, termux-setup-storage deriz, izin isteyen diyalog kutusu gelince ona 'allow (izin ver)' deriz. Artık ana dizinde bir storage adlı bir alt dizin olacak, bu alt dizine bakınca içinde downloads, movies, music gibi Anroid'in bilinen dizinlerini göreceğiz. Bu dizinlere yazılan her dosya dışarıda da gözükecektir. Ya da ters yönde oraya yazılan Termux'da okunur.

ssh var, dışarı bağlanılıp envai türden iş yapılabilir. Kimisi web geliştirmeyi DevX üzerinden direk telefonda yapıyor, flask, django var, mikroservis ya da apache başlatılabilir, yerel servis yerel tarayıcı ile ziyaret edilip sayfalar, servis tarafı kodu test edilebilir.

Veri tabanlarına bağlanmak için PostgreSql var. pkg install postgresql-dev python-dev make clang, ve python seviyesinde pip install psycopg2. Yok yok.

Latex

pkg install texlive ile kapsamli bir TeX kurulabilecegini gorduk. Ama ekler icin TeX paket sistemi ile kurulus mumkun, tlmgr install [paket]. Ama ayri ayri her paket kurmak yerine daha rahati

tlmgr install collection-fontsrecommended
tlmgr install collection-latexextra
tlmgr install collection-mathscience

isletmek.

Scipy

Bu paket cok kritik, mesela statsmodels icin lazim. Fakat pip install ile kurulumda problem cikiyor. Termux'ta paket

pkg install scipy

ile kurulabilir. Fakat böyle yapınca kurulum global python için oluyor, virtualenv ortamlarında nasıl görülecek? Bunu basit bir sembolik bağlantı ile halledebiliriz, global python'a girip import scipy ve print (scipy) derseniz kütüphane yeri gösterilecek. Bu adresi alıp mesela env3/lib/site-packages altında ln -s ile bağlantılarsanız (ki scipy dizini orada görülsün) scipy işleyecektir.

Simdi bir puruz ortaya cikabilir; Eger pip install keras ile kurulus yapmaya calisirsak bazen bu ve benzeri paketler scipy'in zaten kurulu oldugunun farkedemeyebiliyorlar. Bu durumda bu paketleri --no-dependencies secenegi ile kurmak lazim. Tabii boyle olunca gercekten ihtiyac olan paketleri kurmadan atlayacaktir, keras durumunda bu paketleri teker teker elle kurmak lazim. Mesela

pip install theano --no-dependencies
pip install keras-applications --no-dependencies
pip install keras-preprocessing --no-dependencies

Keras icin eger arka plan hesap motorunu theano sectirmek icin kodun en basina alttakini yazin.

import os; os.environ['KERAS_BACKEND'] = 'theano'

Tensorflow'a hic girmiyorum, orada Termux ile problem cikti. Fakat Keras isliyorsa bu yeterli olacaktir. Altta basit ornek bir YSA'yi Keras ile telefonum uzerinde egitirken goruyoruz.



Samsung

Fakat Termux yine de izole bir ortam. Docker'vari daha geniş kapsamlı Linux işletmek için Samsung kolları sıvadı ve Linux on Galaxy adlı bir proje üzerinde çalışıyorlar. Bu şekilde telefon, tablet sahibi geliştiricileri kendilerine çekmeye uğraşıyorlar, ekonomik kısmı mantıklı.

Wednesday, September 12, 2018

Docker

Docker bir sanal makina teknolojisi. MacOs üzerinde Ubuntu, Ubuntu üzerinde Windows, envai türden sanal makina işletebilmek için kullanılabilir.

Docker ile paylaşmak istediğimiz herhangi bir programı artık ona gereken tüm işletim sistemi destek programları ile beraber paketleyip sunabiliriz. Bir servis için filanca python paketleri gerekiyor  bunları python paket listesiyle sunabilirdik. Ya peki apt-get ile kurulması gereken yan programlar, hatta yan dosyalar, diğer büyük programlar da varsa? Docker tüm bunları paketleyebilir.

Bizim şirkette sürekli Docker sözü duyuluyor, "abi _vs_ programı işletmem gerekiyor onun Docker imajı neredeydi?", ya da "Docker'i aldım işlettim, hangi makina üzerinde işleteyim". vs. Yani program kurmaktan bahsetme kalmadı, kurulmuş, hazır programların Docker imajı olarak paylaşılması konuşuluyor.

Çoğunlukla bir sistem Dockerfile dosyası üzerinden kuruluyor, bu Dockerfile için gereken imajlar (Ubuntu gibi) bilinen referans noktalardan indiriliyor. Fakat kendimiz bir docker imajı kaydedip onu paylaşabilirdik.

Ubuntu uzerinde Docker

https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-from-a-package

Deb paket bazli kurmak icin mesela Ubuntu 16 icin,

https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/amd64/

Indirilen deb uzerinde sudo dpkg -i package.deb

MacOS uzerinde Docker (ve ardindan sanal Ubuntu) icin

https://docs.docker.com/docker-for-mac/

https://docs.docker.com/docker-for-mac/install/#install-and-run-docker-for-mac

Siteye kayıt ol, dmg indir, tıkla, app tıkla, makine şifresi ver, kayıt olduğun kullanıcı / şifreyi ver.

Komut satirinda artik

docker --version

isliyor olmali. Basit kontrol

docker run hello-world

Altta bir web servisi isletmenin yolu

docker run -d -p 80:80 --name webserver nginx

Tarayıcı ile localhost ziyaret edince orada bir servis işlediğini göreceksiniz! Alttaki komut mevcut sanal makinaları / kapları (container) gösterir,

docker container ls

Sanal makinayi durdurmak icin

docker container stop webserver

Silmek

docker container rm webserver
docker image rm nginx

Simdi Mac uzerinde Ubuntu kuralim. Docker sitesinde onceden hazirlanmis bir Ubuntu kurulumu var,

docker run -it --name ubuntu ubuntu:xenial bash

docker exec -it ubuntu bash

Bu komut bizi işleyen bir Ubuntu içine taşır! Bu izole bir sanal makina, orada yapılan hiçbir şeyin "dış" sisteme etkisi yok.

Sistem icinde

apt-get update

Sonra mesela C derleyicisi kurabiliriz,

Mesela apt-get install gcc

Python kuralim,


apt-get install python python-pip python3 python3-pip

Ubuntu versiyon

cat /etc/*release

16.04 dedi.

Kopyalama (Dışarıdan içeri)

MacOS'ten sanal makina Ubuntu'ya dosya kopyalamak icin, docker container ls ile listelenen container id (kimlik) alinir, ve

docker cp [YEREL DOSYA] [CONTAINER KIMLIK]:/

Mevcut imajlari listelemek,

docker image ls

Silmek icin

docker image rm [IMAGE ID]

Eğer hata gelirse (container [ID] hala silinmemiş diye) docker container rm ile container silinir, sonra image silinir.

Şimdi üstteki örnekte iskelet bir kap yarattık ve o sanal makinaya girip orada komutlar işlettik. Acaba tek bir komutla üstteki her programı kurduramaz mıyız? Dockerfile yaklaşımı ile evet.

Bir Dockerfile icinde alttakileri yazalim,

FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y python python-pip
RUN apt-get install -y python3 python3-pip
RUN pip install virtualenv
RUN virtualenv -p /usr/bin/python2 pyenv2
RUN /bin/bash -c "source /pyenv2/bin/activate && pip install ipython pandas && deactivate"

apt-get komutuna -y vererek y/n sorusuna otomatik y cevap vermis oluyoruz, bunu yapmazsak apt-get soru sorup cevap bekliyor, biz otomatik kurulum yaptigimiz icin bu takilmayi istemiyoruz.

Simdi imaji yaratalim,

docker build -t ubuntu_image .

Bu kadar. Listeleyelim,

docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu_image        latest              cf7c904f9a65        47 seconds ago      675MB
ubuntu              16.04               b9e15a5d1e1a        7 days ago          115MB

Simdi sanal makinaya girelim,

docker run -it --name ubuntu2 ubuntu_image bash

Kurduğumuz tüm programların hazır bizi beklediğini göreceğiz.

Zihin egzersizi: Docker ile izole bir makina kurulumu yaratmış olduk. Ama üstteki örnekte bu sanal makinada bir de sanal Python ortamı yarattık, aslinda tum Python paketlerini global Python icin kurabilirdik. Sanal ortama gerek var mıydı? Gerek olmayabilir. Fakat virtualenv ile çalışmaya alıştıysak, ve sanal makina bile olsa onun üzerinde de farklı Python derleyicileri kullanma olasılığı olduğu için, yine de virtualenv kullanmakta sakınca yok.

Not: Usttte MacOS üzerinde Ubuntu örneği gösterdik. Docker sanal makina işleticisi bir mikroişlemciyi de mi (mesela Intel) sanal olarak işletiyor? Buna gerek yok, altta kullandığımız makina bir MacBook Pro 3,1 GHz Intel Core i7, yani Intel işlemcisi var, yani mikroislemci komutlarini cevirmeye gerek yok. Makina / ikisel kod olduğu gibi MacOS'in mikroişlemcisinde işletebilir.

https://stackoverflow.com/questions/44480740/how-to-save-a-docker-container-state

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

https://stackoverflow.com/questions/23935141/how-to-copy-docker-images-from-one-host-to-another-without-via-repository

https://www.howtoforge.com/tutorial/how-to-create-docker-images-with-dockerfile/

https://stackoverflow.com/questions/48561981/activate-python-virtualenv-in-dockerfil

Saturday, September 8, 2018

Jupyter Not Defterleri

Not defterleri ipython komut satırının bir ileri hali denebilir; ipython'a bir Web arayüzü sağlıyor, ayrıca görüntü, animasyon, grafiksel çıktıları direk defter içinde tutulmasını sağlıyor. Böylece kaydedilmiş bir defteri yükleyince pat diye onun yaratmış olduğu çıktıyı, grafiğini defter içinde kaydedilmiş şekilde görebiliyorsunuz. Tabii defteri tekrar işletmek te mümkün. 

Matematik ve kodu aynı yerde tutması sebebiyle bilim, eğitim için çok faydalı bir araç. 

Kurulum için pip install jupyter. Bunları bir sanal ortam içinden yapmak iyi olur. Sanal ortamda

ipython kernel install --user --name=Kernel1

ile bir çekirdek yaratmak iyi. Defter jupyter notebook ile başlatılır ve sağ üstte kernel seçiminde üstte tanımlanan isim seçilir. 

Not: bu teknolojiye bir alternatif olarak biz bir Emacs eklentisi yazdik, emacs-ipython ile ipython kernel'ine bağlanıp (aynen jupyter'in yaptigi gibi) md ya da tex dosyaları içine çıktıyı dokuman icinde gösterebiliyoruz. Jupyter dosyaları ipynb formati kullanir, bu dosyaları direk editor ile ziyaret etmek mümkün değil, emacs-ipython bunu sagliyor. Zaten Emacs kullanan kodcular icin daha kullanisli olabilir.

Jupyter not defterleri ipython not defterleri olarak biliniyordu, bu son versiyonda (isim degisikligi ile beraber) artik tek degil birden fazla dili destekliyorlar. 

Video

Wednesday, August 29, 2018

Komut Satırı Seçeneklerini İşlemek (Command Line Option Processing), Python

Python script'lerine verilecek seçenekleri nasıl isleriz? İlk akla gelen sys üzerinden işlem yapmak,

import sys

if __name__ == "__main__":
    print sys.argv[0]
    print sys.argv[1]

gibi.. Burada script ismi sys.argv[0] içinde, ilk argüman sys.argv[1], vs. Eğer len(sys.argv) dersek kaç tane seçenek verildiğini raporlar. 

Fakat bu seçeneklerden hangileri zorunlu, hangileri değil, hiç seçenek verilmeyince güzel bir hata mesajı verilse iyi olmaz mı, gibi ihtiyaçlar için argparse paketi kullanılabilir. Bir test.py icinde,

import argparse

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='Bir program')
    parser.add_argument('arg1', type=str, help='arg1 tanimi.')
    parser.add_argument('arg2', type=str, help='arg2 tanimi.')
    parser.add_argument('--arg3', type=bool, nargs="?", help='arg3.')
    parser.add_argument('--arg4', type=str, nargs="?", help='arg4.')

    args = parser.parse_args()
    print args.arg1
    print args.arg2
    print args.arg3
    print args.arg4

Eğer hiç seçenek vermeden çağırırsak 

usage: test.py [-h] [--arg3 [ARG3]] [--arg4 [ARG4]] arg1 arg2
test.py: error: too few arguments

mesaji gelecek. Istesek -h ile tanımları raporlatabilirdik. 

Önünde -- olan seçenekler isim verilmeden geçilebilir. 

python test.py secenek1 secenek2

gibi. Önünde -- olan ve nargs="?" diyen seçenekler şart olmayan seçeneklerdir.

python -u test.py secenek1 secenek2 --arg3 secenek3 --arg4 secenek4

Sonuç

secenek1
secenek2
True
secenek4

3. seçeneğin True gelmesi doğru, çünkü tip tanımı da yapılabiliyor, ve o tipi bool olarak tanımlamıştık. 




Yerel, Network Dosyasını Canlı, Anlık, Azar Azar Islemek (Stream, Incremental File Processing), Python

Bir dosyayı hızlı bir şekilde canlı olarak, teker teker satır okuyacak şekilde işlemek için csv paketi faydalı. Dikkat bu paket standard Python'un yaptığı gibi önce dosyanın tümünü hafızaya alıp sonra oradan readlines() ile teker teker satır servis etmiyor. Dosyanın her satırı hakikaten Python tarafından teker teker alınıyor.

import csv

with open('[DOSYA]') as csvfile:
    rd = csv.reader(csvfile,delimiter=' ')
    headers = {k: v for v, k in enumerate(next(rd))}
    for row in rd: print row[headers['kolon1']]

Değişken headers içinde dosyanın ilk satırından alınan kolon isimleri var (bu şart değil, atlanabilir) delimiter kolon ayracının ne olduğunu kontrol eder.

Network üzerinden akış işlemi için smart_open var,

from boto.s3.connection import S3Connection
import smart_open
conn = S3Connection('[aws_access_key_id]', '[aws_secret_access_key]')
for line in smart_open.smart_open('s3://bir/dizin/dosya.txt'):
    print (line)

Bu kütüphane sadece S3 ile de sınırlı değil. HDFS, HTTP, envai türden protokol üzerinden okuma yapabiliyor. Eğer yerel dosya ismi verirsek onu da okuyor. Sıkıştırılmış dosyaları açıp onları anlık olarak işliyor, vs. Aslında ilk başta bu paketi kullanmak daha iyi herhalde, pek çok farklı işi yapabiliyor.

https://pypi.org/project/smart_open/