Bu yılın denemeleri

Bu sene ektiğim bazı çiçekleri bahçeye çıkardım sonunda. Burada havalar hala soğuk ama iyi uyum sağladılar gibi görünüyor. Soğuk havanın yanındaki diğer tehlike de sümüklü böcekler. Genelde ektiğim çiçekleri yemeyi çok seviyorlar. Geçen seneden kalan bir çiçeğimi neredeyse komple yediler. Yeni ektiğim çiçeklerle pek ilgilenmediler ama.

Kudret narı

Kudret narının iki tohumunu içerde, diğerlerini de dışarıda. İçeridekilein ikisi de çimlendi ve birini bahçeye aktardım. Şimdilik orada iyi idare ediyor gibi görünüyor. İçerdekini de ne olur ne olmaz diye bekletiyorum hala.

Cosmos bipinnatus

Bunlar da çabucak çimlendi ve ilk parti bahçeye uyum sağladı gibi gözüküyor.

Bahçede de hafif hafif çimlenme başladı ama çok fazla ve işaretlemeden tohum ektiğim için neyin ne olduğunu henüz bilmiyorum.

MongoDB Compass

Uzun zamandır ilişkisel veritabanlarını (RDBMS) programladığım sistemlerde kullanıyorum. Bu sırada tabii ki başka türlü veritabanları da yaygınlaşmaya başladı. Şirketteki işlerim biraz azalır gibi olduğunda NoSQL tipi bir veritabanını öğreneyim dedim. Bilgisayarıma hemen MongoDB sunucusunu kurdum ve çeşitli kaynaklardan bu veritabanını nasıl kullanacağımı öğrenmeye başladım. İşlerimi Linux altında konsolda yapıyordum ve bu sırada MongoDB Compass diye bir programdan haberdar oldum. Onu da kurdum ve kullanmaya başladım. Verileri görme, bazı sorguları çok daha kolay bir şekilde yazma ve komutları otomatik tamamlama özellikleri öok hoşuma gitti ama her türlü sorguyu kullanmak mümkün değildi. Yani hala arada konsolu kullanmam gerekiyordu. Bu sırada programın alt tarafında _MONGOSH beta gibi bir yazı gördüm. Belki shell kısmı buradadır diye bastım ve gerçekten de konsol gibi bir şey açıldı ama yazdığım her komut hata veriyordu.

MongoError: No AuthProvider for DEFAULT defined.

Internette bu hata mesajını yazıp yaptığım aramalarda bir sonuca ulaşamadım ama bağlantı tanımlama penceresinde zaten bir miktar ipucu varmış.

Ben connection string kısmına sadece aşağıdaki komutu yazmıştım.

mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb

Bunu yazınca mongodb compass compressor tanımı için bir uyarı vermişti ama. Bunun üzerine komutu şöyle değiştirmiştim.

mongodb://127.0.0.1:27017/?compressors=zlib&gssapiServiceName=mongodb

Anlaşılan username ve password de tanımlamam gerekiyordu.

Önce bu sayfada anlatıldığı şekilde konsolu kullanarak bir kullanıcı admini ekledim.

use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: passwordPrompt(), // or cleartext password
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)

Bu komuttan sonra mongodb bu kullanıcı için şifreyi soruyor. Ardından kullanıcı tanımlanmış oluyor. Bundan sonra bağlantı komutunu şifre kısmına yukarıdaki komutla beraber tanımladığım şifreyi kullanarak yazdım.

mongodb://myUserAdmin:ş[email protected]:27017/?compressors=zlib&gssapiServiceName=mongodb

Bundan sonra programın altındaki _MONGOSH BETA kısmını da konsol olarak kullanabildim.

Java ve skript programlama

Önce çözmeye çalıştığım sorundan bahsedeyim. Şirkette yazdığım program ürettiğimiz makineyi kontrol eden başka programla haberleşiyor ve bazı durumlarda onların ayarlanmasını da düzenliyor. Yalnız çok değişik türlü makineler ürettiğimizden bu makinelerin ayarları da aynı şekilde olmuyor. Örneğin üretim bantı hızı her makinede eşit olmuyor. Dolayısıyla bant üzerindeki ürünü inceleyecek kameranın hızının da bu bant hızına göre ayarlanması gerekiyor. Bunun gibi birbiriyle ilişkili parametreleri program dışından, makineye özel ayarlayabilmek için bir konfigürasyon dosyası kullanmıştım. Bu dosya basit ilişkileri programlamak için yeterliydi.

Zamanla makinelerimiz daha da kompleks olmaya başladı. Artık o konfigürasyon dosyası ihtiyacımız olan ilişkileri tanımlayacak durumda değildi. Yeni ilişkileri tanımlamak da bunları programlamamı gerektirecekti. Bunun yerine başka bir çözüm aramaya başladım.

Sonuçta konfigürasyon dosyası da bir tür program olduğundan, bu iş en kolay bir programlama diliyle çözülür diye düşündüm. Örneğin parametreler arasındaki ilişkileri bir programlama diliyle programlasak ve bu ayarlar yapılırken programın içinde bu dosyayı (yani programı) çalıştırıp o ilişkileri doğru kursak o zaman sorun çözülmüş olabilirdi. Burada tabii ki şöyle bir özelliğe de ihtiyacım var. Bu konfigürasyon dosyası java ile yazdığım programdaki bazı nesnelere erişebilmeliydi. Java programının yapması gereken tek şey bu programı çalıştırmak olacaktı.

Kısa bir araştırma sonucu Java 6 ile gelen JSR-223 yoluyla bu işleri yapabileceğimi öğrendim. Yalnız internette yapmak istediğim şeyi anlatan bir yazıya ya da açıklamaya rastlayamadım. Bunun üzerine okuduğum bazı makalelerden, javadoc sayfalarından yola çıkarak küçük bir örnek program yazdım. Bu sayede istediğim şeyin yapılabileceğini görmüş oldum.

İlk iş olarak yjthon.org sitesinden günce jython sürümünü indirdim ve orada anlatılan şekilde kurdum.

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.script.*;

public class Tutorial {
	
	public static class Configuration {
		private Map<String, String> configuration = new     HashMap<>();
		
		public String get(String identifier) {
			return configuration.get(identifier);
		}
		
		public void set(String identifier, String value) {
			configuration.put(identifier, value);
		}

		@Override
		public String toString() {
			return "Configuration [configuration=" + configuration + "]";
		}
	}
	
	private static String getScript() {
		StringBuilder builder = new StringBuilder();
		builder.append("import sys\n");
		builder.append("configuration.set(\"id1\", \"234\")\n");
		return builder.toString();
	}

	public static void main(String[] args) throws ScriptException {
		System.setProperty("python.home", new File(
		        System.getProperty("user.home"), "jython2.7.2").getPath()
		);
		ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
		
		ScriptEngine engine = scriptEngineManager.getEngineByName("python");
		Configuration con = new Configuration();
		ScriptContext context = engine.getContext();
		context.setAttribute("configuration", con, ScriptContext.GLOBAL_SCOPE);
		String script = getScript();
		CompiledScript compiledScript = ((Compilable)engine).compile(script);
		compiledScript.eval(context);
        System.out.println("configuration: " + con.toString());
	}
}

Yukarıdaki program denemeyi yaptığım oldukça küçük bir proje. Configuration sınıfı kabaca java programım ile skrip arasındaki haberleşmeyi sağlayacak nesneyi tanımlayacak. Skrip bu nesne aracılığı ile ana programdaki konfigürasyona erişip tanımlanan ilişkiler yardımıyla bu konfigürasyonu güncelleyecek.

getScript metodu örnek olarak minimum python kodunu tanımlıyor. Bu kod java programından gelen configuration nesnesindeki id1 isimli nesneye 234 değerini atıyor. main metodunda ise önce python.home sistem değişkenini tanımladım. Bu değişken jython kurulumunu yaptığım dizini gösteriyor. Ardından ScriptEngineManager ve ScriptEngine tipinden nesneleri yarattım. ScriptEngine nesnesinin kullandığı ScriptContext nesnesini kullanarak yarattığım Configuration nesnesini (con) skripte configuration adı altında global bir şekilde aktaracağımı bildirdim. Bunu yapmak için ScriptContext sınıfının setAttribute metodunu kullandım.

Ardından bu skripti her ayar değişikliğinde tekrar kullanacağımdan sonraki kullanımlarda zamandan kazanmak için ilk seferde derlemeyi denedim. Bunun için

CompiledScript compiledScript = ((Compilable)engine).compile(script);

satırını kullandım. Bu durumda her kullanımda aynı nesneyi kullanmam gerekecek ama bu kolay bir sorun. Ardından bu skripti çalıştırdım ve java programındaki nesnenin içeriğinin değiştiğini gördüm. Tam da istediğim sonuç.

Diyatome

Diyatomeler, silisli sert kabukları olan alg familyası bireyleridir. Bu hafta Ren nehrinden aldığım gelen su örneklerinde çok küçük diyatomeler bulunmaktaydı. O kadar küçüklerdi ki elimdeki mikroskopta bunları 400 kere büyütmede bile doğru düzgün göremedim. Dün Hornesselwiese doğal parkından aldığım örnekler ise tam bir diyatome cenneti çıktı. Çeşitli büyüklükte ve şekillerde örnekleri görmek mümkün oldu. Tabii ki isimlerini henüz bilmiyorum ama aşağıda çekebildiğim kadarıyla fotoğraflarını görebilirsiniz.

https://www.instagram.com/p/B1Bou4wp3m_/
https://www.instagram.com/p/B1Boz6_pTcu/
https://www.instagram.com/p/B1Bo50qp7pV/
https://www.instagram.com/p/B1BpArIpCDf/
https://www.instagram.com/p/B1BpKmwpLKa/
https://www.instagram.com/p/B1BpQVYJVFI/
https://www.instagram.com/p/B1BpXmcpwxN/

Mikroskop safarilerine devam

Topladığım tatlı su örneklerinde hala yeni canlılarla karşılaşmak mümkün oluyor. Tabii ki bu organizmalar çok küçük ve saydam olduklarından detayları mikroskopumda pek net göremiyorum. Bu ilk aşamalarda daha çok mikroskopu ve canlıları tanımayla uğraşmayı düşünüyorum. Mikroskobu geliştirme planlarını ancak ondan sonra düşüneceğim.

Bu hafta aşağıdaki gözlemleri yapabildim. Tabii ki bu canlıların hemen hemen hiçbirini hala tanımıyorum. Bütün çekimleri elimde tuttuğum akıllı telefonla yaptım.

Terliksi hayvan
Bir tatlı su organizmasının estetik virajları.
Mikroyandaş hayvanı
Çift kuyruklu bir organizma.
Ninja turtles
45 numara terliksi hayvan olabilir
Unidentified Swimming Organism (Sanki diğerlerini tanımlayabilmişim gibi oldu)

Mikroskop

Bu dönem sonunda çocuklara karne hediyesi olarak ikinci el ucuz sayılabilecek bir mikroskop aldım. Çocuklardan çok bana kalacağını biliyordum ama o kadar da ilgisiz değiller. Kendi başlarına bir kere kullandılar ama onda da oldukça iyi çalıştılar. Bunun dışında sadece benim hazırlamayı başardığım şeylere bakıyorlar. En azından bakıyorlar.

İlk iş olarak çevrede bulduğum su birikintilerinden kavanozla topladığım örnekleri incelemeye başladım. Tabii ki bu alanda çok yeni olduğum için neyin ne olduğunu henüz bilmiyorum. Yine de bu cahillik aşağıdaki fotoğrafları ve videoları yayınlamama engel değil. Türleri öğrendikçe doğru isimleri yazacağım. O zamana kadar kendi taksonomimi kullanmayı düşünüyorum.

Fotoğraf ve videoları oküler üzerinde elimle tuttuğum cep telefonumla çektim.

Palabıyık yosunu
Portakal yosunu
Akordeon yosunu
üzümsüler
kızılcık sopacığı
Peynirli pide hücresi
Naginus Mini
Mekikus Aqua
Yoyo domesticus
Fasülyus magickus

Basit vektör işlemleriyle ilgili bir oyun (Toplama)

Bu seferki test oyunumuz da vektör işlemleri üzerine. İlk olarak toplama işlemini ele aldım. Koordinat sisteminde verilen iki vektörün toplamını bulmaya dayalı bir oyun. Cevap, toplam vektörünün bitiş ucunu seçerek veriliyor, vektörün başlangıcı (0,0) noktası olarak kabul ediliyor.

Eğer verilen cevap doğruysa seçilen vektör yeşil renkle gösteriliyor, yanlışsa kırmızıyla. Bu durumda doğru cevap tabii ki yeşil bir vektörle gösteriliyor. Her doğru cevap 100 puan. Belki ileride doğru cevapla beraber toplanan vektörlerin oluşturduğu paralelkenarı da çizdirebilirim, ya da vektörlerden birini diğer vektörün ucuna kaydırıp toplamı gösterebilirim.

 

Oyun

 

Doğru denklemleri oyunu – 2

Bu oyunda da geçen oyunun tersi yapılıyor. Her soruda değişik renklerde dört doğru grafiği veriliyor ve altta verilen denklemin hangi grafiğe ait olduğu soruluyor.

Tablet ve cep telefonları için tuşları ve ekran büyüklüklerini bir aksilik çıkmazsa bu hafta iyileştirmeyi düşünüyorum.

Oyun

Bir doğru denklemi bulma oyunu

Geçen yıl bir veli toplantısında bir velinin sorduğu şu soru beni hayretlere düşürmüştü:

– Çocuklar matematik çalışmak için ders kitabından başka nereden soru bulabilir? Ders kitabında çok az soru var.

Ders kitabında çocuğun öğrenmesi beklenen her fikir ya da yöntem için normalde en fazla on tane soru oluyor. Bunların da çoğu derste yapılıyor ya da ev ödevi olarak veriliyor. Sınava hazırlanmak için kitaptaki soruları çöz deyince de çocuklar genelde biz onları zaten yaptık diyorlar. Anlaşılan bu veli de böyle bir cevap almıştı ve daha başka soru kaynağı arıyordu. Oysa sonsuz sayıda sayı olduğuna göre yeni soru üretmek çocuk oyuncağıdır. Kitaptaki örnek sorular alınır ve değişik sayılarla sonsuz adet soru yapılır. Tabii ebeveynler bu iş için zaman harcamak istemez. Ne de olsa sorunun kolay çözülebilmesi için sayıları doğru seçmek biraz enerji gerektiren bir işlemdir.

Geçenlerde çocuklar eve gelince bana bir android uygulaması gösterdi. Verilen bir tamkare sayının kare kökünü bulmaya dayanan bir oyun. Nedense çocuklar bunu sevmişti. Ben de matematik soru üretme işini böyle denemeye karar verdim. İlk programımda x-y koordinat sisteminde verilen bir doğru grafiğinin y = mx + n şeklindeki denklemini seçeneklerden bulma şeklinde bir test oyunu yaptım. Her doğru cevaba 100 puan veriliyor. Bakalım çocukların ilgisini hiç çekecek mi?

Oyun

Evrim ve genetik algoritmalara küçük bir giriş

Richard Dawkins, Kör Saatçi adlı kitabında bir programdan bahseder. Bu program rastgele değişimler ve rastgele olmayan seçimler sayesinde nesiller boyu işleyen bir algoritmanın tamamen rastgele şekilde işleyen bir mekanizmadan çok daha çabuk hedefe ulaşacağını gösteren bir deneydir.

Bu deneyde Dawkins ‘METHINKS IT IS LIKE A WEASEL’ cümlesini kullanır. Eğer bir maymun rastgele İngilizce alfabedeki 26 harfi ve boşluk karakterlerini kullanarak bu cümleyi yazmaya çalışırsa çok çok uzun zaman bu işle meşgul olurdu.

Dawkins, bunun yerine maymunun çalışma prensibinde hafif bir değişiklik yapılırsa çok ilginç bir sonuç çıkacağını söyler kitabında. Diyelim ki maymun yine rastgele 28 harflik (cümle 28 harf uzunluğunda) bir şey yazsın. Daha sonra bu cümleyi kopyalamaya başlasın ama bir farkla. Kopyalarken arada rastgele hatalar yapsın, yani bazı harfler kopyalarda değişsin (mutasyon). Daha sonra maymun o yazdığı ve kopyaladığı cümleler grubunda hedef cümleye en yakın cümleyi seçsin ve o ana kadar yaptığı adımları tekrarlasın. Böylece nesiller sonra maymun hedef cümleyi bulacaktır ve bu iş için gereken nesil sayısı tamamen rastgele seçim olan algoritmadan çok daha az olacaktır.

Bunu denemek için bir javascript simulasyonu programladım. Her nesildeki birey sayısını ve mutasyon oranını girdikten sonra ya animasyonlu ya da animasyonsuz çalıştırılabilir. Öncelikle animasyonsuz çalıştırılmasını öneririm. Böylece daha hızlı çalışacaktır ve daha kısa sürede bütün işlemlerin yaklaşık kaç nesil süreceği görülebilir. Bu esnada yukarıda nesil numaraları ve o nesildeki hedefe en yakın cümleyi görebilirsiniz.

Eğer animasyonla çalıştırılırsa maymunun yaptığı işlemleri ‘ağır çekimde’ görülebilir. Cümlelerdeki mutasyonlar, yani hatalı kopyalanan harfler kırmızı gösteriliyor. Ardından maymunun seçimi yeşil arkaplan rengiyle gösteriliyor. Bundan sonra o nesil komple siliniyor ve yerine maymunun seçtiği cümlenin tam kopyaları koyuluyor. Animasyon bu adımların tekrarlanmalarıyla devam ediyor. Küçük bir uyarı yapayım, bu adımlar çok yavaş gösterildiğinden bütün simulasyonu seyretmek çok zaman alacaktır.

Hedefe çabucak ulaşmak için kalabalık popülasyonlar seçmek daha iyi olacaktır. Animasyon kullanılmayacaksa 100 iyi bir popülasyon büyüklüğüdür. Animasyon için ise ne kadar küçükse o kadar iyi ama bu durumda da bütün simulasyon çok uzun sürecektir. Mutasyon değerini küçük tutmak iyidir. Örneğin 0.05 (Her harf yüzde beş ihtimalle değişebilir) yeterli bir değer. Aşağıdaki linkten simulasyon sayfasına ulaşabilirsiniz.

Gelincik programı