<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-11-01T12:05:54+00:00</updated><id>https://program.sonsuz.us/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Akıllı Hastanelerde Kaynak Optimizasyonu: Yatak, Personel ve Ekipmanı Aynı Ritme Sokmak</title><link href="https://program.sonsuz.us/posts/akilli-hastanelerde-kaynak-optimizasyonu-yatak-personel-ve-ekipmani-ayni-ritme-sokmak/" rel="alternate" type="text/html" title="Akıllı Hastanelerde Kaynak Optimizasyonu: Yatak, Personel ve Ekipmanı Aynı Ritme Sokmak" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/akilli-hastanelerde-kaynak-optimizasyonu-yatak-personel-ve-ekipmani-ayni-ritme-sokmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/akilli-hastanelerde-kaynak-optimizasyonu-yatak-personel-ve-ekipmani-ayni-ritme-sokmak/"><![CDATA[<p>Bir hastaneyi yalnızca boş yatakları sayarak yönetmek, restoranı sadece masa sayısına göre işletmeye benzer: Masalar hazırdır ama aşçı yoksa işler karışır! Hastanelerde de yatak, personel ve ekipman birlikte planlanmalıdır. Akıllı yönetim sistemleri, bu kaynaklar arasındaki bağı algoritmalarla görünür kılar; amaç yalnızca doluluğu artırmak değil, güvenli hizmeti doğru zamanda sunmaktır.</p>

<p><img src="/img/akilli-hastanelerde-kaynak-93.svg" alt="akilli-hastanelerde-kaynak-93" /></p>

<p>``</p>

<h2 id="önce-problemi-doğru-tarif-edelim">Önce problemi doğru tarif edelim</h2>

<p>Kaynak optimizasyonunun temelinde <strong>yöneylem araştırması</strong> bulunur. Sistem; karar değişkenlerini, kısıtları ve hedefleri matematiksel bir modele dönüştürür. Örneğin karar, uygun bir elektif yatışın belirli bir güne planlanıp planlanmayacağı olabilir. Kısıtlar ise kullanılabilir yatakları, bakım saatlerini ve cihaz kapasitesini temsil eder.</p>

<p>Ancak kaynaklar birbirinin yerine geçmez. Boş bir servis yatağı, yoğun bakım yatağının alternatifi değildir; müsait bir çalışan da her uzmanlık görevini üstlenemez. Bu nedenle toplam kapasiteden önce <strong>klinik uygunluk ve yetkinlik</strong> kontrol edilir.</p>

<table>
  <thead>
    <tr>
      <th>Kaynak</th>
      <th>Basit kapasite ölçüsü</th>
      <th>Kritik ek kısıt</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Yatak</td>
      <td>Kullanılabilir yatak sayısı</td>
      <td>Servis türü, izolasyon, temizlik</td>
    </tr>
    <tr>
      <td>Personel</td>
      <td>Vardiyadaki çalışma saati</td>
      <td>Yetkinlik, dinlenme, bakım oranı</td>
    </tr>
    <tr>
      <td>Ekipman</td>
      <td>Kullanılabilir cihaz saati</td>
      <td>Cihaz türü, bakım, eşzamanlı kullanım</td>
    </tr>
  </tbody>
</table>

<h2 id="matematik-kapasiteyi-aşmadan-değer-üretmek">Matematik: Kapasiteyi aşmadan değer üretmek</h2>

<p>Basitleştirilmiş bir günlük modelde $x_i$, aday yatış planlanırsa $1$, aksi durumda $0$ olsun. $u_i$ klinik ekipçe belirlenen öncelik puanını, $a_{ir}$ adayın kaynak tüketimini, $C_r$ ise kapasiteyi göstersin:</p>

\[\max \sum_i u_i x_i\]

\[\sum_i a_{ir}x_i \leq C_r \quad \forall r, \qquad x_i\in\{0,1\}\]

<p>Bu yapı, çok boyutlu sırt çantası problemine benzer: Çantamız hastane, bölmeleri ise kaynaklardır. Gerçek modeller ayrıca bekleme süresi, fazla mesai ve iş yükü dengesizliğini ele alır. Bu hedeflerin ağırlıkları gelişigüzel seçilmemeli; klinik yönetişimle belirlenmelidir. Güvenlik şartları, birkaç puan uğruna esnetilen tercihler değil, zorunlu kısıtlardır.</p>

<h2 id="hangi-algoritma-hangi-iş-için">Hangi algoritma, hangi iş için?</h2>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Güçlü tarafı</th>
      <th>Sınırı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Karma tamsayılı programlama</td>
      <td>Doğrusal maliyet ve kapasite modelleri</td>
      <td>Büyük modellerde çözüm süresi</td>
    </tr>
    <tr>
      <td>CP-SAT</td>
      <td>Mantıksal kurallar ve ayrık çizelgeleme</td>
      <td>Doğru modelleme gerektirir</td>
    </tr>
    <tr>
      <td>Açgözlü sezgiseller</td>
      <td>Hızlı başlangıç planı</td>
      <td>En iyi çözümü garanti etmez</td>
    </tr>
  </tbody>
</table>

<p>Önceliği en yüksek hastayı sırayla yerleştirmek caziptir. Fakat bu hasta kıt bir cihazın çoğunu kullanıyorsa, başka uygun kombinasyonlar toplamda daha iyi sonuç verebilir. Optimizasyonun farkı, kararları tek tek değil, birbirleriyle etkileşimleri içinde değerlendirmesidir.</p>

<h2 id="python-ile-küçük-bir-planlama-modeli">Python ile küçük bir planlama modeli</h2>

<p>Aşağıdaki örnek, OR-Tools üzerinden günlük elektif yatış adaylarını seçer. Kurulum için <code class="language-plaintext highlighter-rouge">pip install ortools</code> kullanılabilir. Her satır sırasıyla yatak, hemşirelik saati, cihaz saati ve öncelik puanı içerir; değerler tamamen örnektir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">ortools.sat.python</span> <span class="kn">import</span> <span class="n">cp_model</span>

<span class="n">adaylar</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">9</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">),</span>
           <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">)]</span>
<span class="n">kapasiteler</span> <span class="o">=</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">16</span><span class="p">]</span>

<span class="n">model</span> <span class="o">=</span> <span class="n">cp_model</span><span class="p">.</span><span class="nc">CpModel</span><span class="p">()</span>
<span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="n">model</span><span class="p">.</span><span class="nf">new_bool_var</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">aday_</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="sh">"</span><span class="p">)</span>
     <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">adaylar</span><span class="p">))]</span>

<span class="k">for</span> <span class="n">r</span><span class="p">,</span> <span class="n">kapasite</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">kapasiteler</span><span class="p">):</span>
    <span class="n">model</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="nf">sum</span><span class="p">(</span><span class="n">adaylar</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">r</span><span class="p">]</span> <span class="o">*</span> <span class="n">x</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
                  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">adaylar</span><span class="p">)))</span> <span class="o">&lt;=</span> <span class="n">kapasite</span><span class="p">)</span>

<span class="n">model</span><span class="p">.</span><span class="nf">maximize</span><span class="p">(</span><span class="nf">sum</span><span class="p">(</span><span class="n">adaylar</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">3</span><span class="p">]</span> <span class="o">*</span> <span class="n">x</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
                   <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">adaylar</span><span class="p">))))</span>

<span class="n">solver</span> <span class="o">=</span> <span class="n">cp_model</span><span class="p">.</span><span class="nc">CpSolver</span><span class="p">()</span>
<span class="n">solver</span><span class="p">.</span><span class="n">parameters</span><span class="p">.</span><span class="n">max_time_in_seconds</span> <span class="o">=</span> <span class="mf">2.0</span>
<span class="n">sonuc</span> <span class="o">=</span> <span class="n">solver</span><span class="p">.</span><span class="nf">solve</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>

<span class="k">if</span> <span class="n">sonuc</span> <span class="ow">in</span> <span class="p">(</span><span class="n">cp_model</span><span class="p">.</span><span class="n">OPTIMAL</span><span class="p">,</span> <span class="n">cp_model</span><span class="p">.</span><span class="n">FEASIBLE</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">([</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">adaylar</span><span class="p">))</span> <span class="k">if</span> <span class="n">solver</span><span class="p">.</span><span class="nf">value</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="n">i</span><span class="p">])])</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Süre içinde uygulanabilir plan bulunamadı.</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu veride en iyi seçim, sıfırdan başlayan indekslerle <code class="language-plaintext highlighter-rouge">[0, 1, 3]</code> olur. Toplam tüketim üç yatak, 22 hemşirelik saati ve 14 cihaz saatidir. <code class="language-plaintext highlighter-rouge">FEASIBLE</code>, uygulanabilir çözüm bulunduğunu söyler; <code class="language-plaintext highlighter-rouge">OPTIMAL</code> ise en iyiliğin kanıtlandığını belirtir.</p>

<p>Önemli ayrıntı: Günlük saat toplamı, aynı anda yeterli personel veya cihaz bulunduğunu garanti etmez. Gerçek çizelgelemede zaman aralıkları tanımlanır; <code class="language-plaintext highlighter-rouge">NoOverlap</code> tek cihazdaki çakışmaları, <code class="language-plaintext highlighter-rouge">Cumulative</code> eşzamanlı kapasite kullanımını sınırlar. Personel yetkinliği ve hasta bakım oranları ayrıca modellenir.</p>

<h2 id="planı-yaşayan-bir-sisteme-dönüştürmek">Planı yaşayan bir sisteme dönüştürmek</h2>

<p>Acil başvurular, geciken taburculuklar ve cihaz arızaları planı değiştirir. Bu yüzden tahminler senaryolarla sınanmalı, beklenmedik talep için kapasite tamponu bırakılmalı ve plan düzenli güncellenmelidir. Her değişimde tüm vardiyayı dağıtmak yerine, mevcut plana sadakati gözeten cezalar kullanılabilir.</p>

<p>Başarıyı yalnızca yatak doluluğuyla ölçmeyin: Bekleme süresi, fazla mesai, iptaller, bakım güvenliği ve çalışan yükü birlikte izlenmelidir. Sistem karar desteğidir; acil bakımın reddini otomatikleştirmez. Klinik onay, insan müdahalesi, erişim kontrolü ve denetlenebilir karar kayıtları korunmalıdır. İyi algoritma, hastaneyi bir elektronik tabloya değil, daha uyumlu çalışan bir ekibe dönüştürür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="kaynak optimizasyonu" /><category term="hastane yönetimi" /><category term="algoritmalar" /><category term="yöneylem araştırması" /><category term="python" /><category term="çizelgeleme" /><summary type="html"><![CDATA[Bir hastaneyi yalnızca boş yatakları sayarak yönetmek, restoranı sadece masa sayısına göre işletmeye benzer: Masalar hazırdır ama aşçı yoksa işler karışır! Hastanelerde de yatak, personel ve ekipman birlikte planlanmalıdır. Akıllı yönetim sistemleri, bu kaynaklar arasındaki bağı algoritmalarla görünür kılar; amaç yalnızca doluluğu artırmak değil, güvenli hizmeti doğru zamanda sunmaktır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/akilli-hastanelerde-kaynak-93.png" /><media:content medium="image" url="https://program.sonsuz.us/img/akilli-hastanelerde-kaynak-93.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Battle Royale’ın Yükselişi: Daralan Harita Oyuncuları Nasıl Yönlendiriyor?</title><link href="https://program.sonsuz.us/posts/battle-royalein-yukselisi-daralan-harita-oyunculari-nasil-yonlendiriyor/" rel="alternate" type="text/html" title="Battle Royale’ın Yükselişi: Daralan Harita Oyuncuları Nasıl Yönlendiriyor?" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/battle-royalein-yukselisi-daralan-harita-oyunculari-nasil-yonlendiriyor</id><content type="html" xml:base="https://program.sonsuz.us/posts/battle-royalein-yukselisi-daralan-harita-oyunculari-nasil-yonlendiriyor/"><![CDATA[<p><img src="/img/battle-royalein-yukselisi-82.svg" alt="battle-royalein-yukselisi-82" /></p>

<p>Battle Royale oyunlarında asıl rakibiniz bazen karşınızdaki oyuncu değil, arkanızdan yaklaşan çemberdir. Daralan harita, devasa bir oyun alanını giderek küçülen bir karar kutusuna dönüştürür. Oyuncuya görünmez bir yönetmen gibi seslenir: “Eşyalarını topladın mı? Güzel, şimdi biraz hareket zamanı!” Peki bu basit geometrik fikir, davranışları nasıl bu kadar güçlü biçimde şekillendiriyor?</p>

<p>``</p>

<h2 id="büyük-haritadan-ortak-finale">Büyük Haritadan Ortak Finale</h2>

<p>PUBG ve Fortnite gibi oyunların popülerleşmesini yalnızca daralan haritaya bağlamak eksik olur. Erişilebilirlik, sosyal oyun deneyimi ve yayın kültürü de önemli etkenlerdir. Ancak güvenli bölge, bu türün seyir zevkini ve maç ritmini taşıyan temel mekaniklerden biridir.</p>

<p>Başlangıçta oyuncular farklı noktalara dağılır; keşif, ekipman toplama ve çatışmadan kaçınma mümkündür. Bölge daraldıkça bu özgürlük azalır. Böylece birbirinden bağımsız küçük hikâyeler, ortak bir final sahnesinde birleşir. Tasarımcı her karşılaşmayı senaryolaştırmadan gerilimi artırabilir.</p>

<h2 id="teorik-temel-alan-azalınca-ne-değişir">Teorik Temel: Alan Azalınca Ne Değişir?</h2>

<p>Dairesel güvenli bölgenin alanı $A(t)=πr(t)^2$ olarak ifade edilir. Burada $r(t)$, zamana bağlı yarıçaptır. Yarıçap yarıya indiğinde alan dörtte bire düşer. Yani harita küçülmesi, oyuncunun gözünde göründüğünden daha sert bir alan kaybı yaratabilir.</p>

<p>Yaşayan oyuncu sayısını $N(t)$ ile gösterirsek ortalama yoğunluk $ρ(t)=N(t)/A(t)$ olur. Oyuncu sayısı azalmasına rağmen alan daha hızlı küçülüyorsa yoğunluk artabilir. Bunun karşılaşma ihtimalini yükseltmesi beklenir; fakat oyuncular eşit dağılmadığından bu, kesin bir çatışma formülü değildir. Binalar, görüş çizgileri ve yüksek araziler sonucu değiştirir.</p>

<table>
  <thead>
    <tr>
      <th>Durum</th>
      <th>Baskın karar</th>
      <th>Başlıca risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Geniş güvenli alan</td>
      <td>Ekipman toplamak</td>
      <td>Hazırlıksız yakalanmak</td>
    </tr>
    <tr>
      <td>Daralma yaklaşırken</td>
      <td>Rotayı planlamak</td>
      <td>Geç hareket etmek</td>
    </tr>
    <tr>
      <td>Küçük güvenli alan</td>
      <td>Konum üstünlüğü kurmak</td>
      <td>Kolay fark edilmek</td>
    </tr>
    <tr>
      <td>Son çember</td>
      <td>Zamanlama ve siper seçmek</td>
      <td>Kaçış seçeneğinin kalmaması</td>
    </tr>
  </tbody>
</table>

<h2 id="çemberin-davranışsal-etkisi">Çemberin Davranışsal Etkisi</h2>

<p>Daralan bölge, hareketsiz kalmanın maliyetini yükseltir. Normalde güvenli görünen bir bina, birkaç dakika sonra tehlikeli bir tuzağa dönüşebilir. Böylece oyun, oyuncuyu zorunlu hareket ile taktiksel bekleme arasında seçim yapmaya iter.</p>

<p>Erken hareket eden oyuncu uygun siper bulabilir; fakat merkezde daha fazla yönden tehdit alabilir. Kenarda kalan oyuncu arkasını daha kolay kontrol edebilir, ancak sonraki bölgeye uzun yol katetmek zorunda kalabilir. Dolayısıyla “merkeze koşmak” her durumda en iyi strateji değildir.</p>

<p>Bu yapı karar teorisiyle okunabilir: Oyuncu beklenen kazancı, hasar riskini ve zaman maliyetini birlikte değerlendirir. Çember bu maliyetleri sürekli değiştirerek aynı taktiğin bütün maç boyunca işe yaramasını engeller.</p>

<h2 id="küçük-bir-python-davranış-modeli">Küçük Bir Python Davranış Modeli</h2>

<p>Aşağıdaki örnek, botun olası hedef noktalarını yolculuk süresi, bölge dışında kalma ve görünürlük riski üzerinden puanlar. Düşük puanlı hedef tercih edilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">math</span>


<span class="k">def</span> <span class="nf">radius_at</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="mi">250</span><span class="p">,</span> <span class="n">delay</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span> <span class="n">duration</span><span class="o">=</span><span class="mi">120</span><span class="p">):</span>
    <span class="n">progress</span> <span class="o">=</span> <span class="nf">min</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="nf">max</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="p">(</span><span class="n">t</span> <span class="o">-</span> <span class="n">delay</span><span class="p">)</span> <span class="o">/</span> <span class="n">duration</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">start</span> <span class="o">+</span> <span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="n">progress</span>


<span class="k">def</span> <span class="nf">choose_target</span><span class="p">(</span><span class="n">position</span><span class="p">,</span> <span class="n">candidates</span><span class="p">,</span> <span class="n">center</span><span class="p">,</span> <span class="n">radius</span><span class="p">,</span> <span class="n">speed</span><span class="o">=</span><span class="mi">6</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">cost</span><span class="p">(</span><span class="n">point</span><span class="p">):</span>
        <span class="n">travel_time</span> <span class="o">=</span> <span class="n">math</span><span class="p">.</span><span class="nf">dist</span><span class="p">(</span><span class="n">position</span><span class="p">,</span> <span class="n">point</span><span class="p">)</span> <span class="o">/</span> <span class="n">speed</span>
        <span class="n">outside</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">math</span><span class="p">.</span><span class="nf">dist</span><span class="p">(</span><span class="n">point</span><span class="p">,</span> <span class="n">center</span><span class="p">)</span> <span class="o">-</span> <span class="n">radius</span><span class="p">)</span>
        <span class="n">exposure</span> <span class="o">=</span> <span class="n">candidates</span><span class="p">[</span><span class="n">point</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">travel_time</span> <span class="o">+</span> <span class="mf">0.4</span> <span class="o">*</span> <span class="n">outside</span> <span class="o">+</span> <span class="mi">12</span> <span class="o">*</span> <span class="n">exposure</span>

    <span class="k">return</span> <span class="nf">min</span><span class="p">(</span><span class="n">candidates</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">cost</span><span class="p">)</span>


<span class="n">candidates</span> <span class="o">=</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="mf">0.8</span><span class="p">,</span> <span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">50</span><span class="p">):</span> <span class="mf">0.2</span><span class="p">,</span> <span class="p">(</span><span class="mi">600</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="mf">0.1</span><span class="p">}</span>
<span class="n">future_radius</span> <span class="o">=</span> <span class="nf">radius_at</span><span class="p">(</span><span class="mi">120</span><span class="p">)</span>
<span class="n">target</span> <span class="o">=</span> <span class="nf">choose_target</span><span class="p">((</span><span class="mi">500</span><span class="p">,</span> <span class="mi">100</span><span class="p">),</span> <span class="n">candidates</span><span class="p">,</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="n">future_radius</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">radius_at</code>, bekleme süresinden sonra yarıçapı doğrusal küçültür. <code class="language-plaintext highlighter-rouge">choose_target</code> ise adayların görünürlük değerlerini kullanır; bu değerler burada elle verilmiştir. Katsayılar farklı maliyetleri ortak bir tercih puanına dönüştüren tasarım ağırlıklarıdır, fiziksel hasar hesabı değildir.</p>

<p>Bu model engelleri ve hareket sırasında değişen çemberi hesaba katmaz. Gerçek bir oyunda yol bulma, takım bilgisi ve bölge hasarı da değerlendirmeye eklenmelidir.</p>

<h2 id="i̇yi-baskı-kötü-sürprizden-nasıl-ayrılır">İyi Baskı, Kötü Sürprizden Nasıl Ayrılır?</h2>

<p>Başarılı bir çember sistemi oyuncuyu sıkıştırırken karar verecek zaman bırakır. Belirsizlik heyecan yaratır; okunamayan veya ulaşılması aşırı zor bölgeler ise sonucu beceriden çok şansa bağlayabilir.</p>

<p>Geliştiriciler daralma hızını, uyarı süresini ve dışarıda alınan hasarı birlikte ayarlamalıdır. Çok yavaş çember temposuzluk, çok hızlı çember ise sürekli koşu üretir. Telemetride bölge kaynaklı ölümler, hareketin başlama zamanı ve çatışmaların konumu izlenebilir; ancak bu ölçümler oyuncu deneyimiyle birlikte yorumlanmalıdır.</p>

<p>Sonuçta daralan harita yalnızca oyuncuları yaklaştırmaz: Kaynakların değerini, risk algısını ve zamanın önemini değiştirir. Battle Royale’ın güçlü numarası budur; basit bir geometrik kural, her maçta farklı bir stratejik hikâye üretir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="battle royale" /><category term="oyun tasarımı" /><category term="oyuncu davranışı" /><category term="python" /><category term="oyun mekaniği" /><category term="karar teorisi" /><summary type="html"><![CDATA[Battle Royale oyunlarında asıl rakibiniz bazen karşınızdaki oyuncu değil, arkanızdan yaklaşan çemberdir. Daralan harita, devasa bir oyun alanını giderek küçülen bir karar kutusuna dönüştürür. Oyuncuya görünmez bir yönetmen gibi seslenir: “Eşyalarını topladın mı? Güzel, şimdi biraz hareket zamanı!” Peki bu basit geometrik fikir, davranışları nasıl bu kadar güçlü biçimde şekillendiriyor?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/battle-royalein-yukselisi-82.png" /><media:content medium="image" url="https://program.sonsuz.us/img/battle-royalein-yukselisi-82.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C Standart Kütüphanesi: Matematik, Metin ve Bellek İçin Hazır Araçlar</title><link href="https://program.sonsuz.us/posts/c-standart-kutuphanesi-matematik-metin-ve-bellek-icin-hazir-araclar/" rel="alternate" type="text/html" title="C Standart Kütüphanesi: Matematik, Metin ve Bellek İçin Hazır Araçlar" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-standart-kutuphanesi-matematik-metin-ve-bellek-icin-hazir-araclar</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-standart-kutuphanesi-matematik-metin-ve-bellek-icin-hazir-araclar/"><![CDATA[<p>C programlamak, her vidayı kendiniz üretmeniz gerektiği anlamına gelmez. Standart kütüphane; matematik hesaplarından metin karşılaştırmaya, dinamik bellek ayırmadan hata bildirimine kadar hazır araçlar sunar. Ancak bu araçları güvenli kullanmak için yalnızca isimlerini değil, çalışma sözleşmelerini de bilmek gerekir.</p>

<p>``</p>

<h2 id="önce-mantık-başlık-dosyası-ne-sağlar">Önce mantık: Başlık dosyası ne sağlar?</h2>

<p><code class="language-plaintext highlighter-rouge">#include</code>, ilgili başlık dosyasını programa dahil eder. Başlıklar, fonksiyon bildirimlerini, türleri ve gerekli makroları sunar; fonksiyonların gerçek uygulamaları ise kütüphanelerdedir. Derleyici çağrının türlerini denetler, bağlayıcı gerekli uygulamaları birleştirir. Kısacası başlık dosyası menüdür; yemeği hazırlayan mutfak, kütüphanenin uygulamasıdır. Bu ayrım, derleme hatasıyla bağlama hatasını birbirinden ayırmayı kolaylaştırır.</p>

<table>
  <thead>
    <tr>
      <th>Başlık</th>
      <th>Temel görev</th>
      <th>Örnek fonksiyonlar</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;math.h&gt;</code></td>
      <td>Matematiksel hesaplama</td>
      <td><code class="language-plaintext highlighter-rouge">sqrt</code>, <code class="language-plaintext highlighter-rouge">pow</code>, <code class="language-plaintext highlighter-rouge">sin</code>, <code class="language-plaintext highlighter-rouge">fabs</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;string.h&gt;</code></td>
      <td>Metin ve bayt işlemleri</td>
      <td><code class="language-plaintext highlighter-rouge">strlen</code>, <code class="language-plaintext highlighter-rouge">strcmp</code>, <code class="language-plaintext highlighter-rouge">memcpy</code>, <code class="language-plaintext highlighter-rouge">memmove</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;stdlib.h&gt;</code></td>
      <td>Bellek ve dönüşüm</td>
      <td><code class="language-plaintext highlighter-rouge">malloc</code>, <code class="language-plaintext highlighter-rouge">calloc</code>, <code class="language-plaintext highlighter-rouge">realloc</code>, <code class="language-plaintext highlighter-rouge">free</code>, <code class="language-plaintext highlighter-rouge">strtol</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;ctype.h&gt;</code></td>
      <td>Karakter sınıflandırma</td>
      <td><code class="language-plaintext highlighter-rouge">isdigit</code>, <code class="language-plaintext highlighter-rouge">isspace</code>, <code class="language-plaintext highlighter-rouge">toupper</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;stdio.h&gt;</code></td>
      <td>Girdi ve çıktı</td>
      <td><code class="language-plaintext highlighter-rouge">printf</code>, <code class="language-plaintext highlighter-rouge">fgets</code>, <code class="language-plaintext highlighter-rouge">fputs</code></td>
    </tr>
  </tbody>
</table>

<h2 id="matematik-formülü-yeniden-icat-etmeyin">Matematik: Formülü yeniden icat etmeyin</h2>

<p><code class="language-plaintext highlighter-rouge">&lt;math.h&gt;</code>, kayan noktalı hesaplamalar için temel araç kutusudur. <code class="language-plaintext highlighter-rouge">sqrt(x)</code> karekök, <code class="language-plaintext highlighter-rouge">pow(x, y)</code> üs, <code class="language-plaintext highlighter-rouge">fabs(x)</code> mutlak değer hesaplar. Tamsayılar için kullanılan <code class="language-plaintext highlighter-rouge">abs</code> ise <code class="language-plaintext highlighter-rouge">&lt;stdlib.h&gt;</code> içindedir. <code class="language-plaintext highlighter-rouge">floor</code>, <code class="language-plaintext highlighter-rouge">ceil</code> ve <code class="language-plaintext highlighter-rouge">round</code> farklı yuvarlama kurallarına sahiptir; özellikle negatif sayılarda birbirlerinin yerine kullanılmamalıdır.</p>

<p>İki noktanın uzaklığı şu bağıntıyla bulunur:</p>

\[d = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2}\]

<p>Bu hesap için <code class="language-plaintext highlighter-rouge">hypot(dx, dy)</code>, ara işlemlerde taşma ve aşırı küçülme riskini azaltabilir. Trigonometrik fonksiyonlar radyan bekler. Ayrıca kayan nokta sonuçları yaklaşık olabilir; matematikteki eşitlik, bilgisayarda her zaman birebir eşitlik değildir. Negatif bir değerin karekökü gibi tanım dışı girdilerin hata davranışı da kontrol edilmelidir.</p>

<h2 id="metin-işleme-sonlandırıcı-karakteri-unutmayın">Metin işleme: Sonlandırıcı karakteri unutmayın</h2>

<p>C dizeleri, <code class="language-plaintext highlighter-rouge">\0</code> karakteriyle biten karakter dizileridir. <code class="language-plaintext highlighter-rouge">strlen</code>, bu sonlandırıcıdan önceki baytların sayısını verir; UTF-8 metindeki görünen harf sayısını garanti etmez. <code class="language-plaintext highlighter-rouge">strcmp</code> eşitlik durumunda sıfır döndürür, diğer durumlarda işaretine bakılır; yalnızca <code class="language-plaintext highlighter-rouge">-1</code> veya <code class="language-plaintext highlighter-rouge">1</code> döneceğini varsaymayın.</p>

<p><code class="language-plaintext highlighter-rouge">memcpy</code>, belirtilen sayıda baytı kopyalar ve bölgeler örtüşmemelidir. Örtüşme ihtimali varsa <code class="language-plaintext highlighter-rouge">memmove</code> kullanılır. <code class="language-plaintext highlighter-rouge">strncpy</code> ise her durumda sonlandırıcı eklemez; adı güvenlik garantisi değildir. Dize fonksiyonları sonlandırıcıya, bellek fonksiyonları verilen uzunluğa güvenir.</p>

<p><code class="language-plaintext highlighter-rouge">&lt;ctype.h&gt;</code> fonksiyonlarına sıradan bir <code class="language-plaintext highlighter-rouge">char</code> verirken <code class="language-plaintext highlighter-rouge">(unsigned char)</code> dönüşümü yapmak önemlidir; negatif karakter değerleri tanımsız davranışa neden olabilir.</p>

<h2 id="bellek-yönetimi-alanın-sahibi-sizsiniz">Bellek yönetimi: Alanın sahibi sizsiniz</h2>

<p>Dinamik bellek, boyutu çalışma sırasında belirlenen verileri saklamaya yarar. Ayırdığınız alanın kapasitesi ile içine koyduğunuz verinin uzunluğu farklı kavramlardır. Dize için gereken kapasite genellikle $uzunluk + 1$ bayttır; fazladan bayt sonlandırıcı içindir. Ayırma işleminin başarısız olabileceğini de unutmamak gerekir.</p>

<table>
  <thead>
    <tr>
      <th>Fonksiyon</th>
      <th>Davranış</th>
      <th>Dikkat noktası</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">malloc</code></td>
      <td>Alan ayırır</td>
      <td>İçerik başlatılmaz</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">calloc</code></td>
      <td>Alan ayırıp baytları sıfırlar</td>
      <td>Eleman sayısı ve boyut verilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">realloc</code></td>
      <td>Alanın boyutunu değiştirir</td>
      <td>Adres değişebilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">free</code></td>
      <td>Alanı serbest bırakır</td>
      <td>Aynı alan iki kez bırakılmaz</td>
    </tr>
  </tbody>
</table>

<h2 id="birlikte-çalışan-küçük-bir-örnek">Birlikte çalışan küçük bir örnek</h2>

<p>Aşağıdaki program bir metni dinamik belleğe kopyalar, kapasitesini artırır ve matematik fonksiyonlarıyla sonuç üretir. Böylece üç araç kutusunu aynı yerde görürüz.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;math.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">kaynak</span> <span class="o">=</span> <span class="s">"Merhaba C"</span><span class="p">;</span>
    <span class="kt">size_t</span> <span class="n">kapasite</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">kaynak</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">char</span> <span class="o">*</span><span class="n">metin</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="n">kapasite</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">metin</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">memcpy</span><span class="p">(</span><span class="n">metin</span><span class="p">,</span> <span class="n">kaynak</span><span class="p">,</span> <span class="n">kapasite</span><span class="p">);</span>
    <span class="kt">char</span> <span class="o">*</span><span class="n">yeni</span> <span class="o">=</span> <span class="n">realloc</span><span class="p">(</span><span class="n">metin</span><span class="p">,</span> <span class="n">kapasite</span> <span class="o">+</span> <span class="mi">16</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">yeni</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">free</span><span class="p">(</span><span class="n">metin</span><span class="p">);</span>
        <span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="n">metin</span> <span class="o">=</span> <span class="n">yeni</span><span class="p">;</span>
    <span class="n">strcat</span><span class="p">(</span><span class="n">metin</span><span class="p">,</span> <span class="s">"!"</span><span class="p">);</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"%s | Uzunluk: %zu | Kok: %.2f | Us: %.2f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
           <span class="n">metin</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">metin</span><span class="p">),</span> <span class="n">sqrt</span><span class="p">(</span><span class="mi">9</span><span class="p">.</span><span class="mi">0</span><span class="p">),</span> <span class="n">pow</span><span class="p">(</span><span class="mi">2</span><span class="p">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">.</span><span class="mi">0</span><span class="p">));</span>
    <span class="n">free</span><span class="p">(</span><span class="n">metin</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">memcpy</code>, sonlandırıcı dahil bütün diziyi kopyalar. Eklenen kapasite, ünlem ve sonlandırıcı için yeterlidir. <code class="language-plaintext highlighter-rouge">realloc</code> sonucu geçici işaretçide tutulur: Sıfırdan büyük boyutla yapılan çağrı başarısız olursa eski alan geçerliliğini korur. Sonucu doğrudan <code class="language-plaintext highlighter-rouge">metin</code> üzerine yazmak, eski adresi kaybettirebilir.</p>

<p>Birçok Unix benzeri ortamda matematik kütüphanesini ayrıca bağlamak gerekir:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cc <span class="nt">-std</span><span class="o">=</span>c11 <span class="nt">-Wall</span> <span class="nt">-Wextra</span> main.c <span class="nt">-o</span> uygulama <span class="nt">-lm</span>
</code></pre></div></div>

<p>Son kontrol listesi basittir: Kapasiteleri doğrulayın, dönüş değerlerini inceleyin ve ayırdığınız belleği bırakın. Genel boyut hesaplarında <code class="language-plaintext highlighter-rouge">n * sizeof(eleman)</code> çarpımının taşmasını önceden denetleyin. Serbest bırakılmış belleğe erişmeyin. Hazır fonksiyonlar işi hızlandırır; güvenli kullanım ise hâlâ programcının sorumluluğudur.</p>

<p><img src="/img/c-standart-kutuphanesi-29.svg" alt="c-standart-kutuphanesi-29" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c" /><category term="standart kütüphane" /><category term="matematik" /><category term="metin işleme" /><category term="bellek yönetimi" /><summary type="html"><![CDATA[C programlamak, her vidayı kendiniz üretmeniz gerektiği anlamına gelmez. Standart kütüphane; matematik hesaplarından metin karşılaştırmaya, dinamik bellek ayırmadan hata bildirimine kadar hazır araçlar sunar. Ancak bu araçları güvenli kullanmak için yalnızca isimlerini değil, çalışma sözleşmelerini de bilmek gerekir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-standart-kutuphanesi-29.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-standart-kutuphanesi-29.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Finansın Dijital Laboratuvarı: Python ile Senaryoları Simüle Etmek</title><link href="https://program.sonsuz.us/posts/finansin-dijital-laboratuvari-python-ile-senaryolari-simule-etmek/" rel="alternate" type="text/html" title="Finansın Dijital Laboratuvarı: Python ile Senaryoları Simüle Etmek" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/finansin-dijital-laboratuvari-python-ile-senaryolari-simule-etmek</id><content type="html" xml:base="https://program.sonsuz.us/posts/finansin-dijital-laboratuvari-python-ile-senaryolari-simule-etmek/"><![CDATA[<p><img src="/img/finansin-dijital-laboratuvari-66.svg" alt="finansin-dijital-laboratuvari-66" /></p>

<p>Bir yatırımın geleceğini tek hücrelik Excel tahminine bağlamak, hava durumuna bakmadan pikniğe çıkmaya benzer: Bazen güneş açar, bazen sandviçler yüzer. Bilgisayar destekli finansal modelleme, gelirleri, maliyetleri ve belirsizlikleri açık varsayımlara dönüştürür. Böylece yalnızca “Ne kadar kazanırız?” sorusunu değil, “Hangi koşullarda zarar ederiz?” sorusunu da araştırabiliriz. Üstelik farklı kararları aynı deney düzeneğinde karşılaştırabiliriz.</p>

<p>``</p>

<h2 id="önce-teori-paranın-zaman-makinesi">Önce teori: Paranın zaman makinesi</h2>

<p>Bugünkü 100 lira ile beş yıl sonraki 100 lira aynı ekonomik değere sahip değildir. Enflasyon, alternatif yatırım getirileri ve risk nedeniyle gelecekteki nakit akışlarını bugüne indirgeriz. Net bugünkü değer, yani NPV, bu yaklaşımın temel araçlarından biridir:</p>

\[NPV=-I_0+\sum_{t=1}^{T}\frac{CF_t}{(1+r)^t}\]

<p>Burada $I_0$ başlangıç yatırımı, $CF_t$ ilgili yılın nakit akışı, $r$ iskonto oranı ve $T$ modelin süresidir. Pozitif NPV, kullanılan iskonto oranı ve varsayımlar altında yatırımın değer yaratabileceğini gösterir; kesin kazanç sözü vermez.</p>

<p>Örneğimizde başlangıç yatırımı bir milyon lira, başlangıç yıllık gelir seviyesi 800 bin liradır. Değişken maliyetleri gelir üzerinden, sabit giderleri ayrı hesaplayacağız. Vergileri, işletme sermayesini, ek yatırımları ve terminal değeri dışarıda bırakıyoruz. Dolayısıyla bu, gerçek yatırım kararına hazır bir değerleme değil, öğretici bir prototiptir.</p>

<h2 id="senaryodan-olasılık-dağılımına">Senaryodan olasılık dağılımına</h2>

<p>Önce üç anlaşılır senaryo tanımlayalım. Bu tablo, değişkenlerin etkisini sezmek içindir; simülasyonun yüzdelik sonuçlarını temsil etmez.</p>

<table>
  <thead>
    <tr>
      <th>Varsayım</th>
      <th style="text-align: right">Kötümser</th>
      <th style="text-align: right">Temel</th>
      <th style="text-align: right">İyimser</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Yıllık gelir büyümesi</td>
      <td style="text-align: right">%0</td>
      <td style="text-align: right">%8</td>
      <td style="text-align: right">%14</td>
    </tr>
    <tr>
      <td>Değişken maliyet / gelir</td>
      <td style="text-align: right">%65</td>
      <td style="text-align: right">%55</td>
      <td style="text-align: right">%45</td>
    </tr>
    <tr>
      <td>İskonto oranı</td>
      <td style="text-align: right">%16</td>
      <td style="text-align: right">%12</td>
      <td style="text-align: right">%9</td>
    </tr>
  </tbody>
</table>

<p>Monte Carlo yöntemi, bu üç fotoğraf yerine binlerce olası kombinasyon üretir. Her kombinasyonda nakit akışları ve NPV yeniden hesaplanır. Sonuç, tek bir tahmin değil, varsayımlara bağlı bir sonuç dağılımıdır. Bilgisayarın yaptığı sihir değil; sistematik biçimde çok sayıda “ya şöyle olursa?” sorusu sormaktır.</p>

<h2 id="python-ile-finansal-deney-düzeneği">Python ile finansal deney düzeneği</h2>

<p>Önce <code class="language-plaintext highlighter-rouge">pip install numpy</code> komutuyla NumPy’ı kurun. Aşağıdaki kod 10.000 senaryo oluşturur. Büyüme ve iskonto oranlarını sınırlandırılmış normal dağılımlardan, maliyet oranını ise minimum, en olası ve maksimum değerleri tanımlanabilen üçgensel dağılımdan örnekler:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="nf">default_rng</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">10_000</span>
<span class="n">years</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span>

<span class="n">growth</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">clip</span><span class="p">(</span>
    <span class="n">rng</span><span class="p">.</span><span class="nf">normal</span><span class="p">(</span><span class="mf">0.08</span><span class="p">,</span> <span class="mf">0.04</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="mi">1</span><span class="p">)),</span> <span class="o">-</span><span class="mf">0.08</span><span class="p">,</span> <span class="mf">0.22</span>
<span class="p">)</span>
<span class="n">cost_ratio</span> <span class="o">=</span> <span class="n">rng</span><span class="p">.</span><span class="nf">triangular</span><span class="p">(</span><span class="mf">0.45</span><span class="p">,</span> <span class="mf">0.55</span><span class="p">,</span> <span class="mf">0.65</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="n">discount</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">clip</span><span class="p">(</span>
    <span class="n">rng</span><span class="p">.</span><span class="nf">normal</span><span class="p">(</span><span class="mf">0.12</span><span class="p">,</span> <span class="mf">0.02</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="mi">1</span><span class="p">)),</span> <span class="mf">0.05</span><span class="p">,</span> <span class="mf">0.20</span>
<span class="p">)</span>

<span class="n">revenue</span> <span class="o">=</span> <span class="mi">800_000</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">growth</span><span class="p">)</span> <span class="o">**</span> <span class="n">years</span>
<span class="n">fixed_cost</span> <span class="o">=</span> <span class="mi">170_000</span> <span class="o">*</span> <span class="mf">1.04</span> <span class="o">**</span> <span class="n">years</span>
<span class="n">cash_flow</span> <span class="o">=</span> <span class="n">revenue</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">cost_ratio</span><span class="p">)</span> <span class="o">-</span> <span class="n">fixed_cost</span>

<span class="n">npv</span> <span class="o">=</span> <span class="p">(</span>
    <span class="n">cash_flow</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">discount</span><span class="p">)</span> <span class="o">**</span> <span class="n">years</span>
<span class="p">).</span><span class="nf">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1_000_000</span>

<span class="n">p5</span><span class="p">,</span> <span class="n">median</span><span class="p">,</span> <span class="n">p95</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">quantile</span><span class="p">(</span><span class="n">npv</span><span class="p">,</span> <span class="p">[</span><span class="mf">0.05</span><span class="p">,</span> <span class="mf">0.50</span><span class="p">,</span> <span class="mf">0.95</span><span class="p">])</span>
<span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">NPV yüzdelikleri: </span><span class="si">{</span><span class="n">p5</span><span class="si">:</span><span class="p">,.</span><span class="mi">0</span><span class="n">f</span><span class="si">}</span><span class="s">, </span><span class="si">{</span><span class="n">median</span><span class="si">:</span><span class="p">,.</span><span class="mi">0</span><span class="n">f</span><span class="si">}</span><span class="s">, </span><span class="si">{</span><span class="n">p95</span><span class="si">:</span><span class="p">,.</span><span class="mi">0</span><span class="n">f</span><span class="si">}</span><span class="s"> TL</span><span class="sh">"</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">Negatif NPV oranı: </span><span class="si">{</span><span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">(</span><span class="n">npv</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span><span class="si">:</span><span class="p">.</span><span class="mi">1</span><span class="o">%</span><span class="si">}</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Rastgele sayı üretecindeki <code class="language-plaintext highlighter-rouge">42</code>, deneyin tekrarlanabilmesini sağlar. <code class="language-plaintext highlighter-rouge">(n, 1)</code> biçimindeki diziler, beş yıllık zaman dizisiyle yayınlama sayesinde birleşir; Python döngüsü yazmadan bütün senaryolar hesaplanır. Her senaryoda seçilen büyüme, maliyet ve iskonto oranı beş yıl boyunca sabittir. Yani burada yıllık şokları değil, model parametrelerindeki belirsizliği örnekliyoruz. Ayrıca 800 bin lira başlangıç seviyesidir; ilk yıl geliri büyüme uygulanarak bulunur.</p>

<h2 id="sonuçları-doğru-okumak">Sonuçları doğru okumak</h2>

<p>Medyan, sonuçların ortasındaki değerdir. Beşinci yüzdelik, simülasyon sonuçlarının yaklaşık %5’inin altında kaldığı eşiği gösterir. Beşinci ve doksan beşinci yüzdelikler arasındaki bölge, model sonuçlarının merkezdeki yaklaşık %90’ını kapsar; medyan için bir güven aralığı değildir.</p>

<p>Negatif NPV oranı da şirketin iflas olasılığı değildir. Yalnızca seçilen dağılımlar altında yatırımın iskonto edilmiş değerinin başlangıç maliyetini karşılamama sıklığıdır. Modeli bir kristal küre değil, varsayımlarınızı sorgulayan bir laboratuvar olarak düşünün.</p>

<h2 id="modeli-gerçek-hayata-yaklaştırmak">Modeli gerçek hayata yaklaştırmak</h2>

<ul>
  <li><strong>Veriyle kalibre edin:</strong> Dağılımları geçmiş satışlar, maliyetler ve piyasa verileriyle gerekçelendirin. Kırpma işlemi sınır noktalarında olasılık yığılması oluşturur.</li>
  <li><strong>Bağımlılıkları modelleyin:</strong> Örnekte değişkenler bağımsızdır. Gerçekte yüksek büyüme, yüksek maliyet veya farklı risk primiyle birlikte gelebilir.</li>
  <li><strong>Tutarlılığı koruyun:</strong> Nominal nakit akışlarını nominal iskonto oranıyla değerlendirin. Sabit giderlerin yıllık %4 artması açık bir varsayımdır.</li>
  <li><strong>Duyarlılığı ölçün:</strong> Bir varsayımı değiştirip diğerlerini sabit tutarak NPV’nin hangi girdiye daha hassas olduğunu inceleyin.</li>
  <li><strong>Nakit ile kârı ayırın:</strong> Tahsilat gecikmeleri, vergiler ve stok finansmanı eklenmeden muhasebe kârını nakit akışı sanmayın.</li>
</ul>

<p>Son olarak senaryo sayısını artırıp yüzdeliklerin kararlı olup olmadığını kontrol edin. Daha fazla simülasyon örnekleme gürültüsünü azaltır; yanlış varsayımları düzeltmez. Finansal modellemenin asıl gücü geleceği bilmek değil, belirsizliği görünür ve tartışılabilir hâle getirmektir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="finansal-modelleme" /><category term="python" /><category term="monte-carlo" /><category term="risk-analizi" /><category term="simülasyon" /><summary type="html"><![CDATA[Bir yatırımın geleceğini tek hücrelik Excel tahminine bağlamak, hava durumuna bakmadan pikniğe çıkmaya benzer: Bazen güneş açar, bazen sandviçler yüzer. Bilgisayar destekli finansal modelleme, gelirleri, maliyetleri ve belirsizlikleri açık varsayımlara dönüştürür. Böylece yalnızca “Ne kadar kazanırız?” sorusunu değil, “Hangi koşullarda zarar ederiz?” sorusunu da araştırabiliriz. Üstelik farklı kararları aynı deney düzeneğinde karşılaştırabiliriz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/finansin-dijital-laboratuvari-66.png" /><media:content medium="image" url="https://program.sonsuz.us/img/finansin-dijital-laboratuvari-66.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">IFTTT ve Otomasyon Zincirleri: Dijital Domino Taşları Nasıl Dizilir?</title><link href="https://program.sonsuz.us/posts/ifttt-ve-otomasyon-zincirleri-dijital-domino-taslari-nasil-dizilir/" rel="alternate" type="text/html" title="IFTTT ve Otomasyon Zincirleri: Dijital Domino Taşları Nasıl Dizilir?" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ifttt-ve-otomasyon-zincirleri-dijital-domino-taslari-nasil-dizilir</id><content type="html" xml:base="https://program.sonsuz.us/posts/ifttt-ve-otomasyon-zincirleri-dijital-domino-taslari-nasil-dizilir/"><![CDATA[<p>Telefonunuz yağmur başlayınca sizi uyarsa, önemli bir GitHub kaydı açıldığında cebinize bildirim düşse nasıl olurdu? IFTTT, farklı servisleri birbirine bağlayarak bu küçük dijital yardımcıları kurmanızı sağlar. Ancak iyi otomasyon, yalnızca uygulamaları eşleştirmek değildir: olayların, koşulların ve yan etkilerin nasıl çalıştığını anlamaktır. Haydi domino taşlarını devirmeden önce doğru sıraya dizelim!</p>

<p><img src="/img/ifttt-ve-otomasyon-71.svg" alt="ifttt-ve-otomasyon-71" /></p>

<p>``</p>

<h2 id="temel-mantık-olay-koşul-ve-eylem">Temel Mantık: Olay, Koşul ve Eylem</h2>

<p>IFTTT adı, “If This Then That” ifadesinden gelir: “Bu olursa, şunu yap.” Platformdaki otomasyon tariflerine <strong>Applet</strong> denir. Basit bir Applet, bir servisin tetikleyicisini başka bir servisin eylemine bağlar.</p>

<p>Burada üç kavramı ayırmak önemlidir. <strong>Olay</strong>, sistemde gerçekleşen değişikliktir. <strong>Koşul</strong>, olayın işlenmeye değer olup olmadığını belirler. <strong>Eylem</strong> ise başka bir sistemde oluşturulan sonuçtur. Örneğin yeni bir kayıt olaydır; kaydın acil olması koşuldur; bildirim göndermek eylemdir.</p>

<p>Bu ilişkiyi şöyle gösterebiliriz:</p>

\[A = E \land C\]

<p>Burada $E$, ilgili olayın gerçekleşmesini; $C$, ek koşulun sağlanmasını; $A$ ise eylemin çalıştırılmasını temsil eder. Yalnızca tetikleyici kullanan basit tariflerde ek koşulu sürekli doğru kabul edebilirsiniz.</p>

<table>
  <thead>
    <tr>
      <th>Bileşen</th>
      <th>Cevapladığı soru</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tetikleyici</td>
      <td>Ne gerçekleşti?</td>
      <td>Yeni GitHub issue kaydı</td>
    </tr>
    <tr>
      <td>Koşul</td>
      <td>İşlem yapılmalı mı?</td>
      <td><code class="language-plaintext highlighter-rouge">urgent</code> etiketi var mı?</td>
    </tr>
    <tr>
      <td>Eylem</td>
      <td>Ne yapılacak?</td>
      <td>Telefona bildirim gönder</td>
    </tr>
  </tbody>
</table>

<p>Önemli ayrıntı: İki bağımsız tetikleyiciyi otomatik olarak “VE” mantığıyla birleştiremezsiniz. Ek filtreler, çoklu eylemler ve kullanılabilir servisler hesap planına veya entegrasyona göre değişebilir. Karmaşık kararlar için araya kendi küçük uygulamanızı koyabilirsiniz.</p>

<h2 id="zincirler-neden-asenkron-çalışır">Zincirler Neden Asenkron Çalışır?</h2>

<p>Servisler aynı programın fonksiyonları değildir. Aralarında ağ bağlantıları, kimlik doğrulama ve bekleme süreleri bulunur. Bazı tetikleyiciler değişiklikleri belirli aralıklarla kontrol eder; bazıları ise olay geldiğinde doğrudan haber verir. Bu ikinci yaklaşımın yaygın araçlarından biri <strong>webhook</strong> mekanizmasıdır.</p>

<p>Webhook, kabaca “Bir şey olduğunda şu adrese HTTP isteği gönder” anlaşmasıdır. Kapıyı sürekli kontrol etmek yerine zil takmak gibi düşünün. Yine de zilin çalması, içerideki herkesin işini tamamladığı anlamına gelmez!</p>

<p>Bir zincirin yaklaşık gecikmesi şöyle modellenebilir:</p>

\[T_{toplam} \approx \sum_{i=1}^{n}(T_{bekleme,i} + T_{işlem,i})\]

<p>Bu yüzden bildirim otomasyonları için uygun bir zincir, milisaniyelik tepki gerektiren kontrol sistemleri için uygun olmayabilir.</p>

<h2 id="uygulama-acil-github-kaydını-telefona-taşıyalım">Uygulama: Acil GitHub Kaydını Telefona Taşıyalım</h2>

<p>Örnek mimarimiz şöyle olsun: <strong>GitHub webhook → Python uygulaması → IFTTT Webhooks → telefon bildirimi</strong>. GitHub olayını alan uygulama, issue verisini inceler; yalnızca <code class="language-plaintext highlighter-rouge">urgent</code> etiketli kayıtları IFTTT’ye iletir.</p>

<p>IFTTT tarafında önce Webhooks servisindeki <strong>Receive a web request</strong> tetikleyicisini seçin. Olay adını <code class="language-plaintext highlighter-rouge">urgent_issue</code> yapın. Ardından Notifications servisindeki bildirim eylemini seçerek mesajda <code class="language-plaintext highlighter-rouge">Value1</code> ve <code class="language-plaintext highlighter-rouge">Value2</code> alanlarını kullanın. Webhooks anahtarınızı ortam değişkenine kaydedin; kaynak koduna veya herkese açık depoya koymayın.</p>

<p>Aşağıdaki fonksiyon, sunucunuzun doğruladığı webhook içeriğindeki <code class="language-plaintext highlighter-rouge">issue</code> nesnesini işler. <code class="language-plaintext highlighter-rouge">requests</code> paketinin kurulu olması gerekir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">os</span>
<span class="kn">import</span> <span class="n">requests</span>

<span class="n">processed</span> <span class="o">=</span> <span class="nf">set</span><span class="p">()</span>

<span class="k">def</span> <span class="nf">route_issue</span><span class="p">(</span><span class="n">issue</span><span class="p">):</span>
    <span class="n">issue_id</span> <span class="o">=</span> <span class="nf">str</span><span class="p">(</span><span class="n">issue</span><span class="p">[</span><span class="sh">"</span><span class="s">id</span><span class="sh">"</span><span class="p">])</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="p">{</span><span class="n">item</span><span class="p">[</span><span class="sh">"</span><span class="s">name</span><span class="sh">"</span><span class="p">]</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">issue</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">labels</span><span class="sh">"</span><span class="p">,</span> <span class="p">[])}</span>

    <span class="k">if</span> <span class="sh">"</span><span class="s">urgent</span><span class="sh">"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">labels</span> <span class="ow">or</span> <span class="n">issue_id</span> <span class="ow">in</span> <span class="n">processed</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">"</span><span class="s">atlandı</span><span class="sh">"</span>

    <span class="n">key</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">[</span><span class="sh">"</span><span class="s">IFTTT_WEBHOOK_KEY</span><span class="sh">"</span><span class="p">]</span>
    <span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">https://maker.ifttt.com/trigger/urgent_issue/with/key/</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="sh">"</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
        <span class="n">url</span><span class="p">,</span>
        <span class="n">json</span><span class="o">=</span><span class="p">{</span><span class="sh">"</span><span class="s">value1</span><span class="sh">"</span><span class="p">:</span> <span class="n">issue</span><span class="p">[</span><span class="sh">"</span><span class="s">title</span><span class="sh">"</span><span class="p">],</span> <span class="sh">"</span><span class="s">value2</span><span class="sh">"</span><span class="p">:</span> <span class="n">issue</span><span class="p">[</span><span class="sh">"</span><span class="s">html_url</span><span class="sh">"</span><span class="p">]},</span>
        <span class="n">timeout</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
    <span class="p">)</span>
    <span class="n">response</span><span class="p">.</span><span class="nf">raise_for_status</span><span class="p">()</span>
    <span class="n">processed</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">issue_id</span><span class="p">)</span>
    <span class="k">return</span> <span class="sh">"</span><span class="s">iletildi</span><span class="sh">"</span>
</code></pre></div></div>

<p>Fonksiyon etiketi denetler, başlık ve bağlantıyı gönderir, başarılı HTTP yanıtından sonra kaydı işaretler. Bu yanıt, telefon bildiriminin kesin teslim edildiğini kanıtlamaz. GitHub webhook imzasının doğrulanması ve ilgili olay türlerinin seçilmesi, bu fonksiyonu çağıran sunucunun sorumluluğudur.</p>

<h2 id="sağlam-zincirin-görünmeyen-kuralları">Sağlam Zincirin Görünmeyen Kuralları</h2>

<p>Örnekteki bellek kümesi yalnızca prototip içindir: uygulama yeniden başladığında temizlenir ve eşzamanlı çağrılarda yarış koşullarını engellemez. Üretimde kalıcı kayıtlar ve atomik kontroller kullanın. Aynı girdinin tekrar işlenmesinin istenmeyen ek sonuç üretmemesine <strong>idempotent davranış</strong> denir.</p>

<table>
  <thead>
    <tr>
      <th>Risk</th>
      <th>Sonuç</th>
      <th>Önlem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tekrarlanan olay</td>
      <td>Çift bildirim</td>
      <td>Kalıcı tekilleştirme</td>
    </tr>
    <tr>
      <td>Geçici bağlantı hatası</td>
      <td>Eksik işlem</td>
      <td>Gecikmeli yeniden deneme</td>
    </tr>
    <tr>
      <td>Servis kotası</td>
      <td>Reddedilen istek</td>
      <td>Kuyruk ve hız sınırı</td>
    </tr>
    <tr>
      <td>Döngüsel tetikleme</td>
      <td>Bitmeyen zincir</td>
      <td>Kaynak veya derinlik kontrolü</td>
    </tr>
  </tbody>
</table>

<p>Son olarak her adımı kaydedin, ancak anahtarları ve hassas verileri loglardan çıkarın. Başarısızlıkları görünür kılın ve yeniden denemeleri sınırlayın. İyi otomasyon, her şeyi körlemesine yapan değil; ne zaman duracağını da bilen dijital yardımcıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ifttt" /><category term="otomasyon" /><category term="webhook" /><category term="api" /><category term="olay-tabanlı-mimari" /><summary type="html"><![CDATA[Telefonunuz yağmur başlayınca sizi uyarsa, önemli bir GitHub kaydı açıldığında cebinize bildirim düşse nasıl olurdu? IFTTT, farklı servisleri birbirine bağlayarak bu küçük dijital yardımcıları kurmanızı sağlar. Ancak iyi otomasyon, yalnızca uygulamaları eşleştirmek değildir: olayların, koşulların ve yan etkilerin nasıl çalıştığını anlamaktır. Haydi domino taşlarını devirmeden önce doğru sıraya dizelim!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/ifttt-ve-otomasyon-71.png" /><media:content medium="image" url="https://program.sonsuz.us/img/ifttt-ve-otomasyon-71.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Lag Nasıl Gizlenir? Çevrimiçi Oyunlarda Gecikme Telafisinin Perde Arkası</title><link href="https://program.sonsuz.us/posts/lag-nasil-gizlenir-cevrimici-oyunlarda-gecikme-telafisinin-perde-arkasi/" rel="alternate" type="text/html" title="Lag Nasıl Gizlenir? Çevrimiçi Oyunlarda Gecikme Telafisinin Perde Arkası" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/lag-nasil-gizlenir-cevrimici-oyunlarda-gecikme-telafisinin-perde-arkasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/lag-nasil-gizlenir-cevrimici-oyunlarda-gecikme-telafisinin-perde-arkasi/"><![CDATA[<p>Çevrimiçi bir oyunda siz tetiğe bastığınızda rakibiniz çoktan duvarın arkasına geçmiş olabilir. Yine de oyun, iki tarafın ekranında mümkün olduğunca tutarlı görünmelidir. İşin sırrı interneti hızlandırmak değil; geçmişi saklamak, geleceği tahmin etmek ve küçük hataları ustaca düzeltmektir. Gelin bu dijital illüzyonun nasıl çalıştığını inceleyelim.</p>

<p>``</p>

<h2 id="önce-fizik-ağ-neden-bekletir">Önce fizik: Ağ neden bekletir?</h2>

<p>Bir komutun istemciden sunucuya ulaşması zaman alır. Gidiş-dönüş süresi <strong>RTT</strong>, paketin gidip yanıtın geri gelmesini kapsar. Yolların yaklaşık simetrik olduğu varsayılırsa tek yönlü gecikme $d \approx RTT / 2$ olarak tahmin edilebilir; gerçek bağlantılarda bu eşitlik garanti değildir.</p>

<p>Üstelik sorun yalnızca gecikme değildir. <strong>Jitter</strong>, paketlerin değişken aralıklarla gelmesi; paket kaybı ise bazı güncellemelerin hiç ulaşmamasıdır. Sunucunun <strong>tick rate</strong> değeri de simülasyonun saniyede kaç kez ilerlediğini belirler. Örneğin 60 Hz sunucuda bir adım yaklaşık 16,7 milisaniyedir.</p>

<p>Çoğu rekabetçi oyunda sunucu otoriterdir: İstemci hareket talep eder, nihai sonucu sunucu belirler. Böylece oyuncunun bilgisayarı hem gösteri sahnesi olur hem de güvenilmeyen bir veri kaynağı olarak değerlendirilir.</p>

<h2 id="dört-teknik-dört-farklı-görev">Dört teknik, dört farklı görev</h2>

<p>Bu yöntemler birbirinin alternatifi değildir. Genellikle aynı oyunda birlikte çalışırlar; çünkü kendi karakterinizi kontrol etmekle uzaktaki oyuncuları izlemek farklı problemler doğurur.</p>

<table>
  <thead>
    <tr>
      <th>Teknik</th>
      <th>Kullanıldığı yer</th>
      <th>Kazancı</th>
      <th>Bedeli</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İstemci tahmini</td>
      <td>Yerel karakter</td>
      <td>Anında tepki</td>
      <td>Yanlış tahmin</td>
    </tr>
    <tr>
      <td>Sunucuyla uzlaştırma</td>
      <td>Yerel karakter</td>
      <td>Doğru duruma dönüş</td>
      <td>Görünür düzeltme</td>
    </tr>
    <tr>
      <td>Enterpolasyon</td>
      <td>Uzak karakterler</td>
      <td>Akıcı hareket</td>
      <td>Ek görüntü gecikmesi</td>
    </tr>
    <tr>
      <td>Geçmişe sarma</td>
      <td>Vuruş kontrolü</td>
      <td>Gecikmeye rağmen isabet değerlendirmesi</td>
      <td>Adalet tartışmaları</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇stemci-tahmini-ve-sunucuyla-uzlaştırma">İstemci tahmini ve sunucuyla uzlaştırma</h2>

<p>Karakterinizin yürümesi için sunucuyu beklerseniz kontrol ağırlaşır. Bunun yerine istemci girdiyi hemen uygular, aynı girdiyi sunucuya gönderir. Basitleştirilmiş hareket modeli $x_{yeni} = x_{eski} + v a dt$ şeklindedir; burada $a$ yön, $v$ hızdır.</p>

<p>Aşağıdaki JavaScript örneği, tek boyutlu hareketi tahmin eder ve sunucu yanıtıyla yeniden hesaplar:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">speed</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">sequence</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">pending</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">let</span> <span class="nx">predicted</span> <span class="o">=</span> <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">0</span> <span class="p">};</span>

<span class="kd">function</span> <span class="nf">step</span><span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="nx">input</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="nx">state</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">speed</span> <span class="o">*</span> <span class="nx">input</span><span class="p">.</span><span class="nx">axis</span> <span class="o">*</span> <span class="nx">input</span><span class="p">.</span><span class="nx">dt</span> <span class="p">};</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">move</span><span class="p">(</span><span class="nx">axis</span><span class="p">,</span> <span class="nx">dt</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">input</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">seq</span><span class="p">:</span> <span class="o">++</span><span class="nx">sequence</span><span class="p">,</span>
    <span class="na">axis</span><span class="p">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">max</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">min</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">axis</span><span class="p">)),</span>
    <span class="nx">dt</span>
  <span class="p">};</span>
  <span class="nx">pending</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span>
  <span class="nx">predicted</span> <span class="o">=</span> <span class="nf">step</span><span class="p">(</span><span class="nx">predicted</span><span class="p">,</span> <span class="nx">input</span><span class="p">);</span>
  <span class="nf">send</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">onSnapshot</span><span class="p">({</span> <span class="nx">state</span><span class="p">,</span> <span class="nx">lastProcessedSeq</span> <span class="p">})</span> <span class="p">{</span>
  <span class="nx">pending</span> <span class="o">=</span> <span class="nx">pending</span><span class="p">.</span><span class="nf">filter</span><span class="p">(</span><span class="nx">i</span> <span class="o">=&gt;</span> <span class="nx">i</span><span class="p">.</span><span class="nx">seq</span> <span class="o">&gt;</span> <span class="nx">lastProcessedSeq</span><span class="p">);</span>
  <span class="nx">predicted</span> <span class="o">=</span> <span class="nx">pending</span><span class="p">.</span><span class="nf">reduce</span><span class="p">(</span><span class="nx">step</span><span class="p">,</span> <span class="p">{</span> <span class="p">...</span><span class="nx">state</span> <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">send</code>, ağ katmanının sağladığı gönderim fonksiyonudur. Sunucu, işlediği son girdi numarasını bildirir. İstemci onaylanan girdileri siler, sunucu durumundan başlayıp kalanları tekrar uygular. Böylece sunucunun henüz görmediği hareketler kaybolmaz. Örnekteki <code class="language-plaintext highlighter-rouge">dt</code> güvenilir sayılmamalıdır; sunucu süreyi, sırayı ve hareket sınırlarını doğrulamalıdır. Gerçek uygulamada sabit simülasyon adımları tercih edilir.</p>

<p>Görsel düzeltme yumuşatılabilir; fakat çarpışma hesabı sırf görüntü güzel olsun diye yanlış konumda bırakılmamalıdır.</p>

<h2 id="enterpolasyon-bilerek-biraz-geriden-bakmak">Enterpolasyon: Bilerek biraz geriden bakmak</h2>

<p>Uzak oyuncuların gelecekteki girdilerini bilemezsiniz. Bunun yerine görüntüyü kısa bir tampon süresi kadar geriden oynatırsınız. İki sunucu örneği arasındaki konum $p(t) = (1-\alpha)p_0 + \alpha p_1$ ile hesaplanır; $\alpha$, iki örnek arasındaki ilerleme oranıdır.</p>

<p>Bu yaklaşım, düzensiz paket gelişlerini akıcı harekete dönüştürür. Tampon küçülürse tepki hızlanır ama takılmalar artabilir. Paket gelmediğinde kullanılan <strong>ekstrapolasyon</strong> ise son hızdan geleceği tahmin eder; ani dönüşlerde kolayca yanılır. Bu yüzden genellikle kısa süreyle sınırlandırılır.</p>

<h2 id="geçmişe-sarma-mermiyi-hangi-zamana-göre-değerlendirmeli">Geçmişe sarma: Mermiyi hangi zamana göre değerlendirmeli?</h2>

<p>Sunucu oyuncu konumlarının kısa bir geçmişini saklar. Ateş komutu geldiğinde, atıcının ekranda gördüğü zamana karşılık gelen konumlarla vuruş testi yapabilir. Basitleştirilmiş hesap $t_{test} = t_{gelis} - d_{yukleme} - D$ şeklindedir; $D$ görüntü tamponudur.</p>

<p>Örneğin yaklaşık 60 milisaniye yükleme gecikmesi ve 80 milisaniye tampon varsa test, komutun gelişinden yaklaşık 140 milisaniye öncesine bakabilir. Gerçek sistemler zaman damgalarını ve saat farklarını ayrıca doğrular.</p>

<p>Bedeli şudur: Hedef, kendi ekranında siper arkasına geçtiği hâlde vurulabilir. Bu nedenle geri sarma penceresi sınırlanır; istemcinin istediği herhangi bir geçmiş zaman kabul edilmez. Dinamik engellerin geçmişi de değerlendirmeyi zorlaştırabilir.</p>

<h2 id="i̇yi-hissettiren-oyun-ölçülerek-yapılır">İyi hissettiren oyun ölçülerek yapılır</h2>

<p>Tek bir sihirli tampon değeri yoktur. RTT dağılımını, jitter seviyesini, düzeltme miktarını ve reddedilen vuruşları ölçün. Yapay gecikme ve paket kaybıyla test yapın; yalnızca yerel ağda akıcı görünen oyun yanıltıcıdır. Rekabetçi nişancı oyunuyla sıra tabanlı oyunun ihtiyaçları aynı değildir. Amaç gecikmeyi yok etmek değil, tepkisellik, doğruluk ve adalet arasında bilinçli bir denge kurmaktır.</p>

<p><img src="/img/lag-nasil-gizlenir-58.svg" alt="lag-nasil-gizlenir-58" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="oyun geliştirme" /><category term="ağ programlama" /><category term="gecikme telafisi" /><category term="istemci tahmini" /><category term="sunucu mimarisi" /><summary type="html"><![CDATA[Çevrimiçi bir oyunda siz tetiğe bastığınızda rakibiniz çoktan duvarın arkasına geçmiş olabilir. Yine de oyun, iki tarafın ekranında mümkün olduğunca tutarlı görünmelidir. İşin sırrı interneti hızlandırmak değil; geçmişi saklamak, geleceği tahmin etmek ve küçük hataları ustaca düzeltmektir. Gelin bu dijital illüzyonun nasıl çalıştığını inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/lag-nasil-gizlenir-58.png" /><media:content medium="image" url="https://program.sonsuz.us/img/lag-nasil-gizlenir-58.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">MR’ın Bilgisayar Bilimi: Manyetik Sinyalden Piksele Uzanan Yol</title><link href="https://program.sonsuz.us/posts/mrin-bilgisayar-bilimi-manyetik-sinyalden-piksele-uzanan-yol/" rel="alternate" type="text/html" title="MR’ın Bilgisayar Bilimi: Manyetik Sinyalden Piksele Uzanan Yol" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/mrin-bilgisayar-bilimi-manyetik-sinyalden-piksele-uzanan-yol</id><content type="html" xml:base="https://program.sonsuz.us/posts/mrin-bilgisayar-bilimi-manyetik-sinyalden-piksele-uzanan-yol/"><![CDATA[<p>MR cihazı, vücudun içine bakan dev bir fotoğraf makinesi değildir. Daha çok, atom çekirdeklerinden gelen zayıf sinyalleri dinleyen ve bunlardan bir görüntü hesaplayan bilimsel bir dedektiftir. Peki dedektifin büyüteci nedir? Manyetik alanlar, sayısal sinyal işleme ve Fourier dönüşümü! Gelin, manyetik fısıltıların nasıl piksellere dönüştüğünü yazılımcı gözlüğüyle inceleyelim.
``</p>

<h2 id="1-önce-fizik-dinlediğimiz-şey-ne">1. Önce fizik: Dinlediğimiz şey ne?</h2>

<p>Vücuttaki su ve yağ molekülleri bol miktarda hidrojen içerir. Hidrojen çekirdeklerinin manyetik özellikleri, güçlü bir ana manyetik alan içinde ölçülebilir bir toplam mıknatıslanma oluşturur. Çekirdeklerin karakteristik dönme hareketinin frekansı, Larmor bağıntısıyla açıklanır:</p>

\[\omega_0 = \gamma B_0\]

<p>Burada $B_0$ ana manyetik alan, $\gamma$ ise jiromanyetik orandır. Protonlar için $\gamma/(2\pi)$ yaklaşık $42{,}58$ MHz/T olduğundan, 3 teslalık bir cihazda rezonans frekansı yaklaşık 128 MHz olur.</p>

<p>Radyo frekansı darbesi mıknatıslanmayı dengeden uzaklaştırır. Darbe sonrasında değişen mıknatıslanma, alıcı bobinlerde elektriksel sinyal indükler. Dokuların $T_1$ ve $T_2$ gevşeme özellikleri farklıdır; çekim parametreleriyle birlikte görüntü kontrastını belirler. Yani parlaklık, yalnızca “burada ne kadar hidrojen var?” sorusunun cevabı değildir.</p>

<h2 id="2-konum-bilgisi-sinyale-nasıl-eklenir">2. Konum bilgisi sinyale nasıl eklenir?</h2>

<p>Tek bir toplu sinyal, hangi dokunun nerede olduğunu söylemez. Bu, kalabalık bir odadaki bütün konuşmaları tek mikrofonla kaydetmeye benzer. MR’ın çözümü, manyetik alanı konuma göre değiştiren <strong>gradyan alanlarıdır</strong>.</p>

<p>Kesit seçimi sırasında gradyanla birlikte uygulanan uygun frekans aralığındaki bir RF darbesi, hedeflenen kesiti uyarır. Diğer gradyanlar, sinyale konuma bağlı faz ve frekans farklılıkları ekler.</p>

<p>Her eksendeki k-uzayı koordinatı, ilgili gradyanın zaman içindeki birikimiyle ilişkilidir:</p>

\[k(t)=\frac{\gamma}{2\pi}\int_0^t G(\tau)\,d\tau\]

<p>Burada önemli programlama fikri şudur: Cihaz doğrudan piksel adreslerini okumaz. Ölçüm zamanlamasını ve gradyanları kontrol ederek görüntüyü hesaplamaya yetecek veriyi toplar. Böylece donanımın zaman çizelgesi, yazılımın veri koordinatlarına dönüşür.</p>

<h2 id="3-k-uzayı-görüntünün-frekans-günlüğü">3. K-uzayı: Görüntünün frekans günlüğü</h2>

<p>Toplanan veriler <strong>k-uzayı</strong> denen uzaysal frekans alanına yerleştirilir. Basitleştirilmiş iki boyutlu model şöyledir:</p>

\[s(k_x,k_y)=\iint m(x,y)e^{-i2\pi(k_xx+k_yy)}\,dx\,dy\]

<p>$m(x,y)$, proton yoğunluğu, gevşeme ve faz etkilerini içeren etkin görüntüdür. Bu sade modelde bobin duyarlılığını sabit kabul ediyoruz.</p>

<table>
  <thead>
    <tr>
      <th>Alan</th>
      <th>Ne temsil eder?</th>
      <th>Sezgisel karşılığı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Görüntü uzayı</td>
      <td>Konuma bağlı doku sinyali</td>
      <td>Ortaya çıkan resim</td>
    </tr>
    <tr>
      <td>K-uzayı merkezi</td>
      <td>Düşük uzaysal frekanslar</td>
      <td>Geniş, yumuşak yapılar</td>
    </tr>
    <tr>
      <td>K-uzayı dış bölgeleri</td>
      <td>Yüksek uzaysal frekanslar</td>
      <td>İnce ayrıntılar ve kenarlar</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/mrin-bilgisayar-bilimi-45.svg" alt="mrin-bilgisayar-bilimi-45" /></p>

<p>Ancak tek bir k-uzayı noktası, tek bir görüntü pikseline karşılık gelmez. Her ölçüm, görüntünün tamamına yayılan bir örüntü hakkında bilgi taşır. Asıl sürpriz burada!</p>

<h2 id="4-bilgisayarın-iş-akışı">4. Bilgisayarın iş akışı</h2>

<p>Alıcı sistem sinyali yükseltir, sayısallaştırır ve demodülasyonla karmaşık taban bant verisine dönüştürür. Karmaşık sayılar hem genliği hem fazı saklar; fazı erkenden atmak, konum bilgisini kaybetmek demektir.</p>

<p>Kartezyen örneklemede rekonstrüksiyonun temel adımı ters ayrık Fourier dönüşümüdür. FFT algoritmaları bu hesabı yaklaşık $O(N\log N)$ maliyetle gerçekleştirir. Ardından bobin görüntüleri birleştirilir, gerekli düzeltmeler uygulanır ve sonuç görüntülenir. Kartezyen olmayan örneklemelerdeyse doğrudan standart FFT yerine yeniden örnekleme veya farklı dönüşüm yöntemleri gerekir.</p>

<h2 id="5-python-ile-minik-bir-sanal-deney">5. Python ile minik bir sanal deney</h2>

<p>Aşağıdaki kod, yapay bir nesneden k-uzayı üretir ve ters dönüşümle nesneyi geri getirir. Gerçek MR fiziğini bütünüyle simüle etmez; Fourier ilişkisinin hesaplama tarafını gösterir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>

<span class="n">n</span> <span class="o">=</span> <span class="mi">128</span>
<span class="n">axis</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">linspace</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">meshgrid</span><span class="p">(</span><span class="n">axis</span><span class="p">,</span> <span class="n">axis</span><span class="p">)</span>
<span class="n">phantom</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="o">-</span><span class="mi">6</span> <span class="o">*</span> <span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">y</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span>
<span class="n">phantom</span> <span class="o">+=</span> <span class="mf">0.6</span> <span class="o">*</span> <span class="p">((</span><span class="n">x</span> <span class="o">-</span> <span class="mf">0.3</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">y</span><span class="o">**</span><span class="mi">2</span> <span class="o">&lt;</span> <span class="mf">0.08</span><span class="p">)</span>

<span class="n">kspace</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">fft</span><span class="p">.</span><span class="nf">fftshift</span><span class="p">(</span>
    <span class="n">np</span><span class="p">.</span><span class="n">fft</span><span class="p">.</span><span class="nf">fft2</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">fft</span><span class="p">.</span><span class="nf">ifftshift</span><span class="p">(</span><span class="n">phantom</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">fft</span><span class="p">.</span><span class="nf">fftshift</span><span class="p">(</span>
    <span class="n">np</span><span class="p">.</span><span class="n">fft</span><span class="p">.</span><span class="nf">ifft2</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">fft</span><span class="p">.</span><span class="nf">ifftshift</span><span class="p">(</span><span class="n">kspace</span><span class="p">))</span>
<span class="p">)</span>

<span class="n">fig</span><span class="p">,</span> <span class="n">axes</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplots</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">imshow</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log1p</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">abs</span><span class="p">(</span><span class="n">kspace</span><span class="p">)),</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">"</span><span class="s">gray</span><span class="sh">"</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nf">imshow</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">abs</span><span class="p">(</span><span class="n">image</span><span class="p">),</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">"</span><span class="s">gray</span><span class="sh">"</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">fftshift</code>, sıfır frekansı merkeze taşır. Logaritmik gösterim, k-uzayındaki geniş genlik aralığını görünür kılar. Son görüntüde <code class="language-plaintext highlighter-rouge">abs</code>, karmaşık sonucun büyüklüğünü gösterir; bazı MR uygulamalarında faz görüntüsü de ayrıca değerlidir.</p>

<h2 id="6-gerçek-dünya-neden-daha-zor">6. Gerçek dünya neden daha zor?</h2>

<p>Hasta hareketi, gürültü ve alan düzensizlikleri ideal modeli bozar. Eksik veri toplamak çekimi hızlandırabilir, fakat bedelsiz değildir:</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Kazanç</th>
      <th>Bedel veya gereksinim</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tam örnekleme</td>
      <td>Daha doğrudan rekonstrüksiyon</td>
      <td>Daha uzun çekim</td>
    </tr>
    <tr>
      <td>Paralel görüntüleme</td>
      <td>Daha kısa çekim</td>
      <td>Bobin duyarlılıkları, gürültü artışı</td>
    </tr>
    <tr>
      <td>Sıkıştırılmış algılama</td>
      <td>Daha az ölçüm</td>
      <td>Uygun örnekleme ve düzenlileştirme</td>
    </tr>
  </tbody>
</table>

<p>Modern algoritmalar bu dengeyi yönetir. MR’ın bilgisayar bilimi tam da burada parlar: Görüntü, yalnızca ölçülen bir şey değil; fiziksel model, örnekleme stratejisi ve sayısal hesaplamanın birlikte ürettiği bir sonuçtur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="mr" /><category term="manyetik rezonans" /><category term="sinyal işleme" /><category term="fourier dönüşümü" /><category term="python" /><category term="görüntü rekonstrüksiyonu" /><summary type="html"><![CDATA[MR cihazı, vücudun içine bakan dev bir fotoğraf makinesi değildir. Daha çok, atom çekirdeklerinden gelen zayıf sinyalleri dinleyen ve bunlardan bir görüntü hesaplayan bilimsel bir dedektiftir. Peki dedektifin büyüteci nedir? Manyetik alanlar, sayısal sinyal işleme ve Fourier dönüşümü! Gelin, manyetik fısıltıların nasıl piksellere dönüştüğünü yazılımcı gözlüğüyle inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/mrin-bilgisayar-bilimi-45.png" /><media:content medium="image" url="https://program.sonsuz.us/img/mrin-bilgisayar-bilimi-45.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Piksel Dedektifleri: Uydu Görüntülerinden Orman, Şehir ve Su Segmentasyonu</title><link href="https://program.sonsuz.us/posts/piksel-dedektifleri-uydu-goruntulerinden-orman-sehir-ve-su-segmentasyonu/" rel="alternate" type="text/html" title="Piksel Dedektifleri: Uydu Görüntülerinden Orman, Şehir ve Su Segmentasyonu" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/piksel-dedektifleri-uydu-goruntulerinden-orman-sehir-ve-su-segmentasyonu</id><content type="html" xml:base="https://program.sonsuz.us/posts/piksel-dedektifleri-uydu-goruntulerinden-orman-sehir-ve-su-segmentasyonu/"><![CDATA[<p>Bir uydu görüntüsüne bakarken göllerin mavisini, ormanların yeşilini ve şehirlerin karmaşasını kolayca ayırt edebiliriz. Bilgisayarın ise biraz dedektiflik eğitimi alması gerekir. Bu projede, çok bantlı görüntülerden özellikler çıkarıp her piksele orman, şehir veya su etiketi atayacağız. Üstelik başlangıç için dev bir derin öğrenme modeli gerekmiyor: Random Forest sağlam bir ilk durak!</p>

<p>``</p>

<h2 id="segmentasyonun-arkasındaki-fikir">Segmentasyonun arkasındaki fikir</h2>

<p><strong>Anlamsal segmentasyon</strong>, görüntüdeki her pikselin bir sınıfa atanmasıdır. Nesne tespitinden farklı olarak yalnızca bir gölün çevresine kutu çizmez; gölün kapladığı pikselleri belirler. Burada problemi denetimli piksel sınıflandırması olarak ele alacağız.</p>

<p>Her piksel, farklı dalga boylarında ölçülen yansıtımlardan oluşan bir özellik vektörüdür. Model, etiketlenmiş örneklerle bu ölçümler arasındaki ilişkileri öğrenir. Random Forest, birçok karar ağacının oylarını birleştirir; böylece tek bir ağacın ezberleme eğilimini azaltır. Ancak komşuluk ilişkilerini doğrudan modellemez, dolayısıyla sonuçta küçük benekler oluşabilir.</p>

<h2 id="önce-veriyi-doğru-hazırlayalım">Önce veriyi doğru hazırlayalım</h2>

<p>Örneğimiz, Sentinel-2 yüzey yansıtımı verilerinden hazırlanmış dört bantlı bir GeoTIFF kullanıyor. Bant sırası <strong>B2, B3, B4, B8</strong>, yani mavi, yeşil, kırmızı ve yakın kızılötesi olmalı. Bunlar doğal olarak 10 metre çözünürlüklüdür.</p>

<p>Bulutları ve gölgeleri kalite maskesiyle önceden dışlayın; dışlanan pikselleri NoData olarak kaydedin. Yansıtım ölçeğini ve varsa ofsetleri ürün metadatasından uygulayın. Aşağıdaki kod, bu işlemler tamamlanmış gerçek yansıtım değerlerini bekliyor; ham tamsayı ürünler için doğrudan kullanılmamalı.</p>

<p>Eğitim etiketleri aynı koordinat sisteminde, piksel boyutunda ve ızgarada bulunmalı. <code class="language-plaintext highlighter-rouge">etiket.tif</code> içinde <code class="language-plaintext highlighter-rouge">1=orman</code>, <code class="language-plaintext highlighter-rouge">2=şehir</code>, <code class="language-plaintext highlighter-rouge">3=su</code>, <code class="language-plaintext highlighter-rouge">0=etiketsiz</code> kullanacağız. Referansları arazi gözlemleri veya güvenilir haritalardan oluşturabilirsiniz.</p>

<table>
  <thead>
    <tr>
      <th>Sınıf</th>
      <th>Tipik spektral ipucu</th>
      <th>Karışabilecek yüzey</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Orman</td>
      <td>Yakın kızılötesinde güçlü yansıtım</td>
      <td>Tarım alanları</td>
    </tr>
    <tr>
      <td>Şehir</td>
      <td>Değişken bant tepkileri</td>
      <td>Çıplak toprak</td>
    </tr>
    <tr>
      <td>Su</td>
      <td>Yakın kızılötesinde düşük yansıtım</td>
      <td>Koyu gölgeler</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/piksel-dedektifleri-uydu-59.svg" alt="piksel-dedektifleri-uydu-59" /></p>

<h2 id="i̇ki-küçük-indeks-büyük-yardım">İki küçük indeks, büyük yardım</h2>

<p>Bitki örtüsünü belirginleştiren NDVI ve suyu vurgulayan NDWI şöyle hesaplanır:</p>

\[NDVI = \frac{NIR - Red}{NIR + Red}\]

\[NDWI = \frac{Green - NIR}{Green + NIR}\]

<p>Sağlıklı bitkiler kırmızı ışığı soğururken yakın kızılötesini güçlü yansıtır. Su ise yakın kızılötesinde genellikle koyudur. İndeksler bu karşıtlıkları sıkıştırılmış özelliklere dönüştürür. Yine de tek bir eşik evrensel çözüm değildir; mevsim, bulanıklık ve yüzey türleri değerleri değiştirir.</p>

<h2 id="python-ile-sınıflandırma">Python ile sınıflandırma</h2>

<p><code class="language-plaintext highlighter-rouge">numpy</code>, <code class="language-plaintext highlighter-rouge">rasterio</code> ve <code class="language-plaintext highlighter-rouge">scikit-learn</code> paketlerini kurduktan sonra aşağıdaki akışı kullanabilirsiniz. Etiketleriniz birden fazla uzamsal bloğa yayılmalı; eğitim bölümünde üç sınıf da temsil edilmelidir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">rasterio</span>
<span class="kn">from</span> <span class="n">sklearn.ensemble</span> <span class="kn">import</span> <span class="n">RandomForestClassifier</span>
<span class="kn">from</span> <span class="n">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">GroupShuffleSplit</span>
<span class="kn">from</span> <span class="n">sklearn.metrics</span> <span class="kn">import</span> <span class="n">classification_report</span>

<span class="k">with</span> <span class="n">rasterio</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="sh">"</span><span class="s">sentinel.tif</span><span class="sh">"</span><span class="p">)</span> <span class="k">as</span> <span class="n">src</span><span class="p">,</span> <span class="n">rasterio</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="sh">"</span><span class="s">etiket.tif</span><span class="sh">"</span><span class="p">)</span> <span class="k">as</span> <span class="n">ref</span><span class="p">:</span>
    <span class="k">if</span> <span class="n">src</span><span class="p">.</span><span class="n">shape</span> <span class="o">!=</span> <span class="n">ref</span><span class="p">.</span><span class="n">shape</span> <span class="ow">or</span> <span class="n">src</span><span class="p">.</span><span class="n">crs</span> <span class="o">!=</span> <span class="n">ref</span><span class="p">.</span><span class="n">crs</span> <span class="ow">or</span> <span class="n">src</span><span class="p">.</span><span class="n">transform</span> <span class="o">!=</span> <span class="n">ref</span><span class="p">.</span><span class="n">transform</span><span class="p">:</span>
        <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">Görüntü ve etiket ızgaraları eşleşmiyor.</span><span class="sh">"</span><span class="p">)</span>
    <span class="n">bands</span> <span class="o">=</span> <span class="n">src</span><span class="p">.</span><span class="nf">read</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span> <span class="n">masked</span><span class="o">=</span><span class="bp">True</span><span class="p">).</span><span class="nf">astype</span><span class="p">(</span><span class="sh">"</span><span class="s">float32</span><span class="sh">"</span><span class="p">).</span><span class="nf">filled</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">nan</span><span class="p">)</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">ref</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">masked</span><span class="o">=</span><span class="bp">True</span><span class="p">).</span><span class="nf">filled</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">profile</span> <span class="o">=</span> <span class="n">src</span><span class="p">.</span><span class="n">profile</span><span class="p">.</span><span class="nf">copy</span><span class="p">()</span>

<span class="n">blue</span><span class="p">,</span> <span class="n">green</span><span class="p">,</span> <span class="n">red</span><span class="p">,</span> <span class="n">nir</span> <span class="o">=</span> <span class="n">bands</span>
<span class="n">ndvi</span> <span class="o">=</span> <span class="p">(</span><span class="n">nir</span> <span class="o">-</span> <span class="n">red</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">nir</span> <span class="o">+</span> <span class="n">red</span> <span class="o">+</span> <span class="mf">1e-6</span><span class="p">)</span>
<span class="n">ndwi</span> <span class="o">=</span> <span class="p">(</span><span class="n">green</span> <span class="o">-</span> <span class="n">nir</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">green</span> <span class="o">+</span> <span class="n">nir</span> <span class="o">+</span> <span class="mf">1e-6</span><span class="p">)</span>
<span class="n">features</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">stack</span><span class="p">([</span><span class="n">blue</span><span class="p">,</span> <span class="n">green</span><span class="p">,</span> <span class="n">red</span><span class="p">,</span> <span class="n">nir</span><span class="p">,</span> <span class="n">ndvi</span><span class="p">,</span> <span class="n">ndwi</span><span class="p">],</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">valid</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">isfinite</span><span class="p">(</span><span class="n">features</span><span class="p">).</span><span class="nf">all</span><span class="p">(</span><span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">training</span> <span class="o">=</span> <span class="n">valid</span> <span class="o">&amp;</span> <span class="n">np</span><span class="p">.</span><span class="nf">isin</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>

<span class="n">rows</span><span class="p">,</span> <span class="n">cols</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">nonzero</span><span class="p">(</span><span class="n">training</span><span class="p">)</span>
<span class="n">blocks_per_row</span> <span class="o">=</span> <span class="p">(</span><span class="n">labels</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">255</span><span class="p">)</span> <span class="o">//</span> <span class="mi">256</span>
<span class="n">groups</span> <span class="o">=</span> <span class="p">(</span><span class="n">rows</span> <span class="o">//</span> <span class="mi">256</span><span class="p">)</span> <span class="o">*</span> <span class="n">blocks_per_row</span> <span class="o">+</span> <span class="n">cols</span> <span class="o">//</span> <span class="mi">256</span>
<span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">features</span><span class="p">[</span><span class="n">training</span><span class="p">],</span> <span class="n">labels</span><span class="p">[</span><span class="n">training</span><span class="p">]</span>
<span class="n">splitter</span> <span class="o">=</span> <span class="nc">GroupShuffleSplit</span><span class="p">(</span><span class="n">n_splits</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.25</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span>
<span class="n">train_idx</span><span class="p">,</span> <span class="n">test_idx</span> <span class="o">=</span> <span class="nf">next</span><span class="p">(</span><span class="n">splitter</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">groups</span><span class="p">))</span>

<span class="k">if</span> <span class="nf">set</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">unique</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="n">train_idx</span><span class="p">]))</span> <span class="o">!=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">}:</span>
    <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">Eğitim bölümünde bütün sınıflar bulunmalı.</span><span class="sh">"</span><span class="p">)</span>

<span class="n">model</span> <span class="o">=</span> <span class="nc">RandomForestClassifier</span><span class="p">(</span>
    <span class="n">n_estimators</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">class_weight</span><span class="o">=</span><span class="sh">"</span><span class="s">balanced</span><span class="sh">"</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span>
<span class="p">)</span>
<span class="n">model</span><span class="p">.</span><span class="nf">fit</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">train_idx</span><span class="p">],</span> <span class="n">y</span><span class="p">[</span><span class="n">train_idx</span><span class="p">])</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">classification_report</span><span class="p">(</span>
    <span class="n">y</span><span class="p">[</span><span class="n">test_idx</span><span class="p">],</span> <span class="n">model</span><span class="p">.</span><span class="nf">predict</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">test_idx</span><span class="p">]),</span>
    <span class="n">labels</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="n">target_names</span><span class="o">=</span><span class="p">[</span><span class="sh">"</span><span class="s">orman</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">şehir</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">su</span><span class="sh">"</span><span class="p">],</span> <span class="n">zero_division</span><span class="o">=</span><span class="mi">0</span>
<span class="p">))</span>

<span class="n">segmentation</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">(</span><span class="n">labels</span><span class="p">.</span><span class="n">shape</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="sh">"</span><span class="s">uint8</span><span class="sh">"</span><span class="p">)</span>
<span class="n">segmentation</span><span class="p">[</span><span class="n">valid</span><span class="p">]</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="nf">predict</span><span class="p">(</span><span class="n">features</span><span class="p">[</span><span class="n">valid</span><span class="p">])</span>
<span class="n">profile</span><span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="n">count</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="sh">"</span><span class="s">uint8</span><span class="sh">"</span><span class="p">,</span> <span class="n">nodata</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">compress</span><span class="o">=</span><span class="sh">"</span><span class="s">lzw</span><span class="sh">"</span><span class="p">)</span>
<span class="k">with</span> <span class="n">rasterio</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="sh">"</span><span class="s">segmentasyon.tif</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">w</span><span class="sh">"</span><span class="p">,</span> <span class="o">**</span><span class="n">profile</span><span class="p">)</span> <span class="k">as</span> <span class="n">dst</span><span class="p">:</span>
    <span class="n">dst</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">segmentation</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<p>Kod, dört bant ile iki indeksi birleştirir, modeli eğitir ve coğrafi referansı korunmuş bir sınıf haritası üretir. Küçük görüntüler için uygundur; büyük sahnelerde bellek tüketimini azaltmak amacıyla pencere bazlı okuma ve tahmin yapılmalıdır.</p>

<h2 id="güzel-harita-güvenilir-sonuç-mu">Güzel harita, güvenilir sonuç mu?</h2>

<p>Rastgele piksel ayırmak, birbirine benzeyen komşuları hem eğitim hem teste taşıyabilir. Bloklarla ayırma daha gerçekçidir; blok sınırlarında tampon bırakmak değerlendirmeyi güçlendirir. Sınıf bazlı F1 değerlerini inceleyin: yüksek toplam doğruluk, az bulunan su alanlarının başarısızlığını gizleyebilir.</p>

<p>Son olarak, bu model her geçerli pikseli üç sınıftan birine zorlar. Tarla, kar veya çıplak toprak varsa ek sınıflar tanımlayın. Haritayı QGIS üzerinde referanslarla karşılaştırın; piksel dedektifinizin gerçekten doğru iz sürdüğünü kontrol edin!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="uzaktan algılama" /><category term="görüntü segmentasyonu" /><category term="python" /><category term="uydu görüntüleri" /><category term="makine öğrenmesi" /><category term="rasterio" /><summary type="html"><![CDATA[Bir uydu görüntüsüne bakarken göllerin mavisini, ormanların yeşilini ve şehirlerin karmaşasını kolayca ayırt edebiliriz. Bilgisayarın ise biraz dedektiflik eğitimi alması gerekir. Bu projede, çok bantlı görüntülerden özellikler çıkarıp her piksele orman, şehir veya su etiketi atayacağız. Üstelik başlangıç için dev bir derin öğrenme modeli gerekmiyor: Random Forest sağlam bir ilk durak!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/piksel-dedektifleri-uydu-59.png" /><media:content medium="image" url="https://program.sonsuz.us/img/piksel-dedektifleri-uydu-59.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Python Jeneratörleri Neden İkinci Döngüde Sessizce Boş Kalır?</title><link href="https://program.sonsuz.us/posts/python-jeneratorleri-neden-ikinci-dongude-sessizce-bos-kalir/" rel="alternate" type="text/html" title="Python Jeneratörleri Neden İkinci Döngüde Sessizce Boş Kalır?" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/python-jeneratorleri-neden-ikinci-dongude-sessizce-bos-kalir</id><content type="html" xml:base="https://program.sonsuz.us/posts/python-jeneratorleri-neden-ikinci-dongude-sessizce-bos-kalir/"><![CDATA[<p><img src="/img/python-jeneratorleri-neden-61.svg" alt="python-jeneratorleri-neden-61" /></p>

<p>Python’da bir jeneratörü ilk döngüde gezersiniz, her şey harika çalışır. Aynı nesneyi ikinci döngüye soktuğunuzda ise ne sonuç vardır ne hata mesajı. Program sanki kahve molasına çıkmıştır! Aslında burada bir arıza yoktur: Jeneratörler, tüketildikçe ilerleyen ve kendiliğinden başa dönmeyen iterator nesneleridir. Gelin bu sessizliğin arkasındaki mekanizmayı inceleyelim.</p>

<p>``</p>

<h2 id="iterable-ile-iterator-aynı-şey-değildir">Iterable ile Iterator Aynı Şey Değildir</h2>

<p>Bir <strong>iterable</strong>, üzerinden iterator elde edilebilen nesnedir. Liste bunun tanıdık örneğidir: <code class="language-plaintext highlighter-rouge">iter(liste)</code> çağrısı, baştan başlayabilen yeni bir iterator oluşturur. Listenin kendisi, dolaşım konumunu tutmaz; bu görev iterator’a aittir.</p>

<p>Bir <strong>iterator</strong> ise sıradaki öğenin hangisi olduğunu hatırlar. <code class="language-plaintext highlighter-rouge">next()</code> çağrıldığında ilerler; öğeler bittiğinde <code class="language-plaintext highlighter-rouge">StopIteration</code> yükseltir. Iterator üzerinde <code class="language-plaintext highlighter-rouge">iter()</code> çağrısı, aynı nesneyi döndürür. Dolayısıyla yeni bir döngü, yeni bir başlangıç konumu yaratmaz.</p>

<p>Jeneratör de bir iterator’dır. <code class="language-plaintext highlighter-rouge">yield</code>, fonksiyonun yürütülmesini askıya alır; sonraki <code class="language-plaintext highlighter-rouge">next()</code> çağrısı yürütmeyi kaldığı yerden sürdürür. Bunu kitaplıktan çok yürüyen bant gibi düşünün: Banttan aldığınız kutu, sonraki turda yeniden önünüze gelmez.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Liste</th>
      <th>Jeneratör</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Değerlerin hazırlanması</td>
      <td>Genellikle önceden</td>
      <td>İstendikçe</td>
    </tr>
    <tr>
      <td>Döngü başlangıcı</td>
      <td>Yeni iterator oluşturulur</td>
      <td>Aynı iterator kullanılır</td>
    </tr>
    <tr>
      <td>Baştan tekrar dolaşma</td>
      <td>Mümkün</td>
      <td>Aynı nesnede mümkün değil</td>
    </tr>
    <tr>
      <td>İlerleme konumu</td>
      <td>Ayrı iterator’da</td>
      <td>Jeneratörün içinde</td>
    </tr>
  </tbody>
</table>

<h2 id="sessiz-boşluğun-küçük-bir-gösterisi">Sessiz Boşluğun Küçük Bir Gösterisi</h2>

<p>Aşağıdaki fonksiyon, kareleri talep geldikçe üretir. Fonksiyonu çağırmak bütün kareleri hesaplamaz; çalıştırılmayı bekleyen bir jeneratör oluşturur:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kareler</span><span class="p">(</span><span class="n">sinir</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">sayi</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">sinir</span><span class="p">):</span>
        <span class="k">yield</span> <span class="n">sayi</span> <span class="o">**</span> <span class="mi">2</span>

<span class="n">g</span> <span class="o">=</span> <span class="nf">kareler</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>

<span class="k">for</span> <span class="n">deger</span> <span class="ow">in</span> <span class="n">g</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">İlk tur:</span><span class="sh">"</span><span class="p">,</span> <span class="n">deger</span><span class="p">)</span>

<span class="k">for</span> <span class="n">deger</span> <span class="ow">in</span> <span class="n">g</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">İkinci tur:</span><span class="sh">"</span><span class="p">,</span> <span class="n">deger</span><span class="p">)</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">next</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="sh">"</span><span class="s">Tükendi</span><span class="sh">"</span><span class="p">))</span>
</code></pre></div></div>

<p>İlk döngü <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">1</code> ve <code class="language-plaintext highlighter-rouge">4</code> değerlerini yazdırır. İkinci döngünün gövdesi hiç çalışmaz. Son satır ise <code class="language-plaintext highlighter-rouge">Tükendi</code> yazar; çünkü <code class="language-plaintext highlighter-rouge">next()</code> için bir varsayılan değer verdik.</p>

<p>Peki neden hata yok? <code class="language-plaintext highlighter-rouge">for</code>, iterator’dan değer isterken gelen <code class="language-plaintext highlighter-rouge">StopIteration</code> sinyalini <strong>normal bitiş</strong> olarak yorumlar. Bu sinyal kullanıcıya hata olarak gösterilmez. Varsayılan değer olmadan <code class="language-plaintext highlighter-rouge">next(g)</code> çağırırsanız, aynı durum açıkça bir istisna olarak görünür. Yani sessizlik, döngü protokolünün tasarlanmış davranışıdır.</p>

<h2 id="tek-kullanımlılık-bir-kusur-değil-tercihtir">Tek Kullanımlılık Bir Kusur Değil, Tercihtir</h2>

<p>Jeneratörler, tüm sonuçları bellekte saklamak zorunda kalmadan hesaplama yapmayı sağlar. Yukarıdaki gibi yalnızca sınırlı durum tutan bir üreticide, $n$ sonuç için yaklaşık ek bellek karşılaştırması şöyledir:</p>

\[M_{liste}=O(n),\qquad M_{generator}=O(1)\]

<p>Bu karşılaştırma, üretilen öğelerin boyutunu sabit kabul eder. Her jeneratörün toplam bellek tüketimi sabit değildir: İçeride büyük bir liste oluşturuyorsa veya kaynak veriyi bellekte tutuyorsa maliyet değişir. Kazanç, jeneratör etiketinden değil, gerçekten tembel üretim yapmaktan gelir.</p>

<h2 id="tekrar-dolaşmak-i̇çin-doğru-strateji">Tekrar Dolaşmak İçin Doğru Strateji</h2>

<p>İki temel seçenek vardır: Hesaplamayı yeniden başlatmak veya sonuçları saklamak.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">yeni_akis</span><span class="p">():</span>
    <span class="k">return</span> <span class="nf">kareler</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>

<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="nf">yeni_akis</span><span class="p">()))</span>

<span class="n">degerler</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="nf">yeni_akis</span><span class="p">())</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">sum</span><span class="p">(</span><span class="n">degerler</span><span class="p">),</span> <span class="nf">max</span><span class="p">(</span><span class="n">degerler</span><span class="p">))</span>
</code></pre></div></div>

<p>İlk bölüm, her turda yeni bir jeneratör oluşturur. İkinci bölüm, sonuçları bir kez listeye alır ve farklı işlemlerde tekrar kullanır. Listeye dönüştürmeyi jeneratör tükenmeden yapmalısınız; boş jeneratörden dolu liste çıkmaz!</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Bedel</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Yeni jeneratör oluşturmak</td>
      <td>Sonuçları saklamaz</td>
      <td>Hesaplama tekrarlanır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">list()</code> ile saklamak</td>
      <td>Kolay tekrar kullanım</td>
      <td>Bellek tüketimi artar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">itertools.tee()</code></td>
      <td>Bağımsız tüketim konumları</td>
      <td>Ara tampon büyüyebilir</td>
    </tr>
  </tbody>
</table>

<p>Kaynak zamanla değişiyorsa, yeniden üretimin aynı değerleri vereceği de garanti değildir. Dosya, ağ veya rastgelelik içeren akışlarda bu ayrım önemlidir.</p>

<h2 id="tee-sihirli-bir-fotokopi-makinesi-değildir"><code class="language-plaintext highlighter-rouge">tee()</code> Sihirli Bir Fotokopi Makinesi Değildir</h2>

<p>İki tüketici aynı akışı farklı hızlarda okuyacaksa <code class="language-plaintext highlighter-rouge">tee()</code> kullanılabilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">itertools</span> <span class="kn">import</span> <span class="n">tee</span>

<span class="n">ilk</span><span class="p">,</span> <span class="n">ikinci</span> <span class="o">=</span> <span class="nf">tee</span><span class="p">(</span><span class="nf">kareler</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">ilk</span><span class="p">))</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">ikinci</span><span class="p">))</span>
</code></pre></div></div>

<p>İki iterator aynı değerleri görür; fakat geride kalan tüketici için öğeler tamponda tutulur. Biri çok ilerlerse bellek kullanımı büyüyebilir. Bölme işleminden sonra özgün iterator yerine döndürülen iterator’ları kullanın.</p>

<h2 id="son-tuzak-kısmen-tüketmek">Son Tuzak: Kısmen Tüketmek</h2>

<p>“Bir kez tüketilir” ifadesi, ilk döngü başladıktan sonra her şeyin kaybolduğu anlamına gelmez. Döngüden <code class="language-plaintext highlighter-rouge">break</code> ile çıkarsanız, sonraki döngü kalan öğelerden devam eder. <code class="language-plaintext highlighter-rouge">sum()</code> akışı tamamen tüketirken, <code class="language-plaintext highlighter-rouge">any()</code> uygun değeri bulunca durabilir. Hata ayıklarken çağırdığınız <code class="language-plaintext highlighter-rouge">list(g)</code> bile akışı bitirebilir.</p>

<p>Kısacası jeneratör bir koleksiyon değil, ilerleyen bir süreçtir. İkinci tur gerekiyorsa önce karar verin: Yeniden üretecek misiniz, saklayacak mısınız, yoksa tüketicileri ayıracak mısınız?</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="python" /><category term="generator" /><category term="jeneratör" /><category term="iterator" /><category term="iterable" /><category term="bellek-yönetimi" /><summary type="html"><![CDATA[Python’da bir jeneratörü ilk döngüde gezersiniz, her şey harika çalışır. Aynı nesneyi ikinci döngüye soktuğunuzda ise ne sonuç vardır ne hata mesajı. Program sanki kahve molasına çıkmıştır! Aslında burada bir arıza yoktur: Jeneratörler, tüketildikçe ilerleyen ve kendiliğinden başa dönmeyen iterator nesneleridir. Gelin bu sessizliğin arkasındaki mekanizmayı inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/python-jeneratorleri-neden-61.png" /><media:content medium="image" url="https://program.sonsuz.us/img/python-jeneratorleri-neden-61.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Salgınların Dijital Provası: Algoritmalarla Epidemileri Simüle Etmek</title><link href="https://program.sonsuz.us/posts/salginlarin-dijital-provasi-algoritmalarla-epidemileri-simule-etmek/" rel="alternate" type="text/html" title="Salgınların Dijital Provası: Algoritmalarla Epidemileri Simüle Etmek" /><published>2026-11-01T00:00:00+00:00</published><updated>2026-11-01T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/salginlarin-dijital-provasi-algoritmalarla-epidemileri-simule-etmek</id><content type="html" xml:base="https://program.sonsuz.us/posts/salginlarin-dijital-provasi-algoritmalarla-epidemileri-simule-etmek/"><![CDATA[<p>Bir hastalığın toplumda yayılması, birbirini tetikleyen olaylardan oluşur: Bir kişi enfekte olur, başkalarıyla karşılaşır ve bazılarına hastalığı bulaştırır. Bilgisayar simülasyonu, bu zinciri sanal bir laboratuvarda incelememizi sağlar. Üstelik zamanı hızlandırabilir, koşulları değiştirebilir ve aynı senaryoyu yüzlerce kez deneyebiliriz. Ancak ekranımızdaki eğri, geleceği gösteren sihirli bir kristal küre değildir!</p>

<p><img src="/img/salginlarin-dijital-provasi-39.svg" alt="salginlarin-dijital-provasi-39" /></p>

<p>``</p>

<h2 id="önce-mantık-sir-modeli">Önce mantık: SIR modeli</h2>

<p>En yaygın başlangıç modellerinden biri <strong>SIR</strong> modelidir. Toplumu üç gruba ayırır:</p>

<ul>
  <li><strong>S — Duyarlı:</strong> Hastalığa yakalanabilecek kişiler.</li>
  <li><strong>I — Bulaştırıcı:</strong> Hastalığı başkalarına aktarabilen kişiler.</li>
  <li><strong>R — İyileşmiş:</strong> Bu modelde artık bulaştırmayan ve yeniden enfekte olmayan kişiler.</li>
</ul>

<p>Doğum, ölüm ve göçü dışarıda bırakırsak toplam nüfus sabittir: $N=S+I+R$. İnsanlar önce S grubundan I grubuna, ardından R grubuna geçer. Bu, herkesin birbirine benzer olasılıkla temas ettiği varsayılan bir modeldir; gerçek hayattaki arkadaş çevreleri ve okul koridorları şimdilik sahne dışında kalır.</p>

<p>Modelin iki temel parametresi vardır. $\beta$, bulaşmayı belirleyen etkin temas hızıdır; $\gamma$ ise iyileşme hızıdır. İkisi de zamanın tersi birimine sahiptir. Sabit iyileşme hızı varsayımında ortalama bulaştırıcılık süresi $1/\gamma$ olur.</p>

\[\frac{dS}{dt}=-\beta\frac{SI}{N},\qquad \frac{dI}{dt}=\beta\frac{SI}{N}-\gamma I,\qquad \frac{dR}{dt}=\gamma I\]

<p>Bu denklemler, grupların değişim hızını anlatır. Yeni enfeksiyonlar hem duyarlı hem bulaştırıcı kişiler bulunduğunda oluşur; iyileşmeler ise bulaştırıcı grubunu küçültür.</p>

<p>Tamamen duyarlı bir toplumda temel üreme sayısı $R_0=\beta/\gamma$ olarak hesaplanır. Örneğin $\beta=0.3$ ve $\gamma=0.1$ için $R_0=3$ çıkar. Fakat duyarlı nüfus azaldıkça etkin üreme sayısı $R_e=R_0S/N$ düşer. Bu modelde $R_e&lt;1$ olduğunda bulaştırıcı sayısının azalma eğilimi beklenir.</p>

<h2 id="hangi-model-hangi-soru">Hangi model, hangi soru?</h2>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Güçlü tarafı</th>
      <th>Temel sınırlaması</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SIR</td>
      <td>Basit, hızlı, anlaşılır</td>
      <td>Bulaştırıcılık öncesi dönemi içermez</td>
    </tr>
    <tr>
      <td>SEIR</td>
      <td>Enfekte ama henüz bulaştırıcı olmayan dönemi ekler</td>
      <td>Daha fazla parametre gerektirir</td>
    </tr>
    <tr>
      <td>Ajan tabanlı</td>
      <td>Bireyleri ve temas ağlarını temsil eder</td>
      <td>Veri ve hesaplama maliyeti yüksektir</td>
    </tr>
  </tbody>
</table>

<p>Denklemleri doğrudan çözmek düzgün eğriler üretir. Olasılıksal simülasyonda ise günlük sayılar dalgalanır. Özellikle başlangıçta az sayıda bulaştırıcı varsa, aynı parametrelerle bazı salgınlar büyüyebilir, bazıları erken sönebilir. Rastgelelik burada süs değil, modelin önemli bir parçasıdır.</p>

<h2 id="python-ile-olasılıksal-simülasyon">Python ile olasılıksal simülasyon</h2>

<p>Aşağıdaki örnekte her adım çeyrek gündür. Bir duyarlı kişinin enfekte olma olasılığını $p=1-e^{-\beta(I/N)\Delta t}$, bir bulaştırıcının iyileşme olasılığını ise $q=1-e^{-\gamma\Delta t}$ olarak hesaplıyoruz. Ardından binom dağılımından geçiş sayıları çekiyoruz. NumPy için <code class="language-plaintext highlighter-rouge">pip install numpy</code> yeterlidir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="nf">default_rng</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">10_000</span>
<span class="n">S</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span> <span class="o">=</span> <span class="n">N</span> <span class="o">-</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">0</span>
<span class="n">beta</span><span class="p">,</span> <span class="n">gamma</span><span class="p">,</span> <span class="n">dt</span> <span class="o">=</span> <span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.25</span>
<span class="n">history</span> <span class="o">=</span> <span class="p">[(</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">S</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">)]</span>

<span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nf">int</span><span class="p">(</span><span class="mi">120</span> <span class="o">/</span> <span class="n">dt</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
    <span class="n">p_infection</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="o">-</span><span class="n">beta</span> <span class="o">*</span> <span class="n">I</span> <span class="o">/</span> <span class="n">N</span> <span class="o">*</span> <span class="n">dt</span><span class="p">)</span>
    <span class="n">p_recovery</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="o">-</span><span class="n">gamma</span> <span class="o">*</span> <span class="n">dt</span><span class="p">)</span>

    <span class="n">infections</span> <span class="o">=</span> <span class="n">rng</span><span class="p">.</span><span class="nf">binomial</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">p_infection</span><span class="p">)</span>
    <span class="n">recoveries</span> <span class="o">=</span> <span class="n">rng</span><span class="p">.</span><span class="nf">binomial</span><span class="p">(</span><span class="n">I</span><span class="p">,</span> <span class="n">p_recovery</span><span class="p">)</span>

    <span class="n">S</span> <span class="o">-=</span> <span class="n">infections</span>
    <span class="n">I</span> <span class="o">+=</span> <span class="n">infections</span> <span class="o">-</span> <span class="n">recoveries</span>
    <span class="n">R</span> <span class="o">+=</span> <span class="n">recoveries</span>

    <span class="k">assert</span> <span class="n">S</span> <span class="o">+</span> <span class="n">I</span> <span class="o">+</span> <span class="n">R</span> <span class="o">==</span> <span class="n">N</span>
    <span class="k">assert</span> <span class="nf">min</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
    <span class="n">history</span><span class="p">.</span><span class="nf">append</span><span class="p">((</span><span class="n">step</span> <span class="o">*</span> <span class="n">dt</span><span class="p">,</span> <span class="n">S</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">))</span>

<span class="n">peak</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="n">history</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">row</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Zirve günü:</span><span class="sh">"</span><span class="p">,</span> <span class="n">peak</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Zirvedeki bulaştırıcı sayısı:</span><span class="sh">"</span><span class="p">,</span> <span class="n">peak</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
</code></pre></div></div>

<p>Geçişler adımın başındaki sayılardan hesaplanır; yeni enfekte olanlar aynı adımda iyileşmez. Bu, sürekli zamanlı sürecin ayrık zaman yaklaşımıdır. Daha küçük adımlar genellikle yaklaşımı iyileştirir, fakat hesaplama yükünü artırır. Sabit rastgelelik tohumu sonucu tekrarlanabilir kılar; <code class="language-plaintext highlighter-rouge">assert</code> ifadeleri de nüfus muhasebesini denetler.</p>

<h2 id="deney-tasarlamak-tek-eğriden-değerlidir">Deney tasarlamak, tek eğriden değerlidir</h2>

<p>Şimdi sanal laboratuvarın düğmeleriyle oynayabiliriz:</p>

<ul>
  <li><strong>Temasları azalt:</strong> Belirli bir günden sonra $\beta$ değerini düşür; zirvenin yüksekliğini ve zamanını karşılaştır.</li>
  <li><strong>Başlangıç bağışıklığını değiştir:</strong> Kusursuz koruma varsayımıyla bazı kişileri başlangıçta R grubuna yerleştir.</li>
  <li><strong>Tekrarlı koşular yap:</strong> Farklı tohumlarla yüzlerce simülasyon çalıştır; yalnızca ortalamayı değil, yüzdelik aralıkları da raporla.</li>
</ul>

<p>Zirvedeki bulaştırıcı sayısı, toplam enfekte olan kişi sayısıyla aynı değildir. Ayrıca daha alçak bir zirve, salgının daha kısa süreceği anlamına gelmez. Ölçütü araştırma sorusuna göre seçmek gerekir.</p>

<h2 id="modelin-sınırlarını-unutma">Modelin sınırlarını unutma</h2>

<p>Buradaki sayılar varsayımsaldır. Yaş, davranış değişimi, mevsimsellik, yeniden enfeksiyon ve eksik bildirim sonuçları değiştirebilir. Gerçek verilerle çalışırken parametre tahmini, duyarlılık analizi ve bağımsız doğrulama gerekir. İyi simülasyon kesinlik satmaz; varsayımlar açıkça belirtilirse, hangi koşullarda hangi sonuçların mümkün olduğunu anlamamıza yardım eder.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="epidemiyoloji" /><category term="simülasyon" /><category term="python" /><category term="sir" /><category term="matematik" /><category term="algoritmalar" /><summary type="html"><![CDATA[Bir hastalığın toplumda yayılması, birbirini tetikleyen olaylardan oluşur: Bir kişi enfekte olur, başkalarıyla karşılaşır ve bazılarına hastalığı bulaştırır. Bilgisayar simülasyonu, bu zinciri sanal bir laboratuvarda incelememizi sağlar. Üstelik zamanı hızlandırabilir, koşulları değiştirebilir ve aynı senaryoyu yüzlerce kez deneyebiliriz. Ancak ekranımızdaki eğri, geleceği gösteren sihirli bir kristal küre değildir!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/salginlarin-dijital-provasi-39.png" /><media:content medium="image" url="https://program.sonsuz.us/img/salginlarin-dijital-provasi-39.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>