<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="tr"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://yinkar.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://yinkar.github.io/" rel="alternate" type="text/html" hreflang="tr" /><updated>2025-04-02T15:51:03+03:00</updated><id>https://yinkar.github.io/feed.xml</id><title type="html">Hüseyin Karabaş</title><subtitle>Yazılım geliştirici ve birçok şey</subtitle><author><name>Hüseyin Karabaş</name></author><entry><title type="html">Kaderi Baştan Yazılmış Olan Bilgisayarlar Nasıl Rastgele Sayı Üretebiliyor?</title><link href="https://yinkar.github.io/programlama/algoritma/2023/08/17/bilgisayarlar-nasil-rastgele-sayi-uretebiliyor.html" rel="alternate" type="text/html" title="Kaderi Baştan Yazılmış Olan Bilgisayarlar Nasıl Rastgele Sayı Üretebiliyor?" /><published>2023-08-17T00:18:00+03:00</published><updated>2023-08-17T00:18:00+03:00</updated><id>https://yinkar.github.io/programlama/algoritma/2023/08/17/bilgisayarlar-nasil-rastgele-sayi-uretebiliyor</id><content type="html" xml:base="https://yinkar.github.io/programlama/algoritma/2023/08/17/bilgisayarlar-nasil-rastgele-sayi-uretebiliyor.html"><![CDATA[<p>Rastgele sayıları kullanmadığımız yer var mı? Çekilişler, oyunlar, dosya isimleri, simülasyonlar, parola oluşturucular, istatistik, sanat… Bu liste uzar gider. Yalnızca sayılar değil, rastgele sayılardan türetilmiş farklı veri türleri de bu işlerin bir kısmında kullanılabilir. Yalnız şöyle bir durum var; tüm bunları bilgisayar üzerinde yapabiliyoruz, ancak bilgisayarın kendisi yapısı gereği gerçek anlamda rastgele sayı üretememekte.</p>

<p>Bilgisayar açıldığı andan itibaren dışarıdan bir veri alana kadar gerçekleşecek her şey bellidir. Dışarıdan bir veri geldiğinde, örneğin bir mouse hareketi gerçekleştiğinde bunu da kullanıcı kendi bilinci dahilinde gerçekleştirdiği için rastgele olarak görmeyiz. Tabii böyle bir girdiyi sayısal olarak yorumlayarak anlık olarak rastgele bir değer olarak yorumlamak da bir fikir. Bunu yapan uygulamalar da yok değil, Windows üzerinden dışarıya SSH bağlantısı kurmayı sağlayan PuTTY buna bir örnek.</p>

<p>Söylediğim gibi, bilgisayarda her şey kesindir. Bilgisayar, üzerine programlanmadığı bir şey düşünemez, rastgele bir veri üretemez. Onun kaderi ya baştan bellidir, ya da verilen girdilerle şekillenecektir. O yalnızca elektrik akımlarından oluşmuş “zihniyle” dışarıdan aldığı veya halihazırda üzerinde bulunan veriler üzerinden işlem yaparak bir çıktı üretir. Bize de bu çıktıyı sunar. Söz konusu rastgele sayı beklentisi olduğunda ise bizi şaşırtacak veya beklemediğimiz bir sonuç gerekiyor.</p>

<p>Bunu çeşitli yöntemlerle gerçekleştirebiliyoruz. Bunlardan en bilineni, en sık kullanılanı ve en basiti Sözde Sayısal Rastgele Sayı Üreteci (Pseudorandom Number Generator - PRNG) adını verdiğimiz bir kategori. Aritmetiği kullanarak, sayıları işleyerek ve bir kısmını da duruma göre yok ederek beklemediğimiz sayılarla karşılaşıyoruz. Elbette bu yöntemin birçok sıkıntısı var, bunlara daha sonra değineceğim.</p>

<p>PRNG yöntemlerine Orta Kare Metodu (Middle-square Method) ile başlayalım. Bu yöntemi anlaması çok basit. Öncelikle tüm PRNG yöntemlerinde kullanacağımız tohum (seed) kavramına bir bakalım. Yalnızca yüksek seviye programlama dilleriyle uğraşmamışsanız bu seed kavramına aşina olmanız beklenebilir. Seed bizim çıkış noktamız, rastgele sayıların üretileceği zincirin alması gereken ilk değer. Bu genellikle sistemin o anki saati olarak belirlenir. Biz ise şimdilik elle belirleyelim. Orta Kare Metodu için öncelikle bize n basamaklı bir sayı gerekiyor, bu bizim için 6 basamaklı “675248” olsun. Bu sayının karesini alıyoruz ve “455959861504” şeklindeki 2n, yani 12 basamaklı sayıya ulaşıyoruz. Bazı durumlarda 2n basamaklı değil, eksik sayıda basamak çıkabilir. Bu durumda sol kısma 0 ekleyerek 2n’e tamamlıyoruz. Şimdi ise yapacağımız şey tam ortasındaki n basamaklı sayıyı almak. 959861 bizim sözde rastgele sayımız. Tekrar bir rastgele sayı üretmemiz gerektiğinde ise 959861 sayısının karesini alacağız, o da bize 921333139321 sayısını verecek, oradan da 333139 sayısına erişeceğiz ve bu böyle gidecek. Elimizde beklenmedik bir sayı var ve önceki sayıyı tahmin etmemiz zor, çünkü veri çıkardık. Bu yöntem oldukça ilkel olsa da bir gün rastgele sayı üreteci yazmanız gerektiğinde hızlıca yazabileceğiniz bir algoritmaya sahip. Yalnız çok önemli problemleri olduğunu söylemek gerek. Örneğin diyelim bu işlemi 4 basamaklı sayılarla yapıyorsunuz. 2500’e ulaştığınızda ağlayarak günlüğünüze yazabilirsiniz. Çünkü 2500’in karesi 6250000 ve bunun ortasındaki 4 haneli sayı yine 2500. Burada bir kısır döngüye giriyorsunuz ve yapı artık rastgele sayı üretememeye başlıyor.</p>

<p>Şimdi bahsedeceğim PRNG yöntemi ise Doğrusal Uyumlu Üreteç olarak çevirebileceğimiz Linear Congruential Generator. İsmine aldanmayın, çok uyduruk bir yöntem. Tabii uygun parametreler seçildiğinde tatmin edici düzeyde başarılı olduğunu da söylemek lazım. Bu yöntemi GNU/Linux’ta C kodu derlediğinizde kullanıyorsunuz aslında. glibc, dolayısıyla da GCC bunu kullanıyor. Yöntem çok basit. Bir adet seed yine gerekiyor, bir adet mod, bir adet çarpan, bir de ek gerekiyor. Moddan kastımı anlamışsınızdır, bölümünden kalanı alacağımız bir sayı. Yapacağımız şey ise şu:
sonuç = (çarpan * seed + ek) % mod
Çıkan sonucu ise bir sonraki rastgele sayının seed’i olarak kullanacağız ve bu, bu şekilde gidecek. %’nin modulus işlemi olduğundan bahsetmeme gerek yoktur herhalde. LCG isimli bu yöntem aşina olduğumuz birçok platformda kullanıldı ve kullanılıyor. Java, Turbo Pascal, Visual Basic, Borland Delphi, Borland C/C++, ANSI C ve bahsettiğim gibi GCC. Daha da uzuyor gidiyor. Örneğin ANSI C ve GCC’nin varsayılan değerlerini inceleyelim:
mod: 2^31
çarpan: 1103515245
ek: 12345
Bu metotlar yeterince rastgele görünen sayılar üretebilmek için çoğunlukla yeterli oluyor.</p>

<p>Bu aritmetik yöntemlerden son olarak V8 motorunun, dolayısıyla da günümüzde JavaScript çalıştıran çoğu ortamın kullandığı yöntemden; XorShift128+ algoritmasından bahsedelim. Bu algoritmada da verilen seed değeri önce bit düzeyinde 23 kere sola kaydırılıyor ve çıkan değer kendisiyle Xor’lanıyor, ardından bunun sonucu 17 kere sola kaydırılıyor ve kendisiyle Xor’lanıyor, bunun sonucu da ilk adımdaki haliyle Xor’lanıyor derken son olarak da ilk adımdaki değer 26 kere sağa kaydırılıp son değerimizle Xor’lanıyor. E tabii bu kadar işkenceden geçen sayının rastgele görünmemesi pek olası olmazdı. Aynı şekilde işlemler de bitwise yapıldığı için aslında oldukça hızlı bir algoritma. Tabii bunu bu şekilde bir cümlede anlatınca kafada pek bir şey oluşmuyor, o nedenle ben bunun Chrome’un da önemli bir kısmını oluşturan V8 motorunun kaynak kodunda yer alan implementasyonunun resmini koyayım.</p>

<p><img src="/images/blog/rastgelelik/rastgelelik-1.png" alt="V8 kaynak kodundaki XorShift128+ implementasyonu" /></p>

<p>Şimdi daha farklı yöntemleri inceleyelim. Unix benzeri işletim sistemlerinde, dolayısıyla GNU/Linux dağıtımlarında da yer alan sözde cihazlar vardır. İşletim sisteminin kök (<code class="language-plaintext highlighter-rouge">/</code>) dizininde yer alan <code class="language-plaintext highlighter-rouge">/dev</code> dizini altında sisteme normal şartlar altında fiziksel olarak bağlı cihazların temsili halleri birer dosya formatında bulunurken bahsettiğim sözde cihazlar da onlarla beraber bu dizinde bulunur. Bunlar /dev/random, /dev/zero, /dev/urandom, /dev/full, /dev/null gibi özel dosyalardır. Bizim odaklanacağımız sözde cihaz ise /dev/random olacak.</p>

<p>/dev/random cihazından veri okuyacak olursanız size bir akış olarak sürekli bir şekilde rastgele byte’lar üretecektir. Örneğin <code class="language-plaintext highlighter-rouge">cat /dev/random</code> gibi bir komutla bunları ham olarak okuduğunuzda işletim sistemi karakter tablosundaki birer karakterle eşleştirmeye çalışacağından anlamsız karakterler olarak gözlemleyeceksiniz.</p>

<p><img src="/images/blog/rastgelelik/rastgelelik-2.png" alt="/dev/random çıktısı" /></p>

<p>Gelelim esas önemli kısma. <code class="language-plaintext highlighter-rouge">/dev/random</code> cihazının bizim için önemi şu: kendisi bu rastgele değerleri donanımlardaki çevresel gürültülerden elde ediyor. Aslına bakarsanız aritmetiksel yöntemlerden daha kullanışlı. Tabii kendi cihazınızın oluşturacağı elektromanyetik gürültüler hiçbir zaman tam olarak tahmin edilemez değildir. Bu nedenle <code class="language-plaintext highlighter-rouge">/dev/random</code> veya onun entropik olarak daha geniş bir havuza sahip olan kuzeni <code class="language-plaintext highlighter-rouge">/dev/urandom</code> “gerçek” rastgele sayı üreteci (True random number generator) kabul edilmiyor. Onlar da birer sözde rastgele sayı üreteci olarak geçmekte.</p>

<p>TRNG olarak anılan bazı çevresel donanımlar mevcut. Bunlar da çevresel bazı değerleri alıp işleyerek bunu yapıyor. Örneğin termal gürültü, fotoelektrik etki, ışın ayırıcı (beam splitter) etkisi veya diğer kuantumsal etkiler gibi, standart bir bilgisayar donanımında bulunmayan sensörlerle yapılan gözlemlerin sonucu ile amacına ulaşıyor. Bunlara hardware random number generator (HRNG) veya non-deterministic (deterministik olmayan) random bit generator (NRBG) de deniyor.</p>

<p><img src="/images/blog/rastgelelik/rastgelelik-3.jpg" alt="Gerçek rastgele sayı üreteci donanımı" /></p>

<p>random.org gibi siteler ise atmosferdeki elektromanyetik gürültüyü kullanarak anlık olarak gerçek rastgele sayı üretme ve size bunu sayfa üzerinden ulaştırma vaadinde bulunuyor.</p>

<p>Son olarak kriptografik olarak güvenli olma konusuna gelelim. Gördüğünüz üzere sözde rastlantısal sayılar tahmin edilemez değil, sayıyı oluşturmadan önce onu tahmin edebilmek olası. Bu ise kullanımda büyük güvenlik açıkları doğuruyor. Örneğin yalnızca adresi bilen kişilerin ulaşabileceği bir sayfa veya dosya ismi belirlediniz ve bunu bir PRNG ile yaptınız. İşi bilen bir insan rastgele olduğunu düşündüğünüz o sonuca ulaşıp erişilmesini istemediğiniz o noktaya erişebilecektir. Senaryolar bundan ibaret de değil elbet, rastgelelik tahmin edilebilir olduğu zaman rastgelelik olmaktan çıkıyor. Bu gibi durumlar için <code class="language-plaintext highlighter-rouge">cryptographically secure random number generator</code> (kriptografik olarak güvenli rastgele sayı üreteci) adı verilen üreteçler kullanılır. /dev/random ve /dev/urandom sözde cihazları da kriptografik olarak güvenli olarak geçer. /dev/random, bir makine özelinde yaklaşık olarak tahmin edilebilir sonuçlar doğurabilir olsa da geniş bir perspektifte güvenli sayılabilir. Şayet özellikle kripto para, blockchain gibi güvenlik gerektiren bir platform kodluyorsanız bakmanız gereken rastgele sayı algoritmaları kriptografik olarak güvenli olanlar olmalıdır. Bunun için araştırma yapmalı ve uygun kütüphaneleri bulmalısınız. Geleceğe selamlar.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="programlama" /><category term="algoritma" /><summary type="html"><![CDATA[Bilgisayarlarda rastgele sayı üreten algoritmalara bir giriş]]></summary></entry><entry><title type="html">Windows için Daha İyi Terminal Kullanım Yolları</title><link href="https://yinkar.github.io/windows/komut-satiri/terminal/2021/11/27/windows-icin-daha-iyi-terminal-kullanim-yollari.html" rel="alternate" type="text/html" title="Windows için Daha İyi Terminal Kullanım Yolları" /><published>2021-11-27T09:26:00+03:00</published><updated>2021-11-27T09:26:00+03:00</updated><id>https://yinkar.github.io/windows/komut-satiri/terminal/2021/11/27/windows-icin-daha-iyi-terminal-kullanim-yollari</id><content type="html" xml:base="https://yinkar.github.io/windows/komut-satiri/terminal/2021/11/27/windows-icin-daha-iyi-terminal-kullanim-yollari.html"><![CDATA[<p>Geliştirme yapıyorsanız Windows özellikle terminal, veya kendi deyimiyle “komut satırı” konusunda oldukça sorun çıkarıyor. Yaklaşık 2.5 yıldır, MacOS kullandığım kısa bir dönemi saymazsak neredeyse kesintisiz şekilde Linux dağıtımları kullanıyorum. Bu süreçte Windows’u ancak 1-2 kere, o da mecburiyetten dolayı olacak şekilde kullanmışımdır. Özellikle düşük özelliklere sahip bilgisayarlarda insanı çıldırtıyor. Kimi zaman, istemesem de mecburiyetten Windows kullanmam gerekebiliyor, şu an da o durumdayım. Elimdeki bilgisayar yeni ve Windows 10 işletim sistemiyle gelmiş durumda. Daha önce daima yaptığımın aksine bu sefer, en azından şimdilik bu bilgisayara farklı bir işletim sistemi kurmayı düşünmüyorum, şu anlık bir stabiliteye ihtiyacım var. Her Windows kullanmam gerektiğinde başta geliştiricilik olmak üzere birçok konuda işletim sisteminin beni yavaşlattığını ve engel olduğunu görebiliyorum. Şimdi terminal konusunu ele almaya başlayalım.</p>

<p>Windows’un “cmd.exe” isimli komut satırı uygulaması zaten daima bildiğiniz gibi. Mecburiyetten kullanılır bir halde. Fakat onunla ilgili birkaç ipucu da vereyim de bu yazı olabildiğine yardımcı bir kaynak olsun.</p>

<p>Belki biliyorsunuzdur fakat bu ipucunu yine de vereyim. Sanırım Windows’ta bu gibi, System32 gibi yol değişkenine ekli klasörlerde yer alan uygulamaları açmanın en hızlı yolu <code class="language-plaintext highlighter-rouge">çalıştır</code> penceresini kullanmak. Bu yüzden, örneğin benim gibi Linux’ta <code class="language-plaintext highlighter-rouge">Ctrl + Alt + T</code> veya <code class="language-plaintext highlighter-rouge">Super + T</code> gibi kısayollarla hızlıca bir terminal penceresi açmaya alıştıysanız bu yolla Windows’ta da işinizi daha hızlı halledebilirsiniz. Biliyorsunuz, Windows tuşu diğer işletim sistemlerinde <code class="language-plaintext highlighter-rouge">Super</code> ismiyle geçer.</p>

<p><code class="language-plaintext highlighter-rouge">Windows + R</code> tuşu, çalıştır penceresini açacaktır. Buraya <code class="language-plaintext highlighter-rouge">cmd</code> yazarak <code class="language-plaintext highlighter-rouge">Enter</code> tuşuna bastığınızda Komut Satırına ulaşabilirsiniz. Sonraki Çalıştır penceresini açtığınız seferlerde, daha önceki yazdığınız komut da orada duruyor olacağından, bir tık daha hızlanabilirsiniz. Tabii buradan <code class="language-plaintext highlighter-rouge">mspaint</code>, <code class="language-plaintext highlighter-rouge">notepad</code> gibi uygulamaları da isimleriyle çağırabileceğinizi biliyorsunuzdur.</p>

<p>Şimdi pek bilinmeyen, fakat çok ihtiyaç duyulan bir ipucuna gelelim. Çoğu zaman Komut Satırı penceresini yönetici modunda çalıştırmak gerekebiliyor, örneğin paket yöneticileriyle global kurulumlar yapılacaksa. Çalıştır penceresinden çalıştırdığınız uygulamaları yönetici moduyla açıp açamayacağınızı merak ettiyseniz, bu mümkün. Uygulamanın ismi yazıldıktan sonra Enter tuşu yerine <code class="language-plaintext highlighter-rouge">Ctrl + Shift + Enter</code> tuş kombinasyonunu tuşladığınızda uygulamayı yönetici modunda açmanızı sağlayacak dialog ekranına ulaşabileceksiniz.</p>

<p>Yazılım geliştiriyorsanız, istediğiniz uygulamaları ve paketleri komut satırından yükleme ihtiyacınız oldukça fazla oluyordur. NPM, Pip gibi paket yöneticiler kurulu olduğunda, onların dahilindeki paketleri, eğer yönetici modundaysanız halihazırda kurabiliyorsunuz. Fakat bizzat Windows dahilinde global olarak çalışacak bir paket yönetici ihtiyacı hissetmişsinizdir. Bunun için <a href="https://chocolatey.org/install">Chocolatey</a>‘yi kullanabilirsiniz. Kurulumunu kendi sayfasında yer alan direktiflere göre Powershell üzerinde yaptıktan sonra, yönetici modunda açılmış terminallerle istediğiniz paketi kurabilir hale geleceksiniz. Örneğin <code class="language-plaintext highlighter-rouge">choco install php</code> diyerek PHP’yi sisteminize kurabileceksiniz. Bu şekilde yazılım geliştirme için ihtiyaç duyulan uygulamalar ve onların bağımlılıkları, ayarlamaları da çok daha hızlı bir şekilde yapılacak, çünkü Chocolatey bu paketleri önünüze olması gerektiği gibi seriyor.</p>

<p>Ha bir de Powershell meselesi var tabii. Kendisini gerçekten hiç sevmiyorum, arkaplan renk seçimi dahi berbat. Komutları ise bana aşırı çirkin geliyor. Komut ve betik dili olarak çok zengin olsa da, kullanım kolaylığı olarak pek bir şey katılmamış durumda. cmd.exe için söylediğim her şeyi Powershell için de kullanabilirsiniz.</p>

<p>Komut satırının çok saçma bir özelliği var: örneğin bir işlemin sonucunu beklerken pencerenin durakladığını fark edebiliyorsunuz ve pencereye bir geribildirimde bulununca aslında o işlemin çoktan bittiğini ve boşu boşuna beklediğinizi anlıyorsunuz. Bunun nedeni farkında olmadan pencereye tıklamış olmaktan kaynaklanıyor. Varsayılan olarak açık gelen bu saçmalık, ister inanın ister inanmayın cmd.exe’nin bir özelliği. Pencere başlığına sağ tıklayarak, <code class="language-plaintext highlighter-rouge">Özellikler</code> seçeneği ile ulaşacağınız pencereden <code class="language-plaintext highlighter-rouge">Hızlı Düzenleme Modu</code> seçeneğini deaktif ederek bundan kurtulabilirsiniz. İngilizcesi de <code class="language-plaintext highlighter-rouge">Quick Edit Mode</code> elbette.</p>

<p>Komut Satırının can sıkan noktalarından biri de kopyalama ve yapıştırma işleri. Bir metni seçtikten sonra <code class="language-plaintext highlighter-rouge">Enter</code> tuşuna bastığınızda metin kopyalanacaktır. Yapıştırmak için ise sağ tıklamanız gerekiyor.</p>

<p>Windows için daha iyi terminal seçenekleri mevcut. Örneğin Git kurulumu yaparsanız, bir klasörde sağ tıkladığınızda gelen seçeneklerden biri olan “Git Bash Here” ile ulaşabileceğiniz MINGW64 terminali. Bununla birçok açıdan tıpkı Linux’ta gibi bir kullanıma sahip olabilirsiniz. O an başka bir seçeneğim olmadığında, Git’e halihazırda daima ihtiyacım olduğundan genelde bunu kullanıyorum. <code class="language-plaintext highlighter-rouge">ls</code>, <code class="language-plaintext highlighter-rouge">cat</code>, <code class="language-plaintext highlighter-rouge">alias</code> ve benzeri Unix komutlarını kullanabilmenize olanak sağlayacaktır.</p>

<p>Bir başka seçenek ise <a href="https://cmder.net/">Cmder</a>. Websitesini incelediğinizde birçok kolaylık sağladığını göreceksiniz. Cmder, bir zip dosyası olarak iniyor. Bunu C:\cmder gibi bir dizine açtıktan sonra sistem yoluna (PATH değişkenine) ekleyerek kullanmaya başlayabilirsiniz. Ben aynı zamanda kendisi için <code class="language-plaintext highlighter-rouge">Ctrl + Alt + T</code> kısayolunu oluşturdum. Cmder’in görev çubuğundaki sekmesine sağ tıklayarak, özellikler seçeneğinden erişeceğiniz penceredeki Kısayol bölümüne istediğiniz kısayolu girebilirsiniz.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="windows" /><category term="komut-satiri" /><category term="terminal" /><summary type="html"><![CDATA[Visual Studio Code'da kenar çubuğundaki yetersiz ağaç girintilemesini arttırmak]]></summary></entry><entry><title type="html">Wayback Machine İpuçları</title><link href="https://yinkar.github.io/internet/ar%C5%9Fiv/2021/11/06/wayback-machine-ipuclari.html" rel="alternate" type="text/html" title="Wayback Machine İpuçları" /><published>2021-11-06T14:20:00+03:00</published><updated>2021-11-06T14:20:00+03:00</updated><id>https://yinkar.github.io/internet/ar%C5%9Fiv/2021/11/06/wayback-machine-ipuclari</id><content type="html" xml:base="https://yinkar.github.io/internet/ar%C5%9Fiv/2021/11/06/wayback-machine-ipuclari.html"><![CDATA[<p>İnternetin en kullanışlı araçlarından biri <a href="https://archive.org">Archive.org</a>‘un <a href="https://web.archive.org">Wayback Machine</a>‘i. Ben nostalji bağımlısı olduğum için kendisini oldukça fazla kullanıyorum. Bunun dışında bir kaynak göstermek gerektiğinde kaynağın aynı şekilde kalacak bir formatını içeren bağlantı verilmesi için de kullanılıyor. <a href="https://twitter.com/esesci/status/1441079965752070151">Geçenlerde yaşanan</a>, bir ders kitabının kaynakça kısmında verilen bir adresin oluşturduğu skandalımsı durum, bunun neden önemli olduğunun güzel bir örneği. Wikipedia’da kaynakça kısmında sıkça Wayback Machine adreslerinin kullanıldığını görebilirsiniz.</p>

<p>Öncelikle bir websiteniz varsa, sayfalarını Wayback Machine’e kaydetmeniz sizin için faydalı olacaktır. Çocukken yaptığım siteleri keşke zamanında kaydetseydim diyorum, şimdi neredeyse hiçbirine Wayback Machine de dahil hiçbir yerden erişemiyorum. Bunu yapmak için Wayback Machine’in ana sayfasında sağ altta bulunan formu kullanabilirsiniz.</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-1.png" alt="Wayback Machine sayfa kaydetme" /></p>

<p>Formu gönderdikten sonra açılan sayfayı da onayladığınızda işleminizin gerçekleştiğini göreceksiniz. Şimdi çok daha faydalı ipuçlarına geçelim.</p>

<p>Wayback Machine’de arama yapabilirsiniz. Çok detaylı bir arama imkanı sunmasa da, çoğu zaman geçmişteki websitelerinde arama yapmak istediğinizde size istediğiniz sonucu sunacaktır. Bunun için tek yapmanız gereken, Wayback Machine’in ana sayfasındaki kutucuğa bir site adresi yerine bir anahtar kelime yazmak.</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-2.png" alt="Wayback Machine'de arama yapmak" /></p>

<p>Adres çubuğunun aşağıdaki gibi değiştiğini görüyorsunuzdur.</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-3.png" alt="Wayback Machine adres çubuğu" /></p>

<p>Ben genelde web arayüzünden önce adres çubuğunu kullanırım. Formatı görüyorsunuz:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://web.archive.org/web/*/msn%20ifadeleri
</code></pre></div></div>

<p>Anahtar kelime yerine şunun gibi bir website adresi yazalım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://web.archive.org/web/*/hoppala.com
</code></pre></div></div>

<p>Sonuç şu şekilde olacak:</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-4.png" alt="Wayback Machine site kayıtları" /></p>

<p>Gördüğünüz gibi, adresin kayıtları çıkıyor. Ben Wayback Machine’i kullanacağım zaman adres çubuğuna <code class="language-plaintext highlighter-rouge">web.archive.org/web/*/</code> ve ardından aramak istediğim kelime veya kayıtlarını bulmak istediğim websitenin adresini yazarak kullanırım. İşler böyle daha hızlı oluyor. Şimdi bu formatın ne anlama geldiğine bakalım.</p>

<p>Herhangi bir kayda tıkladım ve adres çubuğu şu şekilde değişti:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://web.archive.org/web/20050205034905/http://www.hoppala.com/
</code></pre></div></div>

<p>Ekran görüntüsü de şu şekilde:</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-5.png" alt="Wayback Machine site kaydı" /></p>

<p>Anlayacağınız üzere bir önceki adreste yer alan <code class="language-plaintext highlighter-rouge">*</code> ifadesi tüm kayıtlar anlamına geliyordu. Şimdi ise bir zaman damgası (timestamp) var. Bu formatı ezberlemenize hiç gerek çok açıkçası, kısaca <code class="language-plaintext highlighter-rouge">gün-ay-yıl-saat-dakika-saniye</code>, daha doğru bir formatla <code class="language-plaintext highlighter-rouge">YYYYMMDDhhmmss</code> şeklinde.</p>

<p>Şimdi sayfanın kaynağını inceleyelim. <kbd>Ctrl</kbd> + <kbd>U</kbd> veya Mac kullanıyorsanız <kbd>Option</kbd> + <kbd>Command</kbd> + <kbd>U</kbd> kısayoluyla hızlıca açabilirsiniz. Sayfanın üst kısımlarında Wayback Machine’in kendi kodları olduğunu göreceksiniz, onları atlayalım. Kaydedilmiş sitenin, resimlerinin kayıttan çağrıldığı kısımdaki URL’lerinde bir farklılık göreceksiniz.</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-6.png" alt="Wayback Machine resim adresi" /></p>

<p>Adres şu şekilde:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://web.archive.org/web/20070614035910im_/http://www.hoppala.com/images/index_03.gif
</code></pre></div></div>

<p>Görüldüğü gibi, zaman damgası kısmının sonunda bir flag var. Bu onun bir resim olduğunu gösteriyor. Şimdi o flag’le ve o flag’i silerek resme gidelim:</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-7.png" alt="Wayback Machine resim adresi" /></p>

<p>Flag’i sildiğimizde normal bir sayfa gibi açıldı ve Wayback Machine’in çerçevesi de eklendi. Buradan aklınıza şu gelebilir: getirilen bir sayfanın zaman damgasının sonuna <code class="language-plaintext highlighter-rouge">im_</code> eklediğimizde o sayfada Wayback Machine çerçevesi çıkmayacak ve normal bir siteymiş gibi link verebileceğiz. Bu yöntem çalışıyor, ama doğru bir yöntem sayılmaz. Bunun için farklı flag’leri var Wayback Machine’in. Şimdi onları bir tablo olarak vereyim:</p>

<table>
  <thead>
    <tr>
      <th>Flag</th>
      <th>İsim</th>
      <th>Açıklama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>id_</td>
      <td>Identity</td>
      <td>Sayfada hiçbir değişiklik yapmadan, kaydedildiği gibi getirir</td>
    </tr>
    <tr>
      <td>js_</td>
      <td>JavaScript</td>
      <td>Sayfayı JavaScript olarak işaretlenmiş şekilde getirir</td>
    </tr>
    <tr>
      <td>cs_</td>
      <td>CSS</td>
      <td>Sayfayı CSS olarak işaretlenmiş şekilde getirir</td>
    </tr>
    <tr>
      <td>im_</td>
      <td>Image</td>
      <td>Sayfayı resim olarak getirir</td>
    </tr>
    <tr>
      <td>if_/fw_</td>
      <td>Iframe</td>
      <td>Sayfayı normal bir formatta, fakat Wayback Machine’in çerçevesi olmadan getirir</td>
    </tr>
  </tbody>
</table>

<p>Anlayacağınız üzere bir sayfayı getirirken id_, if_ veya fw_ flag’ini kullanmanız, çerçeveyi göstermemek için uygun olacaktır.</p>

<p><img src="/images/blog/wayback-machine/wayback-machine-8.png" alt="Wayback Machine çerçevesiz sayfa" /></p>

<p>Flag’lerin tam listesine Wikipedia’daki <a href="https://en.wikipedia.org/wiki/Help:Using_the_Wayback_Machine">şu</a> adresten eriştim. Belki orada işinize yarayacak başka bilgiler de bulursunuz.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="internet" /><category term="arşiv" /><summary type="html"><![CDATA[archive.org'un zaman makinesini daha detaylı kullanma yolları]]></summary></entry><entry><title type="html">Hex Renklerle ilgili İpuçları</title><link href="https://yinkar.github.io/programlama/css/renkler/2021/11/04/hex-renklerle-ilgili-ipuclari.html" rel="alternate" type="text/html" title="Hex Renklerle ilgili İpuçları" /><published>2021-11-04T19:57:00+03:00</published><updated>2021-11-04T19:57:00+03:00</updated><id>https://yinkar.github.io/programlama/css/renkler/2021/11/04/hex-renklerle-ilgili-ipuclari</id><content type="html" xml:base="https://yinkar.github.io/programlama/css/renkler/2021/11/04/hex-renklerle-ilgili-ipuclari.html"><![CDATA[<p>Genelde web üzerinde kullanılan hexadecimal, yani on altılı değerle gösterilen renkleri öğrenirken insanların atladığı birçok nokta oluyor ve renk kodlarını yalnızca ezberlemeyi tercih ediyorlar. Oysa bu renk kodlarına daha detaylı bir bakış atmak işinizi birçok yönden kolaylaştıracaktır.</p>

<p>On altılı sayı sistemini bildiğinizi umuyorum. Fakat bilmeyenler için yine de üstünden geçelim. Günlük hayatta kullandığımız sayı sistemi 10’luk sistemdir ve <code class="language-plaintext highlighter-rouge">decimal</code> olarak adlandırılır. 10 adet rakamdan oluşur, bunları biliyorsunuz: 0, 1, 2, 3, 4, 5, 6, 7, 8 ve 9. Bunun yanı sıra bilişimin temeli olan ikili sayı sistemi (binary) vardır. İkilik sistemde ise iki adet rakam vardır: 0 ve 1. Tüm sayılar bu sistemde 0 ve 1 ile gösterilir. Örneğin 13 sayısı binary olarak <code class="language-plaintext highlighter-rouge">1101</code> şeklinde yazılır. Bunun dışında octal adını verdiğimiz sekizli sayı sistemi vardır, bunda da 0’dan 7’ye kadar 8 adet rakam bulunur. 10’dan küçük olan sayı sistemlerini göstermemiz kolay, var olan rakamların bir kısmıyla gösterebiliyoruz. Fakat sayı sistemi 10’dan büyük olursa o zaman ne olacak? İşte on altılı sistem yani hexadecimal sistem bunun bir örneği. Rakamları şu şekilde:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, a, b, c, d, e, f
</code></pre></div></div>

<p>Dikkat ederseniz, 10’dan büyük “rakamlar” alfabedeki harflerin bir kısmıyla gösteriliyor. Burada rakam diyorum çünkü 16’lık sistemde 11, 12, 13, 14 ve 15, a, b, c, d, e sembolleriyle gösterilen birer rakam. Hexadecimal’in bir kısaltması olarak bu sistemdeki sayılardan bahsederken <code class="language-plaintext highlighter-rouge">hex</code> ismini kullanıyoruz. Harflerin büyük veya küçük olarak gösterilmesinde herhangi bir sorun yok.</p>

<p>Programlama dillerinde farklı sistemlerden sayılar farklı öneklerle gösterilir. Binary için <code class="language-plaintext highlighter-rouge">0b1000100</code>, octal için <code class="language-plaintext highlighter-rouge">0o104</code> gibi bir kullanım varken hexadecimal için ise <code class="language-plaintext highlighter-rouge">0x44</code> gibi bir kullanım vardır. CSS ve HTML gibi dillerde hex formatındaki renk kodları <code class="language-plaintext highlighter-rouge">#</code> işaretiyle başlar. Farklı dillerde hex kodlarının <code class="language-plaintext highlighter-rouge">0x</code> ile başladığını görebilirsiniz.</p>

<p>Şimdi renk kodlarını ele almaya başlayalım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#000000
</code></pre></div></div>

<p>Bu hex renk kodu olarak ifade edilebilecek en küçük değer. Siyah rengin renk kodu.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#ffffff
</code></pre></div></div>

<p>Bu ise hex renk kodu olarak ifade edilebilecek en büyük değer ve beyaz rengi veriyor.</p>

<p>Tabloyla bazı renk kodlarını gösterelim:</p>

<table>
  <thead>
    <tr>
      <th>Renk kodu</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>#ff0000</td>
      <td>Kırmızı</td>
    </tr>
    <tr>
      <td>#00ff00</td>
      <td>Yeşil</td>
    </tr>
    <tr>
      <td>#0000ff</td>
      <td>Mavi</td>
    </tr>
  </tbody>
</table>

<p>Tabloya bakınca bir şey dikkatinizi çekmiş olmalı. Her ikişer basamak aslında temel renkleri simgeliyor ve buradan da anlaşılıyor ki aslında hex kodları RGB (red-green-blue) renk değerlerini yazmanın başka bir yolu. <code class="language-plaintext highlighter-rouge">ff</code> değeri decimal sistemde 255’e denk geliyor. Yani aslında 0 ile 255 arasında üçer farklı renk seçimi yapıyoruz.</p>

<p>RGB’de olduğu gibi farklı karışımlarla farklı renkler elde edebiliyoruz. Şu şekilde kırmızıyla yeşili karıştıralım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#ffff00
</code></pre></div></div>

<p>Ortaya çıkan renk şöyle olacak:</p>

<div style="background-color: #ffff00; width: 50px; height: 50px"></div>

<p>Hex kodlarını 6 haneli olarak yazabileceğiniz gibi 3 haneli olarak yazmanız da mümkün. Daha dar bir skala sunsa da, temel renkler için kullanımı daha rahat olacaktır.</p>

<table>
  <thead>
    <tr>
      <th>Renk kodu</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>#000</td>
      <td>Siyah</td>
    </tr>
    <tr>
      <td>#fff</td>
      <td>Beyaz</td>
    </tr>
    <tr>
      <td>#f00</td>
      <td>Kırmızı</td>
    </tr>
    <tr>
      <td>#0f0</td>
      <td>Yeşil</td>
    </tr>
    <tr>
      <td>#00f</td>
      <td>Mavi</td>
    </tr>
  </tbody>
</table>

<p>Hex kodlarındaki her değeri aynı tutarsanız grinin çeşitli tonlarını elde edeceksiniz:</p>

<div style="background-color: #000; width: 70px; height: 20px; color: #fff">
    #000
</div>
<div style="background-color: #111; width: 70px; height: 20px; color: #fff">
    #111
</div>
<div style="background-color: #222; width: 70px; height: 20px; color: #fff">
    #222
</div>
<div style="background-color: #333; width: 70px; height: 20px; color: #fff">
    #333
</div>
<div style="background-color: #444; width: 70px; height: 20px; color: #fff">
    #444
</div>
<div style="background-color: #555; width: 70px; height: 20px; color: #fff">
    #555
</div>
<div style="background-color: #666; width: 70px; height: 20px; color: #fff">
    #666
</div>
<div style="background-color: #777; width: 70px; height: 20px; color: #fff">
    #777
</div>
<div style="background-color: #888; width: 70px; height: 20px; color: #fff">
    #888
</div>
<div style="background-color: #999; width: 70px; height: 20px; color: #000">
    #999
</div>
<div style="background-color: #aaa; width: 70px; height: 20px; color: #000">
    #aaa
</div>
<div style="background-color: #bbb; width: 70px; height: 20px; color: #000">
    #bbb
</div>
<div style="background-color: #ccc; width: 70px; height: 20px; color: #000">
    #ccc
</div>
<div style="background-color: #ddd; width: 70px; height: 20px; color: #000">
    #ddd
</div>
<div style="background-color: #eee; width: 70px; height: 20px; color: #000">
    #eee
</div>
<div style="background-color: #fff; width: 70px; height: 20px; color: #000">
    #fff
</div>

<p>Gri tonlar için <code class="language-plaintext highlighter-rouge">#c0c0c0</code>, <code class="language-plaintext highlighter-rouge">#1b1b1b</code> gibi ara değerler de kullanmanız mümkün.</p>

<p>6 haneli hex değerleri kullanırken sona 2 hane daha ekleyerek RGBA formatında kullanabilirsiniz, yani renge saydamlık özelliği verebilirsiniz. 3 haneli hex değerlerinde de bu doğal olarak 1 hane fazla olacak.</p>

<p>%50 opaklığa sahip, yani yarısaydam bir kırmızı renk şöyle bir renk koduyla oluşturulabilir:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#ff000088
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#f008
</code></pre></div></div>

<p>Sanırım bu kadar yeterli.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="programlama" /><category term="css" /><category term="renkler" /><summary type="html"><![CDATA[On altılık renk değerleriyle ilgili küçük tüyolar]]></summary></entry><entry><title type="html">Neden Brainfuck Öğrenmeyelim ki</title><link href="https://yinkar.github.io/programlama/ezoterik/brainfuck/2021/11/04/neden-brainfuck-ogrenmeyelim-ki.html" rel="alternate" type="text/html" title="Neden Brainfuck Öğrenmeyelim ki" /><published>2021-11-04T17:31:00+03:00</published><updated>2021-11-04T17:31:00+03:00</updated><id>https://yinkar.github.io/programlama/ezoterik/brainfuck/2021/11/04/neden-brainfuck-ogrenmeyelim-ki</id><content type="html" xml:base="https://yinkar.github.io/programlama/ezoterik/brainfuck/2021/11/04/neden-brainfuck-ogrenmeyelim-ki.html"><![CDATA[<p>Bir dilin karmaşık bir yapısıyla karşılaşıldığında genelde Brainfuck örneği veriliyor; örneğin Regex ifadeleri ve programlama dillerindeki bazı syntactic sugar’lar. Onlara da değiniriz belki ileride. Brainfuck ise muhtemelen makine diliyle, assembly’lerle uğraşmış bir insana o kadar karmaşık gelmeyecektir. Aslında yapı olarak onların yapısının küçük bir kısmının değişik bir yorumunu barındırıyor.</p>

<p>Dün biraz Brainfuck öğrendim. Uzun zamandır aklımdaydı aslında. Youtube’a ismini yazıp, geçmiş aramalardan görerek hatırlayabilmek istiyordum fakat Youtube, üzerine vazife olmadan brainfuck kelimesini sansürlüyor. Böyle zırva özellikleri kapatamıyorsun da.</p>

<p>Brainfuck bir ezoterik programlama dili olarak geçiyor. İleride ezoterik programlama dillerini konu alacağım bir yazı olacak. Aslında birçoğu için parodi programlama dili daha uygun bir isim olabilirdi. Brainfuck’ın oluşturulmasındaki temel amaç, en küçük boyuttaki derleyiciye sahip olan bir dil yaratmak. Brainfuck o kadar temel kurallara sahip ki, dili öğrendikten sonra derleyicisini veya yorumlayıcısını kodlamayı birçok insan başarabilecektir. Kendisi turing-complete bir dil, bu da demek oluyor ki bu dil ile teorik olarak tüm problemleri çözebilecek programlar yazılabilir.</p>

<p>Brainfuck dilinin teorik kısmını öğrenmek çok basit aslında, vakit alacak olan kısım dilin yapısı gereği geliştirilmek durumunda olan algoritmalar. Şimdi hafif hafif dilin yapısına giriş yapalım.</p>

<p>Brainfuck dili sekiz tane karakterden oluşuyor. Bu ifadeler: <code class="language-plaintext highlighter-rouge">&lt;&gt;+-[].,</code> şeklinde. Bunlar dışında dosyaya yazılacak herhangi bir karakter görmezden geliniyor ve bir nevi yorum satırı görevi görüyor.</p>

<p>Brainfuck diliyle kodlama yaparken yaptığımız esas işlem aslında hafızayı manipüle etmek. Elimizde herbiri birer Byte taşıyan, 30000 adet hafıza bloğu yer alıyor. Biz bu hafıza şeridi üzerinde ileri geri giderek içlerinde olan değerleri arttırıp azaltıyoruz. Bunun dışında çıkmak için tek koşulun bulunduğumuz hafıza bloğunun içindeki değerin 0 olması olduğu döngüler yazabiliyoruz ve çıktı alıp girdi verebiliyoruz.</p>

<p>Aslında bahsettiğim şu operatör karakterlerine bakarak neyin ne için kullanılacağını aşağı yukarı anlayabilirsiniz. Şimdi bir tablo ile detaylandıralım:</p>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&lt;</td>
      <td>Hücreler arasında bir geri git</td>
    </tr>
    <tr>
      <td>&gt;</td>
      <td>Hücreler arasında bir ileri git</td>
    </tr>
    <tr>
      <td>+</td>
      <td>Üzerinde bulunulan hücrenin değerini 1 arttır</td>
    </tr>
    <tr>
      <td>-</td>
      <td>Üzerinde bulunulan hücrenin değerini 1 azalt</td>
    </tr>
    <tr>
      <td>[</td>
      <td>Hücrenin değeri 0’dan farklıysa devam eden bir döngü oluştur</td>
    </tr>
    <tr>
      <td>]</td>
      <td>Döngü kod bloğunu kapat</td>
    </tr>
    <tr>
      <td>,</td>
      <td>Girdi olarak 1 karakter al</td>
    </tr>
    <tr>
      <td>.</td>
      <td>Çıktı olarak 1 karakter bastır</td>
    </tr>
  </tbody>
</table>

<p>Şimdi insan der ki, “e hocam, burada yalnızca bu karakterler var. Elimizde metne benzeyen hiçbir şey yok”. Doğru. İnsanın doğal olarak aklına şu geliyor: “bir hello world örneği yazsak, nasıl yazacağız?”.</p>

<p>Brainfuck dilinde girdi ve çıktı sözkonusu olduğunda hücrelerin değerleri birer ASCII karakteri olarak yorumlanıyor. Örneğin üzerinde bulunduğumuz hafıza bloğunun değeri 65 olduğunda, <code class="language-plaintext highlighter-rouge">.</code> karakteriyle ekrana <code class="language-plaintext highlighter-rouge">A</code> çıktısını basıyoruz.</p>

<p>Aslında <a href="/toys">Toys</a> sayfasında bir ASCII tablosu oluşturmayı düşünüyorum, tercihen markdown kullanarak.</p>

<p>Gelecekten mesaj: <a href="/ascii-table">Kodladım</a></p>

<p>Bunun yanında periyodik tablo, elektromanyetik spektrum, akor cetveli gibi farklı disiplinlerdeki farklı referans tablolarını da kodlayarak bu siteye eklemek gibi bir fikrim var. Şimdilik ASCII tablosundaki rakamları ve büyük ve küçük harfleri gösteren bir tablo oluşturayım buraya:</p>

<table>
  <thead>
    <tr>
      <th>#</th>
      <th>Karakter</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>48</td>
      <td>0</td>
    </tr>
    <tr>
      <td>49</td>
      <td>1</td>
    </tr>
    <tr>
      <td>50</td>
      <td>2</td>
    </tr>
    <tr>
      <td>51</td>
      <td>3</td>
    </tr>
    <tr>
      <td>52</td>
      <td>4</td>
    </tr>
    <tr>
      <td>53</td>
      <td>5</td>
    </tr>
    <tr>
      <td>54</td>
      <td>6</td>
    </tr>
    <tr>
      <td>55</td>
      <td>7</td>
    </tr>
    <tr>
      <td>56</td>
      <td>8</td>
    </tr>
    <tr>
      <td>57</td>
      <td>9</td>
    </tr>
    <tr>
      <td>65</td>
      <td>A</td>
    </tr>
    <tr>
      <td>66</td>
      <td>B</td>
    </tr>
    <tr>
      <td>67</td>
      <td>C</td>
    </tr>
    <tr>
      <td>68</td>
      <td>D</td>
    </tr>
    <tr>
      <td>69</td>
      <td>E</td>
    </tr>
    <tr>
      <td>70</td>
      <td>F</td>
    </tr>
    <tr>
      <td>71</td>
      <td>G</td>
    </tr>
    <tr>
      <td>72</td>
      <td>H</td>
    </tr>
    <tr>
      <td>73</td>
      <td>I</td>
    </tr>
    <tr>
      <td>74</td>
      <td>J</td>
    </tr>
    <tr>
      <td>75</td>
      <td>K</td>
    </tr>
    <tr>
      <td>76</td>
      <td>L</td>
    </tr>
    <tr>
      <td>77</td>
      <td>M</td>
    </tr>
    <tr>
      <td>78</td>
      <td>N</td>
    </tr>
    <tr>
      <td>79</td>
      <td>O</td>
    </tr>
    <tr>
      <td>80</td>
      <td>P</td>
    </tr>
    <tr>
      <td>81</td>
      <td>Q</td>
    </tr>
    <tr>
      <td>82</td>
      <td>R</td>
    </tr>
    <tr>
      <td>83</td>
      <td>S</td>
    </tr>
    <tr>
      <td>84</td>
      <td>T</td>
    </tr>
    <tr>
      <td>85</td>
      <td>U</td>
    </tr>
    <tr>
      <td>86</td>
      <td>V</td>
    </tr>
    <tr>
      <td>87</td>
      <td>W</td>
    </tr>
    <tr>
      <td>88</td>
      <td>X</td>
    </tr>
    <tr>
      <td>89</td>
      <td>Y</td>
    </tr>
    <tr>
      <td>90</td>
      <td>Z</td>
    </tr>
    <tr>
      <td>97</td>
      <td>a</td>
    </tr>
    <tr>
      <td>98</td>
      <td>b</td>
    </tr>
    <tr>
      <td>99</td>
      <td>c</td>
    </tr>
    <tr>
      <td>100</td>
      <td>d</td>
    </tr>
    <tr>
      <td>101</td>
      <td>e</td>
    </tr>
    <tr>
      <td>102</td>
      <td>f</td>
    </tr>
    <tr>
      <td>103</td>
      <td>g</td>
    </tr>
    <tr>
      <td>104</td>
      <td>h</td>
    </tr>
    <tr>
      <td>105</td>
      <td>i</td>
    </tr>
    <tr>
      <td>106</td>
      <td>j</td>
    </tr>
    <tr>
      <td>107</td>
      <td>k</td>
    </tr>
    <tr>
      <td>108</td>
      <td>l</td>
    </tr>
    <tr>
      <td>109</td>
      <td>m</td>
    </tr>
    <tr>
      <td>110</td>
      <td>n</td>
    </tr>
    <tr>
      <td>111</td>
      <td>o</td>
    </tr>
    <tr>
      <td>112</td>
      <td>p</td>
    </tr>
    <tr>
      <td>113</td>
      <td>q</td>
    </tr>
    <tr>
      <td>114</td>
      <td>r</td>
    </tr>
    <tr>
      <td>115</td>
      <td>s</td>
    </tr>
    <tr>
      <td>116</td>
      <td>t</td>
    </tr>
    <tr>
      <td>117</td>
      <td>u</td>
    </tr>
    <tr>
      <td>118</td>
      <td>v</td>
    </tr>
    <tr>
      <td>119</td>
      <td>w</td>
    </tr>
    <tr>
      <td>120</td>
      <td>x</td>
    </tr>
    <tr>
      <td>121</td>
      <td>y</td>
    </tr>
    <tr>
      <td>122</td>
      <td>z</td>
    </tr>
  </tbody>
</table>

<p>Python çok tatlı dil değil mi?</p>

<p><img src="/images/blog/brainfuck/brainfuck-1.png" alt="Python ASCII alfanumerik tablo oluşturma" /></p>

<p>Şimdi Brainfuck’a geri dönelim. Boş bir programda bahsettiğim şu hafıza şeridi şu şekilde görünecektir:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 0 | 0 | 0 | 0 | 0 | ...
  ^
</code></pre></div></div>

<p>Bilişimde Turing makinesi adlı bir konsept vardır. Bunun yapısı da ona oldukça benziyor. Akla gelebilecek ve teorik olarak var olabilecek her programı oluşturabilmeyi sağlamasının nedeni de bu. Tüm programlama dilleri çalıştığında birer turing makinesi oluşturur ve bu şekilde problemleri çözerler. Turing makinesini yalnızca fiziksel bir makine olarak düşünmeyin, soyut olarak da, emülasyon şeklinde de var olabilir. Fiziksel olarak da kullanılması mümkün elbette.</p>

<p>Turing makinesine de ileride bir yazıda değiniriz belki. Basitçe açıklamak gerekirse:</p>

<p>Turing makinesi konseptinde bir okuma kafası olur, makinenin ne yapması gerektiğini belirleyen komutları içeren bir geçiş tablosu olur ve teorik olarak sonsuz kabul edilen, teyp diyebileceğimiz bir hafıza şeridi olur. Makine bu şeritten okur, okuduğu değere göre bir eylem gerçekleştirebilir ve bu şeride bir değer yazabilir.</p>

<p>Bizim de burada, <code class="language-plaintext highlighter-rouge">^</code> sembolüyle gösterdiğimiz bir okuyucu kafa var. Bu bir pointer’dır, C’deki kullanımlarına da girebiliriz, şimdilik bu yazıda girmeyi düşünmüyorum. Pointer, bir değişkenin hafızadaki adresini tutar. Biz istediğimiz zaman o pointer’ı kullanarak o adrese erişebiliriz veya pointer’ın değerini değiştirerek pointer’ın işaret ettiği adresi kaydırabiliriz.</p>

<p><code class="language-plaintext highlighter-rouge">+</code> sembolünün, işaret edilen hücredeki değeri bir arttırdığını söylemiştim. Şimdi şöyle bir program yazalım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+
</code></pre></div></div>

<p>Bu program çalıştığında hafıza blokları şu hali alacak:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 1 | 0 | 0 | 0 | 0 | ...
  ^
</code></pre></div></div>

<p>Şimdi kafanın yeriyle oynayalım. Şöyle bir program yazalım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt;
</code></pre></div></div>

<p>Çalıştığında hafıza blokları bu şekilde olacak:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 0 | 0 | 0 | 0 | 0 | ...
      ^
</code></pre></div></div>

<p>Tek yaptığı pointer’ı bir sağa kaydırmak oldu. Bunları bir arada kullanabiliriz.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+++++ &gt; +++ &gt; ++++ &lt; -
</code></pre></div></div>

<p>Bu operatörler dışında hiçbir karakterin yorumlanmadığını söylemiştim, o yüzden daha anlaşılır gözükmesi için boşluklar ekliyorum. Şimdi bu kod çalıştığında yapı en son şöyle olacak:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 5 | 2 | 4 | 0 | 0 | ...
      ^
</code></pre></div></div>

<p>Program başladığında bulunulan ilk hücrenin değerini 5 arttırdık, bir sonraki hücreye geçtik ve onu 3 arttırdık, bir sonraki hücreye de geçerek onu da 4 arttırdık. Sonra bir önceki hücreye geri dönüp onu bir azalttık.</p>

<p>Değerleri ASCII tablosunun sınırlarını aşmayacak şekilde istediğiniz gibi arttırabilirsiniz. Bu arada bu kodları denemek için herhangi bir Brainfuck interpreter’ı bulabilirsiniz. Hatta <a href="https://fatiherikli.github.io/brainfuck-visualizer/">şuradaki</a> gibi bir görselleştiriciyi de kullanabilirsiniz. Ben de bir tane kodlamayı düşünüyorum.</p>

<p>Gelecekten mesaj: <a href="https://yinkar.github.io/cerebrum-penetrate">Kodladım</a></p>

<p>Tabii gördüğünüz gibi bunları yazıyoruz, ama elimize bir şey geçmiyor. Şimdi ekrana artık bir şeyler basalım.</p>

<p>En basit şekilde <code class="language-plaintext highlighter-rouge">A</code> harfini şöyle basabileceğiniz aklınıza gelmiştir:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .
</code></pre></div></div>

<p>Hafıza blokları şu şekilde olacak:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 65 | 0 | 0 | 0 | 0 | ...
  ^
</code></pre></div></div>

<p>Çıktı:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A
</code></pre></div></div>

<p>İlk hücreye 65 yazıldı ve en son <code class="language-plaintext highlighter-rouge">.</code> operatörüyle de ekrana ASCII tablosundaki <code class="language-plaintext highlighter-rouge">65</code> numaralı karakter olan <code class="language-plaintext highlighter-rouge">A</code> harfi basıldı. <strong>Bunu yapmayın tabii.</strong> Böyle saçmalık mı olur, yoksa programlamanın anlamı mı kalır?</p>

<p>Bunu optimize etmeden önce metnin geri kalanını ekrana basmanın yolunu da göstereyim. Yukarıdaki ifadeye <code class="language-plaintext highlighter-rouge">+.</code> eklediğinizde ekrana <code class="language-plaintext highlighter-rouge">B</code> karakteri de basılacak, yine <code class="language-plaintext highlighter-rouge">+.</code> eklediğinizde <code class="language-plaintext highlighter-rouge">C</code> de basılacak ve çıktı <code class="language-plaintext highlighter-rouge">ABC</code> olacak. Çünkü değer 65’ken basıldı, 66 oldu ve onun değeri de basıldı, son olarak da 67 oldu ve onun değeriyle beraber bu üçü ekrana basılmış oldu.</p>

<p>Bunu daha uygun bir şekilde yapmanın yolu elbette döngü kullanmak:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>++++++++ [ &gt; ++++++++ &lt; - ] &gt; + .
</code></pre></div></div>

<p>Hafıza:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 0 | 65 | 0 | 0 | 0 | ...
      ^
</code></pre></div></div>

<p>Çıktı:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A
</code></pre></div></div>

<p>Bunu görünce Brainfuck’ın adına yakışır noktalara gelmeye başladığımızı düşünebilirsiniz. Aslında çok da büyük bir şey yapmadık, değiştirdiğimiz kısım yalnızca bir çarpma işleminden ibaretti. 8 ile 8’i çarpttık, son olarak da 1 ekledik ve 65’e ulaştıktan sonra değeri ekrana bastık.</p>

<p>65’e ulaşmak için herhangi iki sayıyı kullandım, siz daha farklı sayılar kullanabilirsiniz. İlk olarak ilk hücrenin değerini 8’e çıkartıyorum ve bir döngü başlatıyorum. Bu döngünün yaptığı şey aslında bir sonraki hücreye gidip orayı 8 arttırmak ve geriye dönüp ilk hücrenin değerini her adımda 1 eksiltmek. Her adımda 1 eksilterek o sayı kadar çalışmasını sağlıyorum. Yani ikinci hücrenin değeri 8 kere, 8 arttırılıyor, bu da çarpma demek zaten. Sürekli 1 azaltılan ilk hücrenin değeri 0’a ulaşınca döngüden çıkılıyor ve <code class="language-plaintext highlighter-rouge">&gt;</code> operatörüyle ikinci hücreye gidip <code class="language-plaintext highlighter-rouge">+</code> ile <code class="language-plaintext highlighter-rouge">64</code> olan değerini 1 arttırarak <code class="language-plaintext highlighter-rouge">.</code> ile ekrana basıyoruz.</p>

<p>Bunu, sonucu ilk hücrede olacak şekilde hesaplamak isteseydiniz şöyle olurdu:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; ++++++++ [ &lt; ++++++++ &gt; - ] &lt; +.
</code></pre></div></div>

<p>Hafıza:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>| 65 | 0 | 0 | 0 | 0 | ...
  ^
</code></pre></div></div>

<p>Çıktı:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A
</code></pre></div></div>

<p>Özetle, şu formatta bir kod gördüğünüzde bunun, sonucu ikinci hücrede olacak olan bir çarpma işlemi olduğunu bilin:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{ilk_sayı_kadar_artı} [ &gt; {ikinci_sayi_kadar_artı} &lt; - ]
</code></pre></div></div>

<p>Buraya kadar öğrendiklerinizle, bir “hello world” uygulaması yazabilmeniz mümkün. Ben şöyle bir örnek oluşturayım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt;+++++++++[&lt;++++++++++&gt;-]&lt;-.&gt;+++[&lt;+++++&gt;-]&lt;+.+++++.---.&gt;+++[&lt;---&gt;-]&lt;-.&gt;++++[&lt;++++&gt;-]&lt;+.
</code></pre></div></div>

<p><img src="/images/blog/brainfuck/brainfuck-2.png" alt="Brainfuck örneği" /></p>

<p><code class="language-plaintext highlighter-rouge">bf</code> isimli Brainfuck yorumlayıcısına Debian temelli Linux dağıtımlarında <code class="language-plaintext highlighter-rouge">apt</code> ile ulaşabilirsiniz.</p>

<p>Input alma konusunda da çok kısa değineyim. Programda <code class="language-plaintext highlighter-rouge">,</code> kullandığınız yerde bir karakter girmeniz beklenir. Bu karakter alındığında karakterin ASCII değeri o an bulunulan hücreye yazılır.</p>

<p>Bu yazı bu kadar yeterli. Zaten yorgun kafayla yazdım, hatalar olabilir. Geleceğe selamlar, ben gidiyorum.</p>

<p><a href="https://yinkar.github.io/cerebrum-penetrate">Brainfuck Yorumlayıcısı</a></p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="programlama" /><category term="ezoterik" /><category term="brainfuck" /><summary type="html"><![CDATA[Brainfuck isimli ezoterik programlama diline giriş]]></summary></entry><entry><title type="html">p5.js’e Giriş</title><link href="https://yinkar.github.io/programlama/js/p5js/sanat/2021/10/31/p5js-giris.html" rel="alternate" type="text/html" title="p5.js’e Giriş" /><published>2021-10-31T10:00:00+03:00</published><updated>2021-10-31T10:00:00+03:00</updated><id>https://yinkar.github.io/programlama/js/p5js/sanat/2021/10/31/p5js-giris</id><content type="html" xml:base="https://yinkar.github.io/programlama/js/p5js/sanat/2021/10/31/p5js-giris.html"><![CDATA[<p>p5.js, Processing isimli projenin JavaScript’e uyarlanmış bir versiyonudur. Processing’den biraz bahsetmek gerekirse, çok rahat bir şekilde oyun, elektronik sanat gibi çeşitli görsel uygulamalar tasarlamak için kullanılan bir grafik kütüphanesi ve aynı zamanda IDE (tümleşik geliştirme ortamı)’dir. Processing’in birçok dile birçok uyarlaması vardır. Bu uyarlamalardan p5.js’in kullanımı çok rahattır ve desteği de oldukça iyidir. Hoş da bir dökümantasyona sahip. Processing’de yazılan programlar kolayca p5.js’e uyarlanabilir.</p>

<p>p5.js kullanırken JavaScript yazmaya devam edebilirsiniz. Standart Canvas API yerine p5.js’i kullandığınızda oldukça hızlı işler ortaya çıkarabildiğinizi göreceksiniz. Yalnızca 2 boyutlu değil, 3 boyutlu işler de çıkarmanız mümkün. Benim de birkaç denemem olmuştu, bunlardan birini <a href="/toys/ucank">bu</a> adres üzerinden görebilirsiniz. Belki onu da detaylıca inceleriz.</p>

<p>Bir oyun kütüphanesi kadar yüklü olmayıp, saf JavaScript kadar da temel işlemler için bize bağlı olmayan bir kütüphane olması oyun prototipleri geliştirebilmemiz için p5.js’i ideal kılıyor. Bu kütüphaneyi kullanarak birçok ıvır zıvır kodladım, <a href="/toys/seken-aksu">bu</a>, <a href="/toys/game-of-life">bu</a> ve <a href="/ansi-art-painter">bu</a> birkaç örnek. Yayınlamadığımda onlarca ufak tefek iş var.</p>

<p>Bu kütüphaneyi CDN üzerinden sayfanıza dahil ederek kullanabilirsiniz:</p>

<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"</span><span class="nt">&gt;&lt;/script&gt;</span></code></pre></figure>

<p>Canvas elementini p5.js’in kendi içerisinde oluşturuyorsunuz, bu yüzden HTML sayfasında canvas elementine ihtiyacınız yok. Bir JavaScript dosyası oluşturarak kodlamaya başlayabilirsiniz.</p>

<p>Ancak biz burada p5.js için web üzerinden sunulmuş olan bir geliştirme ortamı olan <a href="https://editor.p5js.org/">p5.js Web Editor</a>‘ü kullanacağız. Sayfayı açın ve incelemeye başlayalım. Bir üyelik oluşturursanız iyi olur, fakat bir şeyler kodlayıp kaydetmek için üyelik zorunlu değil.</p>

<p><img src="/images/blog/p5js/p5js-1.png" alt="p5.js Web Editor arayüzü" /></p>

<p>Şimdi burada bazı bahsedeceğim kısımları işaretledim. Bende karanlık mod seçili. Bunu sağ üstteki <code class="language-plaintext highlighter-rouge">1</code> olarak işaretlediğim çark sembolüyle ayarlar penceresini açarak ayarlayabilirsiniz.</p>

<p><code class="language-plaintext highlighter-rouge">2</code> ile işaretlediğim butona tıkladığınızda, bu editörün aslında basitçe <code class="language-plaintext highlighter-rouge">index.html</code>, <code class="language-plaintext highlighter-rouge">style.css</code> ve <code class="language-plaintext highlighter-rouge">sketch.js</code> ismindeki üç dosyadan ibaret bir proje üzerinde çalıştığını göreceksiniz. Biz burada yalnızca önümüzde açık olan <code class="language-plaintext highlighter-rouge">sketch.js</code>‘i kullanarak p5.js ile oldukça sade bir şekilde kodlama yapabiliyoruz. Başlangıç için basit projelerde bu yeterli. İleride farklı objeleri farklı JS dosyalarında tutmak isteyebilirsiniz, resim gibi dosyalar eklemek isteyebilirsiniz. Bunun için açtığınız bu kenar çubuğunda dosya yükleme ve oluşturma seçenekleri mevcut.</p>

<p><code class="language-plaintext highlighter-rouge">3</code> ile işaretlediğim kısım anlayacağınız üzere projeyi başlatıp durdurmaya yarıyor. “Auto-refresh” seçeneğini yazdığınız an çalışmaya başlayacak ve butonlara tıklamanız gerekmeyecek. Ben hiç kullanma gereği duymadım. Bu kısmın hemen yanında dosya ismi belirlenen kısım mevcut, açtığınızda rastgele bir isim belirleniyor. Şimdilik bir önemi olmadığı için işaretlemedim.</p>

<p><code class="language-plaintext highlighter-rouge">4</code> ile işaretlediğim kısım da görüldüğü gibi kodları yazacağımız kısım. Açar açmaz en temel haliyle p5.js’in kullanımını görüyorsunuz. Odağımız bu kısımda olacak. Kenar çubuğundan başka bir dosyayı seçtiğinizde onun içeri de burada yer alacak.</p>

<p><code class="language-plaintext highlighter-rouge">5</code> ile işaretli kısım ise projenin önizlemesinin yer aldığı kısım. Eğer yukarıda yer alan play butonuna tıklarsanız burada gri bir kare çizildiğini göreceksiniz.</p>

<p>Bu arada sol altta da konsolu görüyorsunuzdur. Hata ayıklama yaptığımızda bastığımız değerler orada görünecek. Kendisinin developer tools’un konsolundan bir farkı yok.</p>

<p>Kodu incelemeye başlayalım. p5.js’i oyun kodlamak için kullanmayı öğretmeyi amaçladığımdan burada projeden “oyun” adıyla bahsedeceğim. <code class="language-plaintext highlighter-rouge">setup()</code> fonksiyonu oyun başladığı an bir kere çalışır ve ilk işlemleri yapmaya yarar. <code class="language-plaintext highlighter-rouge">draw()</code> fonksiyonu ise sürekli olarak çalışır. Amacı ekrana çizim yapmak olduğu için mevcut FPS değeri kadar sıklıkla çalışması gerekir. Oyundaki güncellemeleri de bu kısımda yapabiliriz. İleride belki <code class="language-plaintext highlighter-rouge">update()</code> adından bir fonksiyon ile hesaplamaları yaparak <code class="language-plaintext highlighter-rouge">draw()</code> fonksiyonunu yalnızca çizim yapması için rahat bırakabiliriz. Ben sürekli hızlıca prototip geliştirdiğimden işlemleri de <code class="language-plaintext highlighter-rouge">draw()</code> fonksiyonunda yapıyorum, fakat ciddi bir proje oluşturacağım zaman bu ayrımı yapmak daha iyi olur.</p>

<p><code class="language-plaintext highlighter-rouge">setup()</code> fonksiyonunun içinde görüldüğü üzere <code class="language-plaintext highlighter-rouge">createCanvas()</code> fonksiyonu çağırıyor. Bu, bahsettiğim gibi bir canvas oluşturmaya yarıyor. Şimdi bu fonksiyonun parametrelerini 640, 480 gibi istediğiniz bir değerle değiştirin.</p>

<p><code class="language-plaintext highlighter-rouge">draw()</code> fonksiyonunun içinde de <code class="language-plaintext highlighter-rouge">background()</code> isminde bir fonksiyon çağırılmış. Bu ise tüm canvas’ın arkaplan rengini belirlemeyi sağlıyor. Canvas API’dan yola çıkarsak, bunu tüm canvas’ı kaplayan bir dikdörtgeni boyamak gibi düşünebilirsiniz. Aldığı parametre ise 0 ile 255 arasında yer alıyor ve 0 siyahı, 255 ise beyazı temsil ediyor. Buna örneğin 75 gibi bir değer verelim.</p>

<p>Şimdi play tuşuna bastığınızda şöyle bir sonuç göreceksiniz:</p>

<p><img src="/images/blog/p5js/p5js-2.png" alt="p5.js Web Editor demo" /></p>

<p>Şimdi ekrana bir daire çizelim. Bunun için draw() fonksiyonunun içinde circle() fonksiyonunu çağıracağız. Kendisi şöyle parametreler alıyor</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>circle(x, y, yarıçap)
</code></pre></div></div>

<p>Bu tür görsel programlama uygulamalarında ekranın sol üst kısmı 0, 0 noktasıdır. Sola doğru x değeri artar, aşağı doğru y değeri artar. Bunu kendiniz örneğin terminal üzerinde çalışan görsel bir uygulama kodladığınızda daha iyi anlarsınız.</p>

<p>Şimdi, 50’ye 100 noktasında 75 birim yarıçapa sahip bir daire oluşturalım. draw() fonksiyonuna şunu yazın:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">circle</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">75</span><span class="p">);</span></code></pre></figure>

<p>Çıktımız şu olacak:</p>

<p><img src="/images/blog/p5js/p5js-3.png" alt="p5.js Web Editor demo" /></p>

<p>Hadi bu arkadaşı boyayalım. Canvas’ı daima gerçek hayattaki bir tuval gibi düşünün, bunu bir şekli döndürmeyi anlattığımda daha güzel bir örnekle açıklayacağım. Canvas dediğimiz yapı üzerinde obje kavramı yoktur, yalnızca üst üste çizilen şekiller vardır ve o şekle sonradan ulaşmamız da mümkün değildir. Bu yüzden biz obje oluşturup, o objenin değerlerine göre şekiller çizeriz. Bunu anlatmamın nedeni ise boyamayla ilgili. Ekranda bir şeklin içini doldurabilir ve kenar çizgisini renklendirebiliriz. Bunu yapmak için önce gerçek hayattaki bir durumu gözünüzde canlandırın; fırçamızı bir renge batırıyoruz ve boyuyoruz. Fırçamızı başka bir renge batırana kadar fırçamız o renkte kalıyor.</p>

<p>Nesnenin içini doldurmak için <code class="language-plaintext highlighter-rouge">fill()</code>, dış çizgisini boyamak için <code class="language-plaintext highlighter-rouge">stroke()</code> fonksiyonlarını kullanıyoruz. Bu fonksiyonların parametreleri <code class="language-plaintext highlighter-rouge">background()</code> fonksiyonuyla aynı. İçi şeffaf olsun istiyorsak parametresiz bir şekilde <code class="language-plaintext highlighter-rouge">noFill()</code> fonksiyonunu, dış çizgisiz olsun istiyorsak yine aynı şekilde <code class="language-plaintext highlighter-rouge">noStroke()</code> fonksiyonlarını çağırıyoruz.</p>

<p>Şimdi circle() fonksiyonundan önce fill() ve stroke() fonksiyonlarını örneğin şu şekilde çağırın:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">fill</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
<span class="nx">stroke</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>
<span class="nx">circle</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">75</span><span class="p">);</span></code></pre></figure>

<p>Çıktı şöyle olacak.</p>

<p><img src="/images/blog/p5js/p5js-4.png" alt="p5.js Web Editor demo" /></p>

<p>Şimdiye kadar background(), fill() ve stroke() fonksiyonlarında yalnızca siyah ve beyaz arasında, yani grayscale renkler kullandık. Eğer tek parametre alıyorlarsa bu şekilde, üç tane parametre vererek RGB (red, green, blue) renkler kullanabiliriz. Daha sonradan çok daha fazla renk seçeneği kullanmamızı sağlayan <code class="language-plaintext highlighter-rouge">color()</code> fonksiyonundan bahsederiz.</p>

<p>fill() ve stroke() fonksiyonunun parametrelerini şunun gibi istediğiniz üç değerle değiştirin:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">fill</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="nx">stroke</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">);</span></code></pre></figure>

<p>Çıktı da şu şekilde:</p>

<p><img src="/images/blog/p5js/p5js-5.png" alt="p5.js Web Editor demo" /></p>

<p>Şimdi bazı değerleri değişken üzerinden kontrol ederek biraz hareket katalım. Tüm kodların en başında <code class="language-plaintext highlighter-rouge">daireX</code> adından bir değişken oluşturalım ve <code class="language-plaintext highlighter-rouge">50</code> değeri verelim. draw() fonksiyonu içerisinde de en altta bu değeri <code class="language-plaintext highlighter-rouge">daireX++</code> diyerek birer birer arttıralım. Hatırlayacağınız gibi draw() fonksiyonu her karede sürekli çalışan bir fonksiyon. Son olarak da dairenin x parametresi olarak <code class="language-plaintext highlighter-rouge">daireX</code> değişkenini gönderelim. Kodların son hali şu olacak:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">let</span> <span class="nx">daireX</span> <span class="o">=</span> <span class="mi">50</span><span class="p">;</span>

<span class="kd">function</span> <span class="nx">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">createCanvas</span><span class="p">(</span><span class="mi">640</span><span class="p">,</span> <span class="mi">480</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">draw</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">background</span><span class="p">(</span><span class="mi">75</span><span class="p">);</span>

  <span class="nx">fill</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
  <span class="nx">stroke</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">);</span>
  
  <span class="nx">circle</span><span class="p">(</span><span class="nx">daireX</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">75</span><span class="p">);</span>
  
  <span class="nx">daireX</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>Bunun da çıktısı şu olacak, bu resme özel hareketli olsun:</p>

<p><img src="/images/blog/p5js/p5js-6.gif" alt="p5.js Web Editor demo" /></p>

<p>Şimdi draw fonksiyonunun başındaki <code class="language-plaintext highlighter-rouge">background(75)</code> ifadesini silerek bir şey deneyelim. Şöyle bir şey olacak:</p>

<p><img src="/images/blog/p5js/p5js-7.png" alt="p5.js Web Editor demo" /></p>

<p>Başlarda bahsettiğim bir konu vardı, canvas gerçek bir tuval gibidir. İsterseniz bir resim defterinin, eskiz defterinin sayfaları olarak da düşünebilirsiniz. Bir çizimi yaptıktan sonra başka bir sayfaya geçmeden, buradaki durumda ise o resmin üstünü kaplamadan başka bir şey çizerseniz o çizimin üstüne çizilir. Bu yüzden draw() fonksiyonunun başında bir arkaplan rengi belirliyoruz, yani o renkte bir dikdörtgenle canvas’ı kaplıyoruz ki yeni bir çizimi temiz bir şekilde çizebilelim. Bu tür, üst üste çizme yapısı örneğin bir çizim uygulaması kodladığımızda çok işimize yarıyor.</p>

<p>p5.js’in tanımladığı bazı değişkenler var. Şimdi bunlardan <code class="language-plaintext highlighter-rouge">mouseX</code> ve <code class="language-plaintext highlighter-rouge">mouseY</code> değişkenlerini göreceğiz. Ayrıca dikdörtgen çizmeye de değinelim. Ekrana dikdörtgen çizmek için <code class="language-plaintext highlighter-rouge">rect()</code> fonksiyonunu kullanırız. Bunun da aldığı parametreler şu şekilde.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rect(x, y, genişlik, [yükseklik])
</code></pre></div></div>

<p>Yükseklik parametresini köşeli parantez içine almamın nedenini çeşitli dökümantasyonları okuyorsanız anlamışsınızdır. Bu, isteğe bağlı bir parametre. Yüksekliği vermeden, yalnızca genişlik verdiğinizde genişlik ölçeğinde bir kare elde edeceksiniz.</p>

<p>Şimdi ben istiyorum ki, çizeceğimiz dikdörtgen mouse’u takip etsin. Şu şekilde mouse’un koordinatlarında çizilen, 100 birim genişliğe ve 50 birim yüksekliğe sahip bir dikdörtgen çizebilirsiniz:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">rect</span><span class="p">(</span><span class="nx">mouseX</span><span class="p">,</span> <span class="nx">mouseY</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span></code></pre></figure>

<p><img src="/images/blog/p5js/p5js-8.png" alt="p5.js Web Editor demo" /></p>

<p>Şimdi sildiğimiz <code class="language-plaintext highlighter-rouge">background()</code> fonksiyonunu tekrar ekleyelim de adama benzesin. Onun da ekran görüntüsünü eklemeyeyim artık.</p>

<p>Döndürme konusu biraz karışıktır. Şu kodların teker teker üstünden geçerek açıklayalım:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">function</span> <span class="nx">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">createCanvas</span><span class="p">(</span><span class="mi">640</span><span class="p">,</span> <span class="mi">480</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">draw</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">background</span><span class="p">(</span><span class="mi">225</span><span class="p">);</span>
  
  <span class="nx">push</span><span class="p">();</span>
  
  <span class="nx">translate</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="mi">150</span><span class="p">);</span>
  <span class="nx">rotate</span><span class="p">(</span><span class="nx">degrees</span><span class="p">(</span><span class="mi">45</span><span class="p">));</span>
  
  <span class="nx">fill</span><span class="p">(</span><span class="mi">120</span><span class="p">);</span>
  <span class="nx">rect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
  
  <span class="nx">pop</span><span class="p">();</span>
  
  
  <span class="nx">fill</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
  <span class="nx">rect</span><span class="p">(</span><span class="mi">400</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">90</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<p>Çıktısı şu şekilde:</p>

<p><img src="/images/blog/p5js/p5js-9.png" alt="p5.js Web Editor demo" /></p>

<p>Bir kağıt üzerine kare çizdiğinizi düşünün. Fakat kareyi 45 derece döndürülmüş bir şekilde çizeceksiniz. Bunu yapmanın en iyi yolu kağıdı çevirmektir, bilirsiniz. Kağıdı 45 derece çevirirsiniz, kareyi çizersiniz ve kağıdı eski haline getirirsiniz. Canvasta da durum bu şekilde aslında. <code class="language-plaintext highlighter-rouge">push()</code> ve <code class="language-plaintext highlighter-rouge">pop()</code> fonksiyonları bir kapsayıcı görevi görüyor ve bu kağıdı çevirme gibi işlemleri sadece bir kısımda geçerli olacak halde kullanmayı sağlıyor. Döndürme işlemimizi bunların arasında yapacağız. <code class="language-plaintext highlighter-rouge">translate()</code> fonksiyonu x ve y olarak iki parametre alıyor ve canvasın origin noktasını değiştirmemizi sağlıyor. (0, 0) noktası bu origin noktası ve döndürme işlemi de bunun etrafında yapılıyor. Bu fonksiyona aslında ekrana çizeceğimiz şekli x ve y değerlerini gönderiyoruz ve (0, 0) noktası orası oluyor, ardından şekli çizerken de x ve y değerlerini 0 olarak giriyoruz. Origin noktasını değiştirdikten sonra <code class="language-plaintext highlighter-rouge">rotate()</code> fonksiyonu ile döndürme işlemini gerçekleştiriyoruz. p5.js açı değerlerinde varsayılan olarak radyan kullanır. Bu yüzden derece olarak göndereceğimiz açı değerini önce <code class="language-plaintext highlighter-rouge">degrees()</code> fonksiyonundan geçiriyoruz. İstersek <code class="language-plaintext highlighter-rouge">setup()</code> fonksiyonu içerisinde <code class="language-plaintext highlighter-rouge">angleMode(DEGRESS)</code> yazarak tüm açı değerlerini en baştan derece olarak, degrees() gibi bir fonksiyona gerek kalmadan kullanabiliriz. Ardından içini doldurarak dikdörtgeni ekrana basıyoruz ve söz ettiğim gibi (0, 0) değeri veriyoruz. Ancak dikdörtgen (200, 150) noktasına çiziliyor. <code class="language-plaintext highlighter-rouge">pop()</code> fonksiyonuyla da bu işlemi sonlandırdıktan sonra ekrana çizeceğimiz bir başka dikdörtgenin de döndürülmüş olmasını engelliyoruz.</p>

<p>Şimdi basit bir Flappy Bird oyunu yapmaya çalışalım. Kodları baştaki haliyle bırakıyorum, setup() ve draw() içerisindeki createCanvas() ve background() fonksiyonları dışında eklediğim her şeyi siliyorum.</p>

<p>Şöyle çok basit bir kuş resmi kullanalım:</p>

<p><img src="https://img.icons8.com/plumpy/48/000000/bird.png" alt="Kuş" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://img.icons8.com/plumpy/48/000000/bird.png
</code></pre></div></div>

<p>Bir resmi eklemek için öncelikle setup() fonksiyonu içerisinde loadImage() fonksiyonuyla resmi adresinden çağırmamız, sonra da kullanacağımız yerde image() fonksiyonuyla bastırmamız gerekiyor. Bu arada setup() fonksiyonu içinde de başta yapılacak tek seferlik çizimler yapılabilir, o kısım kafa karıştırmasın.</p>

<p>Bahsettiğim fonksiyonların parametreleri şu şekilde:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>loadImage(URL)
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>image(resim_ismi, x, y, [genişlik], [yukseklik])
</code></pre></div></div>

<p>Resmi aşağıdaki şekilde ekledim:</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">let</span> <span class="nx">birdImage</span><span class="p">;</span>

<span class="kd">function</span> <span class="nx">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">createCanvas</span><span class="p">(</span><span class="mi">640</span><span class="p">,</span> <span class="mi">480</span><span class="p">);</span>
  
  <span class="nx">birdImage</span> <span class="o">=</span> <span class="nx">loadImage</span><span class="p">(</span><span class="dl">'</span><span class="s1">https://img.icons8.com/plumpy/48/000000/bird.png</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">draw</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">background</span><span class="p">(</span><span class="mi">225</span><span class="p">);</span>
  
  <span class="nx">image</span><span class="p">(</span><span class="nx">birdImage</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<p>Çıktı şu şekilde:</p>

<p><img src="/images/blog/p5js/p5js-10.png" alt="p5.js Web Editor demo" /></p>

<p>Resmi tam olarak bu şekilde kullanmayacağız. Bu sefer oyunu kodlayarak kısım kısım oyunun kodları üzerinden yorum satırları ile anlatmayı tercih edeceğim. Kodlar ise <a href="https://editor.p5js.org/hkrabs/sketches/La12j0k-l">şu</a> adreste. Oynanış açısından çeşitli bug’lar olabilir, biraz daha üzerinde uğraşılırsa düzelecektir.</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// Oyunun başlayıp başlamadığı değerini tutmak için bir değişken oluşturuyoruz</span>
<span class="kd">let</span> <span class="nx">play</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

<span class="c1">// Kuşun aşağı düşebilmesi için bir yerçekimi değişkeni oluşturuyoruz</span>
<span class="kd">const</span> <span class="nx">gravity</span> <span class="o">=</span> <span class="mf">0.2</span><span class="p">;</span>

<span class="c1">// Kuşun özelliklerini ve eylemlerini derli toplu bir şekilde tutabilmek için bir obje içinde topluyoruz</span>
<span class="kd">const</span> <span class="nx">bird</span> <span class="o">=</span> <span class="p">{</span>
  <span class="c1">// Sprite, 2D oyun grafiklerine verilen isimdir</span>
  <span class="na">sprite</span><span class="p">:</span> <span class="p">{</span>
    <span class="c1">// Kuşun resmini çağırabilmek için src, resim çağrıldıktan sonra p5.js resim objesi olarak tutulabilsin diye img değeri ekledim ve başlangıç değerini null olarak belirledim</span>
    <span class="na">src</span><span class="p">:</span> <span class="dl">'</span><span class="s1">https://img.icons8.com/plumpy/48/000000/bird.png</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">image</span><span class="p">:</span> <span class="kc">null</span>
  <span class="p">},</span>
  <span class="c1">// Kuşun boyutları</span>
  <span class="na">size</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">width</span><span class="p">:</span> <span class="mi">48</span><span class="p">,</span>
    <span class="na">height</span><span class="p">:</span> <span class="mi">48</span>
  <span class="p">},</span>
  <span class="c1">// Kuşun canvas içindeki konumu</span>
  <span class="na">positions</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">x</span><span class="p">:</span> <span class="mi">75</span><span class="p">,</span>
    <span class="na">y</span><span class="p">:</span> <span class="mi">200</span>
  <span class="p">},</span>
  <span class="c1">// Kuşun dikey konumdaki hızı</span>
  <span class="na">speedY</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
  <span class="c1">// Kuşun sürekli olarak çalışacak güncelleme fonksiyonu</span>
  <span class="na">update</span><span class="p">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Burada bir limit hız kontrolü var, kuşun hızı 8 birimi aşarsa 8'de sabit kalsın</span>
    <span class="c1">// aksi takdirde yerçekimi ivmesi sürekli olarak hıza eklensin</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">speedY</span> <span class="o">&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">speedY</span> <span class="o">=</span> <span class="mi">8</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">else</span> <span class="p">{</span>
      <span class="c1">// Kuşu yere doğru ivmeli bir şekilde çekiyoruz</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">speedY</span> <span class="o">+=</span> <span class="nx">gravity</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="c1">// Hızı konuma ekleyerek konumu hıza göre değiştiriyoruz</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="k">this</span><span class="p">.</span><span class="nx">speedY</span><span class="p">;</span>
  <span class="p">},</span>
  
  <span class="c1">// Kuşun zıplamasını sağlayacak olan fonksiyon</span>
  <span class="na">jump</span><span class="p">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Kuşun dikey hızını yukarı doğru 6 birim birden arttırıyoruz. Yerçekime doğru olan aşağı kısım pozitif olduğu için yukarı yönü negatif seçmek durumundayız</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">speedY</span> <span class="o">=</span> <span class="o">-</span><span class="mi">6</span><span class="p">;</span>
    
    <span class="c1">// Oyunu başlat</span>
    <span class="nx">play</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">};</span>

<span class="c1">// Boruları tutacak olan dizi</span>
<span class="kd">let</span> <span class="nx">pipes</span> <span class="o">=</span> <span class="p">[];</span>

<span class="c1">// Boruları oluşturacağımız taslağı tutan constructor fonksiyonu</span>
<span class="kd">const</span> <span class="nx">Pipe</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="nx">y</span><span class="p">;</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
  
  <span class="c1">// Boruların her güncellendiğinde 4 birim sola kayması</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">update</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">x</span> <span class="o">-=</span> <span class="mi">4</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Oyunun biteceği durumlarda çalışacak fonksiyon</span>
<span class="kd">function</span> <span class="nx">gameOver</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">play</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
  
  <span class="c1">// Game over uyarısı</span>
  <span class="nx">alert</span><span class="p">(</span><span class="dl">'</span><span class="s1">Game over</span><span class="dl">'</span><span class="p">);</span>

  <span class="c1">// Boruların tutulduğu dizi boşaltılıyor</span>
  <span class="nx">pipes</span> <span class="o">=</span> <span class="p">[];</span>
  
  <span class="c1">// Kuşun pozisyonu ekranın ortalarına çekiliyor</span>
  <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// p5.js'in setup() fonksiyonu</span>
<span class="kd">function</span> <span class="nx">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">createCanvas</span><span class="p">(</span><span class="mi">640</span><span class="p">,</span> <span class="mi">480</span><span class="p">);</span>
  
  <span class="c1">// Açı değerlerini derece olarak kullanacağımız için açı modunu derece yapıyoruz</span>
  <span class="nx">angleMode</span><span class="p">(</span><span class="nx">DEGREES</span><span class="p">);</span>
  
  <span class="c1">// Kuşun resmini kendi içindeki URL'den seçerek, kendi içindeki objeye atıyoruz</span>
  <span class="nx">bird</span><span class="p">.</span><span class="nx">sprite</span><span class="p">.</span><span class="nx">image</span> <span class="o">=</span> <span class="nx">loadImage</span><span class="p">(</span><span class="nx">bird</span><span class="p">.</span><span class="nx">sprite</span><span class="p">.</span><span class="nx">src</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// p5.js'in draw() fonksiyonu</span>
<span class="kd">function</span> <span class="nx">draw</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// Eğer oyun başlamamışsa</span>
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">play</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Canvasın arkaplanı siyaha boyansın</span>
    <span class="nx">background</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
    
    <span class="c1">// Beyaz renkli, kenarlıksız, ortalanmış ve canvas'ın tam ortasında bir yazı yazılsın</span>
    <span class="nx">fill</span><span class="p">(</span><span class="mi">255</span><span class="p">);</span>
    <span class="nx">noStroke</span><span class="p">();</span>
    <span class="nx">textAlign</span><span class="p">(</span><span class="nx">CENTER</span><span class="p">);</span>
    <span class="nx">text</span><span class="p">(</span><span class="dl">'</span><span class="s1">Jump to start</span><span class="dl">'</span><span class="p">,</span> <span class="nx">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">height</span> <span class="o">/</span> <span class="mi">2</span><span class="p">);</span>
    
    <span class="c1">// draw() fonksiyonu buradan itibaren devam etmesin. play değişkeni true olduğunda bu kısım</span>
    <span class="c1">// çalışmayacak ve draw() fonksiyonu normal bir şekilde devam edebilecek</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>
  
  <span class="c1">// color() fonksiyonu string olarak HTML renk kodlarını alabilir. Burada bir renk kodunu ismi ile kullandık</span>
  <span class="nx">background</span><span class="p">(</span><span class="nx">color</span><span class="p">(</span><span class="dl">'</span><span class="s1">skyblue</span><span class="dl">'</span><span class="p">));</span>
  
  <span class="c1">// frameCount değişkeni oyunun başlamasından itibaren artar ve kaç adet frame geçildiğini tutar. Bu değer 80'in katları olduğunda çalışacak bir koşul yazıyoruz</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">frameCount</span> <span class="o">%</span> <span class="mi">80</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    
    <span class="c1">// Burada temel olarak üst ve alt boru çiftini rastgele konumdaki açıklıklarıyla oluşturup boruların tutulduğu diziye ekliyoruz</span>
    <span class="kd">let</span> <span class="nx">pipeGap</span> <span class="o">=</span> <span class="nx">random</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">150</span><span class="p">);</span>
    
    <span class="kd">let</span> <span class="nx">topPipeLength</span> <span class="o">=</span> <span class="nx">random</span><span class="p">(</span><span class="nx">pipeGap</span><span class="p">,</span> <span class="nx">height</span> <span class="o">-</span> <span class="nx">pipeGap</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span>
    
    <span class="nx">pipes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span>
      <span class="k">new</span> <span class="nx">Pipe</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="nx">topPipeLength</span><span class="p">),</span>
      <span class="k">new</span> <span class="nx">Pipe</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">topPipeLength</span> <span class="o">+</span> <span class="nx">pipeGap</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="nx">height</span> <span class="o">-</span> <span class="nx">pipeGap</span> <span class="o">-</span> <span class="nx">topPipeLength</span><span class="p">)</span>
    <span class="p">);</span>
  <span class="p">}</span>
  
  <span class="c1">// Kuşun kendi içindeki güncelleme fonksiyonunu çağırıyoruz</span>
  <span class="nx">bird</span><span class="p">.</span><span class="nx">update</span><span class="p">();</span>
  
  <span class="c1">// Döndürme işlemi yapılacağı için push() ve pop() fonksiyonlarıyla işlemleri sarmalıyoruz</span>
  <span class="nx">push</span><span class="p">();</span>
  
  <span class="c1">// Döndürme noktasını kuşun ortasına getirdik</span>
  <span class="nx">translate</span><span class="p">(</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">x</span> <span class="o">-</span> <span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> 
    <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">-</span> <span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">height</span> <span class="o">/</span> <span class="mi">2</span>
  <span class="p">);</span>
  
  <span class="c1">// Kuşun hızı negatifse, yani yukarı doğru çıkıyorsa -30 derece dönsün;</span>
  <span class="c1">// değilse, aşağı düşüyorsa 10 derece dönsün</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">bird</span><span class="p">.</span><span class="nx">speedY</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">rotate</span><span class="p">(</span><span class="o">-</span><span class="mi">30</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">else</span> <span class="p">{</span>
    <span class="nx">rotate</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
  <span class="p">}</span>
   
  <span class="c1">// Kuşun resmini basıyoruz. translate() fonksiyonunda origin noktasını kuşun ortasına getirdiğimiz için</span>
  <span class="c1">// burada da kuşu kendi büyüklüğünün yarısı kadar geriden çiziyoruz</span>
  <span class="nx">image</span><span class="p">(</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">sprite</span><span class="p">.</span><span class="nx">image</span><span class="p">,</span> 
    <span class="o">-</span><span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> 
    <span class="o">-</span><span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">height</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">height</span>
  <span class="p">);</span>
  
  <span class="c1">// translate() ve rotate() ile işimiz bitti</span>
  <span class="nx">pop</span><span class="p">();</span>
  
  <span class="c1">// Kuş aşağı ve yukarıda sınırları aşarsa oyun bitsin</span>
  <span class="k">if</span> <span class="p">(</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">&gt;</span> <span class="nx">height</span> <span class="o">||</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">bird</span><span class="p">.</span><span class="nx">size</span><span class="p">.</span><span class="nx">height</span>
  <span class="p">)</span> <span class="p">{</span>
    <span class="nx">gameOver</span><span class="p">();</span>
  <span class="p">}</span>
  
  <span class="c1">// Tüm boruları teker teker tarayalım</span>
  <span class="nx">pipes</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">pipe</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="c1">// Boruyu yeşilin bir tonuyla boyuyoruz</span>
    <span class="nx">fill</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">120</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span>
    <span class="c1">// Kenar çizgileri olmasın</span>
    <span class="nx">noStroke</span><span class="p">();</span>
    <span class="c1">// Boruyu çiziyoruz</span>
    <span class="nx">rect</span><span class="p">(</span><span class="nx">pipe</span><span class="p">.</span><span class="nx">x</span><span class="p">,</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">y</span><span class="p">,</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span>
    
    <span class="c1">// Boru hareket edebilsin diye kendi içindeki güncelleme fonksiyonunu çağırıyoruz</span>
    <span class="nx">pipe</span><span class="p">.</span><span class="nx">update</span><span class="p">();</span>
    
    <span class="c1">// Eğer kuş boruyla çarpışmışsa oyunu bitir. Tüm borular için teker teker bu döngü çalışacağı için</span>
    <span class="c1">// kuş herhangi biriyle çarpışmışsa bu kısım çalışacak</span>
    <span class="k">if</span> <span class="p">(</span>
      <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">x</span> <span class="o">&gt;</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">x</span> <span class="o">&amp;&amp;</span>
      <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">&gt;</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">y</span> <span class="o">&amp;&amp;</span>
      <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">width</span> <span class="o">&amp;&amp;</span>
      <span class="nx">bird</span><span class="p">.</span><span class="nx">positions</span><span class="p">.</span><span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">pipe</span><span class="p">.</span><span class="nx">height</span>
    <span class="p">)</span> <span class="p">{</span>
      <span class="nx">gameOver</span><span class="p">();</span>
    <span class="p">}</span>
  <span class="p">});</span>
<span class="p">}</span>

<span class="c1">// Herhangi bir tuşa bir kere basılmışsa</span>
<span class="kd">function</span> <span class="nx">keyPressed</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// Basılan tuş space veya yukarı ok tuşuysa</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">key</span> <span class="o">===</span> <span class="dl">'</span><span class="s1"> </span><span class="dl">'</span> <span class="o">||</span> <span class="nx">key</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">ArrowUp</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Kuşu zıplat</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">jump</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Herhangi bir mouse butonuyla tıklanmışsa</span>
<span class="kd">function</span> <span class="nx">mousePressed</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// Basılan buton sol butonsa</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">mouseButton</span> <span class="o">===</span> <span class="nx">LEFT</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Kuşu zıplat</span>
    <span class="nx">bird</span><span class="p">.</span><span class="nx">jump</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<p>Son olarak oyunun çıktısını da şöyle vereyim:</p>

<p><img src="/images/blog/p5js/p5js-11.png" alt="Flappy Bird klonu" /></p>

<p>Bu yazı da gittikçe uzadı. Geleceğe selamlar, hadi ben gidiyorum.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="programlama" /><category term="js" /><category term="p5js" /><category term="sanat" /><summary type="html"><![CDATA[Bir görsel prototipleme kütüphanesi olan p5.js'e giriş dersi]]></summary></entry><entry><title type="html">Visual Studio Code’da Klasör Ağacı Girintisini Arttırmak</title><link href="https://yinkar.github.io/programlama/vscode/2021/10/31/vscode-klasor-agaci-girintisini-arttirmak.html" rel="alternate" type="text/html" title="Visual Studio Code’da Klasör Ağacı Girintisini Arttırmak" /><published>2021-10-31T09:51:00+03:00</published><updated>2021-10-31T09:51:00+03:00</updated><id>https://yinkar.github.io/programlama/vscode/2021/10/31/vscode-klasor-agaci-girintisini-arttirmak</id><content type="html" xml:base="https://yinkar.github.io/programlama/vscode/2021/10/31/vscode-klasor-agaci-girintisini-arttirmak.html"><![CDATA[<p>Visual Studio Code’un kenar çubuğunda yer alan dosya gezgininin girintilemesi (indentation) oldukça az görünüyor, öyle değil mi? Bana göre oldukça yetersiz ve ilk bakışta hangi dosya ve dizinin hangi dizinin içinde bulunduğu rahat bir şekilde anlaşılamayabiliyor.</p>

<p><img src="/images/blog/vscode-indent/vscode-indent-1.png" alt="VSCode varsayılan girintileme" /></p>

<p>Bu girintileme seviyesini arttırabilmek için öncelikle <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> kısayolu ile komut paletini açın (Mac için <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>). Ardından klavyenizde tuşlayarak <code class="language-plaintext highlighter-rouge">Preferences: Open Settings (JSON)</code> seçeneğini seçin.</p>

<p><img src="/images/blog/vscode-indent/vscode-indent-2.png" alt="VSCode command palette" /></p>

<p>Global ayarlar için kullanılan JSON dosyası açılacak. Buraya yeni bir değer ekleyeceğiz. Buradaki JSON objesine</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"workbench.tree.indent": 30
</code></pre></div></div>

<p>gibi bir değer ekleyerek kaydettiğinizde girintilemenin arttığını göreceksiniz.</p>

<p><img src="/images/blog/vscode-indent/vscode-indent-3.png" alt="settings.json dosyası" /></p>

<p>Yazmaya başladığınızda editör kendi de tamamlayacaktır. <code class="language-plaintext highlighter-rouge">30</code> yerine istediğiniz miktarı yazabilirsiniz, varsayılan değeri <code class="language-plaintext highlighter-rouge">8</code>‘dir. Klasör ağacının yeni görünümü aşağıdaki gibi olacaktır:</p>

<p><img src="/images/blog/vscode-indent/vscode-indent-4.png" alt="VSCode yeni girintileme" /></p>

<p>Bu ayarlamayı JSON dosyasında değil de UI üzerinden de yapabilmeniz mümkün. Komut paletindeyken JSON’ı değil de <code class="language-plaintext highlighter-rouge">Preferences: Open Settings (UI)</code> seçeneğini seçtikten sonra, açılan sayfada üstteki arama kutucuğuna “tree.indent” yazdığınızda ilgili seçeneğin çıktığını göreceksiniz.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="programlama" /><category term="vscode" /><summary type="html"><![CDATA[Visual Studio Code'da kenar çubuğundaki yetersiz ağaç girintilemesini arttırmak]]></summary></entry><entry><title type="html">ANSI Art Nedir</title><link href="https://yinkar.github.io/blog/linux/terminal/sanat/curl/2021/10/29/ansi-art-nedir.html" rel="alternate" type="text/html" title="ANSI Art Nedir" /><published>2021-10-29T11:18:00+03:00</published><updated>2021-10-29T11:18:00+03:00</updated><id>https://yinkar.github.io/blog/linux/terminal/sanat/curl/2021/10/29/ansi-art-nedir</id><content type="html" xml:base="https://yinkar.github.io/blog/linux/terminal/sanat/curl/2021/10/29/ansi-art-nedir.html"><![CDATA[<p>Geçenlerde şöyle bir şey oluşturdum:</p>

<p><img src="/images/blog/ansi-art/ansi-art-1.png" alt="curl -L git.io/nightstreet" /></p>

<p>Terminali açarak şunu yazdığınızda, eğer terminaliniz 256 rengi destekliyorsa siz de bu sonucu alacaksınız:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">curl <span class="nt">-L</span> git.io/nightstreet</code></pre></figure>

<p><a href="https://gist.github.com/yinkar/3a7916a370bab438ef9ae05913cf5ade">Kaynak kodu</a> da Github Gist üzerinde yer alıyor.</p>

<p>Daha önceden şu şekilde çalışmalar yapan bir eleman vardı, ondan esinlendim:</p>

<p><img src="/images/blog/ansi-art/ansi-art-2.png" alt="Xero" /></p>

<p>Kendisinin <a href="https://gist.github.com/xero">Github Gist adresini</a> de vereyim.</p>

<p>Şimdi tek tek bunun nasıl çalıştığının üzerinden geçelim. <code class="language-plaintext highlighter-rouge">curl</code>, en basit tanımla uzak bir adresteki içeriğe erişmenizi sağlayan bir yazılımdır. Genelde HTTP istemcisi olarak kullanılsa da birçok protokolü destekler. Biz burada HTTP istemcisi olarak kullanıyoruz. cURL ile bir web sitesine terminal üzerinden bağlanabilirsiniz:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">curl google.com</code></pre></figure>

<p><img src="/images/blog/ansi-art/ansi-art-3.png" alt="curl google.com" /></p>

<p>Görüldüğü gibi adrese bağlandı ve içeriği getirdi. Tabii burada bir sorun var, Google ana sayfasının HTML içeriği bu şekilde değil. cURL, bağlandığı adreste bir HTTP yönlendirmesiyle karşılaştı ve bu yönlendirmeyi takip etmedi. Bunu bizim belirtmemiz gerekiyor. Bunu <code class="language-plaintext highlighter-rouge">-L</code> opsiyonuyla gerçekleştireceğiz.</p>

<p><img src="/images/blog/ansi-art/ansi-art-4.png" alt="curl -L google.com" /></p>

<p>Şimdi olması gereken sonuç karşımıza çıktı.</p>

<p>Tekrar benim kodladığım örneğe dönelim. git.io, Github’a ait olan bir URL kısaltma servisi. Yalnızca Github üzerindeki URL’leri kısaltmayı sağlıyor. Resmi terminale basmak için bağlandığımız git.io adresi de bir yönlendirme içerdiği için <code class="language-plaintext highlighter-rouge">-L</code> opsiyonunu kullanıyoruz. Şimdi o bağlandığımız git.io/nightstreet adresine tarayıcı üzerinden gidelim. Karşımıza şöyle bir sonuç çıkacak:</p>

<p><img src="/images/blog/ansi-art/ansi-art-5.png" alt="ANSI art kodu" /></p>

<p>Bu metin aslında doğrudan terminalimize gelen içerik. Terminal bu kodlamaları yorumluyor ve onları renkler gibi çeşitli görselleştirmelere dönüştürüyor. ANSI art dediğimiz şeyin arkasında da da bu var. Ona geçmeden önce bu içeriğin nerede tutulduğuna bakalım. Adresten anlayabileceğiniz üzere bu sayfa aslında doğrudan benim yazının başında da verdiğim, Github Gist üzerinde yer alan kaynak kodunun yalın olarak görüntülendiği sayfadan başka bir şey değil. Esinlendiğim kişinin kullanıcı adına da böyle ulaşmıştım.</p>

<p>Yalnız şu an fark ediyorum, Visual Studio Code üzerinde bu kodlamaları yaparken kullandığım eklentinin önizleme özelliği varmış. Ben yalnızca metin üzerinden renkleri görerek kodlamış, önizleme için ise basit bir Bash betiği yazmıştım.</p>

<p><img src="/images/blog/ansi-art/ansi-art-6.png" alt="VSCode ANSI art" /></p>

<p>O betik de dosyayı her güncellediğimde ekrana yeni halini basmaya yarıyor. Kendisi de <a href="https://gist.github.com/yinkar/b4190d92d880c3f6e434606691ea81ca">şu</a> adreste.</p>

<p>Yazının devamında ANSI kaçış (escape) karakterleri ve blok karakterlerinden bahsederken bu resmin de kaynak kodunu inceleyeceğiz.</p>

<p>Ben bu resmi kodladıktan sonra bunun aslında bu kadar uğraş gerektirmemesi gerektiğini düşündüm. Yazılımcı dediğin bir eylemi ikinci defa yapmaz, otomatize eder. Bundan dolayı terminal için çıktı üretecek bir pixel art editörü kodladım. Gerçek anlamda, tam donanımlı bir pixel art editörünü de ilerleyen zamanlarda kodlamayı düşünüyorum.</p>

<p><a href="https://yinkar.github.io/ansi-art-painter/">ANSI Art Painter</a></p>

<p><img src="/images/blog/ansi-art/ansi-art-7.png" alt="ANSI Art Painter" /></p>

<p>Bu editörden alacağınız çıktıyı veya kaydedeceğiniz dosyayı komut satırından <code class="language-plaintext highlighter-rouge">cat</code> komutu ile açtığınızda çizdiğiniz resmin terminale basıldığını göreceksiniz, tıpkı bu yazının kapak resminde olduğu gibi. Elbette bu editör ANSI’nin tüm nimetlerinden faydalanmıyor, blok karakterlerini hiç kullanmıyor diyebiliriz. Geliştirme aşamasının hızlı olması için bazı detaylardan feragat ettim, buna yazının devamında değinirim.</p>

<p>Artık ANSI art yazısına tam olarak başlayabiliriz. ANSI aslında American National Standards Institute ifadesinin kısaltmasıdır ve işi standartları belirlemek olan özel bir kuruluşun ismidir. ASCII gibi standartları da bu kuruluş belirlemiştir.</p>

<p>ASCII art’ı hepiniz bilirsiniz. ASCII art olarak örneğin şöyle bir şey çizmiştim:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>               (   (  
                ) )   
               (_(    
               |__|   
           .    ||    
         /  \ ` ||-+  
       /      \   /|  
     /          \/ |  
    +-----------+/||  
    |  _    _   ||/|  
    | |_|  |_|  |  |  
    |  _    __  |  +  
    | |_|  |  | | /   
    |      |' | |/    
    +-----------+     
                      
</code></pre></div></div>

<p>Temel olarak her yazı karakterin birbiriyle aynı boyda olduğu fontlara sahip yerlerde bu karakterlerle yapılan resimler. Bu fontlara monospace adı veriliyor. ASCII art köken olarak 256 karakterlik ASCII tablosunu temel alsa da, zaman zaman sonrasında türeyen karakter kümelerindeki karakterler de kullanılabiliyor. Bak şimdi buna da ASCII art diyen var</p>

<p><strong>̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡ ̡͌l̡̡̡̡.</strong>_</p>

<p>Aslında denmemesi lazım tabii.</p>

<p>ANSI art dediğimiz kavram ise buna benziyor, fakat kaçış karakterleri ile metni formatlama imkanı ve çok daha fazla karakter içeriyor. Örneğin şu blok karakterleri çok önemli: 
<code class="language-plaintext highlighter-rouge">░ ▒ ▓ ▉</code>.</p>

<p>ANSI Art Bulletin Board System (BSS)’larda çok kullanılan bir yöntem. BBS, 1980’lerle 1990’larda yaygın olarak kullanılan, terminal üzerinden bağlanılan sistemlerin ismi. Web’in çok yaygın olmadığı, hatta var olmadığı zamanlarda kullanılan sistemler bunlar. Benim de çok ilgimi çekiyor, o dönemlerde o dünyanın içinde bulunmak isterdim açıkçası. Çocukken teletext dahi çok ilgimi çekerdi. Aslında teletext dahilinde de bir miktar ANSI art’tan söz edebiliriz. Belki bu yazının devamında teletext art’tan da biraz bahsederim.</p>

<p>BBS çok eski bir kavram olsa da, BBS konseptini halen sunan insanlar var. Bağlanmak için tek gereken ise bir Telnet istemcisi. BBS’lerle ilgili ileride bir yazı yazabilirim fakat şimdi örnek olarak bir BBS’e Telnet üzerinden bağlanalım ve orada da ANSI art kullanımını görelim:
<img src="/images/blog/ansi-art/ansi-art-8.png" alt="Örnek BBS" /></p>

<p>ANSI Art çizebilmek için <a href="http://www.roysac.com/roy-sac_downloads_links.html">şu</a> tarz uygulamalar mevcutmuş.</p>

<p>Fakat ben bunun temelinden öğretmeyi düşünüyorum, doğrudan kaçış karakterleri ile. Bu sayede bunları yazdığınız programların çıktılarında da kullanabilirsiniz.</p>

<p>Burada yazacak olduğumuz escape karakterleri içeren metinleri terminal üzerinde gösterecek olmanız yeterli. Bu da demek oluyor ki, istediğiniz herhangi bir dili kullanabilirsiniz, programın çıktısının ANSI kaçış karakterlerini içermesi yeterli. Hatta Unicode formatıyla tarayıcıların geliştirici konsolunda da kullanmanız mümkün. C’de printf(), Python’da print(), PHP’de (komut satırında çalıştıracağımızı unutmadan) echo kullanmak yeterli.</p>

<p>Biz bash komutlarından echo’yu kullanacağız. Fakat echo kullanırken kaçış karakterlerini kullanabilmek için <code class="language-plaintext highlighter-rouge">-e</code> opsiyonunu eklememiz gerekiyor. Bu opsiyon backslash’lerin (\) işlenmesini sağlıyor.</p>

<p>Şimdi bir örnek verelim ve bunun üzerinden gidelim. Şu komutu terminal üzerinde deneyebilirsiniz:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">33[31mDelirmek üzereyim"</span></code></pre></figure>

<p>Çıktısı da şu şekilde olacak:</p>

<p><img src="/images/blog/ansi-art/ansi-art-9.png" alt="ANSI art çıktısı" /></p>

<p>Kodun başında bir adet, bunun bir ANSI kaçış kodu olduğunu belirten kısım bulunuyor. Buna ESC karakteri deniyor ve bunun için birçok alternatif var. <code class="language-plaintext highlighter-rouge">\033</code> olabilir, onun hexadecimal (on altılık) karşılığı olan <code class="language-plaintext highlighter-rouge">\0x1b</code> olabilir, <code class="language-plaintext highlighter-rouge">\e</code> olabilir veya bahsetmiş olduğum Unicode’u sembolize eden <code class="language-plaintext highlighter-rouge">\u001b</code> olabilir. Genel olarak işletim sistemlerinde yaygın olarak kullanılan hali <code class="language-plaintext highlighter-rouge">\033</code> şeklinde.</p>

<p>Sonrasında biraz sinir bozucu bir şekilde gelen <code class="language-plaintext highlighter-rouge">[</code> karakteri var. Sinir bozucu, çünkü bu kapanmayacak. Buna bu yüzden bir parantez açılış karakteri gibi bakmamak lazım. Sonrasında ise asıl yoğunlaşacağımız kısım, renk kodu geliyor. <code class="language-plaintext highlighter-rouge">31</code> kırmızıyı simgeliyor. Bu kodları tablo olarak göreceğiz. Son olarak da bir <code class="language-plaintext highlighter-rouge">m</code> harfi orada kaderine terk edilmiş bir şekilde bekliyor. Format bu. Dinamik kısım üçüncü ele aldığımız kısım. Bu kısım tek bir koşul içermek zorunda değil, birden biçim ifadesi <code class="language-plaintext highlighter-rouge">;</code> karakteriyle ayrılarak yan yana yazılabilir. Şimdi bir tablo ile bu önplan renklerini gösterelim.</p>

<table>
  <thead>
    <tr>
      <th>Kaçış Karakteri</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>\033[30m</td>
      <td>Siyah</td>
    </tr>
    <tr>
      <td>\033[31m</td>
      <td>Kırmızı</td>
    </tr>
    <tr>
      <td>\033[32m</td>
      <td>Yeşil</td>
    </tr>
    <tr>
      <td>\033[33m</td>
      <td>Sarı</td>
    </tr>
    <tr>
      <td>\033[34m</td>
      <td>Mavi</td>
    </tr>
    <tr>
      <td>\033[35m</td>
      <td>Mor</td>
    </tr>
    <tr>
      <td>\033[36m</td>
      <td>Camgöbeği</td>
    </tr>
    <tr>
      <td>\033[37m</td>
      <td>Beyaz</td>
    </tr>
  </tbody>
</table>

<p>Hadi bir de arkaplan renkleri için deneyelim. Aşağıdaki ifade kırmızı bir arkaplana sahip bir metin gösterecek.</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">33[41mÇiğköfteyi mantıklı bulmuyorum"</span></code></pre></figure>

<p><img src="/images/blog/ansi-art/ansi-art-10.png" alt="ANSI art çıktısı" /></p>

<p>Arkaplan renk kodları için de gerekli kodların tablosu da şu:</p>

<table>
  <thead>
    <tr>
      <th>Kaçış Karakteri</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>\033[40m</td>
      <td>Siyah arkaplan</td>
    </tr>
    <tr>
      <td>\033[41m</td>
      <td>Kırmızı arkaplan</td>
    </tr>
    <tr>
      <td>\033[42m</td>
      <td>Yeşil arkaplan</td>
    </tr>
    <tr>
      <td>\033[43m</td>
      <td>Sarı arkaplan</td>
    </tr>
    <tr>
      <td>\033[44m</td>
      <td>Mavi arkaplan</td>
    </tr>
    <tr>
      <td>\033[45m</td>
      <td>Mor arkaplan</td>
    </tr>
    <tr>
      <td>\033[46m</td>
      <td>Camgöbeği arkaplan</td>
    </tr>
    <tr>
      <td>\033[47m</td>
      <td>Beyaz arkaplan</td>
    </tr>
  </tbody>
</table>

<p>İki kodu beraber kullanabileceğimizi söylemiştim.</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">33[045;031mBir kilo domates mantıken 1000 domates demektir"</span></code></pre></figure>

<p><img src="/images/blog/ansi-art/ansi-art-11.png" alt="ANSI art çıktısı" /></p>

<p>Korkunç bir göz infazı oldu sanki.</p>

<p>Önceki yazdığımız kodlarda bir eksik var. Söz konusu kodları kullandığımızda yazının geri kalan tüm kısmı da aynı şekilde stillendirilecek. Bu yüzden aslında bir kapanış ifadesine ihtiyacımız var. Stili sıfırlamak için <code class="language-plaintext highlighter-rouge">\033[0m</code> kodunu kullanıyoruz.</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">33[035mBu bir</span><span class="se">\0</span><span class="s2">33[0m Bu iki"</span></code></pre></figure>

<p><img src="/images/blog/ansi-art/ansi-art-12.png" alt="ANSI art çıktısı" /></p>

<p>Şimdi de diğer stillendirme komutlarına bakalım. Bunlarla yazıyı kalın, ince, italik, yanıp sönen hale getirebiliriz.</p>

<table>
  <thead>
    <tr>
      <th>Kaçış Karakteri</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>\033[0m</td>
      <td>Normal</td>
    </tr>
    <tr>
      <td>\033[1m</td>
      <td>Kalın</td>
    </tr>
    <tr>
      <td>\033[2m</td>
      <td>Düşük yoğunluklu</td>
    </tr>
    <tr>
      <td>\033[3m</td>
      <td>İtalik</td>
    </tr>
    <tr>
      <td>\033[4m</td>
      <td>Altı çizgili</td>
    </tr>
    <tr>
      <td>\033[5m</td>
      <td>Yanıp sönen</td>
    </tr>
    <tr>
      <td>\033[6m</td>
      <td>Hızlı yanıp sönen</td>
    </tr>
    <tr>
      <td>\033[7m</td>
      <td>Arkaplan</td>
    </tr>
    <tr>
      <td>\033[8m</td>
      <td>Görünmez</td>
    </tr>
  </tbody>
</table>

<p>Bunlardan benim en ilgimi çeken yanıp sönme kodu oldu. Arkaplan ile beraber kullanalım:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">33[05;41mCiğerimiz kalmamıştır"</span></code></pre></figure>

<p><img src="/images/blog/ansi-art/ansi-art-13.gif" alt="ANSI art çıktısı" /></p>

<p>Buraya kadar öğrendiklerinizle boşlukları bu birkaç renk ile arkaplan renklendirmesi kullanarak renklendirebilir, daha detaylı kısımlar için ise blok karakterini önplan renklendirmesi ile renklendirebilirsiniz. Kodladığım şu ANSI Art Painter uygulamasında yalnızca boşlukları renklendiriyorum ve her kare için iki boşluk kullanıyorum. İki boşluk neredeyse bir kare boyutuna denk geliyor.</p>

<p>Komutu ekrana bastırdığınızda ekrandaki önceki karakterlerin silinmesi için ise şu kodu kullanabilirsiniz:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\033[H\033[J
</code></pre></div></div>

<p>Basitçe açıklamak gerekirse; <code class="language-plaintext highlighter-rouge">\033[H</code> ifadesi imleci ekranın sol üst köşesine getiriyor, <code class="language-plaintext highlighter-rouge">\033[J</code> ifadesi ise imleçten ekranın sonuna kadar olan kısmı siliyor. Bu H ve J karakterlerine CSI (Control Sequence Introducer) karakterleri, öncesinde gösterdiğim stillendirme ifadelerine de SGR (Select Graphic Rendition) parametreleri deniyor.</p>

<p>Yazı uzayıp gitmiş. Umarım şunu yazının geri kalanında açıklayacağım deyip de unuttuğum bir kısım olmamıştır. Şu an yazıyı baştan sona okumaya üşeniyorum, sonra bakarım. Belki sonraki yazacağım yazılardan birinde 256 renk kullanımına ve daha detaylı kullanımlara girerim. Geleceğe selamlar, hadi ben gidiyorum.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="blog" /><category term="linux" /><category term="terminal" /><category term="sanat" /><category term="curl" /><summary type="html"><![CDATA[Terminal'de pixel art sanatı]]></summary></entry><entry><title type="html">Neden Regex’ten Korkmamak Gerek</title><link href="https://yinkar.github.io/programlama/regex/2021/10/08/neden-regexten-korkmamak-gerek.html" rel="alternate" type="text/html" title="Neden Regex’ten Korkmamak Gerek" /><published>2021-10-08T01:58:00+03:00</published><updated>2021-10-08T01:58:00+03:00</updated><id>https://yinkar.github.io/programlama/regex/2021/10/08/neden-regexten-korkmamak-gerek</id><content type="html" xml:base="https://yinkar.github.io/programlama/regex/2021/10/08/neden-regexten-korkmamak-gerek.html"><![CDATA[<p>Çoğu yazılımcı genellikle Regex ismini duyduğu anda kaçacak delik arıyor. Tabii bunu anlamak kolay. Regex’i tanımlamak adına çok güzel bir ifade duymuştum: write-only language. Tıpkı yıllar önce, çocukluk yıllarında HTML ile web sayfaları oluşturmaya çalışırken Javascript kodlarının bize büyü gibi gelmesi gibi bir hissiyat yaratıyor Regex. Javascript kodlarını sayfamıza eklerdik ve o anlamsız görünen semboller, ifadeler sayfa kodlarına yapıştırıldığı anda havai fişekler patlardı, rengarenk yazılar sayfada dans ederdi, tarayıcı ekranı deprem efektiyle sallanırdı… Tek yapabildiğimiz ise bu işlevsel kodları kullanabilmek için bir yerlerden kopyalayıp yapıştırmaktı. Çünkü o dünya içine dalmak için çok komplike görünüyordu.</p>

<p>Regex sorgularını da yazılımcıların büyük çoğunluğu bu şekilde kullanıyor. Örneğin bir e-mail sorgulaması gerektiğinde bunun için bir Regex sorgusu aratarak bu sorunu çözme yolunu seçiyorlar. Ancak şunu belirtmekte fayda var, Regex yazmayı öğrendiğinizde birçok konuda işiniz çok kolaylaşacak. Bir metin içerisinde istediğiniz formata uyan her şeyi, dosya isimleri arasında istediğiniz formatta olanları seçip alabilecek, web sitelerinden çektiğiniz verileri ayıklayabilecek, bir dökümanda istemediğiniz kısımları silip sadeleştirebilecek, belki de bir dil için parser kodlayabileceksiniz. Üniversitede bir derste, dökümandaki fazlalık olan kısımları kullandığım metin editörü olan Sublime Text’in bul ve değiştir kısmındaki Regex seçeneğini aktive ederek ayıkladığımda, yanımdaki “bilgisayar mühendisi adayları” bana büyü yapıyormuşum gibi bakıyordu gfkjryjnok</p>

<p>Burada Regex’i anlatmaya regexr.com gibi bir web sitesi üzerinden başlamayı düşünüyorum. Daha sonradan programlama dillerindeki kullanımına geçerim. Normal şartlar altında ben daima gerçek hayattaki senaryolar üzerinden doğrudan anlatmayı seçerim fakat konu Regex olunca programlama dilleri üzerindeki yansıması pek bir farkı oluyor. Bu en başta öğreteceğim şekli ile Regex’i yine verimli bir şekilde kullanabilirsiniz. Tıpkı verdiğim örnekteki gibi bir metin editöründe yardımcı olacaktır. Veya Regex’i zaten kullandığınız programlama dilinde çalıştırmanın yolunu biliyorsanız bu sizin için sorun teşkil etmeyecektir. Ben Regex’i hiç kullanmamış olan insanların da anlamasını istiyorum, bu yüzden ilerleyen kısımlarda programlama dilleri üzerindeki kullanımlarına da değineceğim.</p>

<p>Regexr.com’u açtığınızda karşınıza şöyle bir görüntü çıkacaktır.
<img src="/images/blog/regex/regex-1.png" alt="Regexr.com'un görüntüsü" />
Şimdi öncelikle temel kısımları açıklamakla başlayalım. İşaretlediğim kısımlardan 1 numaralı olan kısım Regex sorgusunu yazacağımız, yani metin içerisinde arama yapacağımız ifadeyi içeren kısım. 2 numaralı kısım ise içinde arama yapılacak olan metin. Gerçi bunu niye açıklıyorsam. Düşününce şimdi saçma geldi. Olsun, çoktan işaretledim bile. Tamam tamam, sıkılma emareleri gösterme okuyucum, bu yazıyı biraz kafam güzel yazıyorum da.</p>

<p>Öncelikle en basit senaryoyu ele alalım, hiçbir işimize yaramayacak olanı. Regex olarak dümdüz bir metin yazdığınızda bu doğrudan yazdığınız sorguyu metin içerisinde bulacaktır. Bu haliyle bir işe yaramasa da, karmaşık Regex sorguları içerisinde parça parça kullanacağınız için öğrenmeniz gerekiyor doğal olarak.</p>

<p>Ha, şeyi söylemeyi unutmuşum. Demin söylediğimin örneğini vereceğim de, ondan önce halihazırda yazılı olan sorguya bir bakalım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>([A-Z])\w+
</code></pre></div></div>

<p>Bunu ilerledikçe daha ayrıntılı olarak açıklayacağım fakat kısaca değinmem gerekirse bu büyük harfle başlayan ve birden fazla karakter içeren kelimeleri bulmayı sağlayacak olan bir Regex sorgusu. Buradaki parantezler baş harfleri ayrıca seçebilmemize yarıyor. Bu sorguyu parantez olmadan da yazabilirdik. Daha fazla foreshadowing yapmadan, spoiler vermeden giriş seviyesine geri dönelim.</p>

<p>Regex sorgusu olarak “expression” yazdık ve başımıza bu geldi:
<img src="/images/blog/regex/regex-2.png" alt="Regexr.com'un görüntüsü" /></p>

<p>Sorgunun başındaki ve sonundaki / (slash) karakteri bizim eklediğimiz bir şey değil. Bu JavaScript’te Regex tanımlamanın yolu. Çoğu dilde Regex sorguları çift tırnak işareti içine yazılır, Javascript’te ise slash’ler arasına yazılıyor. Sondaki “g” karakteri ise global anlamına geliyor. Sorguyu metinde bir defa değil, birden çok defa bulmak için kullanılıyor.</p>

<p>Şimdi kısaca temel Regex tanımlamalarının üzerinden geçelim.</p>

<table>
  <thead>
    <tr>
      <th>İfade</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>.</td>
      <td>Herhangi bir karakteri seçer</td>
    </tr>
    <tr>
      <td>+</td>
      <td>Sağında bulunduğu karakterden bir veya daha fazla seçer</td>
    </tr>
    <tr>
      <td>*</td>
      <td>Sağında bulunduğu karakterden sıfır veya daha fazla seçer</td>
    </tr>
    <tr>
      <td>?</td>
      <td>Sağında bulunduğu karakterden sıfır veya bir tane seçer</td>
    </tr>
    <tr>
      <td>\s</td>
      <td>Boşlukları seçer</td>
    </tr>
    <tr>
      <td>\S</td>
      <td>Boşluk olmayanları seçer</td>
    </tr>
    <tr>
      <td>\w</td>
      <td>Kelimeleri seçer</td>
    </tr>
    <tr>
      <td>\W</td>
      <td>Kelime olmayanları seçer</td>
    </tr>
    <tr>
      <td>\d</td>
      <td>Rakamları seçer</td>
    </tr>
    <tr>
      <td>\D</td>
      <td>Rakam olmayanları seçer</td>
    </tr>
    <tr>
      <td>\b</td>
      <td>Kelime sınırlarını seçer</td>
    </tr>
  </tbody>
</table>

<p>Bunlar oldukça temel ifadelerden birkaçı. Şimdi bunları bir cheat sheet edasıyla değil de, detaylandırarak anlamaya çalışalım. Escape karakterleriyle kullanılanların anlamlarını tahmin etmek zor değil, \s space (boşluk), \w word (kelime), \d digit (rakam) ve \b de boundry (sınır) anlamına geliyor. Akılda tutmak için İngilizcelerini bilmek yeterli.</p>

<p>Regexr uygulamasında expression olarak</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\s
</code></pre></div></div>

<p>yazdığınızda tüm boşlukların seçildiğini göreceksiniz.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\s+
</code></pre></div></div>
<p>yazdığınızda bir veya daha fazla boşluk yan yana ise bunların seçildiğini göreceksiniz. Aynısını diğer tüm ifadeler için deneyebilirsiniz.</p>

<p>Alttaki metnin içerisinde birkaç sayı yazarak</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\d+
</code></pre></div></div>

<p>ile bunları seçebilirsiniz.</p>

<p>Boundry ifadesi bir kelimenin başlangıcını ve bitişini işaretleyerek, örneğin belirlediğiniz kurala uygun bir kelime seçebilmenizi sağlar. Kendisi doğrudan bir karakter seçmez, yalnızca sınırları belirler. Fakat bu ifadeyi kullanabilmek için öncelikle başka bir ifadeden bahsetmem gerekiyor.</p>

<p>Regex’te köşeli parantezler ile tek bir karakter seçebilmek için özel kurallar belirleyebilirsiniz. Sonrasında ise bu kuralları birden fazla yan yana karaktere uygulamanız mümkün. Şöyle göstereyim:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[a-z]
</code></pre></div></div>

<p>bu ifade tek bir küçük harfi seçer. Aşağıdaki gibi yazdığınızda ise yan yana olan küçük harfleri seçecektir:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[a-z]+
</code></pre></div></div>

<p>Büyük harfleri seçebilmek için de şöyle bir kullanım gerekiyor:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[A-Z]
</code></pre></div></div>

<p>Sayılar içinse şöyle bir şey:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[0-9]
</code></pre></div></div>

<p>Tabii buradaki aralıklar özelleştirilebilir. Örneğin siz harflerin A’dan Z’ye tamamını değil de, B’dan L’ye kadarını almak istiyorsunuzdur. Öyle bir şeyi neden isteyesiniz bilemem ama, çok spesifik durumlar doğabilir. Aynısı sayılar için de geçerli, 4-8 gibi bir seçim yapabilirsiniz.</p>

<p>Buradaki tüm kullanımlar bir arada kullanılabilir ve tek bir karakter için olasılıklarınızı arttırabilirsiniz. Örneğin büyük ve küçük harf fark etmeden seçmek için şunu yazmak yeterli:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[a-zA-Z]
</code></pre></div></div>

<p>Söylediğim gibi, bu tek bir karakter seçecektir. Şimdi Regexr uygulamasında harflerden oluşan tüm kelimeleri seçmeyi deneyelim:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[a-zA-Z]+
</code></pre></div></div>

<p><img src="/images/blog/regex/regex-3.png" alt="Tüm kelimelerin seçimi" /></p>

<p>Karanlık teması olduğunu fark edince geçtim hemen. Şimdi, istiyorum ki yalnızca baş harfi büyük kelimeleri seçeyim. Bu durumda artık tek değil, iki koşuldan bahsetmemiz gerekecek: ilk harf ve kelimede geri kalan tüm harfler. İki adet köşeli parantez ifadesini yan yana kullanabiliriz:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[A-Z][a-z]*
</code></pre></div></div>

<p>Görüldüğü üzere, ilk harf için tek bir karakter seçtim. Hatırlarsanız asterisk (yıldız) işareti sıfır veya daha fazla karakter seçebiliyordu. Bir kelime yalnızca tek bir harften oluşabilir, “O” gibi.</p>

<p>Şimdi “e” ile başlayan ve “n” ile biten kelimeleri seçelim. Şöyle bir şey denemekle başlayalım:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>e[a-z]+n
</code></pre></div></div>

<p>Tabii burada bir sorun var.</p>

<p><img src="/images/blog/regex/regex-4.png" alt="Örnek seçim" /></p>

<p>Ben yalnızca bütün olarak kelimeleri seçmek istiyordum fakat bu ifade kelimelerin içine girip parçalarına falan dadanıyor. İşte burada bounty kaçış karakterini (\b) kullanabiliriz. İfadeyi \b karakterlerinin arasına sandviç yaparsak sorunumuz çözülecektir.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\be[a-z]+n\b
</code></pre></div></div>

<p><img src="/images/blog/regex/regex-5.png" alt="Örnek doğru seçim" /></p>

<p>Ancak bu koşula uyup, baş harfi büyük olanları da seçmek istiyoruz diyelim. Burada:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\b[E-Ee-e][a-z]+n\b
</code></pre></div></div>

<p>gibi mutant bir çözümde bulunabiliriz, ama yapmayalım onu. Çok da çirkin duruyor. Aslında köşeli parantezlerin içine istediğimiz harfleri tek tek yazmamız da mümkün. Örneğin şu şekilde bir ifade yazabiliriz:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Ee]
</code></pre></div></div>

<p>Belki bunu öğrendikten sonra bu blog yazısının kapak resmindeki Regex ifadesinin hangi metinleri seçebileceğini anlamışsınızdır. Şimdi köşeli parantez değil de farklı bir yöntem kullanalım bunun için. Yeni bir operatöre değinelim.</p>

<p>”|” operatörü programlama dillerindeki “veya” operatörü gibi davranır. İki koşuldan hangisi uygunsa onu seçer. Ancak bunu kullanabilmek için sorgumuzu parantez içine almamız, yani gruplandırmamız gerekecek. Kısaca sadece bu kısma değinirsek şu şekilde olacak:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(E|e)
</code></pre></div></div>

<p>Şimdi bunu asıl sorguya eklersek:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\b(E|e)[a-z]+n\b
</code></pre></div></div>

<p>Bunun da ekran görüntüsünü koymayayım artık.</p>

<p>Bir kullanımdan daha bahsedelim. Eğer sonsuz değil de belirli sayıda karakteri seçmek istiyorsam, ifadenin yanında küme parantezleri kullanabilirim.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[a-z]{2}
</code></pre></div></div>

<p>şeklindeki bir kullanım yan yana iki küçük harf seçecektir. Soluna ve sağına \b karakterini ekleyerek iki harften oluşan kelimeleri seçebilirsiniz. Bu kullanımda tek bir sayı değil, bir aralık da belirtmeniz mümkün. İki, üç veya dört harften oluşan bir seçim yapmak istiyorsanız:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[a-z]{2, 4}
</code></pre></div></div>

<p>gibi bir kullanım yeterli olacaktır. Sanırım bu yazı için bu kadarlık yeter. Zaten yarısını başladıktan birkaç hafta sonra yazdım. Bu yazıyı bir serinin ilk yazısı olarak düşünüyorum ve bir sonraki Regex yazısında da metnin başı, metnin sonu, köşeli parantez içinde özel karakterlerin kullanımı, hariç tutma, gruplama gibi kısımlara değinirim muhtemelen. Genelde ilk olarak bunlar anlatılır fakat ben böyle bir yol çizmeyi tercih ettim. Geleceğe selamlar, hadi ben gidiyorum.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="programlama" /><category term="regex" /><summary type="html"><![CDATA[Regex'e nazikçe giriş]]></summary></entry><entry><title type="html">İlk Yazı</title><link href="https://yinkar.github.io/blog/2021/09/20/ilk-yazi.html" rel="alternate" type="text/html" title="İlk Yazı" /><published>2021-09-20T19:15:00+03:00</published><updated>2021-09-20T19:15:00+03:00</updated><id>https://yinkar.github.io/blog/2021/09/20/ilk-yazi</id><content type="html" xml:base="https://yinkar.github.io/blog/2021/09/20/ilk-yazi.html"><![CDATA[<p>Bu web sitesini <a href="https://jekyllrb.com">Jekyll</a> isminde, Ruby ile kodlanmış bir static page generator ile oluşturdum. Blog yazılarını da markdown formatında yazıyorum ve Git kullanarak siteyi güncel tutuyorum. Web sitesini barındırdığım Github Pages, doğrudan Jekyll desteği sunuyor, bu güzel bir olay. Burası built-in bir şekilde syntax highlight özelliğini de destekliyormuş, dur bir deneyelim:</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="nb">str</span> <span class="o">=</span> <span class="s">"Açmayın dedeler"</span>
<span class="k">print</span><span class="p">(</span><span class="nb">str</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"d"</span><span class="p">,</span> <span class="s">"m"</span><span class="p">))</span></code></pre></figure>

<p>Hoş.</p>

<p>Jekyll kimi konularda sorun çıkarabiliyor tabii, örneğin tema olayına bakış açısını çok da beğenmedim. Standart bir kullanımı yok, birden fazla yolu var ve bu yollar genellikle çok temiz olmuyor. Kendim bir tema oluşturmayı düşünüyorum.</p>

<p><a href="/toys/">Toys</a> sayfasında hobi olarak kodladığım, kodlarken eğlendiğim ve zevkle kodladığım ufak tefek uygulamalar ve oyunlar bulunuyor. Büyük altyapı gereksinimi duymayan, çalışması için yalnızca bir tarayıcı yeterli olan uygulamalar kodladığımda genelde oraya ekliyorum. Daha öncesinde kodladığım bunlar gibi daha çok örnek var fakat içlerinde ayıklama yaparak buraya eklemeyi daha uygun buldum.</p>

<p>Daha önce kodladığım GLSL örneklerini <a href="/glsl/">GLSL</a> sayfasına ekledim, altına da <a href="https://shadertoy.com">ShaderToy</a>‘a eklediğim hallerinin linklerini koydum. İleride oradaki örnekleri geliştirip, daha uygun hale getirerek, daha fazla örnek kodlamayı düşünüyorum. GLSL’in ne olduğu, nasıl başlanacağı ile ilgili yazılar da gelecek.</p>

<p>Pixel Art çizimlerimi de <a href="/pixelart/">Pixel Art</a> sayfasına ekledim. Şimdiye kadar eklediklerimin hepsini telefonda basit bir uygulamada çizmiştim. Genellikle uyuyamadığım geceler, metroda seyahat ettiğim zamanlar veya bir şeyi beklerken geçen zamanlarda çizmişim. Kullandığım uygulamanın ismi 8bit Painter ve gerçekten basit bir uygulama, her piksel için ayrı ayrı uğraşmam gerekiyor, kolaylık sağlayan bir aracı yok. Fakat telefonda bunu yapabildiğim için benim için pratik oluyor. Kendim bir piksel art uygulaması yazma çalışmalarına başlamıştım, hem mobilde hem web üzerinde çalışacak bir web uygulaması şeklinde.</p>

<p><a href="/hakkinda/">Hakkında</a> sayfasını ileride detaylı bir şekilde geliştirmeyi düşünüyorum.</p>

<p>Ha bir de <a href="/experimental/">Experimental</a> isminde gizli bir sayfa var. Kendi geliştirdiğim bir Javascript kütüphanesini burada denedim.</p>]]></content><author><name>Hüseyin Karabaş</name></author><category term="blog" /><summary type="html"><![CDATA[Bu web sitesini Jekyll isminde, Ruby ile kodlanmış bir static page generator ile oluşturdum. Blog yazılarını da markdown formatında yazıyorum ve Git kullanarak siteyi güncel tutuyorum. Web sitesini barındırdığım Github Pages, doğrudan Jekyll desteği sunuyor, bu güzel bir olay. Burası built-in bir şekilde syntax highlight özelliğini de destekliyormuş, dur bir deneyelim:]]></summary></entry></feed>