<?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-01T06:05:55+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">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">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">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">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><entry><title type="html">Akıllı Otoparklar: Boş Park Yerini Sensörden Telefonunuza Taşıyan Yolculuk</title><link href="https://program.sonsuz.us/posts/akilli-otoparklar-bos-park-yerini-sensorden-telefonunuza-tasiyan-yolculuk/" rel="alternate" type="text/html" title="Akıllı Otoparklar: Boş Park Yerini Sensörden Telefonunuza Taşıyan Yolculuk" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/akilli-otoparklar-bos-park-yerini-sensorden-telefonunuza-tasiyan-yolculuk</id><content type="html" xml:base="https://program.sonsuz.us/posts/akilli-otoparklar-bos-park-yerini-sensorden-telefonunuza-tasiyan-yolculuk/"><![CDATA[<p>Otoparkta boş yer ararken aynı koridordan üçüncü kez geçmek, otomobil dünyasının sonsuz döngüsüdür. Akıllı otopark sistemleri bu döngüyü sensörler, mesajlaşma altyapısı ve canlı haritalarla kırar. Ancak sürücünün ekranındaki yeşil kutu, yalnızca bir sensörün verdiği cevap değildir; ölçümün güvenilir biçimde işlenmesiyle ortaya çıkan bir karardır.</p>

<p>``</p>

<h2 id="önce-fizik-bir-park-yeri-nasıl-konuşur">Önce fizik: Bir park yeri nasıl konuşur?</h2>

<p>Sistem, her park alanının fiziksel durumunu dijital bir sinyale dönüştürür. Ultrasonik sensör mesafeyi ölçerken manyetik sensör, aracın oluşturduğu manyetik alan değişimini izler. Kamera tabanlı çözümler ise görüntüdeki araçları ve park sınırlarını analiz eder.</p>

<p>Buradaki temel ayrım, <strong>ölçüm ile durumun aynı şey olmamasıdır</strong>. Sensör mesafe üretir; yazılım bu mesafeyi değerlendirerek “boş” veya “dolu” kararı verir. Yağmur, yaya hareketi ve yanlış hizalama gibi etkenler nedeniyle tek ölçümle karar vermek risklidir. Kurulum sırasında zemine ve araç tiplerine uygun kalibrasyon gerekir.</p>

<table>
  <thead>
    <tr>
      <th>Teknoloji</th>
      <th>Karar dayanağı</th>
      <th>Dikkat noktası</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ultrasonik</td>
      <td>Nesneye olan mesafe</td>
      <td>Montaj açısı</td>
    </tr>
    <tr>
      <td>Manyetik</td>
      <td>Manyetik alan değişimi</td>
      <td>Çevresel parazit</td>
    </tr>
    <tr>
      <td>Kamera</td>
      <td>Görüntüde araç tespiti</td>
      <td>Işık ve mahremiyet</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/akilli-otoparklar-bos-47.svg" alt="akilli-otoparklar-bos-47" /></p>

<h2 id="doluluk-hesabında-üçüncü-bir-durum-var">Doluluk hesabında üçüncü bir durum var</h2>

<p>Bir park yeri yalnızca boş veya dolu değildir: bağlantısı kesildiyse <strong>bilinmiyor</strong> olabilir. Toplam kapasiteyi $C$, boş yerleri $B$, dolu yerleri $D$, bilinmeyenleri $U$ ile gösterelim:</p>

\[C = B + D + U\]

<p>Güncel ölçümü bulunan alanların doluluk oranı, $B + D &gt; 0$ olduğunda şöyle hesaplanır:</p>

\[O = 100 D / (B + D)\]

<p>Bu oran tüm otoparkı değil, gözlemlenebilen bölümünü anlatır. Ekranda bilinmeyen alan sayısı da gösterilmelidir. Aksi halde çevrimdışı sensörler yüzünden otopark olduğundan daha boş görünebilir. Eski veri, boş yer vaadi değildir!</p>

<h2 id="verinin-yolculuğu-sensörden-canlı-haritaya">Verinin yolculuğu: Sensörden canlı haritaya</h2>

<p>Tipik akış şöyledir: <strong>sensör → ağ geçidi → MQTT broker → durum servisi → mobil uygulama</strong>. Ağ geçidi ölçümlere park kimliği, zaman damgası ve sıra numarası ekler. MQTT, küçük mesajları yayınlama-abonelik modeliyle ilgili servislere taşır.</p>

<p>Durum servisi güncel haritayı saklar; değişiklikleri WebSocket veya SSE üzerinden uygulamaya iletir. Böylece telefon sürekli bütün otoparkı sorgulamaz. MQTT QoS 1 kullanıldığında yinelenen teslimatlar mümkün olduğundan, servis aynı mesajı tekrar işlese bile sonucu bozmamalıdır. Sıra numarası kontrolü bunun pratik yollarından biridir.</p>

<h2 id="python-ile-küçük-ama-temkinli-bir-durum-motoru">Python ile küçük ama temkinli bir durum motoru</h2>

<p>Aşağıdaki örnek, eski mesajları reddeder ve aynı sonucu üç ardışık ölçümde gördüğünde durumu değiştirir. Olaylar <code class="language-plaintext highlighter-rouge">slot_id</code>, <code class="language-plaintext highlighter-rouge">occupied</code>, <code class="language-plaintext highlighter-rouge">seq</code> ve <code class="language-plaintext highlighter-rouge">observed_at</code> alanlarını içerir:</p>

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

<span class="n">slots</span> <span class="o">=</span> <span class="p">{}</span>

<span class="k">def</span> <span class="nf">ingest</span><span class="p">(</span><span class="n">event</span><span class="p">):</span>
    <span class="n">age</span> <span class="o">=</span> <span class="nf">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">event</span><span class="p">[</span><span class="sh">'</span><span class="s">observed_at</span><span class="sh">'</span><span class="p">]</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">age</span> <span class="o">&lt;=</span> <span class="mi">10</span><span class="p">:</span>
        <span class="k">return</span>

    <span class="n">slot</span> <span class="o">=</span> <span class="n">slots</span><span class="p">.</span><span class="nf">setdefault</span><span class="p">(</span><span class="n">event</span><span class="p">[</span><span class="sh">'</span><span class="s">slot_id</span><span class="sh">'</span><span class="p">],</span> <span class="p">{</span>
        <span class="sh">'</span><span class="s">seq</span><span class="sh">'</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="sh">'</span><span class="s">candidate</span><span class="sh">'</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span> <span class="sh">'</span><span class="s">hits</span><span class="sh">'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">state</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">bilinmiyor</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">updated</span><span class="sh">'</span><span class="p">:</span> <span class="mi">0</span>
    <span class="p">})</span>
    <span class="k">if</span> <span class="n">event</span><span class="p">[</span><span class="sh">'</span><span class="s">seq</span><span class="sh">'</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">slot</span><span class="p">[</span><span class="sh">'</span><span class="s">seq</span><span class="sh">'</span><span class="p">]:</span>
        <span class="k">return</span>

    <span class="n">value</span> <span class="o">=</span> <span class="sh">'</span><span class="s">dolu</span><span class="sh">'</span> <span class="k">if</span> <span class="n">event</span><span class="p">[</span><span class="sh">'</span><span class="s">occupied</span><span class="sh">'</span><span class="p">]</span> <span class="k">else</span> <span class="sh">'</span><span class="s">bos</span><span class="sh">'</span>
    <span class="n">slot</span><span class="p">[</span><span class="sh">'</span><span class="s">hits</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">slot</span><span class="p">[</span><span class="sh">'</span><span class="s">hits</span><span class="sh">'</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">slot</span><span class="p">[</span><span class="sh">'</span><span class="s">candidate</span><span class="sh">'</span><span class="p">]</span> <span class="k">else</span> <span class="mi">1</span>
    <span class="n">slot</span><span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="n">candidate</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">seq</span><span class="o">=</span><span class="n">event</span><span class="p">[</span><span class="sh">'</span><span class="s">seq</span><span class="sh">'</span><span class="p">],</span>
                <span class="n">updated</span><span class="o">=</span><span class="n">event</span><span class="p">[</span><span class="sh">'</span><span class="s">observed_at</span><span class="sh">'</span><span class="p">])</span>
    <span class="k">if</span> <span class="n">slot</span><span class="p">[</span><span class="sh">'</span><span class="s">hits</span><span class="sh">'</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">3</span><span class="p">:</span>
        <span class="n">slot</span><span class="p">[</span><span class="sh">'</span><span class="s">state</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>


<span class="k">def</span> <span class="nf">snapshot</span><span class="p">():</span>
    <span class="n">now</span> <span class="o">=</span> <span class="nf">time</span><span class="p">()</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="n">key</span><span class="p">:</span> <span class="n">item</span><span class="p">[</span><span class="sh">'</span><span class="s">state</span><span class="sh">'</span><span class="p">]</span> <span class="k">if</span> <span class="n">now</span> <span class="o">-</span> <span class="n">item</span><span class="p">[</span><span class="sh">'</span><span class="s">updated</span><span class="sh">'</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mi">10</span>
        <span class="k">else</span> <span class="sh">'</span><span class="s">bilinmiyor</span><span class="sh">'</span>
        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">slots</span><span class="p">.</span><span class="nf">items</span><span class="p">()</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>Üçlü doğrulama, gelip geçen bir yayayı otomobil sanma ihtimalini azaltır; fakat algılama gecikmesini artırır. On saniye boyunca güncellenmeyen alan, sorgu anında bilinmiyor olarak gösterilir. Üretimde bu eşikler ölçüm sıklığına göre ayarlanmalı, saatler senkronize edilmeli ve sıra numaraları cihaz yeniden başlatıldığında güvenle yönetilmelidir. Ayrıca bellek yerine kalıcı durum depolaması ve eşzamanlı işlem kontrolü gerekir.</p>

<h2 id="anlık-demek-sıfır-gecikme-demek-değildir">“Anlık” demek sıfır gecikme demek değildir</h2>

<p>Ölçümden ekrana toplam gecikme yaklaşık olarak $L = L_{ağ} + L_{işleme} + L_{iletim} + L_{arayüz}$ şeklinde modellenebilir. Örneğin bu aşamalar 80, 40, 100 ve 150 milisaniye sürerse toplam 370 milisaniyedir. Ancak aracın gelişi ile ilk ölçüm arasındaki bekleme ve doğrulama süresi de kullanıcı deneyimine eklenir.</p>

<p>Bu nedenle yalnızca ortalamayı değil, yoğun saatlerdeki yüksek gecikmeleri de izlemek gerekir. Arayüzde son güncelleme zamanı gösterilmeli; bağlantı kopunca yeşil kutular sonsuza kadar yeşil kalmamalıdır.</p>

<h2 id="boş-yer-bildirimi-rezervasyon-değildir">Boş yer bildirimi, rezervasyon değildir</h2>

<p>İki sürücü aynı boşluğu aynı anda görebilir. Sistem yalnızca yönlendirme yapıyorsa müsaitliğin değişebileceğini belirtmelidir. Yer ayırma sunuluyorsa süreli rezervasyon ve atomik güncelleme gerekir; ilk başarılı işlem yeri alır.</p>

<p>Kamera kullanıldığında mümkünse görüntüler yerinde işlenmeli, merkeze yalnızca doluluk bilgisi gönderilmelidir. Başarılı sistemin sırrı daha çok veri toplamak değil; doğru, güncel ve gerekli veriyi sürücüye ulaştırmaktır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="akıllı otopark" /><category term="iot" /><category term="sensörler" /><category term="mqtt" /><category term="gerçek zamanlı sistemler" /><category term="python" /><summary type="html"><![CDATA[Otoparkta boş yer ararken aynı koridordan üçüncü kez geçmek, otomobil dünyasının sonsuz döngüsüdür. Akıllı otopark sistemleri bu döngüyü sensörler, mesajlaşma altyapısı ve canlı haritalarla kırar. Ancak sürücünün ekranındaki yeşil kutu, yalnızca bir sensörün verdiği cevap değildir; ölçümün güvenilir biçimde işlenmesiyle ortaya çıkan bir karardır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/akilli-otoparklar-bos-47.png" /><media:content medium="image" url="https://program.sonsuz.us/img/akilli-otoparklar-bos-47.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Beyin–Bilgisayar Arayüzleri: Düşünceden Komuta Giden Yol</title><link href="https://program.sonsuz.us/posts/beyinbilgisayar-arayuzleri-dusunceden-komuta-giden-yol/" rel="alternate" type="text/html" title="Beyin–Bilgisayar Arayüzleri: Düşünceden Komuta Giden Yol" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/beyinbilgisayar-arayuzleri-dusunceden-komuta-giden-yol</id><content type="html" xml:base="https://program.sonsuz.us/posts/beyinbilgisayar-arayuzleri-dusunceden-komuta-giden-yol/"><![CDATA[<p>Klavyeye dokunmadan bir imleci hareket ettirmek mümkün mü? Evet; ancak bilgisayar zihninizdeki bütün cümleleri okumuyor. Beyin–bilgisayar arayüzleri, belirli sinirsel etkinlik örüntülerini ölçüp sınırlı komutlara dönüştürüyor. Yani mesele telepati değil, gürültülü biyolojik sinyallerle çalışan dikkatli bir mühendislik projesi. Beyninizin gizli bir USB portu yok; keşke kurulum bu kadar kolay olsaydı!</p>

<p>``</p>

<h2 id="önce-beklentiyi-doğru-ayarlayalım">Önce beklentiyi doğru ayarlayalım</h2>

<p>Bir beyin–bilgisayar arayüzü, İngilizce kısaltmasıyla <strong>BCI</strong>, kas hareketlerini zorunlu tutmadan sinirsel etkinlik üzerinden iletişim kurmayı hedefler. Örneğin kullanıcı sağ veya sol elini hareket ettirdiğini hayal eder; sistem bu iki durumu ayırt etmeye çalışır. Bazı sistemlerdeyse kullanıcı yanıp sönen seçeneklerden birine odaklanır. Buradaki bilgi, serbest düşüncenin içeriği değil, önceden tanımlanmış bir görevle ilişkili örüntüdür.</p>

<p>Ölçüm yöntemleri aynı kapıya farklı yollardan ulaşır:</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Nasıl ölçer?</th>
      <th>Avantaj</th>
      <th>Temel sınırlama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>EEG</td>
      <td>Saçlı derideki elektrotlarla</td>
      <td>Ameliyat gerektirmez</td>
      <td>Gürültü ve düşük uzamsal çözünürlük</td>
    </tr>
    <tr>
      <td>ECoG</td>
      <td>Beyin yüzeyindeki elektrotlarla</td>
      <td>Daha yerel sinyaller</td>
      <td>Cerrahi işlem gerekir</td>
    </tr>
    <tr>
      <td>Beyin içi elektrotlar</td>
      <td>Sinir dokusu içinden</td>
      <td>Ayrıntılı kayıt potansiyeli</td>
      <td>Cerrahi risk ve uzun dönem kararlılık</td>
    </tr>
  </tbody>
</table>

<h2 id="sinyalden-komuta-küçük-bir-çeviri-fabrikası">Sinyalden komuta: küçük bir çeviri fabrikası</h2>

<p>Tipik işlem zinciri şöyledir:</p>

<p><strong>Ölçüm → temizleme → özellik çıkarımı → sınıflandırma → komut → geri bildirim.</strong></p>

<p>EEG, tek bir nöronun konuşması değildir. Çok sayıda kaynağın elektriksel etkileri, ölçüm noktasında birbirine karışır. Göz kırpması, çene kasları ve elektrik şebekesi de bu karışıma katılabilir. Dolayısıyla yüksek genlik, otomatik olarak güçlü bir niyet anlamına gelmez.</p>

<p>Motor imgelemede sık incelenen özellikler, yaklaşık <strong>8–13 Hz mu</strong> ve <strong>13–30 Hz beta</strong> bantlarındaki güç değişimleridir. Bu değişimler kişiye ve göreve göre farklılaşır; sabit bir düşünce sözlüğü oluşturmazlar. Özellik vektörünü $h$ ile gösterirsek, basit bir ikili sınıflandırıcı şöyle yazılabilir:</p>

\[z = w^T h + b\]

\[p = 1/(1 + e^{-z})\]

<p>Burada $w$ öğrenilen ağırlıkları, $b$ sabit terimi, $p$ ise modelin bir sınıfa verdiği olasılık tahminini temsil eder. Bu tahminin güvenilirliği ayrıca değerlendirilmelidir. Model, kişinin niyetini doğrudan bilmez; eğitim verisindeki ilişkilere dayanarak karar verir. <strong>Korelasyon, zihin okuma değildir.</strong></p>

<h2 id="python-ile-bant-gücünden-sınıflandırmaya">Python ile bant gücünden sınıflandırmaya</h2>

<p>Aşağıdaki örnek, NumPy, SciPy ve scikit-learn kullanır. Dosyada artefaktları önceden ele alınmış EEG denemeleri bulunmalıdır: <code class="language-plaintext highlighter-rouge">X</code> boyutu <code class="language-plaintext highlighter-rouge">(deneme, kanal, örnek)</code>, <code class="language-plaintext highlighter-rouge">y</code> sağ/sol imgeleme etiketleri, <code class="language-plaintext highlighter-rouge">oturum</code> kayıt oturumu kimlikleri, <code class="language-plaintext highlighter-rouge">fs</code> örnekleme frekansıdır. En az üç farklı oturum gerekir.</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">from</span> <span class="n">scipy.signal</span> <span class="kn">import</span> <span class="n">welch</span>
<span class="kn">from</span> <span class="n">sklearn.pipeline</span> <span class="kn">import</span> <span class="n">make_pipeline</span>
<span class="kn">from</span> <span class="n">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">StandardScaler</span>
<span class="kn">from</span> <span class="n">sklearn.linear_model</span> <span class="kn">import</span> <span class="n">LogisticRegression</span>
<span class="kn">from</span> <span class="n">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">GroupKFold</span><span class="p">,</span> <span class="n">cross_val_score</span>

<span class="n">d</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">load</span><span class="p">(</span><span class="sh">"</span><span class="s">eeg_denemeleri.npz</span><span class="sh">"</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">oturum</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">X</span><span class="sh">"</span><span class="p">],</span> <span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">y</span><span class="sh">"</span><span class="p">],</span> <span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">oturum</span><span class="sh">"</span><span class="p">]</span>
<span class="n">fs</span> <span class="o">=</span> <span class="nf">float</span><span class="p">(</span><span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">fs</span><span class="sh">"</span><span class="p">])</span>
<span class="n">f</span><span class="p">,</span> <span class="n">psd</span> <span class="o">=</span> <span class="nf">welch</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">fs</span><span class="o">=</span><span class="n">fs</span><span class="p">,</span>
               <span class="n">nperseg</span><span class="o">=</span><span class="nf">min</span><span class="p">(</span><span class="mi">256</span><span class="p">,</span> <span class="n">X</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="o">-</span><span class="mi">1</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">bantlar</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">alt</span><span class="p">,</span> <span class="n">ust</span> <span class="ow">in</span> <span class="p">[(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">13</span><span class="p">),</span> <span class="p">(</span><span class="mi">13</span><span class="p">,</span> <span class="mi">30</span><span class="p">)]:</span>
    <span class="n">sec</span> <span class="o">=</span> <span class="p">(</span><span class="n">f</span> <span class="o">&gt;=</span> <span class="n">alt</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">f</span> <span class="o">&lt;</span> <span class="n">ust</span><span class="p">)</span>
    <span class="n">guc</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">trapezoid</span><span class="p">(</span><span class="n">psd</span><span class="p">[...,</span> <span class="n">sec</span><span class="p">],</span> <span class="n">f</span><span class="p">[</span><span class="n">sec</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">bantlar</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">guc</span> <span class="o">+</span> <span class="mf">1e-12</span><span class="p">))</span>
<span class="n">F</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">concatenate</span><span class="p">(</span><span class="n">bantlar</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">model</span> <span class="o">=</span> <span class="nf">make_pipeline</span><span class="p">(</span><span class="nc">StandardScaler</span><span class="p">(),</span>
                      <span class="nc">LogisticRegression</span><span class="p">(</span><span class="n">max_iter</span><span class="o">=</span><span class="mi">1000</span><span class="p">))</span>
<span class="n">skorlar</span> <span class="o">=</span> <span class="nf">cross_val_score</span><span class="p">(</span>
    <span class="n">model</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">groups</span><span class="o">=</span><span class="n">oturum</span><span class="p">,</span>
    <span class="n">cv</span><span class="o">=</span><span class="nc">GroupKFold</span><span class="p">(</span><span class="n">n_splits</span><span class="o">=</span><span class="mi">3</span><span class="p">),</span> <span class="n">scoring</span><span class="o">=</span><span class="sh">"</span><span class="s">balanced_accuracy</span><span class="sh">"</span>
<span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">skorlar</span><span class="p">.</span><span class="nf">mean</span><span class="p">())</span>
</code></pre></div></div>

<p>Welch yöntemi güç spektrumunu tahmin eder; bant integralleri kanal başına özellik üretir. Logaritma, güç değerlerinin geniş aralığını sıkıştırır. Pipeline, ölçekleyicinin yalnızca eğitim bölümünde öğrenilmesini sağlar. Oturum bazlı bölme ise aynı kaydın benzer parçalarının eğitim ve teste karışmasını önler. Kod, NumPy 2 veya üzerindeki <code class="language-plaintext highlighter-rouge">trapezoid</code> işlevini kullanır.</p>

<h2 id="laboratuvardan-gerçek-hayata-geçiş">Laboratuvardan gerçek hayata geçiş</h2>

<p>Yüksek test başarısı, kullanışlı bir arayüz için tek başına yeterli değildir. Gecikme, yanlış komut sıklığı, kalibrasyon süresi ve kullanıcı yorgunluğu da ölçülmelidir. Dengeli doğruluk, sınıfların ayrı ayrı başarılarını eşit ağırlıkla değerlendirir. Rastgele deneme bölmek yerine yeni oturumlarda sınamak, günlük kullanım performansını anlamaya daha çok yardımcı olur.</p>

<p>Gerçek zamanlı sistemde kararsız tahminler komuta dönüştürülmeyebilir. Kullanıcıya geri bildirim vermek ve gerektiğinde onay istemek, özellikle tekerlekli sandalye gibi fiziksel sonuç doğuran uygulamalarda önemlidir. Bu örnek, güvenlik doğrulaması yapılmış bir kontrol sistemi değildir.</p>

<p>Sinirsel kayıtlar da hassas verilerdir: açık rıza, sınırlı saklama ve güvenli erişim tasarımın parçası olmalıdır. Klinik uygulamalarda profesyonel değerlendirme gerekir. Sonuç olarak düşünceden komuta geçmek mümkün; fakat başarılı BCI, sihirli bir okuyucu değil, kullanıcıyla birlikte öğrenen kontrollü bir çevirmen gibi çalışır.</p>

<p><img src="/img/beyinbilgisayar-arayuzleri-dusunceden-37.svg" alt="beyinbilgisayar-arayuzleri-dusunceden-37" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="beyin-bilgisayar-arayüzü" /><category term="eeg" /><category term="makine-öğrenmesi" /><category term="sinyal-işleme" /><category term="nöroteknoloji" /><category term="python" /><summary type="html"><![CDATA[Klavyeye dokunmadan bir imleci hareket ettirmek mümkün mü? Evet; ancak bilgisayar zihninizdeki bütün cümleleri okumuyor. Beyin–bilgisayar arayüzleri, belirli sinirsel etkinlik örüntülerini ölçüp sınırlı komutlara dönüştürüyor. Yani mesele telepati değil, gürültülü biyolojik sinyallerle çalışan dikkatli bir mühendislik projesi. Beyninizin gizli bir USB portu yok; keşke kurulum bu kadar kolay olsaydı!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/beyinbilgisayar-arayuzleri-dusunceden-37.png" /><media:content medium="image" url="https://program.sonsuz.us/img/beyinbilgisayar-arayuzleri-dusunceden-37.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bir Gövde, Birçok Görev: Modüler Robot Tasarımının Esnekliği</title><link href="https://program.sonsuz.us/posts/bir-govde-bircok-gorev-moduler-robot-tasariminin-esnekligi/" rel="alternate" type="text/html" title="Bir Gövde, Birçok Görev: Modüler Robot Tasarımının Esnekliği" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bir-govde-bircok-gorev-moduler-robot-tasariminin-esnekligi</id><content type="html" xml:base="https://program.sonsuz.us/posts/bir-govde-bircok-gorev-moduler-robot-tasariminin-esnekligi/"><![CDATA[<p><img src="/img/bir-govde-bircok-15.svg" alt="bir-govde-bircok-15" /></p>

<p>Bir robotun sabah depoda kutu taşıyıp öğleden sonra serada bitki kontrolü yaptığını düşünün. Bunu iki ayrı makineyle çözmek mümkün; ancak modüler tasarım, aynı gövdenin hareket, algılama ve tutma bileşenlerini değiştirerek farklı görevlere uyarlanmasını sağlar. Robot biraz LEGO setine benzer, fakat burada parçaların yalnızca birbirine oturması değil, birlikte güvenle çalışması gerekir.
``</p>

<h2 id="modülerlik-parçalardan-daha-büyük-bir-fikir">Modülerlik: Parçalardan Daha Büyük Bir Fikir</h2>

<p>Modüler robot, belirli işlevleri bağımsız birimlere ayıran robot mimarisidir. Tekerlek takımı hareketi, kamera çevreyi algılamayı, kavrayıcı ise nesnelerle etkileşimi üstlenebilir. Her birimin görev sınırı ve bağlantı kuralları açıkça tanımlanır. Böylece bir bileşeni değiştirmek, robotun tamamını yeniden tasarlamayı gerektirmez. Buradaki temel ilke, <strong>işlevsel ayrıştırma ve standart arayüzlerdir</strong>.</p>

<p>Bu yaklaşımın iki yaygın biçimi vardır. Sabit gövdeli sistemlerde uç araçlar ve sensörler değiştirilir. Yeniden yapılandırılabilir sistemlerde ise bağlantılı modüller robotun fiziksel biçimini de değiştirebilir. İlk yaklaşım endüstriyel uygulamalarda daha kolay yönetilirken ikincisi daha geniş hareket olanakları sunar; buna karşılık kontrol ve bağlantı tasarımı zorlaşır.</p>

<p>Mimariyi $G=(V,E)$ grafiğiyle düşünebiliriz: $V$ modülleri, $E$ ise aralarındaki bağlantıları temsil eder. Bağlantının mekanik, elektriksel veya veri taşıyan niteliği önemlidir. Bir kameranın takılabilmesi, kontrol yazılımının onu kullanabileceği anlamına gelmez!</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Sabit tasarım</th>
      <th>Modüler tasarım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Görev değişimi</td>
      <td>Yeni tasarım gerekebilir</td>
      <td>Uygun parça değiştirilebilir</td>
    </tr>
    <tr>
      <td>Bakım</td>
      <td>Bütün sisteme müdahale gerekebilir</td>
      <td>Arızalı birim ayrılabilir</td>
    </tr>
    <tr>
      <td>Optimizasyon</td>
      <td>Tek görevde yüksek olabilir</td>
      <td>Arayüzlerden kaynaklanan ödünleşimler vardır</td>
    </tr>
    <tr>
      <td>Başlangıç geliştirmesi</td>
      <td>Daha sade olabilir</td>
      <td>Standartlaştırma yatırımı ister</td>
    </tr>
  </tbody>
</table>

<h2 id="esnekliğin-gizli-kahramanı-arayüzler">Esnekliğin Gizli Kahramanı: Arayüzler</h2>

<p>Başarılı modülerlik, bağlantı noktasında başlar. Mekanik arayüz; ölçüleri, kilitleme yöntemini ve taşınabilecek yükü belirlemelidir. Elektriksel arayüz; gerilim, akım sınırı, kutuplama ve koruma düzenini tanımlar. Veri arayüzü ise mesaj biçimini, haberleşme hızını ve hata davranışını kapsar. CAN veya Ethernet kullanmak tek başına yeterli değildir; modüllerin aynı mesajların anlamında da anlaşması gerekir.</p>

<p>Yazılım tarafında sürücüler, donanım ayrıntılarını ortak yeteneklere dönüştürebilir. Örneğin farklı kavrayıcılar aynı “aç”, “kapat” ve “durum oku” işlemlerini sunar. Böylece görev planlayıcısı marka veya model yerine yeteneklerle çalışır. Yine de kavrama kuvveti ve konum hassasiyeti gibi sınırlar ayrıca bildirilmelidir.</p>

<p>Fizik kuralları ise tak-çıkar heyecanına kapılmaz. Bir kolun yükten kaynaklanan torku basitçe $T=F r$ ile hesaplanır. Burada $F$ kuvvet, $r$ dönme eksenine olan dik uzaklıktır. Aynı yükü iki kat uzağa taşımak, tork ihtiyacını iki katına çıkarır. Dolayısıyla daha uzun modül, daha güçlü motor veya daha düşük taşıma kapasitesi gerektirebilir.</p>

<h2 id="python-ile-göreve-uygun-yapılandırma">Python ile Göreve Uygun Yapılandırma</h2>

<p>Aşağıdaki örnek, seçilen modüllerin besleme gerilimini ve görev yeteneklerini denetler. Donanımı hareket ettirmez; yapılandırmanın yazılım düzeyindeki bir ön kontrolüdür. Python 3.9 ve üzeriyle çalışır.</p>

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

<span class="nd">@dataclass</span><span class="p">(</span><span class="n">frozen</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Module</span><span class="p">:</span>
    <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
    <span class="n">capabilities</span><span class="p">:</span> <span class="nb">frozenset</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
    <span class="n">voltage</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">24</span>

<span class="n">modules</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">"</span><span class="s">drive</span><span class="sh">"</span><span class="p">:</span> <span class="nc">Module</span><span class="p">(</span><span class="sh">"</span><span class="s">Tekerlek</span><span class="sh">"</span><span class="p">,</span> <span class="nf">frozenset</span><span class="p">({</span><span class="sh">"</span><span class="s">hareket</span><span class="sh">"</span><span class="p">})),</span>
    <span class="sh">"</span><span class="s">gripper</span><span class="sh">"</span><span class="p">:</span> <span class="nc">Module</span><span class="p">(</span><span class="sh">"</span><span class="s">Kavrayıcı</span><span class="sh">"</span><span class="p">,</span> <span class="nf">frozenset</span><span class="p">({</span><span class="sh">"</span><span class="s">kavrama</span><span class="sh">"</span><span class="p">})),</span>
    <span class="sh">"</span><span class="s">camera</span><span class="sh">"</span><span class="p">:</span> <span class="nc">Module</span><span class="p">(</span><span class="sh">"</span><span class="s">Kamera</span><span class="sh">"</span><span class="p">,</span> <span class="nf">frozenset</span><span class="p">({</span><span class="sh">"</span><span class="s">görüntüleme</span><span class="sh">"</span><span class="p">})),</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">configure</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="n">required</span><span class="p">):</span>
    <span class="n">selected</span> <span class="o">=</span> <span class="p">[</span><span class="n">modules</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">names</span><span class="p">]</span>
    <span class="k">if</span> <span class="nf">any</span><span class="p">(</span><span class="n">module</span><span class="p">.</span><span class="n">voltage</span> <span class="o">!=</span> <span class="mi">24</span> <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">selected</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">Besleme gerilimi uyumsuz</span><span class="sh">"</span><span class="p">)</span>
    <span class="n">available</span> <span class="o">=</span> <span class="nf">frozenset</span><span class="p">().</span><span class="nf">union</span><span class="p">(</span>
        <span class="o">*</span><span class="p">(</span><span class="n">module</span><span class="p">.</span><span class="n">capabilities</span> <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">selected</span><span class="p">)</span>
    <span class="p">)</span>
    <span class="n">missing</span> <span class="o">=</span> <span class="nf">set</span><span class="p">(</span><span class="n">required</span><span class="p">)</span> <span class="o">-</span> <span class="n">available</span>
    <span class="k">if</span> <span class="n">missing</span><span class="p">:</span>
        <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">Eksik yetenekler: </span><span class="si">{</span><span class="nf">sorted</span><span class="p">(</span><span class="n">missing</span><span class="p">)</span><span class="si">}</span><span class="sh">"</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">module</span><span class="p">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">selected</span><span class="p">]</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">configure</span><span class="p">([</span><span class="sh">"</span><span class="s">drive</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">gripper</span><span class="sh">"</span><span class="p">],</span> <span class="p">{</span><span class="sh">"</span><span class="s">hareket</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">kavrama</span><span class="sh">"</span><span class="p">}))</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">configure</span><span class="p">([</span><span class="sh">"</span><span class="s">drive</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">camera</span><span class="sh">"</span><span class="p">],</span> <span class="p">{</span><span class="sh">"</span><span class="s">hareket</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">görüntüleme</span><span class="sh">"</span><span class="p">}))</span>
</code></pre></div></div>

<p>İlk çağrı taşıma, ikinci çağrı gözlem görevine uygun parçaları seçer. Gerçek uygulamada bu kontrole mekanik uyumluluk, akım bütçesi, haberleşme protokolü ve güvenlik kısıtları da eklenmelidir. Yetenek etiketi, performans garantisi değildir.</p>

<h2 id="parça-değiştiğinde-ne-yeniden-kontrol-edilmeli">Parça Değiştiğinde Ne Yeniden Kontrol Edilmeli?</h2>

<p>Modül değişimi sonrasında robotun kütlesi, ağırlık merkezi ve durma mesafesi değişebilir. Kamera değişirse kalibrasyon; kavrayıcı değişirse kuvvet sınırları ve araç koordinat sistemi güncellenmelidir. Yapılandırma kaydı tutmak, hangi donanımın hangi yazılım sürümüyle test edildiğini izlemeyi kolaylaştırır. Bu kayıtlar bakım ekibinin “Dün çalışıyordu!” bilmecesini çözmesinde özellikle değerlidir.</p>

<p>Sistem özel olarak enerjiliyken değişime uygun tasarlanmamışsa parçalar güç kesilerek değiştirilmelidir. Ardından bağlantılar doğrulanmalı, düşük hızda işlev testi yapılmalı ve güvenlik sınırları yeniden değerlendirilmelidir.</p>

<p>Modülerlik her durumda daha ucuz veya daha hafif değildir. Ek bağlantılar maliyet, boşluk ve arıza noktası yaratabilir. Ancak görevler sık değişiyorsa ortak gövdeyi korumak ciddi avantaj sağlar. İyi tasarlanmış modüler robot, her işi kusursuz yapan sihirli makine değil; yeni işleri kontrollü biçimde öğrenebilen bir mühendislik platformudur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="modüler tasarım" /><category term="mekatronik" /><category term="python" /><category term="otomasyon" /><summary type="html"><![CDATA[Bir robotun sabah depoda kutu taşıyıp öğleden sonra serada bitki kontrolü yaptığını düşünün. Bunu iki ayrı makineyle çözmek mümkün; ancak modüler tasarım, aynı gövdenin hareket, algılama ve tutma bileşenlerini değiştirerek farklı görevlere uyarlanmasını sağlar. Robot biraz LEGO setine benzer, fakat burada parçaların yalnızca birbirine oturması değil, birlikte güvenle çalışması gerekir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bir-govde-bircok-15.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bir-govde-bircok-15.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bir Sensörle Başlayan Zincir: Ev Otomasyonunda Olay Tabanlı Programlama</title><link href="https://program.sonsuz.us/posts/bir-sensorle-baslayan-zincir-ev-otomasyonunda-olay-tabanli-programlama/" rel="alternate" type="text/html" title="Bir Sensörle Başlayan Zincir: Ev Otomasyonunda Olay Tabanlı Programlama" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bir-sensorle-baslayan-zincir-ev-otomasyonunda-olay-tabanli-programlama</id><content type="html" xml:base="https://program.sonsuz.us/posts/bir-sensorle-baslayan-zincir-ev-otomasyonunda-olay-tabanli-programlama/"><![CDATA[<p>Gece koridora çıktığınızda lamba yanıyor, ardından telefonunuza aydınlatmanın açıldığı bilgisi geliyor. Siz yalnızca yürüdünüz; eviniz ise küçük bir yazılım orkestrası gibi çalıştı. Bu davranışın arkasında, cihazları sürekli sorgulamak yerine değişikliklere tepki veren olay tabanlı programlama bulunur. Gelin, tek bir sensör sinyalinin nasıl kontrollü bir otomasyon zincirine dönüştüğünü keşfedelim.</p>

<p>``</p>

<h2 id="olay-nedir-komuttan-farkı-ne">Olay nedir, komuttan farkı ne?</h2>

<p><strong>Olay</strong>, gerçekleşmiş bir durumun kaydıdır: “Hareket algılandı.” <strong>Komut</strong> ise yapılması istenen iştir: “Lambayı aç.” Bu ayrım önemlidir; hareket sensörü lambanın nasıl çalıştığını bilmek zorunda değildir. Yalnızca gözlemini yayınlar, otomasyon kuralları da uygun komutları üretir.</p>

<p>Tipik mimaride üç rol vardır: olayı üreten sensör, mesajı taşıyan olay veri yolu ve mesajı işleyen tüketiciler. MQTT kullanılan sistemlerde aracı sunucu mesajları abonelere iletir. Bununla birlikte, MQTT tek başına otomasyon kurallarını değerlendirmez; bu görev uygulamanıza veya otomasyon platformuna aittir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Çalışma biçimi</th>
      <th>Temel özellik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Periyodik sorgulama</td>
      <td>Sensöre düzenli aralıklarla sorar</td>
      <td>Tepki süresi sorgulama aralığına bağlıdır</td>
    </tr>
    <tr>
      <td>Olay tabanlı model</td>
      <td>Sensör değişikliği bildirir</td>
      <td>Gereksiz sorgulamayı azaltabilir</td>
    </tr>
    <tr>
      <td>Zamanlanmış görev</td>
      <td>Belirlenen saatte çalışır</td>
      <td>Sensör değişimi gerektirmez</td>
    </tr>
  </tbody>
</table>

<p>Bu yöntemler rakip değil, takım arkadaşıdır. Örneğin hareket olayı lambayı açarken, zamanlanmış bir görev gecenin sonunda açık kalan lambaları kapatabilir.</p>

<h2 id="zincirin-matematiği-olay-koşul-ve-durum">Zincirin matematiği: olay, koşul ve durum</h2>

<p>Bir kuralı “olay geldi, koşul doğruysa eylemi gerçekleştir” şeklinde düşünebiliriz. Hareketi $H$, gece koşulunu $G$, lambayı açma kararını $L$ ile gösterirsek:</p>

\[L = H \land G\]

<p>Ancak yalnızca koşulları değerlendirmek yetmez. Lambanın mevcut durumunu da bilmeliyiz. Durum geçişini $S_{t+1} = f(S_t, E_t)$ olarak yazabiliriz: yeni durum, önceki durum ve gelen olay tarafından belirlenir.</p>

<p>Lamba zaten açıksa tekrar açma komutu göndermemek, gereksiz işlemleri azaltır. Üstelik zincirin bir sonraki halkasını yalnızca gerçek durum değiştiğinde tetiklememizi sağlar. Böylece eviniz, aynı düğmeye heyecanla yüz kere basan bir robot gibi davranmaz.</p>

<h2 id="python-ile-küçük-bir-olay-zinciri">Python ile küçük bir olay zinciri</h2>

<p>Aşağıdaki örnek, sensör olayını bir kuyruğa bırakır. Hareket işleyicisi gece koşulunu değerlendirir; lamba açıldığında yeni bir olay üretir. İkinci işleyici de telefon bildirimini temsil eden çıktıyı oluşturur. Gerçek cihaz bağlantıları yerine simülasyon kullanıyoruz.</p>

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

<span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">Event</span><span class="p">:</span>
    <span class="n">kind</span><span class="p">:</span> <span class="nb">str</span>
    <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span>

<span class="n">bus</span> <span class="o">=</span> <span class="n">asyncio</span><span class="p">.</span><span class="nc">Queue</span><span class="p">()</span>
<span class="n">state</span> <span class="o">=</span> <span class="p">{</span><span class="sh">"</span><span class="s">light</span><span class="sh">"</span><span class="p">:</span> <span class="bp">False</span><span class="p">}</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">on_motion</span><span class="p">(</span><span class="n">event</span><span class="p">):</span>
    <span class="n">hour</span> <span class="o">=</span> <span class="n">event</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="sh">"</span><span class="s">hour</span><span class="sh">"</span><span class="p">]</span>
    <span class="n">is_night</span> <span class="o">=</span> <span class="n">hour</span> <span class="o">&gt;=</span> <span class="mi">22</span> <span class="ow">or</span> <span class="n">hour</span> <span class="o">&lt;</span> <span class="mi">6</span>
    <span class="k">if</span> <span class="n">is_night</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">state</span><span class="p">[</span><span class="sh">"</span><span class="s">light</span><span class="sh">"</span><span class="p">]:</span>
        <span class="n">state</span><span class="p">[</span><span class="sh">"</span><span class="s">light</span><span class="sh">"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">True</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Koridor lambası açıldı.</span><span class="sh">"</span><span class="p">)</span>
        <span class="k">await</span> <span class="n">bus</span><span class="p">.</span><span class="nf">put</span><span class="p">(</span><span class="nc">Event</span><span class="p">(</span><span class="sh">"</span><span class="s">light.changed</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">on</span><span class="sh">"</span><span class="p">:</span> <span class="bp">True</span><span class="p">}))</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">on_light</span><span class="p">(</span><span class="n">event</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">event</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="sh">"</span><span class="s">on</span><span class="sh">"</span><span class="p">]:</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Telefon bildirimi: Koridor aydınlatıldı.</span><span class="sh">"</span><span class="p">)</span>

<span class="n">handlers</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">"</span><span class="s">motion.detected</span><span class="sh">"</span><span class="p">:</span> <span class="n">on_motion</span><span class="p">,</span>
    <span class="sh">"</span><span class="s">light.changed</span><span class="sh">"</span><span class="p">:</span> <span class="n">on_light</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="k">await</span> <span class="n">bus</span><span class="p">.</span><span class="nf">put</span><span class="p">(</span><span class="nc">Event</span><span class="p">(</span><span class="sh">"</span><span class="s">motion.detected</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">hour</span><span class="sh">"</span><span class="p">:</span> <span class="mi">23</span><span class="p">}))</span>
    <span class="k">while</span> <span class="ow">not</span> <span class="n">bus</span><span class="p">.</span><span class="nf">empty</span><span class="p">():</span>
        <span class="n">event</span> <span class="o">=</span> <span class="k">await</span> <span class="n">bus</span><span class="p">.</span><span class="nf">get</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">handler</span> <span class="o">=</span> <span class="n">handlers</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">kind</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">handler</span><span class="p">:</span>
                <span class="k">await</span> <span class="nf">handler</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">bus</span><span class="p">.</span><span class="nf">task_done</span><span class="p">()</span>

<span class="n">asyncio</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span><span class="nf">main</span><span class="p">())</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">handlers</code> sözlüğü, olay türlerini ilgili fonksiyonlarla eşleştirir. Kuyruk ise üretici ile tüketiciyi birbirinden ayırır. Bu örnekte işleyiciler sırayla beklenir; <code class="language-plaintext highlighter-rouge">async</code> kullanılması bütün işlemlerin otomatik olarak paralel çalıştığı anlamına gelmez. Ayrıca döngü kuyruk boşalınca biter; sürekli çalışan uygulamada yeni olaylar <code class="language-plaintext highlighter-rouge">await bus.get()</code> ile beklenir.</p>

<p>Gerçek lambada durum değişikliğini, komut gönderildiği anda değil cihazdan doğrulama geldiğinde yayınlamak daha güvenilirdir. Aksi hâlde bağlantısı kopmuş bir lambayı yazılımda açık sanabilirsiniz.</p>

<h2 id="zinciri-güvenilir-tutmak">Zinciri güvenilir tutmak</h2>

<p>Olay tabanlı sistemlerin eğlenceli tarafı bağlantı kurmaktır; zor tarafı ise bağlantıları kontrol altında tutmaktır.</p>

<ul>
  <li><strong>Tekrarlanan mesajlar:</strong> Olay kimliği ve idempotent işleyiciler kullanın. Aynı olayın yeniden gelmesi sonucu değiştirmemelidir.</li>
  <li><strong>Sonsuz döngüler:</strong> Lambanın değişimi sensör kuralını yeniden tetikliyorsa döngü oluşabilir. Kaynak bilgisi ve açık geçiş kuralları ekleyin.</li>
  <li><strong>Sensör titreşimi:</strong> Çok kısa aralıklarla gelen sinyalleri filtrelemek için debounce uygulayın. Hareketli bir perdeyi misafir sanmayın!</li>
  <li><strong>Bağlantı kesintileri:</strong> Yeniden deneme, zaman aşımı ve durum uzlaştırma mekanizmaları tasarlayın. Tek bir mesajı mutlak gerçek kabul etmeyin.</li>
  <li><strong>Güvenlik:</strong> MQTT erişimini kimlik doğrulama ve konu bazlı yetkilerle sınırlandırın; kritik cihazlarda manuel kontrolü koruyun.</li>
</ul>

<p>Sonuç olarak iyi otomasyon, yalnızca cihazları bağlamak değildir. Olayın anlamını, koşullarını ve oluşturduğu durum değişikliklerini açıkça tanımlamaktır. Bu temel sağlam olduğunda, tek bir sensör evinizin geri kalanıyla düzenli ve anlaşılır bir sohbet başlatabilir.</p>

<p><img src="/img/bir-sensorle-baslayan-18.svg" alt="bir-sensorle-baslayan-18" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ev otomasyonu" /><category term="olay tabanlı programlama" /><category term="python" /><category term="sensörler" /><category term="asenkron programlama" /><category term="mqtt" /><summary type="html"><![CDATA[Gece koridora çıktığınızda lamba yanıyor, ardından telefonunuza aydınlatmanın açıldığı bilgisi geliyor. Siz yalnızca yürüdünüz; eviniz ise küçük bir yazılım orkestrası gibi çalıştı. Bu davranışın arkasında, cihazları sürekli sorgulamak yerine değişikliklere tepki veren olay tabanlı programlama bulunur. Gelin, tek bir sensör sinyalinin nasıl kontrollü bir otomasyon zincirine dönüştüğünü keşfedelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bir-sensorle-baslayan-18.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bir-sensorle-baslayan-18.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Sınıflar, Nesneler ve Metotlar: ref ve out ile Nesne Modelini Anlamak</title><link href="https://program.sonsuz.us/posts/c-siniflar-nesneler-ve-metotlar-ref-ve-out-ile-nesne-modelini-anlamak/" rel="alternate" type="text/html" title="C# Sınıflar, Nesneler ve Metotlar: ref ve out ile Nesne Modelini Anlamak" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-siniflar-nesneler-ve-metotlar-ref-ve-out-ile-nesne-modelini-anlamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-siniflar-nesneler-ve-metotlar-ref-ve-out-ile-nesne-modelini-anlamak/"><![CDATA[<p><img src="/img/c-siniflar-nesneler-62.svg" alt="c-siniflar-nesneler-62" /></p>

<p>Bir banka hesabını programlamak istediğinizi düşünün: hesabın bakiyesi vardır, para çekilebilir ve işlemin sonucu öğrenilebilir. C# bu dünyayı sınıflar, nesneler ve metotlarla temsil eder. İşin eğlenceli kısmı, aynı hesaba iki farklı değişkenle ulaşabilmenizdir. Ancak bir nesneyi değiştirmekle, değişkenin gösterdiği nesneyi değiştirmek aynı şey değildir!</p>

<p>``</p>

<h2 id="sınıf-plan-nesne-çalışan-örnektir">Sınıf plan, nesne çalışan örnektir</h2>

<p><strong>Sınıf</strong>, verileri ve davranışları bir araya getiren tür tanımıdır. <strong>Nesne</strong>, bu sınıftan oluşturulan somut örnektir. <strong>Metot</strong> ise bir nesnenin gerçekleştirebildiği işlemi tanımlar; ayrıca sınıfa ait statik metotlar da bulunabilir.</p>

<p>Bir sınıftan oluşturulan iki nesnenin bakiyeleri birbirinden bağımsız olabilir. Buna karşılık iki değişken aynı nesneye bağlanabilir. Aynı televizyonu yöneten iki kumanda düşünün: kumandalar farklıdır, fakat değiştirilen televizyon aynıdır.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Banka örneği</th>
      <th>Görevi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sınıf</td>
      <td><code class="language-plaintext highlighter-rouge">Hesap</code></td>
      <td>Yapıyı ve davranışları tanımlar</td>
    </tr>
    <tr>
      <td>Nesne</td>
      <td>Oluşturulan müşteri hesabı</td>
      <td>Durumu taşır</td>
    </tr>
    <tr>
      <td>Özellik</td>
      <td><code class="language-plaintext highlighter-rouge">Bakiye</code></td>
      <td>Veriye kontrollü erişim sağlar</td>
    </tr>
    <tr>
      <td>Metot</td>
      <td><code class="language-plaintext highlighter-rouge">ParaCek</code></td>
      <td>İşlem gerçekleştirir</td>
    </tr>
  </tbody>
</table>

<p>C# sınıfları <strong>referans türüdür</strong>. Bir sınıf değişkeninin değeri, nesnenin kendisi değil, ona erişmeyi sağlayan referanstır. Referansı kopyalamak, nesneyi çoğaltmaz.</p>

<h2 id="durumu-davranışla-korumak">Durumu davranışla korumak</h2>

<p>Aşağıdaki sınıf, bakiyenin dışarıdan doğrudan değiştirilmesini engeller. Kurucu metot başlangıç durumunu oluşturur; <code class="language-plaintext highlighter-rouge">ParaCek</code> ise çekim kurallarını uygular ve sonucu bildirir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">Hesap</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">decimal</span> <span class="n">Bakiye</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="nf">Hesap</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">bakiye</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">bakiye</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentOutOfRangeException</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="n">bakiye</span><span class="p">));</span>

        <span class="n">Bakiye</span> <span class="p">=</span> <span class="n">bakiye</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="kt">bool</span> <span class="nf">ParaCek</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">tutar</span><span class="p">,</span> <span class="k">out</span> <span class="kt">decimal</span> <span class="n">kalan</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">kalan</span> <span class="p">=</span> <span class="n">Bakiye</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">tutar</span> <span class="p">&lt;=</span> <span class="m">0</span> <span class="p">||</span> <span class="n">tutar</span> <span class="p">&gt;</span> <span class="n">Bakiye</span><span class="p">)</span>
            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>

        <span class="n">Bakiye</span> <span class="p">-=</span> <span class="n">tutar</span><span class="p">;</span>
        <span class="n">kalan</span> <span class="p">=</span> <span class="n">Bakiye</span><span class="p">;</span>
        <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">private set</code>, bakiyenin yalnızca sınıf içinden atanabilmesini sağlar. Bu yaklaşım <strong>kapsülleme</strong> olarak adlandırılır: veriyi saklamaktan çok, geçerli durumları korumak önemlidir. Negatif başlangıç bakiyesi reddedilir; geçersiz çekim ise hesabı değiştirmez.</p>

<p>Başarılı çekimin matematiksel modeli şöyledir:</p>

\[B_{son} = B_{ilk} - T\]

<p>Burada $T$ çekilen tutardır; işlemin kabul koşulu $0 &lt; T \leq B_{ilk}$ şeklindedir. Kod, bu koşulu denetleyerek nesnenin tutarlılığını korur. Para hesaplarında <code class="language-plaintext highlighter-rouge">decimal</code>, ondalık değerleri temsil etmek için genellikle <code class="language-plaintext highlighter-rouge">double</code> türünden daha uygundur.</p>

<h2 id="varsayılan-aktarım-ref-ve-out">Varsayılan aktarım, ref ve out</h2>

<p>C# parametreleri varsayılan olarak <strong>değer ile</strong> aktarır. <code class="language-plaintext highlighter-rouge">decimal</code> parametresinde sayısal değer kopyalanır. <code class="language-plaintext highlighter-rouge">Hesap</code> parametresinde ise referansın değeri kopyalanır. Bu yüzden normal bir parametre üzerinden nesnenin özelliklerini değiştirmek mümkündür; bunun için <code class="language-plaintext highlighter-rouge">ref</code> gerekmez.</p>

<p>Ancak metot içinde normal parametreye <code class="language-plaintext highlighter-rouge">new Hesap(...)</code> atamak, çağıranın değişkenini başka nesneye yönlendirmez. Yalnızca parametrenin yerel kopyası değişir. İşte <code class="language-plaintext highlighter-rouge">ref</code>, çağıranın değişkenine erişim sağlayarak bu ayrımı görünür kılar.</p>

<table>
  <thead>
    <tr>
      <th>Aktarım</th>
      <th>Çağrıdan önce değer gerekli mi?</th>
      <th>Metodun atama zorunluluğu</th>
      <th>Amaç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Normal</td>
      <td>Evet</td>
      <td>Yok</td>
      <td>Değerin kopyasıyla çalışmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ref</code></td>
      <td>Evet</td>
      <td>Yok</td>
      <td>Mevcut değişkeni okuyup değiştirmek</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">out</code></td>
      <td>Hayır</td>
      <td>Her normal dönüş yolunda var</td>
      <td>Sonuç üretmek</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">ref</code> ve <code class="language-plaintext highlighter-rouge">out</code>, hem metot bildiriminde hem çağrıda belirtilir. <code class="language-plaintext highlighter-rouge">out</code> parametresi, metot içinde okunmadan önce atanmalıdır. Örneğimizde <code class="language-plaintext highlighter-rouge">kalan</code> başlangıçta atanır; böylece başarısız çekimde bile kullanılabilir bir sonuç döner.</p>

<h2 id="referansı-değiştirmek-başka-bir-iştir">Referansı değiştirmek başka bir iştir</h2>

<p>.NET 6+ konsol projesinde aşağıdaki üst düzey kullanım kodunu sınıf bildiriminden önce yerleştirebilirsiniz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">hesap</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Hesap</span><span class="p">(</span><span class="m">100m</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">ortak</span> <span class="p">=</span> <span class="n">hesap</span><span class="p">;</span>

<span class="kt">bool</span> <span class="n">basarili</span> <span class="p">=</span> <span class="n">hesap</span><span class="p">.</span><span class="nf">ParaCek</span><span class="p">(</span><span class="m">30m</span><span class="p">,</span> <span class="k">out</span> <span class="kt">decimal</span> <span class="n">kalan</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">$"Başarılı: </span><span class="p">{</span><span class="n">basarili</span><span class="p">}</span><span class="s">, kalan: </span><span class="p">{</span><span class="n">kalan</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>

<span class="n">ortak</span><span class="p">.</span><span class="nf">ParaCek</span><span class="p">(</span><span class="m">10m</span><span class="p">,</span> <span class="k">out</span> <span class="n">kalan</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">hesap</span><span class="p">.</span><span class="n">Bakiye</span><span class="p">);</span> <span class="c1">// 60</span>

<span class="nf">Yenile</span><span class="p">(</span><span class="k">ref</span> <span class="n">hesap</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">hesap</span><span class="p">.</span><span class="n">Bakiye</span><span class="p">);</span> <span class="c1">// 0</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">ortak</span><span class="p">.</span><span class="n">Bakiye</span><span class="p">);</span> <span class="c1">// 60</span>

<span class="k">static</span> <span class="k">void</span> <span class="nf">Yenile</span><span class="p">(</span><span class="k">ref</span> <span class="n">Hesap</span> <span class="n">hedef</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">hedef</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Hesap</span><span class="p">(</span><span class="m">0m</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>İlk atamada <code class="language-plaintext highlighter-rouge">ortak</code> ve <code class="language-plaintext highlighter-rouge">hesap</code> aynı nesneyi gösterir. Dolayısıyla <code class="language-plaintext highlighter-rouge">ortak</code> üzerinden yapılan çekim, <code class="language-plaintext highlighter-rouge">hesap</code> üzerinden görülen bakiyeyi de değiştirir. <code class="language-plaintext highlighter-rouge">Yenile</code> ise <code class="language-plaintext highlighter-rouge">ref</code> sayesinde doğrudan <code class="language-plaintext highlighter-rouge">hesap</code> değişkeninin referansını değiştirir. <code class="language-plaintext highlighter-rouge">ortak</code>, eski nesneyi göstermeyi sürdürür; nesne topluca sıfırlanmamıştır.</p>

<h2 id="küçük-bir-seçim-rehberi">Küçük bir seçim rehberi</h2>

<p>Tek sonuç için çoğunlukla dönüş değerini kullanın. Başarı bilgisiyle ek sonuç gerekiyorsa <code class="language-plaintext highlighter-rouge">out</code> kullanışlıdır; <code class="language-plaintext highlighter-rouge">int.TryParse</code> bunun klasik örneğidir. Çağıranın mevcut değişkenini değiştirmek gerekiyorsa <code class="language-plaintext highlighter-rouge">ref</code> düşünülebilir. Son kontrol sorunuz şu olsun: “Nesnenin durumunu mu, değişkenin değerini mi değiştiriyorum?” Bu ayrım, referans karmaşasının büyük bölümünü çözer.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="nesne-yönelimli-programlama" /><category term="sınıflar" /><category term="nesneler" /><category term="metotlar" /><category term="ref" /><category term="out" /><summary type="html"><![CDATA[Bir banka hesabını programlamak istediğinizi düşünün: hesabın bakiyesi vardır, para çekilebilir ve işlemin sonucu öğrenilebilir. C# bu dünyayı sınıflar, nesneler ve metotlarla temsil eder. İşin eğlenceli kısmı, aynı hesaba iki farklı değişkenle ulaşabilmenizdir. Ancak bir nesneyi değiştirmekle, değişkenin gösterdiği nesneyi değiştirmek aynı şey değildir!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-siniflar-nesneler-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-siniflar-nesneler-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>