Python ve Selenium Denemeleri

Selenium ile karşılaşmışken, nasıl kullanılır diye biraz kurcalamak istedim. Yaptığım aşamaları, aldığım sonuçları falan da ufaktan paylaşayım dedim.

Selenium, WebDriverları kullanarak farklı tarayıcılarda, sürekli tekrar ettiğimiz testleri otomatikleştiren, sonuçlarını kontrol eden ve günün sonunda hem bizi tekrar tekrar aynı testleri yapmaktan kurtaran hem de sürekli yaparken gözümüzden kaçabilecek noktaları engelleyen yapısıyla öne çıkıyor.

Continue reading

Creating Local CentOS Repository

In many Linux distros, package management tools are utilized for getting new packages and their dependencies. They are also used for  In environments that has many boxes, updating packages and installing new packages may lead tremendous bandwidth consumption. In order to avoid this, it is possible to create a local CentOS Repository and add it all the machines. By using this ability, all other machines can get packages locally, means without consuming any bandwidth from outside Internet connection.

Since traffic inside a network for a limited time for updates does not lead to a problem for many local networks, it results in a observable gain in bandwidth usage of Internet connection. Especially, when local network and number of boxes getting bigger, the ratio is becoming more and more profitable. Continue reading

Python, Dict, Hash ve Doğum Günü Problemi

Python’da yer alan dictionary, yani Türkçe’ye çevrilen haliyle sözlüklerle uğraştıysanız, yeni başladığınızda şöyle bir hata almış olmanız oldukça muhtemel:
Bu hatayı biraz araştırdıysanız da, bu veri türünde(sözlüklerde) anahtar olarak listelerin ve bazı farklı veri türlerinin kullanılamayacağına denk gelmişsinizdir.
Eğer böyle bir durumla daha önce karşılaşmadıysanız, şimdi ne yapınca karşılaşabileceğinize bir örnek görelim. Önce boş bir sözlük tanımlayalım. Birden fazla yol ile sözlük oluşturabiliriz. Burda herhangi bir tanesini kullanıyoruz:
Haliyle artık boş bir sözlük oluşturduk. İkinci satırda da bunun içerisinin boş olduğunu gördük. İsterseniz type() ile de bunu doğrulayabilirsiniz.
Şimdi hemen bir değişken oluşturalım. Kendi adımızı yazacağımız değişken şu formatta olsun:
Haliyle bu noktada oluşturduğumuz isim adlı değişkene kendi adımızı değer olarak aktardık. Şimdi, bunu elimizdeki anahtar ile örnek bir tanımlama yapalım:
Artık sözlük içerisinde bir anahtar-değer çifti var. Bunu tabii ki kısaca şöyle de yapabilirdik:
Buraya kadar bir sorun yok. Peki anahtar olarak bir liste vermek istersek ne olacak? Hemen deneyelim:
Son satıra bakarsanız, en başta bahsettiğim hatayı aldık. Peki liste yerine anahtar olarak bir demet (tuple) veya bir sayı kullanabilir miydik? Hemen ona da bakalım:
Bu durumda ortaya çıkan sonuç, elimizde bir liste varsa bunu anahtar olarak kullanamazken, demet, string ve sayıyı kullanabiliyoruz.
Şimdi esas soru geliyor. Neden liste bir anahtar olarak kullanılamadı?
Bu sorunun cevabı aslında verilen hatada yazıyor. Hash alınamaz (unhashable) bir tür olarak liste belirtilmiş.
Şimdi yeni birkaç soruya daha geçiyoruz. Hash nedir? Python’da hash nedir? Hash ile listenin anahtar yapılamaması arasında nasıl bir ilişki var?
Türkçe anlamına bakınca hash, doğramak veya karıştırmak gibi anlamlara geliyor. Bizim konumuzda da, kendisine gönderilen bilgileri karıştırıp, sabit uzunlukta bir çıkış vermesine denk geliyor. Yani örneğin, siz 100 karakterli bir metin de gönderseniz, koca bir kitabı da gönderseniz hash fonksiyonu bunların çıktısını sabit uzunlukta veriyor. Bu uzunluk yerine göre değişken olabiliyor. Örnek bir hash algoritması olan MD5’i bu konuyu test etmek için kullanabiliriz. Hatta Python’un içerisinde zaten MD5 kütüphanesi bulunduğu için kolayca kullanabiliriz:
hash1 isimli değişkende oluşturulan MD5 için 5 harfli bir giriş vermişken, hash2 için ‘uzun bir metin olacak’ ifadesinin 1000 defa yan yana yazılmış halini giriş olarak gönderiyoruz. Ancak hexdigest ile onaltılık sistemde (hexadecimal’in kısaltması) sonuca baktığımızda 32 karakterlik sabit uzunlukta bir çıkış görüyoruz. İşte hash algoritmaları bize basit anlamda böyle bir çıktı sağlıyor. Bu şeklide düşününce aslında bir özet çıkardığı sonucuna varabiliriz. Tek bildiğimiz bu özetin sabit bir uzunluğa sahip olduğu. Şu an çok anlamlı durmuyor olsa da kullanım alanlarını araştırırsanız büyük bir şaşkınlığa kapılacaksınız :)
Hash’in ne olduğundan bahsettik. Peki koca bir kitabı bile verdiğimizde 32 karakterlik bir çıktı oluşmasını kabul ettiğimize göre, iki farklı kitap için aynı çıktı oluşamaz mı? Hash fonksiyonlarında, aynı girişi tekrar gönderdiğimizde, yani tekrar ‘selam’ yazıp gönderdiğimizde aynı çıktıyı alacağımızı biliyoruz. Ancak ‘selam’ yazınca aldığımız çıktıyı hiç tahmin etmediğimiz koskoca bir kitabı yazınca da alabiliriz. Yani bir sonucu birden fazla girişten elde etmemiz mümkün. Zaten düşününce de, hayal edebileceğimiz her veriyi 32 karaktere sığdırmak ve başka hiçbir veri ile karışmaması pek mantıklı olmaz. Son olarak da, elimizde hash değeri bulunan bir veriyi ilk haline çevirmemiz normal şartlarda mümkün değil. Yani ‘selam’ kelimesine karşılık gelen sonuçtaki 32 karakteri kullanarak ‘selam’ ifadesini elde edemiyoruz. Zaten biraz önce dediğimiz birden fazla girişin aynı çıktıyı verebilmesini de düşününce sonuçtan girişe geri gidebilsek bile hangi girişi elde edeceğimiz belli olmayacaktır. Bu konuda daha detaylı bilgi için hash algoritmalarını araştırabilirsiniz.
Böyle bir konsepti Python’a nasıl bağlıyoruz? Bunun için internette biraz daha araştırma yapınca, Python’un dökümantasyonunda hashable olan bir nesnenin, varolduğu sürece değişmeyen bir hash değerine sahip olması gerektiği yazıyor. Bunu yaparken de __hash__() methoduna sahip olması gerektiğini söylüyor[1]. Bir nesnenin ‘hashable’ yani hash değeri alınabilir olması da Python’da bir sözlükte anahtar olarak ya da bir küme (set) içerisinde kullanılabileceği anlamına geliyor[1]. Bu nesnelerin sahip olması gereken diğer özelliklere de dökümantasyondan ulaşabilirsiniz.
Bu durumda karşımıza programlama dillerinde hash kullanımı gibi bir kavram çıkıyor. Sonra bunu araştırmaya koyuluyoruz. Bu da bizi ‘hash table’ yani hash tablosu sonucuna yönlendiriyor. Hash tablolarının ise, anahtar ve değer çiftlerini temsil ederken kullanılan veri yapılarından biri olduğunu görüyoruz [2]. Python’daki dict, yani sözlük türü bunun bir örneği [3]. Bunun avantajı, sözlük gibi türlerde anahtar olarak verilen bilgiden değer bulunurken, anahtarın sadece hash değerinin alınmasıyla ve oluşturulan hash tablosundan karşılığına düşen değerin nerede olduğunun bulunmasıyla, istenilen anahtar-değer çiftinin çok hızlı bir şekilde elde edilmesi. Bu yüzden de dictionary veri yapısının Python’da sıkça önerildiğini görüyoruz.
Kendi tanımladığımız sınıflar için hash fonksiyonlarını da kendimiz tanımlayabiliyoruz. Eğer bir tanımlama yapmazsak, bu amaçla id() değeri alınıyor ve onunla hesaplanan bir hash değeri kullanılıyor. Haliyle aynı sınıftan oluşturduğumuz ve içeriği aynı olan iki nesneyi sorguladığımızda eşit olmadığını görüyoruz [4].
Esas konuya dönecek olursak, listeler üzerinde istediğimiz zaman değişiklik yapabiliyorduk. Örneğin, append ile eleman ekleme şansımız vardı. Demetler üzerinde ise böyle bir işlem yapamıyorduk. Şimdiye kadar bahsettiğimiz kavramlara göre, liste içerisinde bir değişiklik olursa farklı bir hash değeri elde etmemiz gerekiyor. Haliyle artık hash table içerisindeki ilgili veriyi bir türlü elde edemiyoruz çünkü eski girişi veremiyoruz.
Son bahsettiğimiz durum, neden listelerin sözlüklerde anahtar olamadığını açıklıyor. Biraz daha araştırmaya devam edince, bu hash table’ların oluşturulurken karşılaşılan sorunlar arasında ‘collision’ yani çakışmaya denk geliyoruz. Hatırlarsanız hash leri anlatırken, farklı girişlerden aynı çıkışın elde edilebileceğini söylemiştik. Bu noktada ise, programlama dilini yazarken, veya programlama diline hash table uyarlarken çakışmayı azaltmak gerekiyor.
Çakışma olma ihtimali ise ‘Doğum Günü Problemi’ ile açıklanıyor. Bu probleme göre, aynı ortama konulan rastgele 23 kişiden en az 2 tanesinin doğum gününün aynı güne denk gelme olasılığı %50 olarak ortaya çıkıyor. Hatta eğer 70 kişi olursa bu olasılık %99.9’a kadar çıkıyor. Haliyle 365 günlük yıl içerisinde o an bulunan topluluktan en az 2 kişinin doğum gününün aynı olma olasılığını hesaplamış oluyoruz. Şimdi daha inandırıcı bir hale getirmek için bunu nasıl hesapladığımıza da bakalım [5]:
Ortamda yer alacak ilk kişi için zaten bir gün çakışma ihtimali yok. O yüzden onun olasılığına 365/365 diyebiliriz. Diğerleri için;
  2. kişinin doğum gününün,  1. kişiden farklı olma olasılığı 364.0/365
  1. kişinin 2.’den farklı olma olasılığı 363.0/365

Şeklinde ortaya çıkıyor. Haliyle bu sayıların hepsini birbirine çarptıktan sonra, %50 gibi bir oran kalıyor. Hemen görelim:

Yaptığımız işlem sonucunda, ele aldığımız 23 kişinin doğum günlerinin farklı olma olasılığını, ya da aynı olmama olasılığını 0.4927… şeklinde bulduk.
1 – ‘olmama olasılığı’ dediğimizde ise, bu kişilerin doğum günleri için en az 2 kişinin aynı gün doğmuş olma ihtimalini bulabiliriz:

Yani elde ettiğimiz olasılık, %50’den daha büyük, %50.7297 gibi bir sonuca sahip. Burdan da, doğum günü probleminin nasıl oluştuğunu görüyoruz.

Hatta olayı biraz daha ilerletir ve 70 kişi üzerindeki olasılığı hesaplarsak, artık çok daha yüksek bir olasılıkla aynı gün doğan insanların çıkabileceğini görürüz:

Yani artık %99.9’luk bir olasılıkla bir doğum günü çakışması olduğunu biliyoruz.

Hatırlarsanız hash değerlerinin aynı çıkabildiğini söylemiştik. Seçeceğimiz hash alma fonksiyonu her ne kadar düzgün dağılımlı ve rastgele sonuçlar veriyor olursa olsun, doğum günü paradoksu burda devreye giriyor ve elimizdeki giriş kümesi büyüdükçe programlama dillerindeki uyarlamalarda çakışma olma ihtimalini artırıyor.

Bu konuyu çözmek de programlama dillerinde hash tablolarını uyarlayan kişilere bırakılmış durumda. Bu konuda incelemiş olduğumuz Python, ‘collision list’ adı verilen bir çözüm kullanıyor. Bu çözümde, aynı hash çıkışını veren anahtar-değer çiftleri, o hash değerinin gösterdiği yerde bulunan bir listeye konuluyor. Daha sonra bu listenin elemanları arasında(ki çakışma çok beklenmediği için bu sayı bütün sözlüğe göre çok çok daha az) anahtar bulunarak karşılık gelen değere bakılıyor.

Bunu yapmak yerine, en baştan bütün anahtar-değer çiftlerini bir liste içerisinde tutmak da tabii ki bir çözüm. Hem düşününce, bu şekilde anahtar yerine bir liste de konulması mümkün. Ancak burdaki problem, erişmek istediğimiz anahtar-değer çiftini bulabilmek için her anahtarın teker teker kontrol edilmesi gerekliliği. Bu da elimizdeki ‘dictionary’ çözümüne göre çok daha yavaş çalışıyor. (Meraklısı için, dictionary genellikle O(1) karmaşıklığında çalışırken listeye uyarlayarak teker teker bakmak O(n) karmaşıklığında çalışıyor.)
Esas sorunun cevabı da aslında ortaya çıkmış bulunuyor. Listeler, üzerinde değişiklik olabildiği için her değişiklikte farklı hash değerleri üretiyor. Haliyle listeyi anahtar yapmak, ona ait değere geri ulaşmayı her an imkansız hale getirebiliyor. Demetler üzerinde değişiklik yapılamadığı için onlar anahtar olarak kullanılabiliyor. Ve evet, Python’da aslında String türünden değişkenler üzerinde de değişiklik yapılamıyor(detaylı bilgi için bkz. mutable ve immutable objects in Python)
[1] https://docs.python.org/2/glossary.html
[2] https://en.wikipedia.org/wiki/Hash_table
[3] https://wiki.python.org/moin/DictionaryKeys
[4] https://docs.python.org/2/reference/datamodel.html#object.__hash__
[5] https://en.wikipedia.org/wiki/Birthday_problem
Video

IoT, MQTT ve Mosquitto – Devfest Düzce Sunum Videoları

Geçen hafta Devfest için Konya ve Düzce’de iki oturumda konuşmacıydım. Ufak farklılıklar olması dışında, konu olarak MQTT ve Mosquitto’yu seçtim. Internet of Things’de uygulama geliştirirken sıkça kullandığımız protokol olan MQTT’yi ve bu protokolün en yaygın kullanılan broker’larından biri olan Mosquitto’yu, kurulumlarını, ayarlarını ve yayın yapma/takip etme örneklerini elimden geldiğince anlatmaya çalıştım. Sunum videolarını değerli bir abim çekti ve ben de onları yükledim. Videolar aşağıda, sormak istedikleriniz olursa yazmaktan çekinmeyin.

Yaptığım sunumun slaytlarını sunum yaptığım gün burada paylaşmıştım. Videolardan takip etmekte zorlanırsanız veya bulundurmak isterseniz tarayıcınızdan doğrudan görüntüleyebilirsiniz.

Video 3 kısımdan oluşuyor. 1. kısım:

2. Kısım:

3. Kısım:

 

Ücretsiz ESP8266 ile Nesnelerin İnterneti Kitabı

Nesnelerin interneti (Internet of Things, IoT) konusunda uzun zamandır projeler geliştiriyorum. Bunları yaparken birçok farklı teknolojiyle birlikte çalışmak gerekebiliyor. Sağladığı yenilikleri ve kolaylıkları da göz önüne alınca birçok farklı ve üretken fikrin de her geçen gün ortaya çıktığına şahit oluyoruz.

Projeleri gerçekleştirirken düşük maliyetli çözümler arasında yer alan ESP8266 modülü ile ilgili Türkçe yazılmış bir kitap bulamayınca, ben yazmaya karar verdim. Basılı, uzun ve detaylı bir hali önümüzdeki aylarda hazır olacak, ama bu süreçte kaynak ihtiyacı duyanların başlangıç yapabilmesi, hatta daha ileriye giderek ThingSpeak üzerinden grafikler çizdirip, sensör verilerini Tweet atan uygulamalar yapabilmelerini sağlayan örnekleri hazırladım. Arduino ve ESP8266’yı birlikte kullanarak kablosuz internet ağınıza bağlanmanız veya ESP8266 ile kablosuz internet ağı kurarak telefonunuzdan ya da bilgisayarınızdan bu ağa bağlanmanız için gereken her şeyi bu kitap içerisinde bulabilirsiniz.

Kitaba ulaşmak için tıklayın (~750KB, PDF formatında)

(Kitabın güncel haline ve yapılan değişikliklere bu sayfadan ulaşabilirsiniz.)

Kitap hakkında her türlü yapıcı eleştiriyi, geliştirmeleri vb. heyecanla bekliyor olacağım. İster bu sayfaya yorum olarak, isterseniz e-posta ile bunları bildirebilirsiniz. Okumaktan mutluluk duyacağım. Gelen geri dönüşlere göre bu kitap güncelliğini koruyacak. Olmasını istediğiniz konuları da belirtirseniz, en çok istenenleri zamanla içerisine eklemeye veya en kötü ihtimalle basılı çıkan kitaba eklemeye çalışacağım.

[HowTo] Install Kivy and Buildozer on Fedora 22 and Making APK

In a previous post, installing Kivy on Ubuntu 15.04 was issued. Today, there is a main development which is using SDL2 instead of Pygame. You can find why this is significant on Google.

I cannot find Kivy and Buildozer installion document for Fedora 22 and decided to write a recipe for it. So, lets get started. You will find 8 main sections for this topic:

  1. Installing Dependencies
  2. Creating Virtual Environment
  3. Installing Some Required Python Modules
  4. Installing Kivy
  5. Testing Kivy
  6. Installing Dependencies Required to Packaging for Android
  7. Configuring Buildozer
  8. Making APK File

Continue reading

Kivy Course #10 – User Login System With Kivy

In many applications, a login system is applied. As a result of this, in a Kivy course, we believe that we should teach how to make a basic login system with Kivy. To achieve this, the code in following is written. After the login, the program connects to OpenWeatherMap with its API and gets a data from given coordinates in code. After getting data, it shows the temperature in the logged-in screen. There is also a screen that is shown if the username or password does not match.

Continue reading