<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Buğrahan Karamollaoğlu on Medium]]></title>
        <description><![CDATA[Stories by Buğrahan Karamollaoğlu on Medium]]></description>
        <link>https://medium.com/@bugrahankaramollaoglu?source=rss-1d20d304a24d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*7ZXV1Sj4NzcFLeC1NR_crA.jpeg</url>
            <title>Stories by Buğrahan Karamollaoğlu on Medium</title>
            <link>https://medium.com/@bugrahankaramollaoglu?source=rss-1d20d304a24d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 25 May 2026 17:48:58 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@bugrahankaramollaoglu/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[SQLite Nedir & Nasıl kullanılır?]]></title>
            <link>https://medium.com/@bugrahankaramollaoglu/sqlite-nedir-nas%C4%B1l-kullan%C4%B1l%C4%B1r-c0a766e0519e?source=rss-1d20d304a24d------2</link>
            <guid isPermaLink="false">https://medium.com/p/c0a766e0519e</guid>
            <category><![CDATA[sqlite]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Buğrahan Karamollaoğlu]]></dc:creator>
            <pubDate>Sat, 06 Jul 2024 07:52:50 GMT</pubDate>
            <atom:updated>2024-07-06T07:52:50.932Z</atom:updated>
            <content:encoded><![CDATA[<p>SQLite, lokal bilgisayarınızda veritabanları yaratarak işlemler yapabileceğiniz birkaç sorgu yönteminden birisidir (diğer alternatifler: MySQL, MariaDB, PostgreSQL). Özellikle Android programlamada sıklıkla tercih edilir. Veritabanı yerelde tutulduğundan sunucu gerektirmez.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vm9zWcDzYmlmTZ7y4G1h6g.png" /></figure><p>C dilinde yazılan SQLite’ın diğer veritabanı dilleri gibi kendine özgü sentaksı vardır. Bu makalede SQLite nedir ve nasıl kullanılır hakkında genel bir bilgi sahibi etmeyi hedefledim.</p><p>Öncelikle Linux sistemimize sqlite kütüphanesini ekliyoruz:</p><pre>sudo apt install sqlite3<br><br># emin olmak icin calistirin: sqlite --version</pre><p>Daha sonra dilediğimiz dizinde aşağıdaki komut vasıtasıyla veritabanımızı yaratıyoruz:</p><pre>sqlite3 arabalar.db<br><br># asagidaki gibi bir cikti almamiz gerek<br># Output<br># SQLite version 3.31.1 2020-01-27 19:55:54<br># Enter &quot;.help&quot; for usage hints.<br># sqlite&gt; ... </pre><p>Veritabanları tıpkı Excel programında olduğu gibi satır ve sütunlardan oluşan bir tabloya benzer. Sütunlar verilerimizin sahip olmasını istediğimiz özelliklerdir (id, isim, adet vs). Tablo yaratmak için kullanılan komut <strong>CREATE TABLE</strong> komutudur. Mesela <em>arabalar</em> veritabanımıza id, marka, model ve kilometre bilgilerini verdiğimiz bir örnek yaratalım:</p><pre>CREATE TABLE arabalar(id integer NOT NULL, marka text NOT NULL, model text NOT NULL, kilometer integer NOT NULL);</pre><p>ifadelerin yanındaki <strong>NOT NULL </strong>ifadesi o özelliği <em>required</em> yapar. Yani daha sonra o parametre boş bırakılamaz. Ek olarak, SQLite büyük-küçük harf ayrımı yapmaz — yani CREATE ile create aynı şekilde çalışır fakat geleneksel olarak veritabanları sorgularında büyük harf kullanılır.</p><p>Bununla beraber yorum satırı için (--) kullanılır:</p><pre>sqlite&gt; -- bu bir yorum satiri</pre><p>Eğer ki aynı isimde bir tablo olduğundan şüphelenirseniz:</p><pre>CREATE TABLE IF NOT EXISTS ...</pre><p>Tablomuz yaratıldı fakat şuan için boş. Bunları doldurmayı görelim. Bunun için de INSERT INTO<strong> </strong>komutu kullanılır:</p><pre>INSERT INTO arabalar VALUES (1, &quot;Opel&quot;, &quot;Corsa&quot;, 10500);<br>INSERT INTO arabalar VALUES (2, &quot;Honda&quot;, &quot;City&quot;, 26000);<br>INSERT INTO arabalar VALUES (3, &quot;Peugeot&quot;, &quot;507&quot;, 50000);<br>INSERT INTO arabalar VALUES (3, &quot;Peugeot&quot;, &quot;507&quot;); # hata verir</pre><p>Artık verileri eklendi. Şimdi bir veritabanındaki bütün verileri okumayı sağlayan <strong>SELECT * FROM __</strong> komutunu inceleyim:</p><pre>SELECT * FROM arabalar;</pre><p>(*) ifadesi ReGex notasyonundan alışık olduğumuz üzere her şeyi kapsar. Sonuç şu olur:</p><pre>sqlite&gt; SELECT * FROM arabalar;<br><br>1|Opel|Corsa|10500<br>2|Honda|City|26000<br>3|Peugeot|507|50000</pre><p>Yukarıdaki şekil varsayılandır. Bunu özelleştirmek isterseniz</p><pre>sqlite&gt;.header on<br>sqlite&gt;.mode column</pre><p>diyerek güzelleştirebilirsiniz:</p><pre>id  marka    model  kilometer<br>--  -------  -----  ---------<br>1   Opel     Corsa  10500    <br>2   Honda    City   26000    <br>3   Peugeot  507    50000  </pre><p>İstediğiniz kadar sonuç almak isterseniz:</p><pre>SELECT * FROM arabalar LIMIT 10 -- ilk 10 sonuç gelir</pre><p>Eğer sonuçları alırken filtreleme yapmak istiyorsanız WHERE komutunu kullanmalısınız:</p><pre>SELECT * FROM arabalar WHERE kilometer &gt; 20000;<br><br>id  marka    model  kilometer<br>--  -------  -----  ---------<br>2   Honda    City   26000    <br>3   Peugeot  507    50000   </pre><p>gördüğünüz gibi 1 numaralı girdinin kilometer verisi (&gt;20000) şartını sağlamadığı için sorgulamaya dahil edilmedi. Eğer ki kesin bir filtreleme yapmak istiyorsanız IS kalıbını kullanabilirsiniz:</p><pre>SELECT * FROM arabalar WHERE id IS 3</pre><p>Başlarken sütunların verilerin özelliklerini belirttiğini söylemiştik. Şimdi yeni özelliklerin nasıl eklenip çıkarılabileceğine bakalım:</p><pre>ALTER TABLE arabalar ADD COLUMN renk text;</pre><p>Aralık belirtmek isterseniz:</p><pre>SELECT * FROM arabalar WHERE kilometer BETWEEN 20000 and 30000</pre><p>Eğer ki var olan verilerinizi güncellemek isterseniz <strong>UPDATE</strong> komutunu kullanmanız gerekir:</p><pre>UPDATE arabalar SET renk = &#39;siyah&#39; WHERE id=1;<br>UPDATE arabalar SET renk = &#39;gri&#39; WHERE id=2;<br>UPDATE arabalar SET renk = &#39;beyaz&#39; WHERE id=3;</pre><p>Eğer stringlerle uğraşıyorsanız ve belirli bir patern arıyorsanız:</p><pre>SELECT * FROM arabalar WHERE marka GLOB &#39;peu*&#39; ORDER BY id ASC;</pre><p>bu durumda marka bilgisi <em>peu</em> ile başlayan tüm satırlar gelecektir.</p><p>Verileri özelleştirirken ORDER BY komutuyla sıralayabilirsiniz:</p><pre>SELECT * FROM arabalar ORDER BY id DESC;<br><br>id  marka    model  kilometer<br>--  -------  -----  ---------<br>3   Peugeot  507    50000    <br>2   Honda    City   26000    <br>1   Opel     Corsa  10500  <br><br>SELECT * FROM arabalar ORDER BY kilometer ASC;<br><br>id  marka    model  kilometer<br>--  -------  -----  ---------<br>1   Opel     Corsa  10500    <br>2   Honda    City   26000    <br>3   Peugeot  507    50000   </pre><p>Programlama dillerinden aşina olduğumuz mantık operatörleri AND ve OR da benzer şekilde kullanılır:</p><pre>SELECT<br>  name,<br>  surname<br>FROM<br>  persons<br>WHERE<br>  name = &#39;bugra&#39;<br>  OR surname = &#39;kara&#39;</pre><p>Veritabanından girdi silmek isterseniz DELETE komutunu kullanabilirsiniz (! veritabanı sıfırlanır):</p><pre>DELETE * FROM arabalar</pre><p>Birden çok veriyi filtreleyerek silmek isterseniz DELETE komutunu özelleştirebilirsiniz:</p><pre>DELETE FROM arabalar WHERE kilometer &lt;= 30000;</pre><p>Son olarak, veritabanından spesifik bir tablo silmek isterseniz DROP kullanırsınız:</p><pre>DROP TABLE arabalar</pre><p>eğer tabloların listesini görmek isterseniz:</p><pre>sqlite&gt;.tables<br>arabalar</pre><p>SQLite yukarıdakilerin haricinde daha birçok komut içeriyor ama genel bir taslak çizmek adına bu makaleyi yazma gereği duydum. İyi programlamalar!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c0a766e0519e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to implement Onboarding in Flutter?]]></title>
            <link>https://medium.com/@bugrahankaramollaoglu/how-to-implement-onboarding-in-flutter-a334386dfb9b?source=rss-1d20d304a24d------2</link>
            <guid isPermaLink="false">https://medium.com/p/a334386dfb9b</guid>
            <dc:creator><![CDATA[Buğrahan Karamollaoğlu]]></dc:creator>
            <pubDate>Sat, 29 Jun 2024 16:08:56 GMT</pubDate>
            <atom:updated>2024-06-29T16:08:56.313Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yPBRlNw5d3FcdXCXvr1eAQ.png" /></figure><p>These days I’ve been wrestling with my Flutter app to implement the best looking onboarding pages flipping through the endless realm of internet. Then I came across a pub.dev package that fixed all my problems - thanks to <a href="https://pub.dev/packages/flutter_onboarding_slider">appinio</a>. This package comes all-set and all you need to do is minor configurations.</p><p>I will, in layman’s terms, try to explain the way you can implement it in your Flutter app. Let’s see how:</p><p>As it is the case with all flutter packages, you must start by adding the package in your pubspec.yaml — the easier way (and the I always choose) is using terminal for that:</p><pre>flutter pub add flutter_onboarding_slider</pre><p>This will automatically run <em>pub get</em> and <em>pub upgrade</em>. Then, you must import it in the file you are going to use:</p><pre>import &#39;package:flutter_onboarding_slider/flutter_onboarding_slider.dart&#39;;</pre><p>Preparations done! All that is left is to implement the class of Onboarding:</p><pre>class MyHome extends StatelessWidget {<br>  final Color myChosenColor = const Color(0xFF053149);<br><br>  const MyHome({super.key});<br><br>  @override<br>  Widget build(BuildContext context) {<br>    return OnBoardingSlider(<br>      // the button that&#39;ll pop when sliding is done<br>      finishButtonText: &#39;Register&#39;,<br>      onFinish: () {<br>        Navigator.push(<br>          context,<br>          CupertinoPageRoute(<br>            builder: (context) =&gt; const RegisterPage(),<br>          ),<br>        );<br>      },<br>      finishButtonStyle: FinishButtonStyle(<br>        backgroundColor: myChosenColor,<br>      ),<br>      skipTextButton: Text(<br>        &#39;Skip&#39;,<br>        style: TextStyle(<br>          fontSize: 16,<br>          color: myChosenColor,<br>          fontWeight: FontWeight.w600,<br>        ),<br>      ),<br>      trailing: Text(<br>        &#39;Login&#39;,<br>        style: TextStyle(<br>          fontSize: 16,<br>          color: myChosenColor,<br>          fontWeight: FontWeight.w600,<br>        ),<br>      ),<br>      trailingFunction: () {<br>        Navigator.push(<br>          context,<br>          CupertinoPageRoute(<br>            builder: (context) =&gt; const LoginPage(),<br>          ),<br>        );<br>      },<br>      controllerColor: myChosenColor,<br>      totalPage: 3,<br>      headerBackgroundColor: Colors.white,<br>      pageBackgroundColor: Colors.white,<br>      background: [<br>        // these are the background images for each page<br>        Image.asset(<br>          &#39;assets/slide_1.png&#39;,<br>          height: 400,<br>        ),<br>        Image.asset(<br>          &#39;assets/slide_2.png&#39;,<br>          height: 400,<br>        ),<br>        Image.asset(<br>          &#39;assets/slide_3.png&#39;,<br>          height: 400,<br>        ),<br>      ],<br>      speed: 1.8,<br>      pageBodies: [<br>        Container(<br>            // content of page1<br>            ),<br>        Container(<br>            // content of page2<br>            ),<br>        Container(<br>            // content of page3<br>            ),<br>      ],<br>    );<br>  }<br>}</pre><p>Onboarding class has a lot more to it in case you would opt to use them, a few examples being:</p><pre><br>  OnBoardingSlider({<br>    required this.totalPage,<br>    required this.headerBackgroundColor,<br>    required this.background,<br>    required this.speed,<br>    required this.pageBodies,<br>    this.onFinish,<br>    this.trailingFunction,<br>    this.trailing,<br>    this.skipTextButton,<br>    this.pageBackgroundColor,<br>    this.pageBackgroundGradient,<br>    this.finishButtonStyle,<br>    this.finishButtonText,<br>    this.controllerColor,<br>    this.addController = true,<br>    this.centerBackground = false,<br>    this.addButton = true,<br>    this.imageVerticalOffset = 0,<br>    this.imageHorizontalOffset = 0,<br>    this.leading,<br>    this.middle,<br>    this.hasFloatingButton = true,<br>    this.hasSkip = true,<br>    this.finishButtonTextStyle = const TextStyle(<br>      fontSize: 20,<br>      color: Colors.white,<br>    ),<br>    this.skipIcon = const Icon(<br>      Icons.arrow_forward,<br>      color: Colors.white,<br>    ),<br>    this.indicatorAbove = false,<br>    this.indicatorPosition = 90,<br>    this.skipFunctionOverride,<br>  });</pre><p>These are all the features that OnboardingSlider package allows you to use</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*t2mDtHBg4zZP46_1Qph3XA.gif" /><figcaption>After that your Onboarding mechanism is almost completed. You can still embellish with customizations, though.</figcaption></figure><p>That was it for this article. See you in another one!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*snnJr38e1Ul_4HzZNkMmBQ.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a334386dfb9b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ücretsiz API Kaynakları & Nasıl Kullanılır? (Hava Durumu)]]></title>
            <link>https://medium.com/@bugrahankaramollaoglu/%C3%BCcretsiz-api-kaynaklar%C4%B1-nas%C4%B1l-kullan%C4%B1l%C4%B1r-hava-durumu-68036a06d3e2?source=rss-1d20d304a24d------2</link>
            <guid isPermaLink="false">https://medium.com/p/68036a06d3e2</guid>
            <category><![CDATA[api]]></category>
            <category><![CDATA[flutter]]></category>
            <dc:creator><![CDATA[Buğrahan Karamollaoğlu]]></dc:creator>
            <pubDate>Thu, 13 Jun 2024 10:35:40 GMT</pubDate>
            <atom:updated>2024-06-13T10:35:40.420Z</atom:updated>
            <content:encoded><![CDATA[<h3>Ücretsiz API Kaynakları &amp; Nasıl Kullanılır? (Hava Durumu Uygulaması)</h3><p>Sıcaklıkların 40 dereceyi aştığı, her üç dakikada bir telefona girip hava durumuna baktığım bu kavurucu yaz günlerinde kendi hava durumu <a href="https://github.com/bugrahankaramollaoglu/weatherly">uygulamamı</a> (Weatherly) yazmaya karar verdim. API &amp; Json Handling temeller bilindiği müddetçe öğrenmesi ve uygulaması gayet kolay mekanizmalar fakat ilk kullanımda karmaşık gelebiliyor. Bu makalede bulduğum birbirinden güzel ücretsiz ve Türkçe API kaynaklarından ve basit düzeyde nasıl kullanılacağından bahsetmeye çalışacağım.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HIpzH49y-f6c50-MPO-_Gg.png" /></figure><p>Uzun uğraşlar sonucu denk geldiğim <a href="https://collectapi.com/tr/">https://collectapi.com/tr/</a> sitesinde karar kıldım. İçerisinde birbirinden güzel ve herkesin ilgisine hitap edebilecek alanlarda API’ler mevcut. Özellikle indie geliştiriciyseniz 7$ (10.000 req/mo) ve 49$ (200.000 req/mo) gibi premium paketlere ihtiyaç duymaksızın ayda 2500 request hakkı veren ücretsiz versiyonuyla portfolyönüze gayet güzel uygulamalar/websiteleri çıkartabilirsiniz. Unutmadan, API anahtarınıza erişebilmek için üye olmanız gerekiyor</p><p>Seçtiğim hava durumu API’si 7 günlük hava durumu tahmini, güncel tarihler, minimum/maksimum sıcaklıklar, nem oranı ve daha birçok farklı bilgiyle geliyor. Ayrıca farklı dillerde request atabilme seçeneğiniz de var. Fakat her halükarda API’ye hava durumu verilerini almak istediğiniz şehrin adıyla erişebiliyorsunuz. Bunun için şöyle bir yol izledim:</p><ol><li>Fiziksel konumumu enlem/boylam olarak aldım</li><li>Her şehrin enlem/boylam bilgilerinin key-value halinde tutulduğu bir map yarattım</li><li>Bu enlem/boylam verilerinden anahtara yani şehrin adına ulaşıp API çağrımı gerçekleştirdim</li></ol><p>Her şeyden önce uygulamamda cihazımın fiziksel konumu almak için izin istemek zorundaydım. Bunu <em>android/app/src/main</em> dizininde bulunan <strong>AndroidManifest.xml </strong>üzerinden yapıyorsunuz:</p><pre>    &lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot; /&gt;<br>    &lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot; /&gt;<br>    &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;</pre><blockquote>FINE_Location burada hassas konumunuzu, COARSE_Location ise yaklaşık konumunuzu hesaplıyor.</blockquote><p>İzinleri aldıktan sonra konumumu bulacak fonksiyonu yazdım. Bu fonksiyon <em>Geolocator </em>paketini kullanıyor:</p><pre>Future&lt;void&gt; _getCurrentLocation() async {<br>    try {<br>      LocationPermission permission = await Geolocator.requestPermission();<br><br>      if (permission == LocationPermission.denied) {<br>        setState(() {<br>          _currentLocation = &#39;İzin Verilmedi&#39;;<br>        });<br>        return;<br>      }<br><br>      Position position = await Geolocator.getCurrentPosition(<br>          desiredAccuracy: LocationAccuracy.high);<br>      List&lt;Placemark&gt; placemarks =<br>          await placemarkFromCoordinates(position.latitude, position.longitude);<br><br>      String? location;<br><br>      String placemarksStr = placemarks.toString();<br>      List&lt;String&gt; words = placemarksStr.split(&#39; &#39;);<br><br>      for (int i = 0; i &lt; words.length; i++) {<br>        words[i] = words[i].toLowerCase().replaceAll(&#39;,&#39;, &#39;&#39;);<br>      }<br><br>      for (String word in words) {<br>        String lowercaseWord = word.toLowerCase();<br><br>        if (_cities.contains(lowercaseWord)) {<br>          location =<br>              _cities.firstWhere((city) =&gt; city.toLowerCase() == lowercaseWord);<br>          break;<br>        }<br>      }<br><br>      if (location != null &amp;&amp; location.isNotEmpty) {<br>        setState(() {<br>          _currentLocation = location;<br>        });<br>      } else {<br>        setState(() {<br>          _currentLocation = &#39;Unknown&#39;;<br>        });<br>      }<br>    } catch (e) {<br>      setState(() {<br>        _currentLocation = &#39;Error getting location&#39;;<br>      });<br>    }<br>    _getLongLat(_currentLocation);<br>  }</pre><p>Enlem/boylam bilgilerim sayesinde bulunduğum şehri öğrendikten sonra API çağrımı yapabilecek hale gelmiştim:</p><pre>Uri.parse(&#39;https://api.collectapi.com/weather/getWeather?data.lang=tr&amp;data.city=$locationn&#39;)</pre><p>Fakat sadece fiziksel konumun hava durumunu öğrenmenin yetersiz kalacağını düşündüğümden bunu 81 şehirle genişlettim:</p><pre>Map&lt;String, LatLng&gt; coordinates = {<br>  &quot;Adana&quot;: const LatLng(37.0, 35.3213),<br>  &quot;Adıyaman&quot;: const LatLng(37.7648, 38.2765),<br>  &quot;Afyonkarahisar&quot;: const LatLng(38.756, 30.543),<br>  &quot;Ağrı&quot;: const LatLng(39.7217, 43.0567),<br>  &quot;Aksaray&quot;: const LatLng(38.3687, 34.037),<br>  &quot;Kahramanmaraş&quot;: const LatLng(37.5833, 36.9333),<br>  &quot;Karabük&quot;: const LatLng(41.2, 32.6333),<br>  &quot;Karaman&quot;: const LatLng(37.1759, 33.2287),<br>  &quot;Kars&quot;: const LatLng(40.5927, 43.0772),<br>  &quot;Kastamonu&quot;: const LatLng(41.3887, 33.7827),<br>  &quot;Kayseri&quot;: const LatLng(38.737, 35.4977),<br>  &quot;Kırıkkale&quot;: const LatLng(39.8578, 33.5109),<br>  &quot;Kırklareli&quot;: const LatLng(41.7333, 27.2167),<br>  &quot;Kırşehir&quot;: const LatLng(39.1458, 34.1638),<br>  &quot;Kilis&quot;: const LatLng(36.716, 37.115),<br>  &quot;Kocaeli&quot;: const LatLng(40.8533, 29.8815),<br>  &quot;Konya&quot;: const LatLng(37.8664, 32.4922),<br>  &quot;Kütahya&quot;: const LatLng(39.4214, 29.9838),<br><br>  [...]<br><br>};</pre><p>Daha sonra yazdığım AlertDialog ile bu şehirlerden herhangi birini seçen kullanıcı artık o şehrin hava durumunu görebiliyordu.</p><p>İki şekilde de alabildiğim şehir bilgisiyle yaptığım API çağrısı bana Json formatında uzun bir response body döndürdü.</p><pre>{<br>  &quot;success&quot;: true,<br>  &quot;city&quot;: &quot;ankara&quot;,<br>  &quot;result&quot;: [<br>    {<br>      &quot;date&quot;: &quot;13.06.2024&quot;,<br>      &quot;day&quot;: &quot;Perşembe&quot;,<br>      &quot;icon&quot;: &quot;https://cdnydm.com/permedia/LC1i84c3Z2MtLUDNbzWz8A.png?size=512x512&quot;,<br>      &quot;description&quot;: &quot;açık&quot;,<br>      &quot;status&quot;: &quot;Clear&quot;,<br>      &quot;degree&quot;: &quot;33.85&quot;,<br>      &quot;min&quot;: &quot;20.59&quot;,<br>      &quot;max&quot;: &quot;34.43&quot;,<br>      &quot;night&quot;: &quot;23.85&quot;,<br>      &quot;humidity&quot;: &quot;25&quot;<br>    },<br>    {<br>      &quot;date&quot;: &quot;14.06.2024&quot;,<br>      &quot;day&quot;: &quot;Cuma&quot;,<br>      &quot;icon&quot;: &quot;https://cdnydm.com/permedia/zvWjzjmkp5WUUEWob4d48Q.png?size=512x512&quot;,<br>      &quot;description&quot;: &quot;şiddetli yağmur&quot;,<br>      &quot;status&quot;: &quot;Rain&quot;,<br>      &quot;degree&quot;: &quot;31.12&quot;,<br>      &quot;min&quot;: &quot;17.87&quot;,<br>      &quot;max&quot;: &quot;33.47&quot;,<br>      &quot;night&quot;: &quot;18.3&quot;,<br>      &quot;humidity&quot;: &quot;29&quot;<br>    },<br>   <br>    [...]<br><br>  ]<br>}</pre><p>Şimdi asıl iş bu json’dan ekranda görüntülenecek verileri çekmeye yani Json Parsing’e gelmişti:</p><pre>Map&lt;String, dynamic&gt; jsonMap = json.decode(_apiResponse!);<br><br> if (jsonMap.containsKey(&#39;result&#39;) &amp;&amp; jsonMap[&#39;result&#39;].isNotEmpty) {<br>        Map&lt;String, dynamic&gt; firstResult = jsonMap[&#39;result&#39;][0];<br><br>        setState(() {<br>          currentWeather.date = firstResult[&#39;date&#39;] ?? &#39;&#39;;<br>          currentWeather.day = firstResult[&#39;day&#39;] ?? &#39;&#39;;<br>          currentWeather.icon = firstResult[&#39;icon&#39;] ?? &#39;&#39;;<br>          currentWeather.description = firstResult[&#39;description&#39;] ?? &#39;&#39;;<br>          currentWeather.status = firstResult[&#39;status&#39;] ?? &#39;&#39;;<br>          currentWeather.degree = firstResult[&#39;degree&#39;] ?? &#39;0&#39;;<br>          currentWeather.night = firstResult[&#39;night&#39;] ?? &#39;0&#39;;<br>          currentWeather.humidity = firstResult[&#39;humidity&#39;] ?? &#39;&#39;;<br><br>          _currentDegree = double.parse(currentWeather.degree).toInt();<br>          currentWeather.date = formatDate(currentWeather.date);<br>        });<br>      } else {<br>        throw Exception(&#39;Invalid response structure&#39;);<br>      }<br>}</pre><p>Yazdığım parsing fonksiyonuyla verileri de başarıyla çektikten sonra tek iş tasarımı ve temayı halletmek oldu:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/405/1*0yspdVhOWmWtcIxeNUTIaw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/422/1*rSfLQnH1RPu02cQxs28XtA.png" /><figcaption>Weatherly</figcaption></figure><p>Kaynak kodlarını girişte paylaştığım bu uygulama basit de olsa API kullanımı hakkında bir çerçeve çiziyor. Şimdilik bu kadar, görüşmek üzere!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=68036a06d3e2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Makefile Tutorial]]></title>
            <link>https://medium.com/@bugrahankaramollaoglu/makefile-tutorial-e95b25078633?source=rss-1d20d304a24d------2</link>
            <guid isPermaLink="false">https://medium.com/p/e95b25078633</guid>
            <category><![CDATA[makefile]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Buğrahan Karamollaoğlu]]></dc:creator>
            <pubDate>Sat, 10 Feb 2024 18:15:45 GMT</pubDate>
            <atom:updated>2024-06-13T12:03:21.679Z</atom:updated>
            <content:encoded><![CDATA[<p>This article will explain what Make is, why it’s used, what is its alternative(s) and how to use makefiles in 7 modules. These modules will go from simple to complicated — I’ll try to make sure offering a comprehensive understanding of makefiles. Especially if you are a starter, I have no doubt you’ll learn a lot. Here are the <a href="https://github.com/bugrahankaramollaoglu/makefile-exercises">source codes</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*UKyd9rkJ9gOxb8xEqDB8QQ.png" /><figcaption>AI generated, hence the typo</figcaption></figure><p>First things first, Make is a script automatization technique invented by Stuart Feldman back in 70’s when working at Bell Labs. Just as Fertile Crescent is seen as the cradle of civilizations, Bell Labs is the cradle of computer science. UNIX (which will later be Torvald’s inspirer), C/C++ are all inventions of people from there. It is used in UNIX environments (Linux&amp;Mac).</p><p>Make comes built-in in UNIX and here is how to check your Make version</p><pre>make -v <br><br>GNU Make 4.3<br>Built for x86_64-pc-linux-gnu<br>Copyright (C) 1988-2020 Free Software Foundation, Inc.<br>License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;<br>This is free software: you are free to change and redistribute it.<br>There is NO WARRANTY, to the extent permitted by law.</pre><p>It is primarily used to compile (mostly) C/C++ source codes en masse and generating an output file. Compiling a C/C++ file is normally quite easy with mere use of terminal</p><pre>gcc -Wextra main.c -o main</pre><p>But what if we need to compile dozens of .c file if not hundreds at once? Writing the name of each file is of course not the way to go, so here we are aided by <strong>Makefiles</strong>. Let’s compile our <strong>main.c </strong>file using makefile .</p><h4><strong>Example One — Basics</strong></h4><p>First we need to create a file called <em>Makefile</em>, <em>makefile</em> or <em>GNUmakefile</em>. All three will be seen as a valid makefile by your OS but ‘Makefile’ is almost always used. You can use <strong>make -f </strong>command to choose any other file as your makefile but that is way too detail. Our makefile will suffice to look like this</p><pre>CC = gcc # fun fact! if you don&#39;t specify, default compiler is cc<br><br>all: program<br><br>program: main.c<br> ${CC} main.c -o program # this line is the purpose of the whole file<br><br>clean:<br> rm -rf program</pre><p>Let’s analyze our makefile</p><ul><li>We have avariableCC . Lines used with (=) operator are called variables in a makefile. It’ll later be enough to say ${CC} (or $(CC) or $CC) to mean ‘gcc’.</li><li>We have also commands. Lines used with (:) are called commands. They will later be used with command make to execute different sorts of execution blocks. What you write after a command is called dependency. A dependency, by its nature, is bound to its command. Make makes sure the dependency(ies) of a command is executed before executing the command itself. In our example, command programis executed before running command all. Similarly, command program is executed only after Make checks a) there is a file named main.c b) there are some changes in this main.c. This solves a problem called relink , which I will later dive into.</li><li>Command clean works when user wants to clean the main.out file and go back to the initial status of the project.</li></ul><blockquote>If you want to execute a certain command, type it after keyword Make. i.e: <br>make clean<br>make myCommand …<br><strong>! just saying &lt;make&gt; always executes automatically &lt;make all&gt; !</strong></blockquote><p>Then, we need to put our main.c file in the same directory, ready to be compiled with the command make.</p><h4>Example Two —Multiple Files</h4><p>Imagine we have three .c files:</p><ul><li>main.c</li></ul><pre>int main()<br>{<br> printf(&quot;%d\n&quot;, ft_strlen(&quot;bugra&quot;));<br> ft_putchar(&#39;c&#39;);<br> ft_putchar(&#39;\n&#39;);<br>}</pre><ul><li>file1.c</li></ul><pre>int ft_strlen(char *str)<br>{<br> int i = 0;<br> while (str[i])<br>  i++;<br> return i;<br>}</pre><ul><li>file2.c</li></ul><pre>void ft_putchar(char c)<br>{<br> write(1, &amp;c, 1);<br>}</pre><p>Now, normally — we’d compile these like</p><pre>gcc file1.c file2.c main.c -o program</pre><p>But no need for verbosity when makefiles are cut out tools for the job</p><pre>CC = gcc<br><br>CFLAGS = -Wall -Werror<br><br>all: program<br><br>program: main.c file1.c file2.c<br> $(CC) main.c file1.c file2.c -o program<br><br>clean:<br> rm -f program</pre><p>The gist of above makefile is the indirectional command hierarchy and dependencies. By declaring main.c, file1.c and file2.c as dependencies for the command program, we are avoiding what is called relink, which occurs when users are able executemake again and again though no changes made in the files — which is something we don’t want. By building an indirectionate relation, changes are always checked before execution of main make command.</p><h4>Example Three - Source Files under a Variable</h4><p>By fetching source files from a directory, we don’t have to write name of each file</p><pre>CC = gcc<br><br>SRC_DIR = src<br><br># directory where .o files will be extracted to<br>OBJ_DIR = obj<br><br>SRC_FILES = $(wildcard $(SRC_DIR)/*.c)<br># or you could say<br># SRC_FILES = $(shell ls $(SRC_DIR)/*.c)<br><br>OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))<br><br>all: program<br><br>program: $(OBJ_FILES)<br> $(CC) -o program $(OBJ_FILES)<br> @echo &quot;\033[32mCompiled ✅\033[0;37m&quot;<br><br><br># -p means ignore parent directory if extant<br>$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c<br> mkdir -p $(OBJ_DIR)<br> $(CC) -c $&lt; -o $@<br><br>clean:<br> @echo &quot;\033[0;31mCleaning objects🧹&quot;<br> rm -rf program $(OBJ_DIR)<br> <br>fclean: clean<br> @echo &quot;\033[0;31mRemoving $(NAME) 🗑\033[0;37m&quot;</pre><p>Let’s analyze this makefile</p><ul><li>We first defined two directories : SRC_FILES, from which to take source files and OBJ_DIR, in which the .out files will be written</li><li>$(OBJ_DIR)/%.o : puts all files ending with .o in the OBJ_DIR/ directory</li><li>$&lt; -o $@ : these are called <em>automatic variables</em> and are used as shortcuts. For instalce <strong>$&lt;</strong> refers to the first dependency in the rule and $@ to the target of the file, in here program</li></ul><pre># most important automatic variables in makefile are below<br>$@  denotes the target (file that rule updates or creates)<br>$&lt;  denotes the first dependency of a rule<br>$^  denotes all the dependencies of a rule<br>$?  denotes all the dependencies newer than the target</pre><h4>Example Four - Phony</h4><p>We also have another conventional feature: phony</p><pre>CC = gcc<br><br>CFLAGS = -Wall -Werror<br><br>all: program<br><br>program: main.c file1.c file2.c<br> $(CC) main.c file1.c file2.c -o program<br><br>clean:<br> rm -f program<br><br>.PHONY: all clean<br><br></pre><p>We said that using make with a command name executes that spesific command. But what if user has a file with the same name of one of the commands? That’s what phony exists for. By adding this line, you can safely use make all and make clean without worrying there are files with such names</p><h4>Example Five — Conditions</h4><p>You can also use conditions in your makefile for spesific situations</p><pre>CC = gcc<br><br>CFLAGS = -Wall<br><br>SRC_DIR = src<br><br>INC_DIR = include<br><br>OBJ_DIR = obj<br><br># if it is debugged, compile with -g flag<br>DEBUG ?= 0<br>ifeq ($(DEBUG), 1)<br>    CFLAGS += -g<br> @echo asdasdasd<br>endif<br><br>SRC_FILES = $(wildcard $(SRC_DIR)/*.c)<br><br>OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))<br><br>all: program<br><br>program: $(OBJ_FILES)<br> $(CC) -o program $(OBJ_FILES)<br><br>$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c<br> mkdir -p $(OBJ_DIR)<br> $(CC) -I$(INC_DIR) -c $&lt; -o $@<br><br>clean:<br> rm -rf program $(OBJ_DIR)<br><br>fclean: clean<br> rm -rf program</pre><p>If user decides to use this makefile under debug mode, he should say</p><pre>make DEBUG=1</pre><h4>Example Six — Implicit Rules</h4><p>Implicit rules are rules that you imply the make to do the job by setting predefined dependencies and targets, all without writing user-defined, explicit rules</p><pre>CC = gcc<br><br>SRCS = main.c file1.c file2.c<br><br>OBJS = $(SRCS:.c=.o)<br><br>all: program<br><br>program: $(OBJS)<br> $(CC) $(OBJS) -o program<br><br># that is implicit rule<br>%.o: %.c<br> $(CC) -c $&lt; -o $@<br><br>re: clean all<br><br>clean:<br> rm -f program<br> rm -f *.o</pre><p>That way makefile automatically generates .o files from .c files without user having to write a compiling command</p><h4>Example Seven — Wildcards</h4><p>You can use a keyword called wildcard that will comprehense your multiple files at once</p><pre>SRCS = main.c file1.c file2.c # ya da<br>SRCS = $(wildcard *.c) <br><br>OBJS = $(SRCS:.c=.o)<br><br>all: program<br><br>program: $(OBJS)<br> $(CC) $(OBJS) -o program<br><br>%.o: %.c<br> $(CC) -c $&lt; -o $@<br><br>re: clean all<br><br># mesela *.o demek .o ile bütün her şey demektir<br>clean:<br> rm -f *.o</pre><p>That way it will count all the files that end with .c. This is actually a bash technique frequently used with makefiles for it makes things much easier and code less shorter.</p><p>There are still hundreds of more features and details to these, these are just what I generally use if I can’t convince AI to write a makefile for me. Here is my makefile notes and in it you’ll find some (probably much better) sources I benefited for this article</p><p><a href="https://bugrahankaramollaoglu.notion.site/makefile-notlar-346c7ce6374a44c08f9b26f9ffe0b76c?pvs=74">my notion notes on makefile</a></p><p><a href="https://github.com/bugrahankaramollaoglu/my-programming-notes">my other notes about CS</a></p><p>bye!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e95b25078633" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ListView and RecyclerView — Android]]></title>
            <link>https://medium.com/@bugrahankaramollaoglu/listview-and-recyclerview-android-78e4d38b23c6?source=rss-1d20d304a24d------2</link>
            <guid isPermaLink="false">https://medium.com/p/78e4d38b23c6</guid>
            <category><![CDATA[listview]]></category>
            <category><![CDATA[recyclerview]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Buğrahan Karamollaoğlu]]></dc:creator>
            <pubDate>Wed, 31 Jan 2024 11:58:54 GMT</pubDate>
            <atom:updated>2024-02-10T18:45:29.992Z</atom:updated>
            <content:encoded><![CDATA[<h3>ListView and RecyclerView</h3><p>There are two rival UI components in Android: <a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=&amp;ved=2ahUKEwiBqaTysoeEAxWyQvEDHe9LCHAQFnoECBUQAQ&amp;url=https%3A%2F%2Fdeveloper.android.com%2Freference%2Fandroid%2Fwidget%2FListView&amp;usg=AOvVaw2iFKnkbMHrVy9m00vFJFPf&amp;opi=89978449">ListView</a> and <a href="https://developer.android.com/reference/android/support/v7/widget/RecyclerView#glossary-of-terms">RecyclerView</a>. Both are used to display scrollable list items. While mainly similar, there are some critic differences.</p><p>Though relatively harder to implement, RecyclerView is usually preferred when it comes to performance issues. The other, on the other hand, is opted when dealing with smaller and primitive data sets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6IYGZs6XX9fqtDMfWPTrtA.jpeg" /></figure><p>I will try to elaborate on the points they diverge and plainly explain how they are implemented, especially with <strong>built-in</strong> vs. <strong>custom</strong> parameters. I will use Kotlin as the language. Here are some differences</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/934/1*0TX42c6NDIFo7uPE7yIt6w.png" /><figcaption>main differences</figcaption></figure><p>The keystone is to keep in mind the fact that RecyclerView is costly, yet the efficient one.</p><p>Now, let’s see their implementations.</p><p>To implement a ListView with a built-in data type parameter (like a List&lt;String,Integer,Double&gt; etc.), you need only the listView widget and a layout file, nothing else.</p><p>First, place the ListView component in your activity/fragment:</p><pre># activity_layout.xml<br><br>&lt;ListView<br>        android:id=&quot;@+id/list_view&quot;<br>        android:layout_width=&quot;match_parent&quot;<br>        android:layout_height=&quot;match_parent&quot; /&gt;</pre><p>We also need to create a layout file in res/layout that will symbolize a single item</p><pre># list_view.xml <br><br>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br>&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br>    android:layout_width=&quot;match_parent&quot;<br>    android:layout_height=&quot;wrap_content&quot;<br>    android:padding=&quot;15dp&quot;&gt;<br><br>    &lt;TextView<br>        android:id=&quot;@+id/color_textview&quot;<br>        android:layout_width=&quot;wrap_content&quot;<br>        android:layout_height=&quot;wrap_content&quot;<br>        android:text=&quot;COLOR&quot;<br>        android:textAlignment=&quot;center&quot;<br>        android:textSize=&quot;24sp&quot; /&gt;<br><br>&lt;/RelativeLayout</pre><p>Then, in our, let’s say Activity, implement it</p><pre>// MainActivity.kt <br><br>class MainActivity : AppCompatActivity() {<br>    override fun onCreate(savedInstanceState: Bundle?) {<br>        super.onCreate(savedInstanceState)<br>        setContentView(R.layout.activity_main)<br><br>        // we can create an array whose items will be listed<br>        val colors = listOf(&quot;red&quot;, &quot;purple&quot;, &quot;pink&quot;, &quot;white&quot;, &quot;cyan&quot;)<br>        <br>        // here we need an adapter variable. simple_list_item_1<br>        val listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, colors)<br><br>        val list_view = findViewById&lt;ListView&gt;(R.id.list_view)<br>        list_view.adapter = listAdapter<br>        // list_view.setAdapter(listAdapter) // alternatively<br><br>        list_view.setOnItemClickListener { parent, view, position, id -&gt;<br>            val selected_item = listAdapter.getItem(position)<br>            Toast.makeText(this, &quot;You clicked ${selected_item}.&quot;, Toast.LENGTH_SHORT).show()<br>        }<br>    }<br>}</pre><p>and these steps suffice to display a most-basic list of items</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dq_BJX7ypAQtniIXb1kOpw.jpeg" /></figure><p>Pretty simple, isn’t it? Now let’s dive into the realm of custom classes. We now shall use a custom class, say a User class, to list in our list view. Generally, bear in mind that if you are going to use a list whose items are sophisticated, that is, storing multiple properties — you would and should use RecyclerView. Yet, here is how to implement it with ListView.</p><p><strong>Unlike simple data types, you will have to implement two more features to use your custom class: </strong>The class and an Adapter. First you need to create the class itself. Our example has a <strong>name</strong> and <strong>age</strong> property.</p><pre>// User.kt<br><br>data class User(val name: String, val age: Int)</pre><p>Then, likewise before, create a layout file so that you will decide how to locate and use each property in a single item row</p><pre># list_row.xml <br><br>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br>&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br>    android:layout_width=&quot;match_parent&quot;<br>    android:layout_height=&quot;wrap_content&quot;&gt; // this is crucial<br><br>    &lt;TextView<br>        android:id=&quot;@+id/user_name&quot;<br>        android:layout_width=&quot;wrap_content&quot;<br>        android:layout_height=&quot;wrap_content&quot;<br>        android:padding=&quot;10dp&quot;<br>        android:text=&quot;NAME&quot;<br>        android:textAlignment=&quot;center&quot;<br>        android:textSize=&quot;24sp&quot;<br>        android:textStyle=&quot;bold&quot; /&gt;<br><br>    &lt;TextView<br>        android:id=&quot;@+id/user_age&quot;<br>        android:layout_width=&quot;wrap_content&quot;<br>        android:layout_height=&quot;wrap_content&quot;<br>        android:layout_toRightOf=&quot;@id/user_name&quot;<br>        android:padding=&quot;10dp&quot;<br>        android:text=&quot;AGE&quot;<br>        android:textAlignment=&quot;center&quot;<br>        android:textSize=&quot;24sp&quot; /&gt;<br><br>&lt;/RelativeLayout&gt;</pre><p>Now it’s time you created the UserAdapter. It will be used when you create&amp;bind each item from your source right into your list.</p><pre>// UserAdapter.kt <br><br>class UserAdapter(context: Context, users: List&lt;User&gt;) :<br>    ArrayAdapter&lt;User&gt;(context, R.layout.list_row, users) {<br>    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {<br>        var view = convertView<br>        val viewHolder: ViewHolder // you should use viewHolder for user-defined data types<br><br>        if (view == null) {<br>            view = LayoutInflater.from(context).inflate(R.layout.list_row, parent, false)<br>            viewHolder = ViewHolder()<br>            viewHolder.nameTextView = view.findViewById(R.id.user_name)<br>            viewHolder.ageTextView = view.findViewById(R.id.user_age)<br>            view.tag = viewHolder<br>        } else {<br>            viewHolder = view.tag as ViewHolder<br>        }<br><br>        // current user to be displayed on the list<br>        val user = getItem(position)<br>        // and its properties<br>        viewHolder.nameTextView?.text = user?.name<br>        viewHolder.ageTextView?.text = &quot;, ${user?.age} years old.&quot;<br><br>        return view!!<br>    }<br><br>    // ViewHolder pattern for efficient view recycling<br>    private class ViewHolder {<br>        var nameTextView: TextView? = null<br>        var ageTextView: TextView? = null<br>    }<br>}</pre><p>Finally in your activity/fragment, use it like</p><pre>// MainActivity.kt<br><br>class MainActivity : AppCompatActivity() {<br>    override fun onCreate(savedInstanceState: Bundle?) {<br>        super.onCreate(savedInstanceState)<br>        setContentView(R.layout.activity_main)<br><br>        val list_view = findViewById&lt;ListView&gt;(R.id.list_view)<br><br>        val user_list = listOf&lt;User&gt;(<br>            User(&quot;Edward&quot;, 22),<br>            User(&quot;John&quot;, 11),<br>            User(&quot;Constable&quot;, 46)<br>        )<br><br>        // creating &amp; setting the adapter <br>        val list_adapter = UserAdapter(this, user_list)<br>        list_view.setAdapter(list_adapter)<br><br>        list_view.setOnItemClickListener { parent, view, position, id -&gt;<br>            val selected_item = user_list[position]<br>            /* do what you gonna d- */<br>        }<br><br>        list_view.setOnItemLongClickListener { parent, view, position, id -&gt;<br>            val selected_item = user_list[position]<br>            /* do what you gonna d- */<br>            false<br>        }<br>    }<br>}</pre><p>Here is the outcome:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Htb94N1U9qrBoE3yxSttCg.jpeg" /></figure><p>This was the core of ListViews. Now I will explain RecyclerViews with a custom class implementation. Let’s once again suppose we have list of type User (<strong>List&lt;User&gt;</strong>) and we want to display content of this list. We ought to</p><ul><li>Create the User class</li></ul><pre>data class User(private val name, private val age)</pre><ul><li>Create UserAdapter, implement its member methods</li></ul><pre>class UserAdapter(private val userList: List&lt;User&gt;) :<br>    RecyclerView.Adapter&lt;UserAdapter.UserViewHolder&gt;() {<br><br>    class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {<br>        val nameTextView: TextView = itemView.findViewById(R.id.nameTextView)<br>        val ageTextView: TextView = itemView.findViewById(R.id.ageTextView)<br>    }<br><br>    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {<br>        val itemView = LayoutInflater.from(parent.context)<br>            .inflate(R.layout.user_item, parent, false)<br>        return UserViewHolder(itemView)<br>    }<br><br>    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {<br>        val currentUser = userList[position]<br>        holder.nameTextView.text = currentUser.name<br>        holder.ageTextView.text = currentUser.age.toString()<br>    }<br><br>    override fun getItemCount(): Int {<br>        return userList.size<br>    }<br>}</pre><ul><li>In Activity create and populate a list of User</li></ul><pre>val users = listOf(User(&quot;Bugra&quot;, 25), User(&quot;Cemre&quot;, 30), &quot;Ugur&quot;, 22))</pre><ul><li>Finally, bind the list with our RecyclerView widget via adapter</li></ul><pre>val adapter = UserAdapter(users)<br>recyclerView.adapter = adapter</pre><p>With these steps, we have completed the implementation of our RecyclerView with our custom class. Becomes pretty plain once you familiarize yourself over repetitive exercises. See you in the next article 👋</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=78e4d38b23c6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pillars of OOP]]></title>
            <link>https://medium.com/@bugrahankaramollaoglu/pillars-of-oop-ed42fb6d29e8?source=rss-1d20d304a24d------2</link>
            <guid isPermaLink="false">https://medium.com/p/ed42fb6d29e8</guid>
            <category><![CDATA[oop]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[inheritance]]></category>
            <category><![CDATA[cpp]]></category>
            <dc:creator><![CDATA[Buğrahan Karamollaoğlu]]></dc:creator>
            <pubDate>Wed, 17 Jan 2024 22:54:35 GMT</pubDate>
            <atom:updated>2025-08-16T20:11:16.214Z</atom:updated>
            <content:encoded><![CDATA[<p>What is OOP? Object Oriented Programming is a relatively new programming paradigm coined by Alan Kay in the ‘60s.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/972/1*vPrBye_aBfUXAVCodQcnFg.png" /><figcaption>Alan Kay in the ‘60s</figcaption></figure><p>However, the concept started forming earlier, around the 1950&#39;s. Its roots can be traced back to John McCarthy who invented the LISP programming language. Though not technically the same, LISP set the ground for the emerge of modern-day OOP. The first closest language in the real sense was Simula, developed by Ole-Johan Dahl and Kristen Nygaard. Up until ’90s, the %99 of the programs in the world was procedural. Then came the famous modern-languages like C++, Java, C#, Python and JavaScript which all share the notion of OOP. It first came as an alternative to the existing paradigms like procedural programming (like C) where there is a strict linear flow of code or functional programming (like Haskell) that treats computation as the evaluation of mathematical functions. OOP then became immeasurably popular. For many experts, it still holds its lasting currency in the programming world.</p><p>OOP is basically the way of writing code with classes and objects that symbolize single units that are only meaningful in relation to one another. It harmonises programming with real-life concepts. It stands on the shoulders of four fundamental concepts:</p><ol><li><em>Polymorphism</em> → the idea of having multiple forms of a method. To understand it better, we shall think of an Animal Kingdom. Though every animal inherits from at least one Base class (Animal-ness), they all must have their unique features as well. Cats meow, lions roar, fish — well, they just swim. Therefore, the programmer must find a way to do some specializations for each one of them accordingly. Overriding the methods to change the morphology in each of these derived classes is called polymorphism.</li><li><em>Abstraction</em> → the idea of hiding unnecessary information from the user. Imagine you are driving a car. Unless you are a qualified mechanic or a keen hobbist, most people just need to know about a handful of information in order to drive. You don’t need to know about the engineering of your tires or the mathematical calculations of your fuel use — these are hidden from you. That is abstraction in a nutshell — which itself, is nutshell-ing.</li><li><em>Encapsulation</em> → the idea of combining the attributes and methods in a single unit, namely your class. Think of a big library. Suppose all single books are either data members or methods but when encapsulated together, they create another entity — the library. Encapsulation also allows you to decide on the secrecy of your books. Some of them are accessable by anyone (public), some only allowed for the students (protected) and some only within the reach of the librarian (private).</li><li><em>Inheritance</em> → the idea of transferring information from an older class to the newly-created ones. Imagine the aforementioned animal kingdom (that being your base class) and many different species under it (all the derived classes). They all <strong><em>inherit</em></strong> from your Animal class, literally. That means they have all the information that their parent has but they may have their own features (methods) as well.</li></ol><p>these are merely shallow definitions to familiarize newcomers with the basic concepts of OOP. now let’s see each in code to get the gist of them!</p><h3>1) POLYMORPHISM</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/748/1*EUJOjQamuqQgqmsMvAosFg.png" /></figure><p>a. compile-time polymorphism:</p><p>a1. Function Overloading: It allows us to rewrite a method in the same scope with the same name as long as their return types and/or parameter(s) are not identical.</p><pre>class Base {<br>  public:<br>    void fun(int a) {<br>      std::cout &lt;&lt; &quot;this is &quot; &lt;&lt; a &lt;&lt; std::endl;<br>    }<br>    void fun(float b) {<br>      std::cout &lt;&lt; &quot;this is &quot; &lt;&lt; b &lt;&lt; std::endl;<br>    }<br>};<br><br>int main() {<br>  Base base;<br><br>  base.fun(53);<br>  base.fun(2.99);<br>}</pre><p>a2. Operator Overloading: It allows us to rewrite an operator so that they might gain extra features</p><pre>class Deneme {<br> public:<br>  int val;<br><br>  Deneme() {<br>   val = 5;<br>  }<br>  <br>  void operator--() {<br>   val = val - 3;<br>  }<br>};<br><br>int main() {<br> Deneme deneme;<br> --deneme;<br> std::cout &lt;&lt; deneme.val &lt;&lt; std::endl; // 2<br>}</pre><p>b. run-time polymorphism</p><p>b1. Function Overriding: It is termed as the redefinition of base class function in its derived class with the same signature i.e. return type and parameters.</p><pre>class Base {<br>  public:<br>    void func() {<br>      std::cout &lt;&lt; &quot;this is base func&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>class Derived : Base {<br>  public:<br>    void func() {<br>      std::cout &lt;&lt; &quot;this is derived func&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>int main() {<br>  Derived derived;<br>  derived.func(); // this is derived func<br><br> Base base;<br> base.func(); // this is base func<br>}</pre><p>Or if you use a pointer to the Base class, Base class’ function will be invoked</p><pre>class Base {<br>  public:<br>    void func() {<br>      std::cout &lt;&lt; &quot;this is base func&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>class Derived : public Base {<br>  public:<br>    void func() {<br>      std::cout &lt;&lt; &quot;this is derived func&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>int main() {<br>  Derived derived;<br>  Base *basePtr = &amp;derived;<br> basePtr-&gt;func(); // this is base func<br>}</pre><p>Or you can use <strong>::</strong> operator to access Base class through Derived class</p><pre>class Base {<br>  public:<br>    void func() {<br>      std::cout &lt;&lt; &quot;this is base func&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>class Derived : public Base {<br>  public:<br>    void func() {<br>      std::cout &lt;&lt; &quot;this is derived func&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>int main() {<br>  Derived derived;<br>  derived.func(); // this is derived func<br> derived.Base::func(); // this is base func<br>}</pre><p>b2. Virtual Methods: A virtual function is a member function that is declared in the base class using the keyword virtual and is re-defined (Overridden) in the derived class</p><pre>class Base {<br>  public:<br>    virtual void fun() {<br>      std::cout &lt;&lt; &quot;base fun() called&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>class Derived : Base {<br>  public:<br>    void fun() override {<br>      std::cout &lt;&lt; &quot;overridden fun() called&quot; &lt;&lt; std::endl;<br>    }<br>};<br><br>int main() {<br>  Base base;<br>  base.fun(); // base fun() called<br><br>  Derived derived;<br>  derived.fun(); // overridden fun() called<br>}</pre><p>there are more to <strong><em>virtual</em></strong> keyword, perhaps its best utility is that it allows the right function to be invoked when a function is called through an object with contradicting classes. let’s see how</p><pre>#include &lt;iostream&gt;<br><br>// imagine we have such a base class<br>class Base<br>{<br>public:<br> virtual void announce()<br> {<br>  std::cout &lt;&lt; &quot;hello from base&quot; &lt;&lt; std::endl;<br> }<br>};<br><br>// and such a derived class publicly inheriting<br>class Derived : public Base<br>{<br>public:<br> void announce()<br> {<br>  std::cout &lt;&lt; &quot;hello from derived&quot; &lt;&lt; std::endl;<br> }<br>};<br><br>int main()<br>{<br> // Base base;<br> // base.announce(); // hello from base<br><br> // Derived derived;<br> // derived.announce(); // hello from derived<br><br> // it is okay so far for we kept it simple<br> // but what if one would want to say<br><br> /*  we create an object with Base pointer but from Derived()<br>  class. it must say &quot;hello from derived&quot; since it is instantiated<br>  from Derived class. and actually it does, only thanks to the &quot;virtual&quot;<br>  keyword and the equality of names in the both classes. if we were to<br>  remove the virtual keyword from the function in the base class,<br>  obj-&gt;announce() would print &lt;hello from base&gt; because OS wouldn&#39;t know<br>  it is supposed to implicitly override the function according to the derived<br>  class. Or, another scenario - if we kept the virtual but assigned different<br>  names for the functions, it&#39;d still use Base&#39;s function. */<br> Base *obj = new Derived();<br> obj-&gt;announce(); <br>}</pre><h3>2) ABSTRACTION</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wFRElb38Y8CiO4wmEn-W4w.png" /></figure><p>There are two types of abstraction:</p><ol><li>data abstraction: it involves hiding the complex details of data and representing only the essential features. For instance user just creates objects from a certain class. S/he doesn’t need to know about the data types these properties are stored in, architecture and/or structure used in the class etc.</li></ol><pre>class Car {<br> private:<br>     std::string brand;<br>     int year;<br> <br> public:<br>     Car(std::string b, int y) : brand(b), year(y) {}<br> <br>     void displayInfo() {<br>         std::cout &lt;&lt; &quot;Brand: &quot; &lt;&lt; brand &lt;&lt; &quot;, Year: &quot; &lt;&lt; year &lt;&lt; std::endl;<br>     }<br>};</pre><p>2. process abstraction: it is where we shortcut certain executions using functions/methods. User only needs to know what a function does and not its content.</p><pre>int addNumbers(int a, int b) {<br>    return a + b;<br>}<br><br>int main() {<br>    int result = addNumbers(5, 7);<br>    <br>    std::cout &lt;&lt; &quot;Result: &quot; &lt;&lt; result &lt;&lt; std::endl;<br><br>    return 0;<br>}</pre><h3>3) INHERITANCE</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ehsxEuFiOnucBuktSFltCQ.png" /></figure><p>Inheritance is another pillar of OOP which means a class can inherit from another class. Therefore, it copies its attributes and methods but it can also add some extra features in future.</p><ol><li>public inheritance: it inherits all the public and protected members as public and protected respectively. however, private members are NOT inherited to the derived class.</li></ol><pre>class Animal {<br>public:<br>  void eat() { std::cout &lt;&lt; &quot;Animal is eating.&quot; &lt;&lt; std::endl; }<br>};<br><br>class Dog : public Animal {<br>public:<br>  void bark() { std::cout &lt;&lt; &quot;Woof!&quot; &lt;&lt; std::endl; }<br>};<br><br>// Usage:<br>Dog dog;<br>dog.eat();  // Inherited from Animal<br>dog.bark(); // Dog&#39;s own method</pre><p>2. private inheritance: the public and protected members of the base class are inherited as private members of the derived class.</p><pre>class Animal {<br>public:<br>  void eat() { std::cout &lt;&lt; &quot;Animal is eating.&quot; &lt;&lt; std::endl; }<br><br>protected:<br>  void sleep() { std::cout &lt;&lt; &quot;Animal is sleeping.&quot; &lt;&lt; std::endl; }<br>};<br><br>class Snake : private Animal {<br>public:<br>  void hiss() {<br>    std::cout &lt;&lt; &quot;SSSnake sound...&quot; &lt;&lt; std::endl;<br>    sleep();  // Inherited from Animal, but not accessible outside<br>  }<br>};<br><br>int main() {<br>  Snake snake;<br>  snake.hiss();  // OK<br>  // snake.eat();  // Error: eat() is private in Snake<br>}</pre><p>3. protected inheritance: the public and protected members of the base class are inherited as protected members of the derived class. The private members are NOT accessible by the derived class.</p><pre>class Shape {<br>protected:<br>  double width, height;<br>public:<br>  void setDimensions(double w, double h) { width = w; height = h; }<br>};<br><br>class Rectangle : protected Shape {<br>public:<br>  double getArea() const { return width * height; }<br>};</pre><h3>4) ENCAPSULATION</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VTfXPnCdFnsUqSJCf_Ssyw.png" /></figure><p>This is where the two main cores of a class (attributes &amp; methods) are bundled together and start acting like a single unit. Then, encapsulation permits us to control their accessibility &amp; modifiability.</p><ol><li>data hiding is where the attributes/data members of a class are made private, so they are not accessible from the outer scopes. This enables safer and integrated codes.</li></ol><pre>class Person {<br> private:<br>     int age;<br> <br> public:<br>     // ... public methods that interact with name and age<br>};</pre><p>2. the total opposite, encapsulation also offers an interface that allows the user to interact &amp; modify content. these are conventionall called <strong>getter()</strong> &amp; <strong>setter()</strong> functions</p><pre>class Person {<br>private:<br>    int age;<br><br>public:<br><br>    // getter() function for the data member<br>    int getAge() const {<br>        return age;<br>    }<br><br>    // setter() function for the data member<br>    void setAge(int newAge) {<br>        if (newAge &gt;= 0) {<br>            age = newAge;<br>        }<br>    }<br>};</pre><p>Encapsulation allows for three different levels of protection:</p><ol><li>public: variables defined under the public tag can be used in different scopes</li></ol><pre>class User {<br> public:<br>  int age;<br>};<br><br>int main() {<br> User u1;<br> u1.age = 30;<br> std::cout &lt;&lt; u1.age &lt;&lt; std::endl; // 30<br>}</pre><p>2. private: variables defined under private tag can only be called/modified through getter/setter functions</p><pre>class User {<br> private:<br>  int age;<br><br> public:<br>  int getAge() {<br>   return age;<br>  }<br>  void setAge(int _age) {<br>   age = _age;<br>  }<br><br>};<br><br>int main() {<br> User u1;<br> u1.setAge(30);<br> std::cout &lt;&lt; u1.getAge() &lt;&lt; std::endl; // 30<br>}</pre><p>3. protected: variables defined under protected tag can be accessed both by getter/setters and inheriting classes</p><pre>class BaseUser {<br>protected:<br>    int protectedAge;<br><br>public:<br>    void setProtectedAge(int _age) {<br>        protectedAge = _age;<br>    }<br><br>    int getProtectedAge() const {<br>        return protectedAge;<br>    }<br>};<br><br>class DerivedUser : public BaseUser {<br>public:<br>    void modifyProtectedAge() {<br>        protectedAge = 25; // we access it in the inheriting class<br>    }<br>};<br><br>int main() {<br>    DerivedUser u1;<br><br>  // because it is not public, we can&#39;t say<br>  // u1.protectedAge = 40;<br><br>  // but we can modify it through setters()<br>    u1.setProtectedAge(30);<br>  // reach it through getters()<br>    std::cout &lt;&lt; u1.getProtectedAge() &lt;&lt; std::endl;  // 30<br>    // or access through inheriting class&#39; object<br>  u1.modifyProtectedAge();<br>    std::cout &lt;&lt; u1.getProtectedAge() &lt;&lt; std::endl;  // 25<br><br>    return 0;<br>}</pre><p>So that was OOP in a nutshell. There might be slight errors and/or lacks— yet, thanks for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ed42fb6d29e8" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>