Sunday, December 25, 2011

pdftk

Bazi pdftk numaralari:

Dokumanlari birlestirmek

pdftk doc1.pdf doc2.pdf output dokuman.pdf

Bir belgenin cift sayfalarini 90 derece saga, tek sayfalarini 90 derece sola dondurmek

pdftk A=doc.pdf shuffle AevenE AoddW output out.pdf

Bir kitabin 100. ve 110. sayfalari arasindaki sayfalari ayri bir dokuman olarak yazmak

pdftk doc.pdf cat 100-110 output out.pdf

1-9 sayfalarini 180 derece cevirmek, geri kalanini oldugu gibi almak

pdftk doc.pdf cat 1-9S 10-end output out.pdf

20. ve 30. sayfalar arasindaki sayfalari atlayip, geri kalanlari tutmak,

pdftk doc.pdf cat 1-10 30-end output parcalar.pdf

YouTube Video'larini Kaydetmek

En iyisi youtube-dl adinda bir Python script'i. pip ile kurulabilir, pip install youtube-dl.

youtube-dl [youtube video baglantisi]

Eger baska secenek verilmezse script dosya ismini bile kendisi yaratiyor, bir mp4 dosyasina video yaziliyor. Cok basit.

Eger indirme islemini durdurup tekrar baslatmak isterseniz, ikinci kez script'i baslattiginizda -c secenegini kullanabilirsiniz.

Cauchy Ortalama Deger Teorisi (Cauchy Mean-value Theorem)

Indir

Wednesday, December 21, 2011

PDF Formlari Otomatik Olarak Doldurmak

English

PDF bazli formlari otomatik olarak doldurmak icin ekteki Python scriptlerini paylasiyoruz. Kullanicinin yapmasi gerekenler once PDF dosyasini jpg dosyalarina cevirmek, sonra UI aracimiz uzerinden bu imajlar uzerinde kutularin yerlerini tiklayarak isaretlemektir. Sonra doldurulacak bilgiler bir text dosyasina yazilir, ve script tum bunlari otomatik olarak birlestirir.

Once cevirme islemi

python convert.py BELGE.pdf [hedef dizin]

Program bitince [hedef dizin] icinde BELGE-0.jpg, BELGE-1.jpg, vs. gibi dosyalar olacak.

Simdi kutu yerlerini belirleyin

python locs.py [hedef dizin]/BELGE-0.jpg

GUI programi baslayacak, burada kutulara belli bir sirayla tiklayin. Siranin mantiki bir sira olmasi iyi olur, yukaridan asagi, soldan saga gibi. Cogu PDF formu kutular uzerinde bir sira no'su da verir, bu kullanilabilir mesela.

Her tiklama o tiklanan kordinati BELGE-0.jpg.loc dosyasina yazacaktir. Dosyaya yazim islemi her tiklamada yapilir, yani isiniz bitince locs.py programini kapatmak yeterli.

Simdi doldurulacak veriler icin BELGE-0.jpg.fill diye bir dosya baslatin, diger dosyalar ile ayni dizinde olsun. Bu dosyadaki her bilgi, loc dosyasindaki kordinat satirina tekabul ediyor olmali.

Eger gerekiyorsa, mesela [down=30] komutu ile 30 piksel asagi gidilebilir. Ayni sekilde down, yerine up, left, right komutlari da kullanilabilir. Font kucultulmek, buyultulmek isteniyorsa, mesela [font=20] ile yeni deger tanimlanabilir.

Bu dosya tamamlaninca

python fill.py [hedef dizin]/BELGE-0.jpg

Bu son script loc, fill, jpg dosyalarini birlestirecek, ve doldurulmus formu BELGE-0.jpg-out.jpg olarak goreceksiniz.

Aracimiz ImageMagick kullanir, baslamadan once kurulmus oldugunu kontrol edin. Gerekli diger Python kutuphaneleri icin Ubuntu uzerinde

sudo apt-get install python python-tk idle python-pmw python-imaging python-imaging-tk

Bu program icin bir potansiyel ilerleme bir oruntu tanima algoritmasi kullanarak kutularin yerlerini otomatik olarak belirlemektir; boylece kutulari tiklama ile isaretleme islemine gerek kalmaz, loc dosyasi kendiliginden ortaya cikar.

Indir

Imaj Gosterip Tiklama Almak, ImageTk

TkInter diye bir paket gerekli

sudo apt-get install python python-tk idle python-pmw python-imaging python-imaging-tk

Tiklama almak icin ornek kod. [DIZIN] baslangic dizininden secilen imaj secilir, ekranda gosterilir, sonra bu imaj uzerindeki tiklamalar konsola yazilir.
from Tkinter import *
from tkFileDialog import askopenfilename
import Image, ImageTk

if __name__ == "__main__":
root = Tk()

#setting up a tkinter canvas with scrollbars
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscroll = Scrollbar(frame, orient=HORIZONTAL)
xscroll.grid(row=1, column=0, sticky=E+W)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscroll.config(command=canvas.xview)
yscroll.config(command=canvas.yview)
frame.pack(fill=BOTH,expand=1)

#adding the image
File = askopenfilename(parent=root, initialdir="/[DIZIN]",title='Choose an image.')
img = ImageTk.PhotoImage(Image.open(File))
canvas.create_image(0,0,image=img,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL))

#function to be called when mouse is clicked
def printcoords(event):
#outputting x and y coords to console
print (event.x,event.y)
#mouseclick event
canvas.bind("<Button 1>",printcoords)

root.mainloop()
Daha oz kisa bir ornek
import Tkinter
from PIL import ImageDraw, Image, ImageTk
import sys

window = Tkinter.Tk(className="bla")

image = Image.open(sys.argv[1])
image = image.resize((1000, 800), Image.ANTIALIAS)
canvas = Tkinter.Canvas(window, width=image.size[0], height=image.size[1])
canvas.pack()
image_tk = ImageTk.PhotoImage(image)

canvas.create_image(image.size[0]//2, image.size[1]//2, image=image_tk)

def callback(event):
print "clicked at: ", event.x, event.y

canvas.bind("", callback)
Tkinter.mainloop()

Saturday, December 17, 2011

GPU

Bilgisayarimizda hesaplari yapan islemci var, bu islemci son zamanlarda cok cekirdekli hale de gelmeye basladi. Fakat bilgisayarimizda islem yapan cok kuvvetli bir parca daha var: grafik islemci (GPU).

GPU paralel islem acisindan neredeyse pur mikroislemci kadar kuvvetlidir, hatta bazi acilardan daha hizlidir, cunku tarihsel sebeplerle parallellige daha fazla yatkin olmasi gerekmistir. GPU bir goruntunun hizla cizilmesi (rendering) icin piksel bazinda paralellige gitmek zorundaydi ve NVIDIA sirketinin urunleri icin artik bu normal bir operasyondur.

Arastirmacilar bu paralellikten istifade etmeye karar vermisler, ve grafiksel olmayan hesap islemlerini sanki oyleymis gibi GPU'ya sunuyorlar, ve cevabi geri tercume ediyorlar, boylece GPU'nun hizli paralel islemci ozelliginden faydalaniyorlar. Pek cok matematiksel hesabi bu sekilde yaptiran olmus, mesela matris carpimi, PDE cozumu, simulasyon.

NVidia sirketi grafik kartlarinin GPU'suna erisim icin CUDA diye bir kutuphane sagliyor. Onun ustune PyCUDA ile Python bazli erisim de var. Cin universiteleri CUDA egitimini universitelerinin mufredatina dahil etmisler.

Dikkat: NVidia karti piyasadaki grafik kartlarindan bir tanesidir, her laptop uzerinde NVidia olmayabilir (fakat NVidia piyasadaki en unlulerden birisi, bunu da ekleyelim). Simdilik GPU kodlamasi icin NVidia kartina sahip bir bilgisayar lazim, ve oldukca yeni modeller gerekiyor.

Altta konu hakkinda bir video:

Sunday, December 11, 2011

Polinom Bolmek

Baglanti

Tuesday, December 6, 2011

Excel, CSV, Python

Icinde pur text verisi olan Excel dosyasini CSV dosyasina cevirmek icin iyi bir kod

https://github.com/dilshod/xlsx2csv

Hizli isliyor, kurmaya bile gerek yok. Indirilen py dosyasi direk isletilir,

python xlsx2csv.py dosya.xlsx dosya.csv

seklinde.

Sunday, December 4, 2011

DTA, TXT Cevirmek, R Dili

S, R, Stata gibi paketler DTA dosyalari kullanabiliyorlar, bu dosyalari R dilinde txt formatina cevirmek icin
library ("foreign")
x = read.dta ("[dta file name]")
write.table(x, file = "[txt file name]")

Saturday, October 22, 2011

Python Radyo

Internet'ten bedava radyo dinleyebilmek icin bazi sayfalar var, fakat hepsine HTML bazli girip, belli yerlere tiklamak, beklemek, vs. gibi isler cok ugrastirici olabiliyor. Python bazli bir program yazilmis, kodlar acik, programi komut satirindan baslatiyorsunuz, bir suru kanal icinden istediginiz seciyorsunuz, alet arka planda o kanaldaki muzigi calan HTML sayfalarina baglanip oradan gelen muzigi canli olarak aktariyor (streaming). Kodlar surada:

Github

Bazi puf noktalar: Radyoyu baslatabilmek icin komut satiri tam ekran (fullscreen) olmali, biz o isi otomatik yapmak icin Ubuntu'da bir ikon yarattik, ve ikon gerekli xterm penceresini gerektigi sekilde baslatiyor. Komut soyle:

xterm -fn *-fixed-*-*-*-20-* -maximize -e "python [DIZIN]/jspricke-radio-6956368/radio.py"

Ayrica, birkac kez kanal degistirince program takilabiliyor, ama bu pek onemli degil, 24/7 islemesi gereken bir program degil zaten, kapatip acinca buyuk bir ihtimalle tekrar islemeye baslayacaktir.

Thursday, October 20, 2011

Otonom Arabalar

Sebastian Thrun ve takiminin Google icin tasarladiklari kendi kendine giden arabanin yazilim, YZ yapisi hakkinda bazi ilginc bilgiler. Video'ya gore arabanin kullandigi ana algilayicisi lazer, ve bu lazer ile arabanin 360 derece etrafi gozleniyor, sadece gorsel girdi ile yetinilmemis. Bilindigi gibi lazer algilayici direk bir uzaklik bilgisi verir. Neyse, tum bu bilgiler ile SLAM isletiliyor ve etrafin haritasi cikartiliyor. Sonra bu haritaya "uymayan", onun disinda kalan, yani sabit durmayan objeler surekli takip ediliyor, insan, bisiklet, diger arabalar, vs gibi.

Monday, October 17, 2011

EPUB -> PDF

EPub dosyalarini PDF'e cevirmek icin program: epub2pdf. Java bazli yazilmis, binary zip dosyasini kullanmak daha iyi.

Wednesday, October 12, 2011

Oyun Programini Oynayan Program - FPS Play

Robot konularinda teorilerin test edilmesi icin simulatorler faydali araclar, grafikleme teknikleri cok ilerledi ve oyun icindeki dunya dis dunyaya benzemeye basladi. Robotlari kontrol eden kodlar bu tur sanal ortamlarda test edilmeye baslandi.

Bogazici CmpE 565 dersinde mesela Unreal Tournament adindaki 1SG (Birinci Sahis Gozunden -FPS-) oyunu uzerine kurulmus USARSim yapisini odevde kullanmistik, bu ortamda disaridan yazilimlarin baglanip 3D oyun ortamindaki sanal robotlarin oyun icindeki kontrolu mumkun oluyor. USARSim'de oyun icindeki fiziksel dunya yapisi, yollar, engeller, agaclar, vs, goruntu, uzaklik bilgileri sanal algilayicilar uzerinden disari aktarilabilmekteydi. Bu bilgiyi ve kontrolu saglamak aslinda 1SG oyunlari icin kolay, grafikleme amaclari icin zaten o bilgiye sahipler, sadece bir arayuz ile disari aktarmalari gerekiyor. UT ve USARSim bu arayuzu sagliyor.

Ilginc ek bir yontem su olabilir: Bir 1SG oyununu masaustumuzde ufaltilmis bir pencerede kosturdugumuz dusunelim. Eger masaustumuzun ekran goruntusunu (screenshot) alabilirsek, ki bu kolay bir istir, o zaman oyun penceresinde olanlarin grafigini alabiliriz. Oyuncuyu kontrol etmek icin ise oyuna aynen gercek bir oyuncunun yapacagi gibi tus, ve mouse tiklamalari, hareketlerini yollayabiliriz.

Bu fikirden hareketle fps-play adli bir proje baslattik. Test icin kullandigimiz oyun populer Quake grafik motorunu kullanan bedava UrbanTerror 1SG oyunudur. Oyun pencerede baslayinca Python bazli kodlar gtk.gdk.Pixbuf kullanarak surekli olarak ekranin belli bir bolumunun "fotografini cekiyor", ve bir dongu icinde bu fotograflar oyuncunun bakisini disari aktariyor. Bu ardi ardina fotograflar OpenCV kutuphanesi ile imaj isleme algoritmalarina tabi tutularak, imaj ve arkasindan yapay zeka hesaplarina tabi tutalabilir, etrafinin haritasini cikarmak, diger oyunculari tanimak, vs. gibi. Bunlardan sonra oyuna tus, mouse bilgisi gondermek icin xdotool Unix kutuphanesini kullaniyoruz. Bu arac disaridan herhangi bir programa sanki gercek bir kisi gibi tus tiklamalari, hatta mouse x,y hareketi ve tiklamasi gonderebiliyor.

Su anda Github'da bulunan kodlar UrbanTerror oyununu OpenCV ekraninda gosterip, aksiyon olarak oyuncuyu biraz ileri hareket ettirip, durdurup, sonra bir el ates ettiriyor.

Bunun ustune neler eklenebilir?

Mesela optik akis (optical flow) kavrami Kalman Filtreleri ile birlestirilebilir; etraftaki objelerin (yer, duvarlar, engeller) etrafinda dolastikca onlarin yerlerini haritamiza yerlestirebiliriz. Etraflarinda gezindigimiz zaman optik akis vektorleri objelerin sekli hakkinda bize ipucu verecektir, bu vektorler, objelerin gercek yerinin dis dunyaya olan "bir tercumesi / yansimasi" olarak gorulebilir. Gizli degisken obje konumu, acik degisken ise optik akis vektorleridir. Kendi hareketimizi bildigimize gore x_{t+1} = Ax_t + w formulundeki A degisimini de (translation) biliyoruz demektir, cunku biz kendi hareketimizi biliyoruz, diger objeler sabit.

Ekran fotografi, tus yollama temelli bu teknik her turlu oyunu disaridan oynamak icin kullanilabilir, oyunun disariya API acmasina gerek kalmaz.

X Windows bazli ekran kapma teknigine gelene kadar diger bazi yollara baktik, mesela OpenGL'e cengel takmak (bir onceki yazi), fakat bazi oyunlar libGL.so kutuphanesini direk kendileri program icinden yukluyorlar (hile yapilmasini engellemek icin, bazilari OpenGL cengellerini duvarlarin arkasini gormek icin kullaniyor mesela), ve temiz yollarla grafiklerini cekip cikartmak mumkun olmuyor. Bu yontemle ekranda gordugumuz her seyi fps-play gorebilir, ve oynayabilir.

Monday, October 10, 2011

LD_PRELOAD ile Fonksiyon Yakalamak

Linux'ta isleyen herhangi bir kodun ic fonksiyonlarinin yerine bir baskasini gecirmek icin kullanilan bir teknik fonksiyon bindirme (function interposition). Kullanim soyle:

LD_PRELOAD=`pwd`/bizim-kodlar.so ./demo.exe

Dinamik kutuphane bizim-kodlar.so icinde derlenmis C/++ kodlari var. LD_PRELOAD degiskeni bir cevre degiskeni, ve orada tanimlanan kutuphaneler, diger tum kutuphanelere gore oncelik kazanir, yani once LD_PRELOAD'da tanimli kodlar isletiliyor. Cengel takmak icin o yuzden bicilmis kaftan.

Ornek: OpenGL kutuphanesinin ekrana bastigi goruntuyu yakalamak mesela, ekrana cizilen goruntuler glXSwapBuffers cagrisi yaparlar, bu cagri yerine kendi yazdigimiz bir fonksiyonu gecirip, esas fonksiyona aktarma yapmadan once arada goruntuyu alip bir dosyaya yazabiliriz. Alttaki kod demo.cpp basit bir OpenGL ornegi, bir objeyi alip surekli donduruyor. Bu cizimi, bindirilmis yeni fonksiyon uzerinden isletince, goruntunun kare kare ciktisi bir imaj dosyasi olarak /tmp altinda yazilacak.

make.sh

# sudo apt-get install freeglut3 freeglut3-dev libglew1.5 libglew1.5-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa-glx libgl1-mesa-dev
g++ -o demo.exe demo.cpp -lglut -lGL -lGLU -lGLEW
gcc -shared -fPIC -o glcapture.so glcapture.c -ldl

load.sh

rm /tmp/*.tga
rm /tmp/*.jpg
LD_PRELOAD=`pwd`/glcapture.so ./demo.exe 

glcapture.c

/*
 * Use something like this:
 *
 * gcc -shared -fPIC -o glcapture.so glcapture.c -ldl
 * LD_PRELOAD=`pwd`/glcapture.so ./demo
 */

#include
#include
#include
#include
#include

#ifndef RTLD_NEXT
#define RTLD_NEXT ((void *) -1l)
#endif

#define WIDTH 640
#define HEIGHT 480
#define FPS 4

static char buf[WIDTH * HEIGHT * 3];
static int frameno = 0;

void glXSwapBuffers( Display *dpy, GLXDrawable drawable )
{
  printf("swap\n");
  void (*real_swap)(Display*, GLXDrawable);
  real_swap = (void(*)(Display*, GLXDrawable))dlsym(RTLD_NEXT, "glXSwapBuffers");

  FILE *ppm;
  char filename[256];
  glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGR, GL_UNSIGNED_BYTE, buf);

  sprintf(filename, "/tmp/frame%05u.tga", frameno++);
  ppm = fopen(filename, "w");
  fwrite("\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, 1, ppm);
  {
    unsigned short w = WIDTH;
    fwrite(&w, 2, 1, ppm);
  }
  {
    unsigned short h = HEIGHT;
    fwrite(&h, 2, 1, ppm);
  }
  fwrite("\x18\x00", 2, 1, ppm);
  fwrite(buf, WIDTH*HEIGHT*3, 1, ppm);
  fclose(ppm);

  real_swap(dpy, drawable);
}

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
  printf("gettimeofday frame %u\n", frameno);
  //tv->tv_sec = frameno / FPS;
  //tv->tv_usec = ((double)(frameno % FPS) / FPS) * 1000000;
  return 0;
}

int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
  //tp->tv_sec = frameno / FPS;
  //tp->tv_nsec = ((double)(frameno % FPS) / FPS) * 1e9;
  return 0;
}

demo.cpp

#include
#include
#include
#include
#include

static int useRGB = 1;
static int useLighting = 1;
static int useFog = 0;
static int useDB = 1;
static int useLogo = 0;
static int useQuads = 1;

static int tick = -1;
static int moving = 1;

#define GREY 0
#define RED 1
#define GREEN 2
#define BLUE 3
#define CYAN 4
#define MAGENTA 5
#define YELLOW 6
#define BLACK 7

static float materialColor[8][4] =
{
  {0.8, 0.8, 0.8, 1.0},
  {0.8, 0.0, 0.0, 1.0},
  {0.0, 0.8, 0.0, 1.0},
  {0.0, 0.0, 0.8, 1.0},
  {0.0, 0.8, 0.8, 1.0},
  {0.8, 0.0, 0.8, 1.0},
  {0.8, 0.8, 0.0, 1.0},
  {0.0, 0.0, 0.0, 0.6},
};

static float lightPos[4] =
{2.0, 4.0, 2.0, 1.0};
#if 0
static float lightDir[4] =
{-2.0, -4.0, -2.0, 1.0};
#endif
static float lightAmb[4] =
{0.2, 0.2, 0.2, 1.0};
static float lightDiff[4] =
{0.8, 0.8, 0.8, 1.0};
static float lightSpec[4] =
{0.4, 0.4, 0.4, 1.0};

static float groundPlane[4] =
{0.0, 1.0, 0.0, 1.499};
static float backPlane[4] =
{0.0, 0.0, 1.0, 0.899};

static float fogColor[4] =
{0.0, 0.0, 0.0, 0.0};
static float fogIndex[1] =
{0.0};

static unsigned char shadowPattern[128] =
{
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,  /* 50% Grey */
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55
};

static unsigned char sgiPattern[128] =
{
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  /* SGI Logo */
  0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef,
  0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef,
  0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef,
  0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83,
  0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff,
  0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb,
  0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3,
  0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf,
  0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7,
  0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff,
  0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb,
  0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb,
  0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf,
  0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

static float cube_vertexes[6][4][4] =
{
  {
    {-1.0, -1.0, -1.0, 1.0},
    {-1.0, -1.0, 1.0, 1.0},
    {-1.0, 1.0, 1.0, 1.0},
    {-1.0, 1.0, -1.0, 1.0}},

  {
    {1.0, 1.0, 1.0, 1.0},
    {1.0, -1.0, 1.0, 1.0},
    {1.0, -1.0, -1.0, 1.0},
    {1.0, 1.0, -1.0, 1.0}},

  {
    {-1.0, -1.0, -1.0, 1.0},
    {1.0, -1.0, -1.0, 1.0},
    {1.0, -1.0, 1.0, 1.0},
    {-1.0, -1.0, 1.0, 1.0}},

  {
    {1.0, 1.0, 1.0, 1.0},
    {1.0, 1.0, -1.0, 1.0},
    {-1.0, 1.0, -1.0, 1.0},
    {-1.0, 1.0, 1.0, 1.0}},

  {
    {-1.0, -1.0, -1.0, 1.0},
    {-1.0, 1.0, -1.0, 1.0},
    {1.0, 1.0, -1.0, 1.0},
    {1.0, -1.0, -1.0, 1.0}},

  {
    {1.0, 1.0, 1.0, 1.0},
    {-1.0, 1.0, 1.0, 1.0},
    {-1.0, -1.0, 1.0, 1.0},
    {1.0, -1.0, 1.0, 1.0}}
};

static float cube_normals[6][4] =
{
  {-1.0, 0.0, 0.0, 0.0},
  {1.0, 0.0, 0.0, 0.0},
  {0.0, -1.0, 0.0, 0.0},
  {0.0, 1.0, 0.0, 0.0},
  {0.0, 0.0, -1.0, 0.0},
  {0.0, 0.0, 1.0, 0.0}
};

static void
usage(void)
{
  printf("\n");
  printf("usage: scube [options]\n");
  printf("\n");
  printf("    display a spinning cube and its shadow\n");
  printf("\n");
  printf("  Options:\n");
  printf("    -geometry  window size and location\n");
  printf("    -c         toggle color index mode\n");
  printf("    -l         toggle lighting\n");
  printf("    -f         toggle fog\n");
  printf("    -db        toggle double buffering\n");
  printf("    -logo      toggle sgi logo for the shadow pattern\n");
  printf("    -quads     toggle use of GL_QUADS to draw the checkerboard\n");
  printf("\n");
#ifndef EXIT_FAILURE    /* should be defined by ANSI C
                            */
#define EXIT_FAILURE 1
#endif
  exit(EXIT_FAILURE);
}

void
buildColormap(void)
{
  if (useRGB) {
    return;
  } else {
    int mapSize = 1 << glutGet(GLUT_WINDOW_BUFFER_SIZE);
    int rampSize = mapSize / 8;
    int entry;
    int i;

    for (entry = 0; entry < mapSize; ++entry) {
      int hue = entry / rampSize;
      GLfloat val = (entry % rampSize) * (1.0 / (rampSize - 1));
      GLfloat red, green, blue;

      red = (hue == 0 || hue == 1 || hue == 5 || hue == 6) ? val : 0;
      green = (hue == 0 || hue == 2 || hue == 4 || hue == 6) ? val : 0;
      blue = (hue == 0 || hue == 3 || hue == 4 || hue == 5) ? val : 0;

      glutSetColor(entry, red, green, blue);
    }

    for (i = 0; i < 8; ++i) {
      materialColor[i][0] = i * rampSize + 0.2 * (rampSize - 1);
      materialColor[i][1] = i * rampSize + 0.8 * (rampSize - 1);
      materialColor[i][2] = i * rampSize + 1.0 * (rampSize - 1);
      materialColor[i][3] = 0.0;
    }

    fogIndex[0] = -0.2 * (rampSize - 1);
  }
}

static void
setColor(int c)
{
  if (useLighting) {
    if (useRGB) {
      glMaterialfv(GL_FRONT_AND_BACK,
        GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]);
    } else {
      glMaterialfv(GL_FRONT_AND_BACK,
        GL_COLOR_INDEXES, &materialColor[c][0]);
    }
  } else {
    if (useRGB) {
      glColor4fv(&materialColor[c][0]);
    } else {
      glIndexf(materialColor[c][1]);
    }
  }
}

static void
drawCube(int color)
{
  int i;

  setColor(color);

  for (i = 0; i < 6; ++i) {
    glNormal3fv(&cube_normals[i][0]);
    glBegin(GL_POLYGON);
    glVertex4fv(&cube_vertexes[i][0][0]);
    glVertex4fv(&cube_vertexes[i][1][0]);
    glVertex4fv(&cube_vertexes[i][2][0]);
    glVertex4fv(&cube_vertexes[i][3][0]);
    glEnd();
  }
}

static void
drawCheck(int w, int h, int evenColor, int oddColor)
{
  static int initialized = 0;
  static int usedLighting = 0;
  static GLuint checklist = 0;

  if (!initialized || (usedLighting != useLighting)) {
    static float square_normal[4] =
    {0.0, 0.0, 1.0, 0.0};
    static float square[4][4];
    int i, j;

    if (!checklist) {
      checklist = glGenLists(1);
    }
    glNewList(checklist, GL_COMPILE_AND_EXECUTE);

    if (useQuads) {
      glNormal3fv(square_normal);
      glBegin(GL_QUADS);
    }
    for (j = 0; j < h; ++j) {
      for (i = 0; i < w; ++i) {
        square[0][0] = -1.0 + 2.0 / w * i;
        square[0][1] = -1.0 + 2.0 / h * (j + 1);
        square[0][2] = 0.0;
        square[0][3] = 1.0;

        square[1][0] = -1.0 + 2.0 / w * i;
        square[1][1] = -1.0 + 2.0 / h * j;
        square[1][2] = 0.0;
        square[1][3] = 1.0;

        square[2][0] = -1.0 + 2.0 / w * (i + 1);
        square[2][1] = -1.0 + 2.0 / h * j;
        square[2][2] = 0.0;
        square[2][3] = 1.0;

        square[3][0] = -1.0 + 2.0 / w * (i + 1);
        square[3][1] = -1.0 + 2.0 / h * (j + 1);
        square[3][2] = 0.0;
        square[3][3] = 1.0;

        if (i & 1 ^ j & 1) {
          setColor(oddColor);
        } else {
          setColor(evenColor);
        }

        if (!useQuads) {
          glBegin(GL_POLYGON);
        }
        glVertex4fv(&square[0][0]);
        glVertex4fv(&square[1][0]);
        glVertex4fv(&square[2][0]);
        glVertex4fv(&square[3][0]);
        if (!useQuads) {
          glEnd();
        }
      }
    }

    if (useQuads) {
      glEnd();
    }
    glEndList();

    initialized = 1;
    usedLighting = useLighting;
  } else {
    glCallList(checklist);
  }
}

static void
myShadowMatrix(float ground[4], float light[4])
{
  float dot;
  float shadowMat[4][4];

  dot = ground[0] * light[0] +
    ground[1] * light[1] +
    ground[2] * light[2] +
    ground[3] * light[3];

  shadowMat[0][0] = dot - light[0] * ground[0];
  shadowMat[1][0] = 0.0 - light[0] * ground[1];
  shadowMat[2][0] = 0.0 - light[0] * ground[2];
  shadowMat[3][0] = 0.0 - light[0] * ground[3];

  shadowMat[0][1] = 0.0 - light[1] * ground[0];
  shadowMat[1][1] = dot - light[1] * ground[1];
  shadowMat[2][1] = 0.0 - light[1] * ground[2];
  shadowMat[3][1] = 0.0 - light[1] * ground[3];

  shadowMat[0][2] = 0.0 - light[2] * ground[0];
  shadowMat[1][2] = 0.0 - light[2] * ground[1];
  shadowMat[2][2] = dot - light[2] * ground[2];
  shadowMat[3][2] = 0.0 - light[2] * ground[3];

  shadowMat[0][3] = 0.0 - light[3] * ground[0];
  shadowMat[1][3] = 0.0 - light[3] * ground[1];
  shadowMat[2][3] = 0.0 - light[3] * ground[2];
  shadowMat[3][3] = dot - light[3] * ground[3];

  glMultMatrixf((const GLfloat *) shadowMat);
}

static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)";
static char *windowNameRGB = "shadow cube (OpenGL RGB)";
static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)";
static char *windowNameIndex = "shadow cube (OpenGL Index)";

void
idle(void)
{
  tick++;
  if (tick >= 120) {
    tick = 0;
  }
  glutPostRedisplay();
}

/* ARGSUSED1 */
void
keyboard(unsigned char ch, int x, int y)
{
  switch (ch) {
  case 27:             /* escape */
    exit(0);
    break;
  case 'L':
  case 'l':
    useLighting = !useLighting;
    useLighting ? glEnable(GL_LIGHTING) :
      glDisable(GL_LIGHTING);
    glutPostRedisplay();
    break;
  case 'F':
  case 'f':
    useFog = !useFog;
    useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
    glutPostRedisplay();
    break;
  case '1':
    glFogf(GL_FOG_MODE, GL_LINEAR);
    glutPostRedisplay();
    break;
  case '2':
    glFogf(GL_FOG_MODE, GL_EXP);
    glutPostRedisplay();
    break;
  case '3':
    glFogf(GL_FOG_MODE, GL_EXP2);
    glutPostRedisplay();
    break;
  case ' ':
    if (!moving) {
      idle();
      glutPostRedisplay();
    }
  }
}

void
display(void)
{
  GLfloat cubeXform[4][4];

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();
  glTranslatef(0.0, -1.5, 0.0);
  glRotatef(-90.0, 1, 0, 0);
  glScalef(2.0, 2.0, 2.0);

  drawCheck(6, 6, BLUE, YELLOW);  /* draw ground */
  glPopMatrix();

  glPushMatrix();
  glTranslatef(0.0, 0.0, -0.9);
  glScalef(2.0, 2.0, 2.0);

  drawCheck(6, 6, BLUE, YELLOW);  /* draw back */
  glPopMatrix();

  glPushMatrix();
  glTranslatef(0.0, 0.2, 0.0);
  glScalef(0.3, 0.3, 0.3);
  glRotatef((360.0 / (30 * 1)) * tick, 1, 0, 0);
  glRotatef((360.0 / (30 * 2)) * tick, 0, 1, 0);
  glRotatef((360.0 / (30 * 4)) * tick, 0, 0, 1);
  glScalef(1.0, 2.0, 1.0);
  glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) cubeXform);

  drawCube(RED);        /* draw cube */
  glPopMatrix();

  glDepthMask(GL_FALSE);
  if (useRGB) {
    glEnable(GL_BLEND);
  } else {
    glEnable(GL_POLYGON_STIPPLE);
  }
  if (useFog) {
    glDisable(GL_FOG);
  }
  glPushMatrix();
  myShadowMatrix(groundPlane, lightPos);
  glTranslatef(0.0, 0.0, 2.0);
  glMultMatrixf((const GLfloat *) cubeXform);

  drawCube(BLACK);      /* draw ground shadow */
  glPopMatrix();

  glPushMatrix();
  myShadowMatrix(backPlane, lightPos);
  glTranslatef(0.0, 0.0, 2.0);
  glMultMatrixf((const GLfloat *) cubeXform);

  drawCube(BLACK);      /* draw back shadow */
  glPopMatrix();

  glDepthMask(GL_TRUE);
  if (useRGB) {
    glDisable(GL_BLEND);
  } else {
    glDisable(GL_POLYGON_STIPPLE);
  }
  if (useFog) {
    glEnable(GL_FOG);
  }
  if (useDB) {
    glutSwapBuffers();
  } else {
    glFlush();
  }
}

void
fog_select(int fog)
{
  glFogf(GL_FOG_MODE, fog);
  glutPostRedisplay();
}

void
menu_select(int mode)
{
  switch (mode) {
  case 1:
    moving = 1;
    glutIdleFunc(idle);
    break;
  case 2:
    moving = 0;
    glutIdleFunc(NULL);
    break;
  case 3:
    useFog = !useFog;
    useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
    glutPostRedisplay();
    break;
  case 4:
    useLighting = !useLighting;
    useLighting ? glEnable(GL_LIGHTING) :
      glDisable(GL_LIGHTING);
    glutPostRedisplay();
    break;
  case 5:
    exit(0);
    break;
  }
}

void
visible(int state)
{
  if (state == GLUT_VISIBLE) {
    if (moving)
      glutIdleFunc(idle);
  } else {
    if (moving)
      glutIdleFunc(NULL);
  }
}

int
main(int argc, char **argv)
{
  int width = 640, height = 480;
  int i;
  char *name;
  int fog_menu;

  glutInitWindowSize(width, height);
  glutInit(&argc, argv);
  /* process commmand line args */
  for (i = 1; i < argc; ++i) {
    if (!strcmp("-c", argv[i])) {
      useRGB = !useRGB;
    } else if (!strcmp("-l", argv[i])) {
      useLighting = !useLighting;
    } else if (!strcmp("-f", argv[i])) {
      useFog = !useFog;
    } else if (!strcmp("-db", argv[i])) {
      useDB = !useDB;
    } else if (!strcmp("-logo", argv[i])) {
      useLogo = !useLogo;
    } else if (!strcmp("-quads", argv[i])) {
      useQuads = !useQuads;
    } else {
      usage();
    }
  }

  /* choose visual */
  if (useRGB) {
    if (useDB) {
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
      name = windowNameRGBDB;
    } else {
      glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
      name = windowNameRGB;
    }
  } else {
    if (useDB) {
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH);
      name = windowNameIndexDB;
    } else {
      glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX | GLUT_DEPTH);
      name = windowNameIndex;
    }
  }

  glutCreateWindow(name);

  buildColormap();

  glutKeyboardFunc(keyboard);
  glutDisplayFunc(display);
  glutVisibilityFunc(visible);

  fog_menu = glutCreateMenu(fog_select);
  glutAddMenuEntry("Linear fog", GL_LINEAR);
  glutAddMenuEntry("Exp fog", GL_EXP);
  glutAddMenuEntry("Exp^2 fog", GL_EXP2);

  glutCreateMenu(menu_select);
  glutAddMenuEntry("Start motion", 1);
  glutAddMenuEntry("Stop motion", 2);
  glutAddMenuEntry("Toggle fog", 3);
  glutAddMenuEntry("Toggle lighting", 4);
  glutAddSubMenu("Fog type", fog_menu);
  glutAddMenuEntry("Quit", 5);
  glutAttachMenu(GLUT_RIGHT_BUTTON);

  /* setup context */
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(0.0, 0.0, -2.0);

  glEnable(GL_DEPTH_TEST);

  if (useLighting) {
    glEnable(GL_LIGHTING);
  }
  glEnable(GL_LIGHT0);
  glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
#if 0
  glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir);
  glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80);
  glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25);
#endif

  glEnable(GL_NORMALIZE);

  if (useFog) {
    glEnable(GL_FOG);
  }
  glFogfv(GL_FOG_COLOR, fogColor);
  glFogfv(GL_FOG_INDEX, fogIndex);
  glFogf(GL_FOG_MODE, GL_EXP);
  glFogf(GL_FOG_DENSITY, 0.5);
  glFogf(GL_FOG_START, 1.0);
  glFogf(GL_FOG_END, 3.0);

  glEnable(GL_CULL_FACE);
  glCullFace(GL_BACK);

  glShadeModel(GL_SMOOTH);

  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  if (useLogo) {
    glPolygonStipple((const GLubyte *) sgiPattern);
  } else {
    glPolygonStipple((const GLubyte *) shadowPattern);
  }

  glClearColor(0.0, 0.0, 0.0, 1);
  glClearIndex(0);
  glClearDepth(1);

  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}


Saturday, October 1, 2011

OpenCV Imajlarinin Boyutunu Degistirmek (Resize)

Eger OpenCV Resize cagrisi problem yaratiyorsa, bu islemi Python IPL icinden yapabiliriz. Ipl2PIL ile bir OpenCV video karesini PIL imajina cevirebiliyoruz. Bu imaj uzerinde resize(..) cagrisi yapilabilir. Hatta np.array(..) ile bu imaj Numpy dizinine de cevirilebilir. Boyle bir dizin elde edilince her turlu Uygulamali Matematik teknigi bu dizin uzerinde uygulanabilir. PIL imaji OpenCV'ye PIL2Ipl ile geri cevirilebilir.

Alttaki ornek bir kareyi ucte birine indirgiyor.
__scale__ = 3
frame = cvQueryFrame(capture)
gray = cvCreateImage ((frame.width, frame.height), 8, 1)
cvCvtColor( frame, gray, CV_BGR2GRAY )
ipl = Ipl2PIL(gray)
ipl = ipl.resize((int(frame.width/__scale__),int(frame.height/__scale__)),
Image.ANTIALIAS)
nimg = np.array(ipl)
..
ipl2 = PIL2Ipl(ipl)
..
cvShowImage("Example2", ipl2)

Piksel Takibi, Optik Akış (Optical Flow), Lucas Kanade

Monday, September 12, 2011

PDF Formlarin Uzerine Yazi Yazmak

Alttaki Python programi, biraz da Imagemagick yardimi ile bir PDF bazli formu otomatik olarak doldurma servisini sagliyor. PDF dokuman.pdf dosyasi isleniyor ve bu dosyanin 7. sayfasina bazi bilgiler eklenerek doldurulmus halde out7.jpg adli bir dosya yaratiliyor. Bu teknik basit bir ayar dosyasi ve biraz OCR yardimiyla herhangi bir PDF formunu doldurabilecek bir programa evrilebilir. Altta hem text hem de biraz imza jpg (signature.jpg) imajini belli noktalara koyuyoruz.

Ilk once ImageMagick convert cagrisi ile PDF dosyasini alip eger birden fazla sayfa varsa, o kadar jpg dosyasina ceviriyoruz. Not: convert islemi biraz zaman alir, ve sadece bir kez yapilmasi yeter zaten, script'in diger kisimlarini ardi ardina test ederken convert satiri sonraki isletimlerde iptal edilebilir.

Imza imajini koyarken, paste kullaniyoruz. Bir imaji digerinin icine yapistirirken paste cagrisina bir "kutu (box)" parametresi verilir, bu dort ogeli bir Python tupu (tuple), yani (100,100,200,200) gibi bir deger. Ornekte verilen degerler sol ust kosesi 100,100'de sag alt kosesi (200,200)'de olan bir kutuyu tarif ediyor.

Sonra, diyelim ki degistirilen dosya out7.jpg sadece, ama diger sayfalar hala oldugu gibi, yine ImageMagic convert kullanarak tum bu dosyalari degisen imaj ile beraber toparlayip tekrar bir PDF haline getirebiliriz.

convert Dokuman-1.jpg Dokuman-2.jpg ... out7.jpg Dokuman-8.jpg Yeni_Dokuman.pdf

gibi. Tek sayfa uzerinde degisim yapan script asagida.
import os, sys
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw

os.system("convert -density 200x200 -quality 60 ~/Desktop/Dokuman.pdf Dokuman.jpg")
img = Image.open("Dokuman-7.jpg")
sign = Image.open("signature.jpg")
x = 900
y = 1450
sizex = 350
sizey = 122
img.paste(sign, (x,y,x+sizex,y+sizey))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf",27)
draw.text((350, 1500), "Isim Soyad, Vesaire", font=font, fill='black')
img.save("out7.jpg")

Tuesday, September 6, 2011

Ikili PDF Sayfalari Tek Sayfali Yapmak (Ortadan Bolmek)

2 sayfa yanyana scan edilmis PDF dokumanlarini normal hale getirmek icin alttaki yontem kullanilabilir. Once pdfjam adli program lazim, apt-get bunu kurar. Ardindan

pdfjam -o cift.pdf --trim '14cm 0cm 0cm 0cm' --clip true --scale 1.0 dokuman.pdf
pdfjam -o tek.pdf --trim '0cm 0cm 14cm 0cm' --clip true --scale 1.0 dokuman.pdf
pdftk A=cift.pdf B=tek.pdf shuffle BE AE output final_dokuman.pdf

Bu komutlarin yaptigi su; biri sagdan bir soldan olmak uzere 14 cm'lik bolumu kesip atiyoruz (trim ve clip true), ve bu budanmis dokumanlardan birini tek sayili sayfalar, digerini cift sayili sayfalar olarak kaydediyoruz. Sonra bir pdftk taklasi atmak gerekiyor, bu komuta iki dokumani birlestirmesini soyluyoruz, ama tek sayfalari bir yerden, cift sayfalari baska bir yerden almasini soyluyoruz (shuffle B A secenegi, E ekini biz yaptik, E harfi dogu yonunde -east- cevirim, boylece BE AE oldu cunku bizim sayfalari bir de 90 derece saga cevirmek gerekti).

Thursday, September 1, 2011

Uygulamalı Matematik Kitapçığı ve Github

Ornek Python kodlariyla Uygulamali Matematik yazilarinin LaTex, png, vs. dosyalarinin tamami Github uzerinde.

Github

Monday, August 29, 2011

Ders Notlari ve Github

ODE, Lineer Cebir ve Hesapsal Bilim ders notlarinin tex, png, py dosyalari Github uzerindeki classnotes adli projede.

Github


Wednesday, August 24, 2011

Lokal Dosya Arama - recoll

Google Desktop yerel dosyalari indekslerken bazen hata yapiyor. Onun yerine daha yalin / basit bir sistemi denedik: recoll. Kurmak icin

sudo apt-get install recoll

Komutta recoll yazilinca GUI acilir. Preferences | Indexing configuration ile indekslenecek dizinler eklenebilir, cikartilabilir. Komut satirindan indeksleme icin recollindex cagrisi yeterli.

Lineer Optimizasyon, Simplex ve Berlin Hava Ikmali

Baglanti

Monday, August 15, 2011

Emacs Uzerinden Twitter

Emacs icinde Twitter kullanabilmek icin, once TwitteringMode kodlari indirilir.

http://github.com/hayamiz/twittering-mode/tree/master

Acildiktan sonra kodlarin [DIZIN] icinde oldugunu farzedelim, .emacs icinde

(add-to-list 'load-path "[DIZIN]")
(require 'twittering-mode)
(setq twittering-use-master-password t)

Emacs icinde M-x twit komutunu kullandiktan sonra Twitter mod'u acilacak. Ilk kullanimda eger Web uzerinden Twitter kullaniyorsaniz, ve sifreniz hep hatirlaniyorsa, OAuth uzerinden Emacs'ten erisim icin izin istenecek. Bu y ve n sorusuna y ile cevap verin, bundan sonra tarayici bir sayfayi acip o sayfada bir PIN kodu verecek. Bu kod Emacs'e girilirse, Emacs bir sifre soracak. Bu sifre artik Emacs uzerinden Twitter kullanma sifresidir. Her M-x twit sonrasi bu sifre sorulur.

Programa girince 'i' ile kisi ikonlari gosterilebilir. Yeni tweet icin 'u' kullanilir, mesaj girildikten sonra eklemek icin C-c C-c.

Kaynak

Thursday, August 11, 2011

Arastirmacilar Icin Bedava EC2

Su baglantiya gore edu alanindan bir email ve 4000 harflik bir tasari / teklif mesaji sonrasi $7500'lik bedava EC2 kullanim kredisi elde edilebiliyor, ve her 6 ay bu kredi yenilenebiliyor. Gunun 24 saatinde 4 cekirdekli bir islemci mi, 4 saatlige 100 cekirdekli islemci mi kullanmak istersiniz? GPU kullanimi mi istiyorsunuz? 16 cekirdek ve 60 GB RAM? 10 Gig-E ic network baglantili kumeler mi istersiniz? Bunlarin hepsi mumkun. Hatta ve hatta buyuk verili projeler icin hard diskleri postayla Amazon'a gondermek bile mumkun. Veriyi postadan alip onlar sisteme yukluyorlar.

Fiziksel Veri Transeri


EC2


Saturday, August 6, 2011

KineticsKit

VPython uzerine kurulu bir paket: KineticsKit. Bu paket kutleler ve yaylardan olusan sistemleri kurmayi iyice rahatlastiriyor, hatta kutlelerin uzerine mouse ile tiklanip hareket edilebilmelerine bile izin veriyor. Biz bu sistemi MIT OCW Hesapsal Bilim problemlerinden biri icin kullandik.

Iki ucu sabitlenmis du^2/dx^2 = 1 sisteminin ayriksal cozulmesi u(x) icin bir parabol ortaya cikartti (sistemin matematiksel detaylari MIT OCW Hesapsal Bilim Ders 1 sonunda). Bu parabol zincir halindeki bir kutle, yay sisteminde ortadaki kutlelerin daha fazla yer degistirmesi anlamina geliyordu. Bunun fiziksel olarak nasil gozukebilecegini gormek icin alttaki simulasyonu yaptik. Resmin sol tarafi once, sag tarafi yercekim etkisi sonrasi.

KineticsKit kurmak icin baglanti: http://kineticskit.sourceforge.net. Buradan zip indirilir, acilir ve

sudo mv  KineticsKit /usr/lib/python2.7/dist-packages/

ile gereken yere kopyalanir, setup.py secenegi vermemisler, yani kurulumu elle yapmak gerekiyor. Ustteki simulasyon icin

from KineticsKit import *
from visual import vector

system = System(timestep=0.04, gravity=1)

mass1 = Mass(m=0.1, pos=(0.0, 0.0, 0.0), fixed=1)
mass2 = Mass(m=0.1, pos=(0.0, 0.5, 0.0))
mass3 = Mass(m=0.1, pos=(0.0, 1.0, 0.0))
mass4 = Mass(m=0.1, pos=(0.0, 1.5, 0.0))
mass5 = Mass(m=0.1, pos=(0.0, 2.0, 0.0))
mass6 = Mass(m=0.1, pos=(0.0, 2.5, 0.0))
mass7 = Mass(m=0.1, pos=(0.0, 3.0, 0.0), fixed=1)

system.insertMass(mass1)
system.insertMass(mass2)
system.insertMass(mass3)
system.insertMass(mass4)
system.insertMass(mass5)
system.insertMass(mass6)
system.insertMass(mass7)

spring1 = SingleHelixSpring(m0=mass1, m1=mass2, k=1, damping=0.5)
system.insertSpring(spring1)
spring2 = SingleHelixSpring(m0=mass2, m1=mass3, k=1, damping=0.5)
system.insertSpring(spring2)
spring3 = SingleHelixSpring(m0=mass3, m1=mass4, k=1, damping=0.5)
system.insertSpring(spring3)
spring4 = SingleHelixSpring(m0=mass4, m1=mass5, k=1, damping=0.5)
system.insertSpring(spring4)
spring5 = SingleHelixSpring(m0=mass5, m1=mass6, k=1, damping=0.5)
system.insertSpring(spring5)
spring5 = SingleHelixSpring(m0=mass6, m1=mass7, k=1, damping=0.5)
system.insertSpring(spring5)

loc_1 = [mass2.sphere.pos.y, mass3.sphere.pos.y,
        mass4.sphere.pos.y, mass5.sphere.pos.y,
        mass6.sphere.pos.y]

count = 0

while 1:
   system.step()
   count += 1
   if count == 100: break
 
loc_2 = [mass2.sphere.pos.y, mass3.sphere.pos.y,
        mass4.sphere.pos.y, mass5.sphere.pos.y,
        mass6.sphere.pos.y]

from itertools import izip
for x,y in izip(loc_1, loc_2):
   print x-y
SingleHelixSpring yay cesitlerinden bir tanesi, bir sure sonra sistemin durmasini istiyorsak surtunme eklemek gerekli, damping=0.5 bunun icin verildi. System olustururken gravity secenegi verilmezse sistem baslangic halinde kalir, tabii kullanici mouse ile kutleleri cekip cevirirse sistem buna gore kendini duzenliyor.

Wednesday, August 3, 2011

Ubuntu ve Masaustu Goruntu, Video Kaydi

Ekranda olanlari, ozellikle belli bir pencerede olanlari, video olarak kaydetmek icin biz sunlari yaptik.

Kaydedilecek gorsel programi baslatin.

Sonra baska bir komut satirindan xwininfo programini baslatin. Bu program ok isaretini bir arti haline donusturecek, ve bu arti isareti hangi diger pencere uzerine getirilirse o pencerenin bilgileri dokulecek. Bizim ihtiyacimiz olan "Window id" satirinin ne soyledigi. Burada mesela 0x4200003 gibi bir sayi var. Bu sayiyi alin ve

recordmydesktop --windowid=0x4200003

olarak kayit islemini baslatin. Istediginiz kadar kaydedince Ctrl-C ile cikin, kaydedilen her sey out.ogv adli bir video dosyasina yazilacak. Eger recordmydesktop kurulu degilse, su sekilde kurulabilir.

sudo apt-get install recordmydesktop zenity

Eger ogv dosyasini animasyonlu gif formatina cevirmek istiyorsak, su komut yeterli

ffmpeg -i out.ogv -loop_output 0 -pix_fmt rgb24 -r 5 -s 250x250 output.gif

-loop_output gif'in ne kadar tekrar edilecegini kontrol eder, 0 degeri sonsuza kadar demektir. -r secenegi bir saniye icinde kac kare (frame) gosterilecegi.

Tek Goruntu

Eger masaustundeki goruntuyu tek imaj olarak (screenshot) almak istiyorsak, secenekler sunlar. PRTSC, yani print screen dugmesi kullanilabilir. Bu ise yaramazsa, ImageMagick kurulur (apt-get install imagemagick), ve komut satirinda su girilir:

import [dosya.png]

Bu komutun hemen arkasindan ekrandaki isaret (cursor) arti isaretine donusecek. Bu isaret ile hangi pencereye tiklanirsa onun goruntusu dosya.png icine yazilir.

Ya da Applications | Accessories | Take Screenshot programi baslatilir.

Tuesday, August 2, 2011

vpython

3 boyutlu animasyon, fiziksel objelerin modellenmesi icin bir paket: vpython. Fizik derslerinde egitim amaclari icin ideal. Paket fiziksel objelerin sanal olarak 3 boyutlu ortama konulmasi, onlarin diger objelere verecegi tepkilerin kodlanmasi icin ozellikler sunuyor.

Ubuntu 11 uzerinde kurmak icin

sudo apt-get install python-visual

Eger KineticKit eklemek istersek, suraya bakilabilir.

Orneklerden biri sabit ay ve dunya kosullarinda Apollo 13 uzay seferinin takip ettigi yolu simule etmek. Sonuc animasyonlu olarak gosterilecek. Kodlar alttaki baglantida.


VPython paketinden cikan bazi ornek kodlar surada. Cok objeli bir yayli sistemi canli olarak gosteren ilginc bir program crystal.py. Sonuc alttaki gibi (yuklenmesi biraz zaman alabilir). Bu animasyonu yapan kod 160 kusur satirlik bir koddan ibaret. Tum fiziksel kosullari tanimlanmis ve canli halde isliyor. Bu tur simulasyonlari yapmak cok daha fazla kodlama ve eskiden ozel bilgisayarlar gerektirirdi.



Kaynak

Monday, August 1, 2011

Git Tavsiyeleri

Kaynak Kod Idare Sistemi Git ile calisirken takip edilmesi tavsiye edilen bir is akisi (workflow) surada. Tavsiyeye gore dis dunyaya acik (public) bir dal (branch) olmali, bu dalin uzerindeki kod degisim notlari (commit history) olabildigince lineer, temiz olmali. Programci bir ozellik uzerinde calisiyorsa bunu kendine ozel, disa kapali (private) bir dal uzerinde yapar, o dala bol bol, istedigi kadar commit yapar, vs. Fakat -ve burasi onemli nokta- master dalina kod birlestirme (merge) yapmadan once bu kapali dalin degisim tarihini tekrar yazabilir. Gelistirme dallari bir nevi taslak olarak gorulmelidir, ve "disa yayin yapilmadan once" yani birlestirme operasyonundan once temizlenmelidirler. Pek cok kez yapilan birkac commit birlestirilip tek hale getirilebilir mesela. Bu temizlik isi icin kullanilabilecek bir rebase numarasi da gosterilmis.

Sunday, July 24, 2011

Scipy 2011

Austin Teksas'ta Scipy 2011 konferansi oldu, video'lar surada. Birkac tanesine goz attik, zaman serisi (time series) konusmasi fena degildi (sadece sondaki DLM ornegi Statsmodel ile alakali degil, baska bir paket, onun da kurulma problemleri var). Statsmodels kodunun Github'a gectigini ve artik versiyon 0.3'te olduklarini gorduk.

https://github.com/statsmodels/statsmodels

Bu yeni koda gore onu kullanan bizim

https://github.com/burakbayramli/gelman-arm-bda-python

projesinde bazi degisiklikler gerekti. En son kod commit edildi.

Thursday, July 14, 2011

Data Science Toolkit

Imajdan metin (text) cikarma (OCR) komutlari (ve pek cok diger kabiliyet) iceren bir paket: Data Science Toolkit. Kurmak icin siteden python_tools.zip indirilir. Unzip edip sudo ./install ile kurulur. OCR icin kullanilacak komut file2text komutu. Turkce karakter biraz problemli, fakat Ingilizce karakterleri iyi taniyor. Imajdaki harflerin buyuklugu, goruntunun netligi vs gibi isleri file2text kendisi hallediyor. Komut kullanimi basit, file2text [dosya]. Sonuc ekrana basiliyor.

Monday, July 4, 2011

Basit Rasgele Muzik Calici

Sabit diskinizde olan mp3'lerin rasgele calinmaya baslamasi icin bir Python script:
import glob, os, random, sys
import threading
import select

list = glob.glob("[MUZIK DIZINI]/*.mp3")
while True:
idx = int(random.random() * len(list))
print list[idx]
os.system("mplayer '%s'" % list[idx] )
print "Delete? (Press d for delete)..."
k=""
def input():
global k
i = 0
while i < 1:
i = i + 1
r,w,x = select.select([sys.stdin.fileno()],[],[],2)
if len(r) != 0:
k =sys.stdin.readline()

T = threading.Thread(target=input)
T.setDaemon(1)
T.start()
T.join(2) # wait for 2 seconds
print ">>>>>>>>>" + k
if k == 'd':
print "deleting " + list[idx]
cmd = "rm '%s'" % list[idx]
os.system(cmd)
Ubuntu uzerinde bu script'e bir kisayol koyduk, kisayolun komutu su sekilde
xterm -e "python /dizin/rasgele_cal.py"
Tiklayinca script icin ayri bir xterm acilacak. Muzik calarken Ctrl-C ile bir sonraki sarkiya gecilebilir (cunku os.system'den disari cikmis oluruz, dongu devam eder). Ses acmak *, azaltmak / (bunlar mplayer'in komutlari). Begenmediginiz sarkiyi diskten sildirmek icin "Delete?" diye sordugunda 'd' ve Enter'e basin.

Thursday, June 30, 2011

Kinect

Microsoft Xbox 360 ile beraber gelen algilayici Kinect, robotik ile ugrasanlarin oldukca ilgisini cekti. Kinect bilgisayar oyunlarini el hareketleri ile oynamayi mumkun kilan bir teknoloji, bunu oda icindeki kullanicinin ve aslinda her objenin gorsel, ses, hatta derinlik bilgisini hesaplayarak sagliyor. Bunun robotik ile ilgisi ne? Robotikte ayni anda etrafi haritalama ve olunan yeri hesaplama SLAM problemi olarak bilinir, SLAM icin etraftaki objelerin derinlik bilgisi gerekir.

Bu bilgi iki kamera uzerinden sadece gorsel imaj kullanilarak ve karsilastirmali olarak hesaplanabiliyor, fakat bu islem cok hesap gucu ister. Diger bir alternatif olan laser algilayicilari ise pahalidir. Kinect cok ucuz bir donanim uzerinden derinlik bilgisinin alinabilmesini sagliyor. Kinect'in iki kamerasindan bir tanesi etrafa infrared noktalari sacabiliyor ve o noktalarin buyuklugunu gorsel olarak olcerek o noktanin gosterdigi objenin uzaklik ve yer hesabini yapabiliyor. Robotik ile ugrasanlar ve kurcalamaya meraklilar hemen Kinect'i Xbox'dan cikartip bir robotun uzerine takmislar ve SLAM icin kullanmislar. Bir MIT'de, bir Almanya'da bir universitede bunu deneyenler oldu.

O'Reilly Answers


Wired

Monday, June 27, 2011

Web Sayfalarindan Gorunen Metni Kazimak (Scraping)

Bir web sayfasindaki Turkce, Ingilizce kelimeleri almak icin Python uzerinde Beautiful Soup adinda bir paket var. "Gorunen metin" derken bir sayfada okunabilir olan, HTML etiketleri haricindeki kelimeleri kastediyoruz, istatistiki analiz icin mesela herhangi bir gunun "kelime dagarcigini" cekip cikarmak icin boyle kodlar gerekebilir.
import re
import urllib
import BeautifulSoup

keywords = ['script', '<b>', '\n']

def visible(element):
if element.parent.name in ['style', 'script', '[document]', 'head', 'title']:
return False
elif re.match('<!--.*-->', str(element)):
return False
return True

def tokenize_site(url):
html = urllib.urlopen(url).read()
soup = BeautifulSoup.BeautifulSoup(html)
texts = soup.findAll(text=True)
visible_texts = filter(visible, texts)
tmp = []
for x in visible_texts:
if (x not in keywords): tmp.append(x)
res = []
for x in tmp:
for xx in x.split():
res.append(xx)
return res

if __name__ == "__main__":
res = tokenize_site('[MEDYA SITE ISMI]')

Monday, June 20, 2011

Ses Kayit, audiolab

Audiolab kurulusu surada. Python audiolab ile beyaz ses (white noise) yaratmak icin
import numpy as np
from scikits.audiolab import play
# output one second of stereo gaussian white noise at 48000 hz
data = np.random.randn(2, 480000)
play(0.001 * data)
Uc dakikalik bir beyaz ses toplamini dosyaya kaydetmek icin
from scikits.audiolab import Format, Sndfile
import numpy as np
filename = 'foo.wav'
data = 0.001 * np.random.randn(48000, 2)
format = Format('wav')
f = Sndfile(filename, 'w', format, 2, 48000)
for i in range(60*3):
f.write_frames(data)
f.close()
Audiolab ne yazik ki MP3 formatinda yazamiyor. Wav dosyalari komut satirindan cevirmek icin
sudo apt-get install shntool
sudo apt-get install lame

lame -V2 foo.wav foo.mp3

Thursday, June 16, 2011

App Arama Motoru

Yahoo mobil uygulamalar icin ozel bir arama motoru baslatmis. iPhone, Android secimini bir tab uzerinden yaptiktan sonra uygulama ismi, turu gibi anahtar kelimeler girerek arama yapabiliyorsunuz.

http://apps.search.yahoo.com/

Sunday, June 12, 2011

OpenCV ve Goruntu Kaydetmek

Ekrandaki goruntuyu MPEG formatinda kaydeden basit bir program. Keywords: python, record, opencv, capture, mpeg, video
from opencv import cv
from opencv import highgui

if __name__ == '__main__':

MPEG1VIDEO = 0x314D4950
highgui.cvNamedWindow ('Camera', highgui.CV_WINDOW_AUTOSIZE)
highgui.cvMoveWindow ('Camera', 10, 10)

capture = highgui.cvCreateCameraCapture (0)

frame = highgui.cvQueryFrame (capture)
frame_size = cv.cvGetSize (frame)
fps = 30
writer = highgui.cvCreateVideoWriter ("output.mpg", MPEG1VIDEO,
fps, frame_size, True)
if not writer:
print "Error opening writer"
sys.exit (1)

while 1:
frame = highgui.cvQueryFrame (capture)
if frame is None:
break
highgui.cvWriteFrame (writer, frame)
highgui.cvShowImage ('Camera', frame)
k = highgui.cvWaitKey (5)
if k % 0x100 == 27:
break

highgui.cvReleaseVideoWriter (writer)

Sol Tarafta Cikan Formuller, Paragraf Araligi

Latex ile calisirken formullerimizin ve yazimizin ortada degil tam sol tarafta, numarasiz, paragraf bosluksuz, araliginin cok az olmasini istiyorsak, sunlari kullaniriz:
\documentclass[12pt,fleqn]{article}
\usepackage{graphicx}
\setlength{\parindent}{0pt}
\setlength{\parskip}{8pt}
\setlength{\parsep}{0pt}
\setlength{\headsep}{0pt}
\setlength{\topskip}{0pt}
\setlength{\topmargin}{0pt}
\setlength{\topsep}{0pt}
\setlength{\partopsep}{0pt}
\setlength{\mathindent}{0cm}

\begin{document}
\[ y=x^2 \]
\end{document}
\[ ve \] isaretleri \begin{equation} ve \end{equation} komutlarinin numarasiz halidir.

Thursday, June 9, 2011

Emacs, Ubuntu, Yeni Font (Monaco)

Suradaki baglanti Monaco isminde bir fontun Emacs icin nasil kurulacagini anlatir. Ubuntu 11 uzerinde de isledi.

Font suradan alinir.

sudo mv Monaco_Linux.ttf /usr/share/fonts/truetype/custom

sudo fc-cache -f -v

echo “Emacs.font: Monaco-11″ > ~/.Xresources

xrdb -merge ~/.Xresources

Bundan sonra Monaco font isminin Emacs'te nasil kodlandigini gormek icin editoru baslatip *scratch* buffer'ina girin, ve alttaki komutu yazip, eval-buffer ile isletin.

(insert (prin1-to-string (x-list-fonts "*")))

Sonuc icinde "-unknown-Monaco-normal-normal...." turunde bir font tanimi gelecek. Bu ismi alip .emacs icinde

(set-default-font "-unknown-Monaco-normal-...")

olarak tanimlayinca Emacs'in hep kullandigi font haline getirebilirsiniz. Guzel bir font! Ozellikle Python kodunu guzel gosteriyor.

Wednesday, June 8, 2011

Ubuntu 11

Ubuntu 11 versiyonunu kurduk, bazi notlar:

11.10

Her Ubuntu surumunde masaustu biraz daha degisiyor. 11.04 ve 11.10 arasinda bazi farklar var, once 10'dan bahsedelim, sonra 04 okunabilir. Oncelikle kubuntu ortami 04'ten farkli, ve artik bizim kullanabilecegimiz bir halde degil. Onun yerine Gnome masaustu kullaniyoruz.

sudo apt-get install gnome-shell

Sonra Logout yapilir ve tekrar girmeden once tekerlek sembolune tiklanir, ve Gnome secilir.

Emacs ile Alt-Space cok kullaniyoruz, ama Gnome'da bu kapilmis, iptal etmek icin System Tools | System Settings | Keyboard. Oradan Keyboard, Shortcuts, Windows. Activate the window menu secenegi Alt-Space tanimlamis. Uzerine iki tiklayin, ve alakasiz baska bir tuslama tanimlayin (backspace ile disable etmek ise yaramiyor).

Sonra

sudo apt-get install gnome-tweak-tool
gnome-tweak-tool

Bu program ile cop sepeti, vs. gibi seyleri geri alabilirsiniz. "Have File Manager Handle Desktop" On yapilmali.

11.04

Bu versiyon kurulus sirasinda masaustu (desktop) secenegi sunmuyor. Kurulum bittikten sonra ilk yuklenen desktop, asiri buyuk dugmelerle, habire animasyon yapan Windows Vista'ya benzer acaip bir ortam. Buradan hemen kurtulmak icin soldaki program ikonlari (toolbar) icinde + isaretinden uygulamalara girilir, oradan "Ubuntu Software Center" bulunur, ve center icinde "kubuntu-desktop" yazilir. Bu paket Internet'ten indirilecek, ve kurulacak. Sonra classic desktop secerek basit, sade bir desktop ortamina kavusabilirsiniz.

Tex / Latex icin

tetex-.. paketleri degil alttaki kullanilmali

sudo apt-get install texlive

Ubuntu 11 Emacs 23'u destekliyor, apt-get ile 22 alinamiyor, apt-get ile 23 gelecek,

sudo apt-get install emacs

Emacs uzerindeki preview-latex programini tekrar kurarken sunlari kullandik

sudo apt-get install emacs-extra emacs-goodies-el preview-latex dvipng

.emacs icindeki tanimlar su hale geldi:

(custom-set-variables
..
'(preview-scale-function 1.2)
'(preview-image-type (quote dvipng))
..
)

Eger bunlara ragmen islemediyse, Auctex (preview-latex paketi artik bu isimde) paketini kaynak olarak indirin, ve configure, make, sudo make install ile kurun. .emacs icine (load "preview-latex.el" nil t t) yazin ve hersey guzelce islemeye baslayacak.

OpenCV 2.0

Ubuntu paketleri icinde OpenCV 2.1 icin destek var. Kurmak icin apt-get install python-opencv. Bu gerekli ek paketleri indirip kuracaktir. Eger webcam'e erisilemiyorsa, gstreamer-properties programindan WebCam ismini direk secmek gerekebilir.

Chat Ikonu

Sag ust kosede bir mektup zarfi ve balon sekillerinde gereksiz iki ikon var. Bunlar silmek uzerine tiklayarak mumkun olmadi. Suraya gore apt-get kullanmak lazim:

sudo apt-get remove indicator-me indicator-messages

Matplotlib

show() komutu en son kurulumda problem cikardi. Cizim yaptirilan arka plandaki motorun (backend) secilmesi gerekiyor. WX iyi bir secenek, kurmak icin

sudo apt-get install wxgtk2.8

Matplotlib'in bundan haberdar olmasi icin

sudo gedit /usr/local/lib/python2.7/dist-packages/matplotlib/mpl-data/matplotlibrc

Dosyada

backend : WXAgg

yazilmasi yeterli. Bu satir buyuk bir ihtimalle sadece Agg iceriyor olacakti.

Animasyonlar

Masaustunde pencere acma, kapama hareketlerinin animasyon yapmasini durdurmak istiyorsak

sudo apt-get install compizconfig-settings-manager

Sonra menuden System | Settings | Compbiz Settings Manager secilir ve "Effects" bolumunde Effects icin secim kutusu iptal edilir.

Tor

sudo apt-get install tor tor-geoipdb
sudo apt-get install privoxy

ile kurulur. Privoxy ayari icin sudo gedit /etc/privoxy/config ile dosyayi edit edin, ve icerik olarak

forward-socks4a / localhost:9050 .

Firefox 4 uzerinde TorButton icin https://www.torproject.org/torbutton/

Install Alpha baglantisindan xpi dosyasi isletilebilir. YouTube video'larini ve flash icerik gorebilmek icin eklenti kurulduktan sonra Firefox sol ustte Tor statusunu gosteren bir isaret cikacak. Bu isaret uzerinde mouse sag dugme click yaparak "preferences" secenegine girin. Security Preferences tab'inden "disable plugins during Tor usage" secenegini de-aktive edin.

Simdi kirmizi xarpi isareti uzerine tiklayin, bu isaret yesile donusecek. Bu kadar. Artik istediginiz siteye baglanabilirsiniz.

Alt-Tab

Masaustu uzerinde klavye kisayolu kullanarak programlar arasinda gecis yapmak, Ubuntu 11 olagan ayarlarinda ayvayi yemis. Genelde en son kullanilan ilk geri gelir kurali islemiyor. Duzeltmek icin Sytem | Preferences | CompizConfig Settings Manager uzerinde Window Management secilir ve Static Application Switcher yerine Application Manager secilir.

Ses Efektleri

Eger konsol icine mesela gidilemeyecek durumda bile backspace yapilinca cikan bip, tan, tun seslerini kapatmak istiyorsak System Tools | System Settings, oradan Sound ve Sound Effects. Bir ses kontrol ayari var, onun yaninda Mute secilirse artik uyarici sesleri cikmaz.

Sifre

Eger kullanicinizin sifresini kisa yapmak isterseniz, passwd uzerinden gireceginiz sifre Ubuntu tarafindan begenilmeyebilir (kisa, cetrefil olmayan sifreyi guvensiz buluyor). Ama illa ki kisa / basit bir sifre vermek isterseniz, o zaman "sudo passwd [kullanici isminiz]" ile istediginiz sifreyi verebilirsiniz. Kendiniz super kullanici olmaniza ragmen sudo uzerinden tekrar kendi kullanicinizi referans etmeniz garip olabilir, ama kisa sifre bu sekilde memnun oluyor.

Thursday, May 5, 2011

GAE ve Facebook Connect

GAE uygulamamizdan Facebook Connect iliskisini nasil kurariz? Java baglaminda bu konudan bahsettigimizde xd_receiver.htm sayfasini gormustuk. Bu dosya sitenin ana dizininde olmaliydi. GAE baglaminda bu sayfa nasil erisilir hale getirilir? Bu statik dosyayi GAE Python'a tanitmak icin app.yaml icinde
- url: /xd_receiver.htm
static_files: xd_receiver.htm
upload: xd_receiver.htm
tanimini yapmak lazim. Dosyanin icerigi degismiyor. Facebook sitesinden kullaniciniza ait gelistirme sayfasinda uygulamamizi tanitmis olmamiz lazim. Admin sayfasi surada:

http://www.facebook.com/developers/apps.php

Facebook Connect testini yapabilmek icin, mesela bizim pocketbudda.appspot.com adresini "yerele" yonlendiriyoruz, onun icin Ubuntu uzerinden /etc/hosts icinde

127.0.0.1 pocketbudda.appspot.com

tanimini yaptik (bu bir numara). Bu numara lazim cunku Facebook Uygulama konsolunda sitemizin gercek URL'ini kayit ettik, ve bu uygulama uzerinden localhost'ta test yapmak istiyorsak, 127.0.0.1 (yerel makinayi) sanki sitenin adresiymis gibi gostermemiz lazim, boylece tarayici uzerinde calisan Facebook Connect Javascript kodlari gercek site ile iletisimde olduklarini zannedecekler.

Bu tanimi yapinca da GAE uygulamamiz yerel makinada port 80 uzerinden calismali, cunku site isminde port tanimi yok. Bu degisimi yapinca bir problem daha cikiyor, duz dev_appserver.py isletmek port 80'e erisemez, belli port sayisi altindakiler Unix tarafindan korunurlar, o zaman gelistirme servisine root haklari vermek lazim. Onu halletmek icin de gelistirme servisini su sekilde baslatmali:

sudo python dev_appserver.py ~/kod/pocketbudda/app --port=80 --debug

En basit HTML kodu surada:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<title>FQL Friend Demo</title>
</head>
<body>

<h1>
FQL Friend Demo
</h1>

<fb:login-button/>

<script
src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"
type="text/javascript"></script>

<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function()
{
FB.Facebook.init("[APP ID BURAYA]", "xd_receiver.htm");
FB.Facebook.get_sessionState().waitUntilReady(function()
{
var uid = FB.Facebook.apiClient.get_session().uid ;
var sql = "SELECT name, birthday FROM user WHERE uid IN " +
"(SELECT uid2 FROM friend WHERE uid1 = "+uid+")";
FB.Facebook.apiClient.fql_query(sql, function(result, ex) {
var userName= result[0]['name'];
alert(userName);
var bday = result[1]['birthday'];
alert(bday);
});
});
});
</script>

</body>
</html>
Bu sayfaya site ismini kullanip baglaninca kod arkadas listesine bakip ilk arkadasin dogum tarihini gosterecek.

Thursday, April 14, 2011

Sosyal Kodlama = Github

Twitter, Facebook gibi sitelerin etkisiyle yeni Web uygulamalarindan artik "sosyal ozellikler" bulundurmasi bekleniyor. Sirketler yazdiklari uygulamalara "sosyal icerik" eklemek istiyorlar. Github bu akima dahil ve programcilar icin sosyal kaynak kod kontrolu olarak nitelenebilecek bir noktada.

Sosyal ozellikler, kod idaresi ve acik yazilim dunyasi icin aslinda bicilmis kaftan. Yazilimi acanlar baskalarinin takip etmesi icin kodlarini aciyorlar. Yani kod idaresini "sosyal" hale getiren bir site camianin ruhuna tamamen uygun.

Ek olarak Github'in temelinde kod idare sistemi Git var. Git'den daha once bahsettik; Linus Torvalds tarafindan yazilmistir, ve CVS, ClearCase (allah korusun) PVCS gibi sistemlerden bir adim otesini temsil etmektedir. Bu alanda Bazaar, Mercurial gibi sistemler de var.

Github'a donelim: site sosyal ozellikleri otesinde kullanim, gorsel acisindan da daha sukseli, ve rahat bir havada. Sourceforge artik daha kaba / agir (clunky) bir hale dustu. Biz bu siteyi kullanmiyoruz. Git yapisinin kuvvetleri dogal olarak Github'a yansiyor. Git ile calisirken bir projeyi "klonlarsiniz" ve bir anlamda kendi ozel kod deponuza sahip olursunuz. Bu klonlama islemi Github altinda tek bir dugme tiklamasi ile gerceklesiyor. Bunun ustune Twitter'vari "izleme (watch)" operasyonu var; Kendi sayfaniza girdiginizde "izlediginiz" acik yazilim projelerinin yaptiklari commit operasyonlarini mesaj olarak goruyorsunuz. Sizden klonlama yapan bir kisi sizden "birlestirme istegi" talep edebiliyor, yine tek bir tiklama ile, vs.

Github her turlu Git operasyonunu destekler, eger ssh id_rsa.pub gibi acik anahtarinizi Admin secenekleri uzerinden hesabiniza eklerseniz, git push yaparken sifre bile sorulmayacaktir. Not: Bunun islemesi icin depoyu bastan https uzerinden degil git@github diye baslayan adresten klonlamis olmaniz gerekir.

$.getJSON Hata Durumlari

Javascript kodu icinde eger servis tarafina soyle bir $.getJSON Ajax cagrisi yaptik diyelim:
$.getJSON('/bizim/url', {'param1': param1},
function(data){
...
});
Eger bu fonksiyon normal sekilde geri donerse isleyis "function(data)" icine dusecektir. Ama hata dondururse ne yapariz? O zaman finally mantigina benzer bir kullanim gerekli:
$.getJSON('/bizim/url', {'param1': param1},
function(data){
...
}).complete(function() { /* temizlik islemleri */ });
Dikkat: Ajax cagrilari yaparken, cagri dondukten sonra hemen bir sonraki Javascript kodunun "sirasiyla" isleyecegini farz etmeyelim. Ajax asenkron olarak isler, ve cagri sonrasi, cagri geri donmeden bile, bir sonraki Javascript kodu isleme konabilir.

jQuery ve Radyo Dugme Gruplari

Radyo dugmeleri icinden sadece biri isaretlenebilecek secenekler icin kullanilir. Fakat ayni sayfa uzerinde birden fazla grup istersek, mesela secmeli bir sinav sayfasi icin diyelim, o zaman radyo dugme gruplari kullaniriz. HTML ile:
<div>
..
<p>
<input type="radio" name="group0" value="1"/>
<input type="radio" name="group0" value="2"/>
<input type="radio" name="group0" value="3"/>
</p>
</div>

<div>
...
<p>
<input type="radio" name="group1" value="1"/>
<input type="radio" name="group1" value="2"/>
<input type="radio" name="group1" value="3"/>
</p>
</div>
Gruplari birbirinden ayirmak icin "name" icin her grupta degisik olacak bir isim vermek yeterli.

Peki jQuery ile bu secenekleri nasil okuruz? Soyle:
for (var i=0;i<[GRUP SAYISI];i++){
res = $("input[name='group"+i+"']:checked").val();
...
}
Dongu icinde tum gruplar gezilecek, ve her grubun secilmis dugmesinin degeri "res" icine atanacak.

Deger atamasi nasil yapilir?
$('input[name=group1]:eq(2)').attr('checked', 'checked');
Bu kodla 'group1' dugme grubunde '2' no'lu dugmeyi seciyoruz.

Monday, April 4, 2011

Sympy

Python'da sembolik matematik, cebirsel manipulasyon gibi pek cok yararli islem icin bir paket: Sympy. Kurmak icin suradan paket indirilir, ve klasik sekilde kurulur.

Basit bir test icin x**2 (x kare 2) fonksiyonunun turevini alalim:
from sympy import *

x = Symbol('x')
f = x**2
pprint (diff(f, x))
Sonuc beklenecegi sekilde 2x gelecektir. Turev almak diff komutu uzerinden, hangi degiskene gore turev alinacagi bu fonksiyona ikinci parametre ile bildiriliyor. pprint, "pretty print"'ten geliyor ve "guzel baski" demek, text ortaminda olabildigince "grafikimsi" bir baski yap anlaminda. 2x gibi ufak bir formulde pek fark gorulmeyebilir, ama daha cetrefil formullerde guzel baski farkini gosterecektir (altta gorulecegi gibi).

Daha sofistike bir ornek icin Isi Denklemini kullanalim. Bu denklem bir kismi diferansiyel (partial differential equation) denklemidir.


Bu denklemin cozumlerinden biri altta verilmistir (kismi diferansiyel denklemlerde cozum bir foksiyon bulmak demektir, ve birden fazla fonksiyon cozum olabilir)


Peki bu son denklemin Isi Denklemi icin cozum olup olmadigini kontrol etmek istesek ne yapardik? Ustteki u(t,x) formulunun bir t'ye gore kismi turevini (isi denkleminin sol tarafi), sonra x'e gore iki kez parcali turevini alip (isi denkleminin sag tarafi) sonuclarin birbiriyle esit olup olmadigina bakabiliriz. u(t,x) turevlerini manuel olarak ta yapabiliriz, ama biz ornek olmasi icin Sympy kullanalim.
from sympy import *
x = Symbol('x')
t = Symbol('t')
u = (exp((-x**2)/(4*t)) / 2*sqrt(pi*t))
pprint (diff(u, t))
pprint (diff(diff(u, x),x))
Sonuc olarak
        2               2
-x -x
─── ───
⎽⎽⎽ 4⋅t ⎽⎽⎽ 2 4⋅t
╲╱ π ⋅ℯ ╲╱ π ⋅x ⋅ℯ
────────── + ─────────────
⎽⎽⎽ 3/2
4⋅╲╱ t 8⋅t

formulunun iki kere arka arkaya basildigini gorecegiz, yani formulun iki tarafi birbirine esit cikiyor. Demek ki u(t,x) hakikaten bir cozumdur.

Entegrasyon
from sympy import *

x = Symbol('x')
q = Symbol('q')
I = Symbol('I')
f = 1/(I*x-q)
pprint (integrate(f, x))
Bu ornekte q,I sabit degerlerdi, onlari da sembol olarak tanimladik. Sonuc:
log(I⋅x - q)
────────────
I

Friday, March 18, 2011

Liste Gezerken Eleman Silmek

Python ile bir listeyi gezdigimiz anda gezdigimiz listeden eleman silersek, gezme islemi negatif sekilde etkilenmis olacaktir. Mesela soyle bir kod dusunelim:
list = [["1","1"], ["2","2"]]

for item in list:
print item
if ["1","1"] in list: list.remove(["1","1"])
Bu kod sadece ['1', '1'] sonucunu basacaktir, cunku gezme sirasinda bir eleman (['1', '1']) silinmistir, ve bu listeyi kucultmustur.

Eger silme isleminin gezme islemini etkilememesini istiyorsak, o zaman listenin bir "kopyasi" uzerinde gezinti yapmamiz lazim. Python'da kopya cikartmak icin clone, copy gibi cagrilar yerine bir operator kullaniliyor; bu operator [:] operatoru. O zaman:
list = [["1","1"], ["2","2"]]

for item in list[:]:
print item
if ["1","1"] in list: list.remove(["1","1"])
istedigimiz sonucu verecektir.

Friday, March 11, 2011

USGS Deprem Verileri - pyearthquake

Bu Python paketi ile USGS sitesine baglanarak istenen zaman araligindaki deprem verilerini almak, onlari bir harita uzerinde basmak mumkun oluyor. Daha once blog'da paylastigimiz deprem Python kodu statik, tek bir veri dosyasi icinde, pyearthquake ile en son verileri, istenen detayda almak mumkun.

Suradaki yazida guzel bilgiler var. Kurmak icin PyPi paketini indirin. Derlemeden once basemap paketini de indirin. Basemap acildiginda geos-... alt dizinine girin, ve ./configure, make, sudo make install ile bu paketi kurun, sonra bir uste cikip basemap python setup.py install yapin. Sonra ayni komutu pyearthquake icin yapabilirsiniz.

Ornek kod:
from pyearthquake import *
catalog = usgs.retrieve_catalog("M1+PAST_7DAY")
print len(catalog)
mag6_list = [event for event in catalog if float(event["Magnitude"]) >= 6.0]
print len(mag6_list)
for row in mag6_list:
print row["Eqid"], row["Magnitude"], row["Depth"],
row["Datetime"], row["Depth"], row["Region"]
usgs.plot_events(catalog)
Bu kod en son 7 gunluk, sonra Richter olceginde 6.0'dan buyuk deprem verileri alacaktir, ve sonuncu verileri bir haritada basacaktir. Istediginiz noktalara zoom yapmak icin zoom ikonuna tiklayip istenen bolgeyi haritada bir dikdortgen icine aldiginiz zaman o bolgenin detaylari gorulecektir. Ustte paylastigimiz yazida bunun Japonya icin yapildigini goruyoruz.

Saturday, March 5, 2011

String Birlestirmek

Python ile String parcalarini biraraya getirmenin birkac yolu var. Bunlardan en basiti ve ilk akla geleni + isaretini kullanmaktir:

s = "aaa" + "-" + "bbb" + "-" + "ccc"
print s

Sonuc aaa-bbb-ccc olacak. Diger bir yontem yerine gecen String (subsitution) yontemi. Bu yontem aslinda C/++ dilinde bilinen sprintf mantigina benziyor. Format belirleyen bir kisim var, bir de formatin tanimladigi yerlere yeni degerler parametre olarak gecilen degerler var, ve bu degerler ile yeni bir String olusturuluyor. Ornek:

s = "%s-%s-%s" % ("aaa","bbb","ccc")

s ekrana basildiginda ilk ornekle ayni sonucu gorecegiz. Bu kullanimin birkac avantaji var, String tipini temsil eden %s yerine diger tipler de kullanilabilir, mesela float'lari temsil eden %f. O zaman hem String birlestirme hem de tiplere gore formatlama ayni anda yapilabilecektir. Ornek:

s = "Burada bir float deger var: %f" % (3.43455)

Bu ornekte 3.43455 degeri %f yerine koyulmus olacak ve ekrana

Burada bir float deger var: 3.434550

basilacak. %f daha sofistike sekilde de kullanilabilir. Mesela:

s = "Burada bir float deger var: %3.2f" % (3.43455)

Bu formatlamaya gore float degerini noktadan sonra sadece 2 basamak olacak sekilde ayarladik. O zaman sonuc:

Burada bir float deger var: 3.43

olacaktir.

Monday, February 28, 2011

meshgrid

Bu fonksiyon 2 kordinat vektoru alir ve geriye 2 kordinat matrisi dondurur. Diyelim ki 3 boyutlu bir fonksiyon hesaplatacagiz, fonksiyon alani ise x kordinati -5 ve 5 arasinda, y kordinati -3, 3 arasinda olacak. O zaman bu araliktaki her noktanin kombinasyonu bize lazim. Bu kombinasyon [-5,-3], [5.1,-3],..,[-5,-3.1] diye gidecekti.

meshgrid fonksiyonunun yaptigi bu kombinasyonu rahat erisilir hale getirmekten ibaret. meshgrid cagrisindan geri gelecek X ve Y matrislerinde X[1] ve Y[1]'e baktigimizda (her iki tarafta ayni indisi kullandigimizda yani) kombinasyonlardan birini aninda alabilecegiz. Ornek
x = np.arange(-5, 5, 0.1)
y = np.arange(-3, 3, 0.1)
xx, yy = np.meshgrid(x, y)
z = np.sin(xx**2+yy**2)/(xx**2+yy**2)
Not: Bu kodda meshgrid'den gelen xx ve yy uzerinde direk indis kullaniliyormus gibi gozukmuyor, fakat arka planda aslinda kullaniliyor. xx ile yy uzerinde aritmetik islemler kullanilinca, bu otomatik olarak her xx ve yy elemanin teker teker, ayni indiste olanlarinin beraber isleme sokulmasi demektir, +, -, ** gibi islemler perde arkasinda buna gore kodlanmistir.

Kaynak

Sunday, February 27, 2011

Operatorler

Bir class tipi uzerinde islemesini istedigimiz operatorler icin o tipin class'i icindeki "ozel" fonksiyon isimlerini kullanmamiz gerekir. Mesela X adli bir tip icin kucuktur isaretini tanimlamak isteseydik, __lt__ fonksiyonunu tanimlamamiz gerekirdi. Ornek:
class X:
def __init__(self, x):
self.x = x
def __lt__(self, other):
if (other < self.x):
return True
return False

xx = X(10)
yy = X(20)

if (xx < yy): print "kucuk"
if (xx > yy): print "degil"

Esnek Parametre Listesi

Bir fonksiyona gecilecek parametre listesi onceden belli degilse, yildiz isareti, mesela *liste gibi bir kullanimla parametre listesi esnek hale getirilebilir. Mesela gecilen parametreleri sadece ekrana basan bir fonksiyon yazsak:
def f(*list):
for x in list:
print x
Fonksiyon f()'de gecilen parametreler esnek olarak tanimlanmis. Bu fonksiyonu cagirmak icin
f(3,4,5,6)  
ya da
f(3,4)  
kullanilabilir.

imap

Python itertools paketinden bir fonksiyon daha: imap. Bu yardimci cagri adindan anlasilabilecegi uzere "eslestirme" yapar. Iki veya daha fazla parametre alir, birinci parametre her zaman cagirilacak bir fonksiyon F olacaktir (evet fonksiyona parametre olarak fonksiyon geciyoruz), geri kalan parametreler icinde F'e verilecek olan parametrelerin listesi oluyor. Mesela pow cagrisini dusunelim, bu cagri iki parametre alir, pow(2,2) mesela 2 uzeri 2 hesabini yapar, 2^2 = 4. Diyelim ki bunun gibi pek cok sayi var elimizde, ustu alinacak sayilar bir listede, ust degerleri baska bir listede duruyor. imap ile bu isi soyle hallederiz:
from itertools import imap

aa = [2,3,4]
bb = [2,4,6]

for x in imap(pow, aa, bb):
print x
Bu cagri 2^2, 3^4, 4^6 hesaplarini sirasiyla yapar ve sonuclarin "gezilebilir" hale getirilmesini saglar (imap kodlamasinda yield kullanimi var yani).

Fonksiyon Gezmek ve Yield

Bir vektörün, listenin elemanlarını gezebildiğimizi (iteratation) biliyoruz.

Python'un üretici (generatörs) özelliği ile bir fonksiyonu gezmek te mümkün.

Bu nasıl oluyor? Hokus pokus yield adı verilen bir komutta.

Bir fonksiyon return çağrısı ile bir değer döndürebilir. Fakat o noktada o fonksiyondan dışarı çıkmış oluruz yani o fonksiyon ile işimiz biter. Kıyasla yield ile bir değer döndürürüz, geriye bir sonuç gelir ama fonksiyonun yield anındaki hali dondurulur -- yani unutulmaz. Fonksiyondan dışarı çıkmış olsak bile geri dönebiliriz, ve lokal değişkenleri oldukları halde kullanmaya devam edebiliriz: Alttaki fonksiyona bakalım:

def fib():
a, b = 0, 1
while 1:
  yield b
  a, b = b, a+b

Bu fonksiyon Fibonaccı sayılarını üretir, Fibonaccı sayıları 1,1,2,3 diye gider, bir sonraki sayı her zaman önceki iki sayının toplamıdır. Görüldüğü gibi yield ile en son toplamı donduruyoruz, fonksiyondan çıkıyoruz, fakat gezme işlemi bir sonraki değeri istediğinde fib()'e geri dönülüyor ve işlem yield'den bir sonraki satırdan, yani kaldığı yerden devam ediyor. Fonksiyon içindeki tüm lokal değişkenler hala değerlerini koruyorlar.

Kullanmak için fib() çağrısını sanki bir listeymiş gibi çağırabiliriz:

for x in fib(): print x

Yukarıda anlatılan türden değer gezme olanağının faydası nedir? Kod düzenlemesi açısından getirdiği faydalar ötesinde (temizlik gibi, geçici bir liste objesine gerek yok), performans bakımından faydası olabilir. Bir şekilde hesaplanan ve üretilen elemanları gezmek için onların önceden bir listeye doldurulmuş olması gerekmiyor -- her eleman fonksiyon tarafından "gerektiği anda" hesaplanıp teker teker alınıyor, ve bu bir tür "tembel (lazy)" hesaplama olarak görülebilir. CPU bedelini her Fibonaccı sayısını üretirken sadece o sayı için ödüyoruz. 10 tane önceden üretip bir yerde bekletmiyoruz.

Üreticilerin ne kadar kuvvetli özelliklerinin olduğunu tekrar belirtmek iyi olur: içinde yield içeren bir fonksiyonu aslında bir bakıma konumu olan bir obje gibi bile düşünebiliriz, daha doğrusu onlar bir bakıma "konumlu fonksiyonlar" oluyorlar. Mesela azar azar işlem yapan ortamlarda tipik bir ihtiyaç bir dosyanın açılması, ve o dosyadan azar azar satır alınabilmesi.

Üretici yaklaşımı ile bu iş şöyle yapılır, in.csv dosyası şöyle olsun

y,x1,x2
1,6,10
2,5,20
3,4,30
4,3,40
5,2,50

Kod

import csv
def get_row(cols):
    with open("in.csv", 'r') as csvfile:
        rd = csv.reader(csvfile)
        headers = {k: v for v, k in enumerate(next(rd))}
        for row in rd:
            label = float(row[headers['y']])
            # sadece istenen kolonlari al
            rrow = [row[headers[x]] for x in headers if x in cols]
            yield rrow, label

Bu akıllı fonksiyon aynen bir class gibi yaratılıyor, sonra çağrılıyor. Mesela ilgilendiğimiz belli bir kolon listesini verip geziciyi oluşturabiliriz, sonra ondan bir satır isteyebiliriz,

getter = get_row(['x1','x2'])
Y,x = getter.next() 
print Y,x

Şu sonucu görürüz,

['10', '6'] 1.0

Şu anda fonksiyon bekler durumda. Biz başka çağrılar yapabiliriz, gidip kahve içebiliriz, geri geldiğimizde

Y,x = getter.next() 
print Y,x
Y,x = getter.next() 
print Y,x

çağrıları bize iki yeni satır verir. 

['20', '5'] 2.0
['30', '4'] 3.0

Elimizdeki fonksiyon göstergecini başka birini versek o next() çağırsa o da aynı yerden devam ederdi. Ama biz tekrar başa dönmek istiyoruz, problem değil, yeni bir gezici fonksiyon yaratırız, 

getter = get_row(['x1','x2'])
Y,x = getter.next() 
print Y,x

['10', '6'] 1.0

Başa dönmüş olduk.

Üreticilerin gezme işlemini başlatmadan önce bazı hazırlık işleri, atamaları yapmaları en önemli özelliklerinden. Aynen bir obje başlatıldığında onun kurucusunda başlangıç kodları işletilebildiği gibi, ilk yield anına kadar işletilen her şey bir fonksiyonda hazırlık aşaması sayılabilir, ondan sonra bir döngüye girilip daha az mıktarda kod sürekli işlenip yield ile dönülecektir. Üstteki örnekte dosyanın açılması, başlık kolonların okunması, vs gibi işlemlerin hepsi bu başlangıç aşamasında. Bir gezici fonksiyonu ismiyle ve istenen parametreleri ile yarattığımız zaman bu hazırlık kodları işleyecek. 

Kaynaklar

http://www.python.org/dev/peps/pep-0255/