<?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"><channel><title><![CDATA[Elisha Codes]]></title><description><![CDATA[Let's go on a journey together and take notes of all the interesting technology we have around. My blog will have all my notes and understanding of Cyber Security, Web 3.0 &amp; Next.JS, Vue.JS]]></description><link>https://elisha.loktioncode.org</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1657385384557/YIVZGGfG1.png</url><title>Elisha Codes</title><link>https://elisha.loktioncode.org</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 05:58:34 GMT</lastBuildDate><atom:link href="https://elisha.loktioncode.org/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building an Aerial Crop Monitoring System with Raspberry Pi, NoIR Picamera and u-blox GPS: A Guide to DIY Precision Agriculture]]></title><description><![CDATA[In precision agriculture, monitoring crop health from an aerial perspective is invaluable. This project walks through building a compact aerial crop monitoring system using a Raspberry Pi Zero 2 W, u-blox NEO-6M GPS module, and NoIR Picamera. With th...]]></description><link>https://elisha.loktioncode.org/building-an-aerial-crop-monitoring-system-with-raspberry-pi-noir-picamera-and-u-blox-gps-a-guide-to-diy-precision-agriculture</link><guid isPermaLink="true">https://elisha.loktioncode.org/building-an-aerial-crop-monitoring-system-with-raspberry-pi-noir-picamera-and-u-blox-gps-a-guide-to-diy-precision-agriculture</guid><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[agriculture]]></category><category><![CDATA[iot project]]></category><category><![CDATA[iot]]></category><category><![CDATA[gps]]></category><category><![CDATA[rpiblogs]]></category><category><![CDATA[Python]]></category><category><![CDATA[noir]]></category><dc:creator><![CDATA[Elisha Bere]]></dc:creator><pubDate>Sat, 26 Oct 2024 19:37:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729971156865/3c84c2e0-3f50-4138-8ba2-18750cd8c76c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In precision agriculture, monitoring crop health from an aerial perspective is invaluable. This project walks through building a compact aerial crop monitoring system using a <strong>Raspberry Pi Zero 2 W</strong>, <strong>u-blox NEO-6M GPS module</strong>, and <strong>NoIR Picamera</strong>. With this setup, we'll capture GPS-tagged multispectral images to analyze crop stress, focusing on the red band data to detect potential vegetation issues.</p>
<p>This guide covers hardware setup, configuring serial communication on the Raspberry Pi, connecting the GPS module, and using basic Python code to retrieve GPS coordinates. Along the way, I'll share the challenges I faced in integrating the GPS module, configuring <code>ttyAMA0</code> for serial communication, and building a stable power supply.</p>
<h2 id="heading-hardware-setup">Hardware Setup</h2>
<p>To achieve a lightweight, reliable aerial setup, here’s the equipment I used:</p>
<ul>
<li><p><strong>Raspberry Pi Zero 2 W</strong></p>
</li>
<li><p><strong>u-blox NEO-6M GPS Module</strong></p>
</li>
<li><p><strong>NoIR Picamera</strong> (for near-infrared imaging)</p>
</li>
<li><p><strong>Custom Power Supply</strong> (ensures stable power during flight)</p>
</li>
<li><p>Stable drone to attach the setup on</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729969918159/fd04d0de-2101-491d-b24b-145a97dffaaf.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-challenges-and-solutions">Challenges and Solutions</h3>
<ol>
<li><p><strong>Finding Reliable Information</strong>: Many sources were outdated or incomplete regarding u-blox GPS setup with the Raspberry Pi Zero 2 W.</p>
</li>
<li><p><strong>Powering the Setup</strong>: The drone requires stable voltage; I built a power supply circuit with regulated outputs to meet both the Pi and GPS module requirements.</p>
</li>
<li><p><strong>Serial Communication Configuration</strong>: Configuring the Raspberry Pi's <code>ttyAMA0</code> for serial communication involved troubleshooting permissions and UART conflicts.</p>
</li>
</ol>
<h2 id="heading-step-1-setting-up-the-u-blox-neo-6m-gps-module-with-raspberry-pi">Step 1: Setting Up the u-blox NEO-6M GPS Module with Raspberry Pi</h2>
<p>The u-blox NEO-6M GPS module communicates over serial. First, we need to connect the GPS module to the Raspberry Pi:</p>
<ol>
<li><p><strong>Connections</strong>:</p>
<ul>
<li><p>Connect <strong>GPS TX</strong> to <strong>Raspberry Pi RX (GPIO15)</strong>.</p>
</li>
<li><p>Connect <strong>GPS RX</strong> to <strong>Raspberry Pi TX (GPIO14)</strong>. (not needed for reading)</p>
</li>
<li><p>Connect <strong>Ground</strong> and <strong>Power (3.3V)</strong> as needed.</p>
</li>
<li><p><strong>Enable Serial Communication</strong>:</p>
<ul>
<li><p>Open the Raspberry Pi configuration file to enable the serial interface.</p>
<pre><code class="lang-plaintext">  sudo raspi-config
</code></pre>
</li>
<li><p>Navigate to <strong>Interfacing Options</strong> &gt; <strong>Serial</strong>.</p>
</li>
<li><p>Disable the login shell over serial, then enable the serial interface.</p>
</li>
</ul>
</li>
<li><p><strong>Configure</strong> <code>ttyAMA0</code> for GPS Serial Communication:</p>
<ul>
<li><p>Edit the <code>/boot/config.txt</code> file to configure the UART:</p>
<pre><code class="lang-markdown">  sudo nano /boot/firmware/config.txt
</code></pre>
</li>
<li><p>Add the following lines:</p>
<pre><code class="lang-markdown">  enable<span class="hljs-emphasis">_uart=1
  dtoverlay=disable-bt</span>
</code></pre>
</li>
<li><p><strong>Reboot</strong> the Raspberry Pi to apply changes.</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<h2 id="heading-step-2-basic-code-to-access-gps-data">Step 2: Basic Code to Access GPS Data</h2>
<p>        With the GPS connected and the serial port configured, we can use Python to read NMEA sentences from the GPS and extract location data.</p>
<h3 id="heading-script-reading-gps-coordinates-in-python">Script: Reading GPS Coordinates in Python</h3>
<ol>
<li><p><strong>Install Required Libraries</strong>:</p>
<ul>
<li><p>Install <code>pyserial</code> and <code>pynmea2</code> to communicate with the GPS module and parse NMEA sentences:</p>
<pre><code class="lang-markdown">  pip install pyserial pynmea2
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Python Script for GPS Data Retrieval</strong>:</p>
<pre><code class="lang-markdown"> import serial
 import pynmea2

 # Initialize the serial connection to the GPS module
 serial<span class="hljs-emphasis">_port = "/dev/ttyAMA0"  # Port for GPS
 baud_</span>rate = 9600  # Default GPS baud rate

 def get<span class="hljs-emphasis">_gps_</span>data():
<span class="hljs-code">     try:
         # Open serial port
         with serial.Serial(serial_port, baud_rate, timeout=1) as ser:
             while True:
                 line = ser.readline().decode('ascii', errors='replace')
                 # Check for GPRMC sentence (contains position and time)
                 if line.startswith('$GPRMC'):
                     try:
                         msg = pynmea2.parse(line)
                         if msg.status == 'A':  # Ensure it's a valid fix
                             print(f"Latitude: {msg.latitude}, Longitude: {msg.longitude}")
                             return msg.latitude, msg.longitude
                         else:
                             print("Waiting for valid GPS fix...")
                     except pynmea2.ParseError as e:
                         print(f"Parse error: {e}")
     except serial.SerialException as e:
         print(f"Serial error: {e}")
</span>
 if <span class="hljs-strong">__name__</span> == "<span class="hljs-strong">__main__</span>":
<span class="hljs-code">     latitude, longitude = get_gps_data()
     print(f"Current Location: {latitude}, {longitude}")</span>
</code></pre>
</li>
</ol>
<p>        This script establishes a serial connection to the GPS module, reads NMEA sentences, and parses the <code>$GPRMC</code> sentence to retrieve the latitude and longitude.</p>
<h2 id="heading-step-3-capturing-gps-tagged-images-with-the-noir-picamera">Step 3: Capturing GPS-Tagged Images with the NoIR Picamera</h2>
<p>        To complete the crop monitoring setup, the NoIR Picamera captures images, and GPS metadata is embedded directly into each image file. Here’s a simplified script for capturing images with GPS metadata:</p>
<ol>
<li><p><strong>Install GPSPhoto for Metadata Tagging</strong>:</p>
<ul>
<li><p>Use <code>gpsphoto</code> to embed GPS coordinates in image files:</p>
<pre><code class="lang-markdown">  pip install GPSPhoto
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Python Script for Capturing GPS-Tagged Images</strong>:</p>
<pre><code class="lang-markdown"> from picamera2 import Picamera2
 from GPSPhoto import gpsphoto
 import time

 def capture<span class="hljs-emphasis">_image_</span>with<span class="hljs-emphasis">_gps(lat, lng):
     camera = Picamera2()
     camera.configure(camera.create_</span>still<span class="hljs-emphasis">_configuration())
     camera.start()
     time.sleep(2)  # Allow time for auto-adjustment

     timestamp = time.strftime('%Y%m%d_</span>%H%M%S')
<span class="hljs-code">     image_path = f"image_{timestamp}.jpg"
     camera.capture_file(image_path)
     camera.stop()
</span>
<span class="hljs-code">     # Embed GPS data into the image
     photo = gpsphoto.GPSPhoto(image_path)
     info = gpsphoto.GPSInfo((lat, lng), timeStamp=time.strftime('%Y:%m:%d %H:%M:%S'))
     photo.modGPSData(info, image_path)
</span>
<span class="hljs-code">     print(f"Captured image with GPS data at {image_path}")
</span>
 # Example usage
 lat, lng = get<span class="hljs-emphasis">_gps_</span>data()  # Fetch GPS coordinates
 capture<span class="hljs-emphasis">_image_</span>with<span class="hljs-emphasis">_gps(lat, lng)</span>
</code></pre>
</li>
</ol>
<p>        This script configures the NoIR Picamera, captures an image, and embeds the current GPS coordinates as metadata.</p>
<h2 id="heading-step-4-using-multispectral-data-for-crop-health-analysis">Step 4: Using Multispectral Data for Crop Health Analysis</h2>
<p>The NoIR Picamera is ideal for capturing near-infrared (NIR) data, essential for analyzing crop health. By focusing on the red band, we can detect vegetation stress from aerial imagery. Healthier vegetation reflects more NIR light, while stressed vegetation reflects less.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Creating an aerial crop monitoring system with the Raspberry Pi, NoIR Picamera, and u-blox GPS is more than just a tech project—it’s a step toward transforming how we care for our crops and use technology in agriculture. With just a lightweight board, some affordable components, and a bit of perseverance, we can gain a bird’s-eye view into crop health and stress indicators, giving farmers critical insights that were once only accessible through costly and complex systems.</p>
<p>This DIY setup invites a world of possibilities. Imagine your drone gently buzzing over fields, autonomously capturing images that reveal vital data about crop conditions, and doing so with a tool that you built yourself. This project’s blend of hardware, software, and aerial innovation makes it a powerful tool not only for agriculture but for anyone passionate about using technology to solve real-world challenges.</p>
<p>In a world where sustainability and efficiency are essential, this system can be a game-changer—pioneering a new way to make agriculture smarter, greener, and more resilient. So why not get started? Build, test, fly, and let your crops—and your imagination—thrive.</p>
]]></content:encoded></item><item><title><![CDATA[Cybersecurity Unwrapped: Fortifying Businesses with Open-Source Guardians]]></title><description><![CDATA[The African Cyber Scene: Why the Hesitation?
So, here's the deal: businesses in Africa are still playing catch-up with cybersecurity. It's time to change that narrative. But here's the exciting twist – you don't need a massive budget for high-tech se...]]></description><link>https://elisha.loktioncode.org/fortifying-businesses-with-open-source-guardians</link><guid isPermaLink="true">https://elisha.loktioncode.org/fortifying-businesses-with-open-source-guardians</guid><category><![CDATA[cybersecurity]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[IT Support]]></category><category><![CDATA[network security]]></category><dc:creator><![CDATA[Elisha Bere]]></dc:creator><pubDate>Wed, 15 Nov 2023 18:28:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1700071612432/909b2944-775d-43f1-9398-e387b5a0c19c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>The African Cyber Scene: Why the Hesitation?</strong></p>
<p>So, here's the deal: businesses in Africa are still playing catch-up with cybersecurity. It's time to change that narrative. But here's the exciting twist – you don't need a massive budget for high-tech security. Enter open-source solutions, your new digital allies.</p>
<p><strong>Cybersecurity 101: Open-Source, Open Arms</strong></p>
<p>Let's break it down. Cybersecurity isn't just for the elite. Open-source platforms like Wazuh and Suricata bring the power of protection to businesses of all sizes. And guess what? They're absolutely free. It's like having your own security detail without breaking the bank.</p>
<p><strong>Budget-Friendly Armor: Why It's a No-Brainer</strong></p>
<p>Hold on to your hats because it gets better. Wazuh is not just open source; it's an all-in-one security information and event management (SIEM) tool. Think of it as your personal cybersecurity assistant, collecting and analyzing data to keep your digital world safe. And the best part? It doesn't cost a thing.</p>
<p><strong>Suricata: The Untamed Guardian of Your Digital Realm</strong></p>
<p>Now, let's talk about Suricata. This open-source intrusion detection and prevention system (IDPS) is like the superhero patrolling your digital borders. It's fast and efficient, and did I mention it's free? Suricata watches for suspicious activity, ensuring your business stays one step ahead of cyber threats.</p>
<p><strong>Beyond Geek Speak: Policies, Procedures, and Open Source Magic</strong></p>
<p>Now, let’s blend the tech talk with some real magic. Open-source platforms like Wazuh and Suricata work seamlessly with your policies and procedures. It's not just about the tools; it's about how you use them. Imagine building a digital fortress with tools that cost nothing and policies that make sense.</p>
<p><strong>Cybersecurity in Action: From Policies to Open-Source Practice</strong></p>
<p>Crafting a cybersecurity policy is cool, but it's even cooler when you have open-source tools to back it up. Wazuh and Suricata play by the rules you set, ensuring your business is not just secure but smart about it.</p>
<p><strong>Real-World Success Stories: Because Who Doesn’t Love Free and Secure?</strong></p>
<p>Let's throw some success stories into the mix. Real businesses, real challenges, and real victories with open-source guardians. These aren’t tales of hefty investments; these are stories of businesses that fortified their digital realms without spending a dime.</p>
<p><strong>Wrapping It Up: Your Digital Armor Awaits</strong></p>
<p>In a nutshell, cybersecurity is not just necessary; it's achievable without burning a hole in your budget. Open-source solutions like Wazuh and Suricata are the knights in shining armor for businesses in Africa. So, why not take advantage of tools that won’t cost you a penny? It’s not just a smarter move; it's a game-changer.</p>
<p>So, here's to embracing open-source cybersecurity, your new cost-effective digital superheroes. Three minutes well spent, right? Now, go fortify that digital castle of yours without spending a cent! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[A Software Developer's Odyssey into Cybersecurity and the CISSP 8 Domains]]></title><description><![CDATA[For software developers looking to pivot into the realm of cybersecurity, understanding the NIST CISSP 8 security domains is crucial. These domains serve as a comprehensive framework for building a robust cybersecurity strategy, ensuring that busines...]]></description><link>https://elisha.loktioncode.org/a-software-developers-odyssey-into-cybersecurity</link><guid isPermaLink="true">https://elisha.loktioncode.org/a-software-developers-odyssey-into-cybersecurity</guid><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[softwaresecurity]]></category><category><![CDATA[risk management]]></category><category><![CDATA[CISSP]]></category><dc:creator><![CDATA[Elisha Bere]]></dc:creator><pubDate>Sat, 11 Nov 2023 17:13:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/BxELNNMN88Y/upload/c489a11d98fd1084097769bd3ba4256d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For software developers looking to pivot into the realm of cybersecurity, understanding the NIST CISSP 8 security domains is crucial. These domains serve as a comprehensive framework for building a robust cybersecurity strategy, ensuring that businesses can safeguard their digital assets effectively.</p>
<h1 id="heading-the-nist-cissp-8-security-domains"><strong>The NIST CISSP 8 Security Domains</strong></h1>
<p>The NIST CISSP 8 security domains provide a structured approach to cybersecurity, covering key areas that every cybersecurity professional should be familiar with:</p>
<ol>
<li><p><strong>Security and Risk Management:</strong></p>
<ul>
<li><p>Involves understanding and applying security policies, risk management, and legal and regulatory issues.</p>
</li>
<li><p>Crucial to ensure that cybersecurity measures align with business objectives and comply with industry regulations.</p>
</li>
</ul>
</li>
<li><p><strong>Asset Security:</strong></p>
<ul>
<li><p>Focuses on protecting organizational assets, including data, technology, and facilities.</p>
</li>
<li><p>Software developers can leverage their understanding of code and system architecture to contribute to secure coding practices and data protection.</p>
</li>
</ul>
</li>
<li><p><strong>Security Architecture and Engineering:</strong></p>
<ul>
<li><p>Encompasses the design and implementation of secure systems and architectures.</p>
</li>
<li><p>Software developers can use their coding expertise to contribute to creating secure software and designing systems with a focus on cybersecurity.</p>
</li>
</ul>
</li>
<li><p><strong>Communication and Network Security:</strong></p>
<ul>
<li><p>Involves securing communication channels and networks.</p>
</li>
<li><p>Software developers, with their understanding of network protocols and communication patterns, can contribute to ensuring the secure transmission of data.</p>
</li>
</ul>
</li>
<li><p><strong>Identity and Access Management:</strong></p>
<ul>
<li><p>Focuses on controlling access and managing identities within a system.</p>
</li>
<li><p>Developers can apply their knowledge of authentication and authorization mechanisms to contribute to robust identity and access management systems.</p>
</li>
</ul>
</li>
<li><p><strong>Security Assessment and Testing:</strong></p>
<ul>
<li><p>Involves evaluating the effectiveness of security controls.</p>
</li>
<li><p>Software developers can apply their testing skills to identify and rectify vulnerabilities in software and systems.</p>
</li>
</ul>
</li>
<li><p><strong>Security Operations:</strong></p>
<ul>
<li><p>Encompasses the day-to-day tasks required to manage and respond to security incidents.</p>
</li>
<li><p>Developers can contribute by developing tools and scripts for security monitoring and incident response.</p>
</li>
</ul>
</li>
<li><p><strong>Software Development Security:</strong></p>
<ul>
<li><p>Integrates security into the software development lifecycle.</p>
</li>
<li><p>This domain directly aligns with a software developer's expertise, emphasizing the importance of secure coding practices.</p>
</li>
</ul>
</li>
</ol>
<p>Implementing robust cybersecurity measures based on the NIST CISSP 8 security domains is paramount for businesses. It not only safeguards sensitive information but also builds trust with clients and partners. A breach in any of these domains could result in financial losses, reputational damage, and legal consequences.</p>
<p>The transition from software development to cybersecurity is smoother than one might think. Communication skills, vital for explaining complex technical concepts, are equally important in cybersecurity when conveying security policies and risks to non-technical stakeholders. Furthermore, coding skills are highly transferable, allowing developers to contribute to secure software development, automate security processes, and understand the intricacies of potential vulnerabilities.</p>
<p>For software developers eyeing a career in cybersecurity, understanding and applying the NIST CISSP 8 security domains is a pivotal step. By recognizing the importance of these domains for businesses and leveraging transferable skills like communication and coding, developers can seamlessly bridge the gap between software development and cybersecurity, contributing to a safer digital landscape.</p>
]]></content:encoded></item><item><title><![CDATA[Flutter State management with Redux]]></title><description><![CDATA[What is state management in Flutter?
State management is essentially a way to facilitate communication and sharing of data across widgets. It creates a tangible data structure to represent the state of your app that you can read from and write to.
Wh...]]></description><link>https://elisha.loktioncode.org/flutter-state-management-with-redux</link><guid isPermaLink="true">https://elisha.loktioncode.org/flutter-state-management-with-redux</guid><category><![CDATA[Flutter]]></category><category><![CDATA[Redux]]></category><category><![CDATA[Flutter Examples]]></category><category><![CDATA[Flutter Widgets]]></category><category><![CDATA[Flutter SDK]]></category><dc:creator><![CDATA[Elisha Bere]]></dc:creator><pubDate>Thu, 15 Apr 2021 13:14:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1618488793501/s20vb3No5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="what-is-state-management-in-flutter">What is state management in Flutter?</h3>
<p>State management is essentially a way to facilitate communication and sharing of data across widgets. It creates a tangible data structure to represent the state of your app that you can read from and write to.</p>
<p>When it comes to managing state in a flutter application, there are many options, but I find myself relying on stateful widgets and these have a downfall as I have to observe the change of states and rebuild widgets. Flutter is fast, but we should be smart about what we ask Flutter to rebuild! The smartest way to solve this problem is by using state management tools like Bloc, Provider, and Momentum but today I would like to write how we can use Redux to manage states in our flutter application. </p>
<p>While <code>Redux</code> is mostly used as a state management tool with React I found it quite easy to apply it in flutter projects I have contributed to so far. With  <code>redux</code> &amp;<code>flutter_redux</code> we can use Redux in our flutter applications, so the state of our application is kept in a store, and each widget can access any state that it needs from this store.  </p>
<h4 id="redux-utilities-to-easily-consume-a-redux-store-to-build-flutter-widgets">Redux utilities to easily consume a Redux Store to build Flutter Widgets:</h4>
<ol>
<li><code>StoreProvider</code> - The base Widget. It will pass the given Redux Store to all descendants that request it.</li>
<li><code>StoreBuilder</code> - A descendant Widget that gets the Store from a StoreProvider and passes it to a Widget builder function.</li>
<li><code>StoreConnector</code> - A descendant Widget that gets the Store from the nearest <code>StoreProvider</code> ancestor, converts the <code>Store</code> into a <code>ViewModel</code> with the given converter function, and passes the <code>ViewModel</code> to a builder function.</li>
</ol>
<p><em>Any time the Store emits a change event, the Widget will automatically be rebuilt. No need to manage subscriptions!</em></p>
<h5 id="below-is-an-example-of-how-we-can-use-redux-in-a-simple-counter-app">Below is an example of how we can use redux in a simple counter app:</h5>
<pre><code><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_redux/flutter_redux.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:redux/redux.dart'</span>;

<span class="hljs-comment">// One simple action: Increment</span>
<span class="hljs-keyword">enum</span> Actions { Increment }

<span class="hljs-comment">// The reducer, which takes the previous count and increments it in response</span>
<span class="hljs-comment">// to an Increment action.</span>
<span class="hljs-built_in">int</span> counterReducer(<span class="hljs-built_in">int</span> state, <span class="hljs-built_in">dynamic</span> action) {
  <span class="hljs-keyword">if</span> (action == Actions.Increment) {
    <span class="hljs-keyword">return</span> state + <span class="hljs-number">1</span>;
  }

  <span class="hljs-keyword">return</span> state;
}

<span class="hljs-keyword">void</span> main() {
  <span class="hljs-comment">// Create your store as a final variable in the main function or inside a</span>
  <span class="hljs-comment">// State object. This works better with Hot Reload than creating it directly</span>
  <span class="hljs-comment">// in the `build` function.</span>
  <span class="hljs-keyword">final</span> store = Store&lt;<span class="hljs-built_in">int</span>&gt;(counterReducer, initialState: <span class="hljs-number">0</span>);

  runApp(FlutterReduxApp(
    title: <span class="hljs-string">'Flutter Redux Demo'</span>,
    store: store,
  ));
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FlutterReduxApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-keyword">final</span> Store&lt;<span class="hljs-built_in">int</span>&gt; store;
  <span class="hljs-keyword">final</span> <span class="hljs-built_in">String</span> title;

  FlutterReduxApp({Key key, <span class="hljs-keyword">this</span>.store, <span class="hljs-keyword">this</span>.title}) : <span class="hljs-keyword">super</span>(key: key);

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-comment">// The StoreProvider should wrap your MaterialApp or WidgetsApp. This will</span>
    <span class="hljs-comment">// ensure all routes have access to the store.</span>
    <span class="hljs-keyword">return</span> StoreProvider&lt;<span class="hljs-built_in">int</span>&gt;(
      <span class="hljs-comment">// Pass the store to the StoreProvider. Any ancestor `StoreConnector`</span>
      <span class="hljs-comment">// Widgets will find and use this value as the `Store`.</span>
      store: store,
      child: MaterialApp(
        theme: ThemeData.dark(),
        title: title,
        home: Scaffold(
          appBar: AppBar(
            title: Text(title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                <span class="hljs-comment">// Connect the Store to a Text Widget that renders the current</span>
                <span class="hljs-comment">// count.</span>
                <span class="hljs-comment">//</span>
                <span class="hljs-comment">// We'll wrap the Text Widget in a `StoreConnector` Widget. The</span>
                <span class="hljs-comment">// `StoreConnector` will find the `Store` from the nearest</span>
                <span class="hljs-comment">// `StoreProvider` ancestor, convert it into a String of the</span>
                <span class="hljs-comment">// latest count, and pass that String  to the `builder` function</span>
                <span class="hljs-comment">// as the `count`.</span>
                <span class="hljs-comment">//</span>
                <span class="hljs-comment">// Every time the button is tapped, an action is dispatched and</span>
                <span class="hljs-comment">// run through the reducer. After the reducer updates the state,</span>
                <span class="hljs-comment">// the Widget will be automatically rebuilt with the latest</span>
                <span class="hljs-comment">// count. No need to manually manage subscriptions or Streams!</span>
                StoreConnector&lt;<span class="hljs-built_in">int</span>, <span class="hljs-built_in">String</span>&gt;(
                  converter: (store) =&gt; store.state.toString(),
                  builder: (context, count) {
                    <span class="hljs-keyword">return</span> Text(
                      <span class="hljs-string">'The button has been pushed this many times: <span class="hljs-subst">$count</span>'</span>,
                      style: Theme.of(context).textTheme.display1,
                    );
                  },
                )
              ],
            ),
          ),
          <span class="hljs-comment">// Connect the Store to a FloatingActionButton. In this case, we'll</span>
          <span class="hljs-comment">// use the Store to build a callback that will dispatch an Increment</span>
          <span class="hljs-comment">// Action.</span>
          <span class="hljs-comment">//</span>
          <span class="hljs-comment">// Then, we'll pass this callback to the button's `onPressed` handler.</span>
          floatingActionButton: StoreConnector&lt;<span class="hljs-built_in">int</span>, VoidCallback&gt;(
            converter: (store) {
              <span class="hljs-comment">// Return a `VoidCallback`, which is a fancy name for a function</span>
              <span class="hljs-comment">// with no parameters and no return value. </span>
              <span class="hljs-comment">// It only dispatches an Increment action.</span>
              <span class="hljs-keyword">return</span> () =&gt; store.dispatch(Actions.Increment);
            },
            builder: (context, callback) {
              <span class="hljs-keyword">return</span> FloatingActionButton(
                <span class="hljs-comment">// Attach the `callback` to the `onPressed` attribute</span>
                onPressed: callback,
                tooltip: <span class="hljs-string">'Increment'</span>,
                child: Icon(Icons.add),
              );
            },
          ),
        ),
      ),
    );
  }
}
</code></pre><blockquote>
<p>NB: I wrote this article assuming that you have some experience with React-redux and you understand how actions, reducers, and dispatchers work in react-redux.</p>
</blockquote>
<p><strong>Thank you for reading, and let's connect!</strong>
Thank you for reading my blog. Feel free to subscribe to connect on <a target="_blank" href="https://twitter.com/loktioncode">Twitter</a></p>
]]></content:encoded></item><item><title><![CDATA[Code Reviews using Github Team]]></title><description><![CDATA[Before we even get started I know someone is thinking, " Why should I bother with doing code reviews?". Well, it is good practice to do code reviews, it helps give a fresh set of eyes to identify bugs and simple coding errors before your product gets...]]></description><link>https://elisha.loktioncode.org/code-reviews-using-github</link><guid isPermaLink="true">https://elisha.loktioncode.org/code-reviews-using-github</guid><dc:creator><![CDATA[Elisha Bere]]></dc:creator><pubDate>Thu, 03 Sep 2020 10:15:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1599123786601/aecLHxI_J.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before we even get started I know someone is thinking, " Why should I bother with doing code reviews?". Well, it is good practice to do code reviews, it helps give a fresh set of eyes to identify bugs and simple coding errors before your product gets to the next step, making the process for getting the software to the customer more efficient. Simply reviewing someone's code and identifying errors is great. To do this we use branches on Github.</p>
<p>Creating branches is very simple to do and in this tutorial, I am going to create only one branch called <strong>develop</strong> as shown below. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599124390078/mCG4G2spt.png" alt="git.png" /></p>
<p>To learn more about how to create branches please see  <a target="_blank" href="https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/managing-branches">GitHub docs</a>. When done creating a new branch we have to make it the default branch so all changes will be pushed to this branch. To do this we have to go to <strong>Settings</strong> and select <strong>Branches</strong> then select the new branch to make it default and update.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599125095973/3QXAeKEd1.png" alt="git3deafultbranch.png" /></p>
<p>When all this is done we have to <em>add rules </em>to our branches both <em> master </em> and <em>develop</em>. These rules are where we control what is merged to <em>develop</em> branch. Depending on the magnitude of your team you set how many people must review code before it is <em>merged</em> with other code in the branch, you can set it to three code reviewers so that there are fewer delays in merging the code to the branch.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599126153356/Ci56i0b_B.png" alt="addGitRules.png" /></p>
<p>Click on <strong>Add rule</strong> to add a new rule. The branch name pattern is the name of the branch. Select <strong>Require to pull request reviews before merging</strong> and select 3 from the dropdown.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599126589565/G6zQ_mIcJ.png" alt="addGitRules.png" /></p>
<p>If you scroll down on the branch rule page you will find a lot more rules which you can select depending on the needs of your team. I recommend you also select who can push to matching branches as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599126789515/TzL0uhBFj.png" alt="addGitRules.png" /></p>
<p>After all the rules are selected save changes and do the same for the <strong>master </strong> branch. For the master branch add senior team member/s that can merge code to this branch. </p>
<blockquote>
<p>Note: The purpose of this article was to hopefully get you started on using Github Team for contributing and collaborating, it does not in any way cover everything about managing teams and collaborating, to learn more, I encourage you to go over the <a target="_blank" href="https://docs.github.com/en/desktop/">official documentation </a> ...</p>
</blockquote>
]]></content:encoded></item></channel></rss>