<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Marvin</title>
    <description>The latest articles on Forem by Marvin (@marvinkweyu).</description>
    <link>https://forem.com/marvinkweyu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F188302%2F18511314-4069-4ae7-a2f4-481d3e58966c.jpg</url>
      <title>Forem: Marvin</title>
      <link>https://forem.com/marvinkweyu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marvinkweyu"/>
    <language>en</language>
    <item>
      <title>CI/CD for Licensed Software You Don't Host</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Tue, 07 Apr 2026 06:43:41 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/cicd-for-licensed-software-you-dont-host-2al9</link>
      <guid>https://forem.com/marvinkweyu/cicd-for-licensed-software-you-dont-host-2al9</guid>
      <description>&lt;p&gt;We are three weeks away from shipping &lt;a href="https://navengine.encha.cloud/" rel="noopener noreferrer"&gt;NavEngine v4&lt;/a&gt;, an echo from the previous piece on &lt;a href="https://www.marvinkweyu.net/indulge/business-minded-development" rel="noopener noreferrer"&gt;Business Driven development&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I say "&lt;em&gt;shipping&lt;/em&gt;" loosely. There is no deployment script I run, no SSH session I open and no Kubernetes rollout I watch. The software lives on infrastructure I have never seen, behind firewalls I cannot reach, on machines whose specs I do not know. Shipping, in this context, means pushing an image to a registry and trusting that a process running inside a container on a customer's server will eventually notice and do something about it.&lt;/p&gt;

&lt;p&gt;That gap - between what I push and what the customer runs - is what this piece is about.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Assumption Collapse
&lt;/h3&gt;

&lt;p&gt;Every CI/CD tool I have ever used was built on a premise so foundational that nobody thought to state it: you control the deployment target. You own the server. You have the keys. Deployment, in the conventional sense, is just automation wrapped around access you already have.&lt;/p&gt;

&lt;p&gt;NavEngine is quite the opposite. It exists as a custom image - qcow2 - shipped onto the customer's infrastructure. The customer owns the machine. I do not have SSH access unless I go through DWService and even then, that is a support channel, not a deployment one. Yet somehow, we need to continuously deliver updates to machines we cannot reach, across connections we cannot guarantee, without breaking software that is actively in use.&lt;/p&gt;

&lt;p&gt;So the question became: if you cannot push, how do you deliver?&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Indulge&lt;/strong&gt; &lt;em&gt;The moment you decide to ship software you don't host, you have made a decision with consequences that will follow you for the life of the product. Not just operationally. Architecturally. Every assumption your codebase makes about the environment it runs in now belongs to someone else's infrastructure. That is not a deployment problem. It is a design problem that shows up at deployment time.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  The Answer is Pull
&lt;/h3&gt;

&lt;p&gt;Watchtower. It runs as a container alongside the rest of the stack, polls the Docker registry on a configured interval, and when it detects a new image digest on the tag it is watching, it pulls and restarts the relevant containers. No webhook, no push, no SSH. The installation phones home for updates and takes what it finds.&lt;/p&gt;

&lt;p&gt;The key design decision here was the floating tag. Every customer's Butane config ships with &lt;code&gt;core:stable&lt;/code&gt;. Not &lt;code&gt;core:v3.0.39&lt;/code&gt;. Not a digest pin. &lt;code&gt;stable&lt;/code&gt;. When Watchtower polls the registry and sees that &lt;code&gt;stable&lt;/code&gt; now resolves to a different digest than what is currently running, it pulls. What "stable" points to is entirely under my control, from the registry side, without touching anything on the customer's machine.&lt;/p&gt;

&lt;p&gt;This sounds obvious once you say it. It took longer than I would like to admit to get there.&lt;/p&gt;




&lt;h3&gt;
  
  
  Two Registries, Two floating tags, One gate
&lt;/h3&gt;

&lt;p&gt;Here is the full pipeline as it actually runs.&lt;/p&gt;

&lt;p&gt;Every push to &lt;code&gt;main&lt;/code&gt; triggers a build on the dev registry. The image gets tagged with a version identifier and a floating tag - &lt;code&gt;staging&lt;/code&gt;. A staging environment - running the same Compose stack, same Butane configuration, same structure as a customer installation - pulls from &lt;code&gt;staging&lt;/code&gt;. This is where the image lives until I am satisfied it works.&lt;/p&gt;

&lt;p&gt;When staging looks good, I create a release. The production registry builds from that release, tags the image with the version (&lt;code&gt;v3.0.40&lt;/code&gt;) and overwrites the floating &lt;code&gt;stable&lt;/code&gt; tag. Customer installations, on their next Watchtower poll interval, see a new digest on &lt;code&gt;stable&lt;/code&gt; and update.&lt;/p&gt;

&lt;p&gt;The critical detail: &lt;code&gt;stable&lt;/code&gt; is never overwritten by a push to &lt;code&gt;main&lt;/code&gt;. Only by a release. The staging gate is the only thing standing between a broken image and a customer's running installation. There is no automated rollout percentage, no canary fleet, no gradual traffic shift. The gate is a human decision, made after watching staging run and deciding it is ready.&lt;/p&gt;

&lt;p&gt;For a solo-operated product at this stage, that is the right call. Complexity in release infrastructure that you do not need is just surface area for things to go wrong.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Indulge&lt;/strong&gt; &lt;em&gt;A staging environment that does not accurately reflect production is a very expensive placebo. It gives you confidence without giving you information. The hardest thing about shipping self-hosted software is that your staging environment runs on infrastructure you understand, with data you created, on a network you control. Your customer's environment is none of those things. No pipeline fully closes that gap. The best you can do is know exactly where your confidence ends.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  What Happens When stable is broken
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvrufoq82g9jwaemp94n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvrufoq82g9jwaemp94n.png" alt=" " width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will happen. An image that passes staging will break in a customer environment for a reason that staging did not surface - a schema migration that assumed a clean database, a dependency that behaves differently on older hardware, a configuration value that was present in staging and absent in the field.&lt;/p&gt;

&lt;p&gt;The recovery flow is: fix on &lt;code&gt;main&lt;/code&gt;, watch it pass staging, cut a new release. &lt;code&gt;v3.0.41&lt;/code&gt; overwrites &lt;code&gt;stable&lt;/code&gt;. Watchtower picks it up on the next poll interval. The customer, who may or may not have noticed anything, is now running the fixed image.&lt;/p&gt;

&lt;p&gt;The window between the broken image landing and the fix arriving is real. Depending on how fast the hotfix moves through staging and how long the Watchtower poll interval is, a customer could be running broken software for anywhere from minutes to hours. There is no remote kill switch. There is no way to reach in and restart a service. There is DWService if the situation is bad enough to warrant it, but that is a support escalation, not a deployment tool.&lt;/p&gt;

&lt;p&gt;This is the honest cost of not controlling the deployment target. You accept a recovery latency that you cannot compress below a certain floor. The mitigation is not a cleverer pipeline. It is investing deeply in staging fidelity and in making sure the image fails loudly rather than silently - health checks that surface problems immediately, startup validation that refuses to run on bad configuration rather than running badly.&lt;/p&gt;

&lt;p&gt;A system that fails loudly is a system that can be fixed. A system that degrades quietly is a system that erodes trust before anyone knows there is a problem.&lt;/p&gt;




&lt;h3&gt;
  
  
  Enterprise and standard: different cadences, same pattern
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;How do we manage customers that diverge from the main product line with an enterprise license?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;NavEngine has two license tiers. Enterprise customers are on a separate release cadence from standard customers. The mechanism is straightforward: separate floating tags on the production registry. &lt;code&gt;core-enterprise:stable&lt;/code&gt; and &lt;code&gt;core-standard:stable&lt;/code&gt;. The Butane config shipped to each customer points at the appropriate tag. Enterprise releases can go out on a different schedule, carry different feature sets, and move more cautiously than standard releases.&lt;/p&gt;

&lt;p&gt;What prevents a standard customer from pointing Watchtower at the enterprise tag? Mostly friction. The Compose file is baked into the Butane config at provisioning time. There is no SSH access to change it. A customer would need console access and the motivation to go looking - unlikely for most, impossible to rule out for all.&lt;/p&gt;

&lt;p&gt;The proper answer is registry-level access control: pull tokens scoped to the tags each customer is entitled to, issued at license activation and revoked at expiry. This means the registry enforces entitlement, not just the application. An expired license means an expired pull token means no updates, enforced at the point of delivery rather than after the fact.&lt;/p&gt;

&lt;p&gt;This is on the roadmap. For v4, the answer is friction and trust.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Indulge&lt;/strong&gt; &lt;em&gt;License enforcement in self-hosted software is a negotiation between what you can technically control and what you have to trust. You cannot fully control what runs on a machine you do not own. At some point, a sufficiently motivated customer can circumvent almost any enforcement mechanism you build. The goal is not to make circumvention impossible. It is to make compliance easier than circumvention, and to make the value proposition strong enough that the question rarely comes up.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  The license server is not in the update path
&lt;/h3&gt;

&lt;p&gt;One decision I am glad we made early: the licensing server and the Docker registry are separate infrastructure. They do not share a failure domain.&lt;/p&gt;

&lt;p&gt;Watchtower polls the registry. The license server is called from within one of the running containers as part of normal application operation. If the registry is unreachable, the software keeps running. If the license server is unreachable, the backend falls back to its last known state - persisted to disk, not held in memory, so it survives a container restart. The check runs periodically. The grace window is generous enough that a license server outage does not immediately affect customers, but not so generous that expired licenses can run indefinitely.&lt;/p&gt;

&lt;p&gt;This matters because the failure modes compound. A product update that requires a license check to proceed has just made the license server a dependency of your deployment pipeline. Any outage that hits your license infrastructure also hits your ability to ship updates to paying customers. Keeping these paths separate means they fail independently, and independent failures are recoverable in ways that cascading ones are not.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What the pipeline actually looks like&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The immutable version tags are not just for auditing. They are the rollback reference. If &lt;code&gt;v3.0.40&lt;/code&gt; breaks everything, &lt;code&gt;v3.0.39&lt;/code&gt; still exists in the registry. I can retag it as &lt;code&gt;stable&lt;/code&gt; manually and customers will roll back on the next poll. This has not been needed yet. It is there for the day it is.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Indulge&lt;/strong&gt; &lt;em&gt;Most CI/CD writing treats deployment as the end of the story. Ship it, watch the metrics, move on. Self-hosted software inverts this. Deployment is the beginning of a period during which software you cannot reach is running in an environment you cannot see, on behalf of a customer whose experience you will only hear about if something goes wrong. The pipeline is not a delivery mechanism. It is a trust mechanism. Every decision in it is a decision about how much you trust the image before it leaves your hands.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Three Weeks Out&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;NavEngine v4 is three weeks away. The pipeline is running. Staging has held. The tags are in place.&lt;/p&gt;

&lt;p&gt;None of that answers the only question that matters: &lt;em&gt;what happens when the software leaves you?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It will run on machines you have never touched, against data you have never seen, in environments that do not care about your assumptions. By the time it fails, if it fails, it will already be someone else’s problem - and still entirely yours. The customer notices before you do. That is the thing. I am shit scared.&lt;/p&gt;

&lt;p&gt;I suppose that this is the essence of &lt;a href="https://www.marvinkweyu.net/indulge/why-distributed-systems-field-notes" rel="noopener noreferrer"&gt;these notes&lt;/a&gt; - to document real systems in real time. This is the inversion self-hosted systems force on you: treating deployment not as the end of control but as the beginning of its absence. &lt;/p&gt;

&lt;p&gt;So you design for that absence.&lt;/p&gt;

&lt;p&gt;You design for recovery over prevention.&lt;/p&gt;

&lt;p&gt;For visibility over certainty and trust over control.&lt;/p&gt;

&lt;p&gt;Everything else is just what it takes to make that possible.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>Necessity versus Opportunity</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Thu, 20 Apr 2023 06:57:34 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/necessity-versus-opportunity-4h98</link>
      <guid>https://forem.com/marvinkweyu/necessity-versus-opportunity-4h98</guid>
      <description>&lt;p&gt;Over the past few weeks, I have been exploring the world of entrepreneurship, attending various events where accelerators gather, joining breakfasts for entrepreneurial-minded individuals, and participating in debates on the subject. Throughout this journey, I have been focusing on funding opportunities, education, and mindset shifts that ultimately lead to the creation of successful businesses.&lt;/p&gt;

&lt;p&gt;An opinion piece that caught my attention was one by Adam Molai entitled "&lt;a href="https://www.businesslive.co.za/bd/opinion/2022-06-25-adam-molai-africa-has-entrepreneurs-just-not-the-right-kind/" rel="noopener noreferrer"&gt;Africa lacks the right kind of entrepreneurs&lt;/a&gt;," along with the paper "&lt;a href="https://www.afdb.org/en/documents/working-paper-336-jobs-economic-growth-and-capacity-development-youth-africa" rel="noopener noreferrer"&gt;Jobs, Economic Growth and Capacity Development for Youth in Africa&lt;/a&gt;," both of which form the basis of my thoughts today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Indulge
&lt;/h3&gt;

&lt;p&gt;With the world at 8 billion persons as of &lt;a href="https://www.un.org/en/dayof8billion" rel="noopener noreferrer"&gt;15th November 2022&lt;/a&gt;, Africa remains one of the poorest continents on the globe, despite the fact that it will account for 2 out of 5 working-age individuals by the end of the 21st century. The peculiar part of this statement is the quality and purposes with which we build our ventures within the African economic zones.&lt;/p&gt;

&lt;p&gt;The crux? Was this business built out of a pure innovative spirit - to create what once was not - or was it a means to an end?&lt;/p&gt;

&lt;p&gt;Returning to the population question, with a 245.0% increase in population within the working age group, we expect a rise in the number of graduates and professionals alike. All this while, the market is not primed to absorb this number of individuals. If anything, the &lt;a href="https://layoffs.fyi/" rel="noopener noreferrer"&gt;tech lay-offs&lt;/a&gt; that have happened over the last couple of months have been a testament to what happens when projects fail and companies are bloated.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Was this business built out of a pure innovative spirit - to create what once was not - or was it a means to an end?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This raises the question, what does this mean for education?&lt;/p&gt;

&lt;p&gt;Having been brought up in an African household and in relation to how we raise this generation of dreamers and builders alike, provided we exist in the space where entrepreneurship is treated as a side-hustle for those incapable of being absorbed into the job market, we cease to create foundations upon which the future can stand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The next Bill Gates will not build an operating system. The next Larry Page or Sergey Brin wont make a search engine. And the next Mark Zuckerberg wont create a social network. If you are copying these guys, you arent learning from them. - Peter Thiel (Zero To One)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is high time we create sustainable solutions that navigate from bringing in the everyday meal to those that impart beyond sustenance. To leave you something to nibble and ponder, here is an article from TechCabal about &lt;a href="https://techcabal.com/2022/11/08/african-tech-talent-emigration-jobs/" rel="noopener noreferrer"&gt;tech talent navigating its way back to Africa&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thought:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Perhaps the danger of Artificial Intelligence is not in it taking away employment ( unless you champion for &lt;a href="https://www.youtube.com/watch?v=uK3OBAxCi6k" rel="noopener noreferrer"&gt;bullshit jobs&lt;/a&gt;) but that with the increased use of the same technology, AI relearns from itself and other old content rather than what is made a-new. The limit remains; Artificial Intelligence will only learn from what already exists.&lt;/p&gt;

</description>
      <category>startup</category>
      <category>entrepreneurship</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>To OpenSource and Beyond</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Wed, 13 Oct 2021 19:11:40 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/to-opensource-and-beyond-3828</link>
      <guid>https://forem.com/marvinkweyu/to-opensource-and-beyond-3828</guid>
      <description>&lt;p&gt;It is yet another October, or better yet, another period and time frame set aside for opensource contribution.&lt;/p&gt;

&lt;p&gt;We have had an incredible year here at &lt;a href="https://thegreencodes.com/" rel="noopener noreferrer"&gt;TheGreenCodes&lt;/a&gt;, and with all this , we still come back at some of the projects that might spark interest and might give in to some learning along the way. We mention a few whose source code is out for the naked eye to peruse, learn from and contribute to (Find a bug? Why not make a pull?).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://assessme-project.herokuapp.com/" rel="noopener noreferrer"&gt;TheAssessMe Project&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634148860714%2FdyokdP805.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634148860714%2FdyokdP805.gif" alt="assessme.gif" width="760" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MarvinKweyu/AssessMe" rel="noopener noreferrer"&gt;https://github.com/MarvinKweyu/AssessMe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built as a quiz application, The AssessMe Project has two kinds of users; a teacher and a student. The instructor, in our case, the teacher, creates multiple-choice questions form where the students enrolled in a certain topic can give their answers and have the results right on. No, wait times anymore! The instructor then gets the results in a CSV file neatly formatted together with the average score. I'm sure we can work more off of this. Keep an eye on the project. There's more to come here.&lt;/p&gt;

&lt;p&gt;So what seems to be the issue? Simple. We intend to &lt;a href="https://github.com/MarvinKweyu/AssessMe/issues/23" rel="noopener noreferrer"&gt;split the settings into those for production and development&lt;/a&gt;. That's about it!&lt;/p&gt;

&lt;p&gt;We , as well, want to show &lt;a href="https://github.com/MarvinKweyu/AssessMe/issues/24" rel="noopener noreferrer"&gt;a timer on our student portal&lt;/a&gt;. How else would users know the time left on the quiz?&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://feed-creator-app.herokuapp.com/news" rel="noopener noreferrer"&gt;FeedCreator&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634149056742%2FRX33dJcp_.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634149056742%2FRX33dJcp_.gif" alt="feedcreator.gif" width="600" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MarvinKweyu/FeedCreator" rel="noopener noreferrer"&gt;https://github.com/MarvinKweyu/FeedCreator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Created as a Django SSR, FeedCreator is a blog application serving to publish blog articles of any kind, with tags, RSS feed , comments and article filtering. A great entry point for Django eyy? We all know that tutorial all so well.&lt;/p&gt;

&lt;p&gt;Here, however, we aim to improve upon and build it together. To work through the changes we deem fit for an application of its like.&lt;/p&gt;

&lt;p&gt;We currently have two issues attached to the project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/MarvinKweyu/FeedCreator/issues/5" rel="noopener noreferrer"&gt;Make the landing page responsive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MarvinKweyu/FeedCreator/issues/4" rel="noopener noreferrer"&gt;Create an admin page for the blog owner to write articles from&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://pypi.org/project/ColorDetect/" rel="noopener noreferrer"&gt;ColorDetect&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634149140760%2F2S-3JXZKM.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1634149140760%2F2S-3JXZKM.jpeg" alt="color-detect.jpg" width="640" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MarvinKweyu/ColorDetect" rel="noopener noreferrer"&gt;ColorDetect repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We know this one all too well by now. So we shall just give an overview of the tasks at hand. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We want to not only get the colors present in a video , but &lt;a href="https://github.com/MarvinKweyu/ColorDetect/issues/54" rel="noopener noreferrer"&gt;also get the colors present at a specific time cap in the file parsed&lt;/a&gt; (Sneaky one here).&lt;/li&gt;
&lt;li&gt;We also still need &lt;a href="https://github.com/MarvinKweyu/ColorDetect/issues/55" rel="noopener noreferrer"&gt;tests&lt;/a&gt; ! 
Have I mentioned it? Tests. Any test really. Find a feature you think has not been tested well enough or could be done better and make a task of that.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tickle that curiosity of yours and see what you come up with as you work through the issues or walk through the code you find. Ask any questions you may in the project pages and share what you discover. The community , you and I included , are online.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>hacktoberfest</category>
      <category>django</category>
    </item>
    <item>
      <title>Software Engineering Principles To Live By</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Tue, 15 Jun 2021 17:16:38 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/software-engineering-principles-to-live-by-3cmj</link>
      <guid>https://forem.com/marvinkweyu/software-engineering-principles-to-live-by-3cmj</guid>
      <description>&lt;p&gt;Back again, with another off the top shelf; Software principles to recite before bed - literally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Throughout the software engineering lifecycle, practices have come and gone. Those that have stuck and those that have withstood the test of time have been the building blocks of what we have today. They've pushed teams and developers alike to better codebases and practices. Here , we discuss a few of the most notable.&lt;/p&gt;

&lt;h2&gt;
  
  
  YAGNI (You Ain't Gonna Need it)
&lt;/h2&gt;

&lt;p&gt;An echo off the &lt;a href="https://thegreencodes.com/if-you-dont-know-about-it-you-most-likely-dont-need-it" rel="noopener noreferrer"&gt;last article&lt;/a&gt;, where we discussed the endless stream of libraries , and our constant want to know them all. Are you going to use it really? Another dead end , eyy? The libraries you are actually going to use are those that you stumble upon while looking for a specific need and problem to solve, not those that you blindly go online and scroll for.&lt;/p&gt;

&lt;h2&gt;
  
  
  SOLID
&lt;/h2&gt;

&lt;p&gt;Not a state of matter. Coined by Robert C. Martin, SOLID is a software engineering acronym, broken down to:&lt;/p&gt;

&lt;p&gt;S - Single-responsibility Principle&lt;/p&gt;

&lt;p&gt;O - Open-closed Principle&lt;/p&gt;

&lt;p&gt;L - Liskov Substitution Principle&lt;/p&gt;

&lt;p&gt;I - Interface Segregation Principle&lt;/p&gt;

&lt;p&gt;D - Dependency Inversion Principle&lt;/p&gt;

&lt;p&gt;The goal of this is to make whatever that project you, as the engineer,is working on, be maintainable and extendable. Elaborate this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Single-responsibility principle
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;A class or module should have one and only one function. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For instance, we have a class that renders a GUI application, for instance , a PyQt program. Lots of things happening within this. Our program, in this case, streams our favourite music streams from source ABC , a video player of sorts. What about creating just one class for this, seems simple enough, right? &lt;br&gt;
Well no. Beyond that corner of 'the program worked! ' lies a wet mop willing and ready to slap you in the face. &lt;/p&gt;

&lt;p&gt;As with any other program, we expect downtimes , a stream not found , an additional functionality to be added to make it pomp out. You get this gist. So break it down. Our single class cannot have all this all at once, make modules to work on error logging, make modules specific for the video player, a class-specific to listing our feed and another to show history. If it can be small, make it smaller. Just do not overdo it and clear out the whole point of it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Open-closed Principle
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Objects or entities should be open for extension but closed for modification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A function, class or module can be extended, but not modified by an external entity. Within this function, method or module, include items that are mandatory for controlling the ,  but none of the optional methods which would limit the flexibility of the implementations. &lt;/p&gt;

&lt;p&gt;All notification services show a , well, notification, but do all of them show an error notification? Break it off. Utilize polymorphism. All my error service needs to do is pass ABC to XYZ. The rest should be none of its concern. Pass it relevant info and let the rest be handled. this same principle would be extended for the success or information notification services.&lt;/p&gt;

&lt;h4&gt;
  
  
  Liskov Substitution Principle
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Derived classes must be substitutable for their base classes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Objects in a program should be replaceable with instances of their subtypes, without changing the correctness of the program.&lt;/p&gt;

&lt;p&gt;Let's simplify this: what we mean is &lt;strong&gt;if S is a T subtype, then Type T objects can be replaced with Type S objects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Bear with me; A school application.&lt;/p&gt;

&lt;p&gt;We have a class &lt;code&gt;Staff&lt;/code&gt; that houses all the staff of an institution. As well, we have two subclasses, that is, &lt;code&gt;Instructor&lt;/code&gt; and &lt;code&gt;Support staff&lt;/code&gt;, both of whom are still staff members.&lt;/p&gt;

&lt;p&gt;As usual, we have our assumptions as to what properties and methods belong to what object. Following the same principle, we state the below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not enforce stricter rules in the subclass&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the example; we break the programming principle by stating , as a property that &lt;code&gt;class Instructor&lt;/code&gt;, must not only be an instructor , but also be an instructor of a specific institution.  Pause a little and reason this out. &lt;/p&gt;

&lt;p&gt;We are modifying the parent class from within the child. This is similar to saying a dog species class, say &lt;code&gt;Grayhound&lt;/code&gt;, modifies a parent class , &lt;code&gt;Dog&lt;/code&gt;, to have color red. We just break everything else that depends on that single class &lt;code&gt;Dog&lt;/code&gt;. We have, essentially, stated that all dogs are red, even though it is just this one species.&lt;/p&gt;

&lt;h4&gt;
  
  
  Interface Segregation Principle
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Make fine grained interfaces that are client-specific.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have a program, a class , &lt;code&gt;Library&lt;/code&gt;, that helps manage our books. Creating an instance of this class is the same as interfacing with it. &lt;/p&gt;

&lt;p&gt;Take , as another example , an e-commerce platform. We lean towards micro services at this point. We have a database that houses our stall , an admin panel for the store owner and the user navigation section, where our buyers get to see, and hopefully purchase, our products. As micro services, at the top level this becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin panel micro service&lt;/li&gt;
&lt;li&gt;Client micro service(we assume our buyers are the users)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why should the buyer interface with the admin panel when they are not using it in the first place? Why would all that code be with them at that specific instance?&lt;/p&gt;

&lt;h4&gt;
  
  
  Dependency Inversion Principle
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Depend upon abstractions, [not] concretions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last of the solid principles, which, if you have been following those before, should fall right into place.&lt;br&gt;
A higher class should always depend upon the abstraction of the class rather than the detail.&lt;br&gt;
A good example of this is the implementation of abstract classes in Django models; the Abstractuser model. &lt;/p&gt;

&lt;p&gt;In our application models, we would , upon migration, have models from classes that inherited from it, but have no table within the database, to represent the abstract model itself, because it's, well, abstract.&lt;br&gt;
You may note , how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;High-level modules do not depend on low-level modules. &lt;em&gt;Both should depend on the abstraction&lt;/em&gt;. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abstractions should not depend on details. Details should depend on abstractions.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;A high-level module in any program, is one that depends on others. We specify, I repeat, abstraction; an interface upon which we build.&lt;/p&gt;

&lt;h2&gt;
  
  
  DRY(Do not repeat yourself)
&lt;/h2&gt;

&lt;p&gt;Oh, duplicate code , where have you been? You have a piece of code from A that is exactly familiar to the one in C. you have a &lt;code&gt;div&lt;/code&gt;, (a  little web development for a while), across multiple pages. Repeating the same CSS styles and methods across those multiple pages. Why not make it a component in itself? Then tag it and write one CSS file and so forth and change data based on props?&lt;/p&gt;

&lt;h2&gt;
  
  
  KISS(Keep It Stupid Simple)
&lt;/h2&gt;

&lt;p&gt;Often than not, engineers find themselves getting lost in algorithms and data flow other than the value the application is going to bring to the table. We focus more on 'features' as opposed to what the user will actually want our program to do. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So go forth engineer, KISS it, keep it SOLID, keep it DRY and remember to install libraries you actually need. No bloatware! Even on your current device. Do you need that app or is it there for that one time you thought about it? &lt;/p&gt;

&lt;p&gt;Yours, &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/marvinus_j" rel="noopener noreferrer"&gt;TheGreenCodes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>management</category>
      <category>python</category>
    </item>
    <item>
      <title>Vue unit testing: Tests must fail</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Mon, 03 May 2021 17:14:41 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/vue-unit-testing-tests-must-fail-nih</link>
      <guid>https://forem.com/marvinkweyu/vue-unit-testing-tests-must-fail-nih</guid>
      <description>&lt;p&gt;Kicking off from &lt;a href="https://thegreencodes.com/unit-testing-in-vue" rel="noopener noreferrer"&gt;A guide to better predictable code&lt;/a&gt;, we create our project boilerplate; assuming you have the vue-cli already installed. Right on, our &lt;code&gt;awesome-todo&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vue create awesome-todo 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We manually select our project setup. Using Vue-2, allowing the &lt;code&gt;router&lt;/code&gt;, &lt;code&gt;vuex&lt;/code&gt; as well as &lt;code&gt;unit testing&lt;/code&gt; along with the defaults selected. We select &lt;code&gt;jest&lt;/code&gt; when it comes to our unit testing solution as well and store the configuration in our package.json file. Are you ready? Good, let's get on to the next step.&lt;/p&gt;

&lt;p&gt;For purposes of this guide, we'll use bootstrap; particularly, bootstrap-vue. Let's shorten those CSS classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;bootstrap-vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your &lt;code&gt;main.js&lt;/code&gt; file, add the necessary configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BootstrapVue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BootstrapVueIcons&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap-vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap/dist/css/bootstrap.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap-vue/dist/bootstrap-vue.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BootstrapVue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BootstrapVueIcons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spot on! &lt;/p&gt;

&lt;p&gt;On the home/ landing page of our application, we want a welcome message displayed. For our case; &lt;/p&gt;

&lt;p&gt;' &lt;em&gt;Welcome to TheGreenCodes awesome to-do list&lt;/em&gt;.  '&lt;/p&gt;

&lt;p&gt;First of all, though, we test. As I said, we think before we implement. We think of the feature we want to implement before actually implementing it. We then write tests for this feature, to avoid the addiction cheat trap where we say we'll write a test after then never actually get to it.&lt;/p&gt;

&lt;p&gt;Create a file &lt;code&gt;home.spec.js&lt;/code&gt; under the &lt;strong&gt;unit&lt;/strong&gt; directory in the &lt;strong&gt;tests&lt;/strong&gt; folder. &lt;/p&gt;

&lt;p&gt;Notice how we name the file. Our test runner will look for javascript files with the &lt;em&gt;spec&lt;/em&gt; keyword, through the project, under this directory. Now copy the following code snippet below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue/test-utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/views/Home.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// what componet are the tests referring to&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Home.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="c1"&gt;// what feature or spec are we targetting specifically&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Displays a welcome message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;welcomeMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome to TheGreenCodes awesome to-do list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;welcomeMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run this as well as consecutive tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;: unit 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our test fails; rather horribly. Reading the shell, you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  expect&lt;span class="o"&gt;(&lt;/span&gt;received&lt;span class="o"&gt;)&lt;/span&gt;.toMatch&lt;span class="o"&gt;(&lt;/span&gt;expected&lt;span class="o"&gt;)&lt;/span&gt;

    Expected substring: &lt;span class="s2"&gt;"Welcome to TheGreenCodes awesome to-do list"&lt;/span&gt;
    Received string:    &lt;span class="s2"&gt;""&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We gave it a variable with the message to expect in the component &lt;code&gt;Home&lt;/code&gt;. What we know for certain, however, is that we haven't even touched that component.; hence the failure. Head over the Home component under views, remove the HelloWorld import and use and add an &lt;code&gt;h2&lt;/code&gt; tag with our welcome message. Re-run this test and see the difference.&lt;/p&gt;

&lt;p&gt;Before we get any further, we should explain what the elements in our Home test mean.&lt;/p&gt;

&lt;p&gt;As we have made use of comments, we shall describe target areas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a variable , &lt;code&gt;wrapper&lt;/code&gt;, that holds our component. How we do this you ask? We import &lt;code&gt;shallowMount&lt;/code&gt; from Vue test utils. Just like the default component life-cycle hooks, our component is initialized, only this time, since we specified we wanted a shallow mount, any child component within this parent component is not included. &lt;/p&gt;

&lt;p&gt;We then ask the question:&lt;br&gt;
&lt;em&gt;'Hey! Is there any mention of our title from within this component?'&lt;/em&gt; To which the suite complies with a yes or no depending on what we have. We expect this component to have text, not only text but that which matches our welcome message.&lt;/p&gt;

&lt;p&gt;Behold! We have done the foundation building block of a test; tests must fail, tests must pass and the code must be refactored.&lt;/p&gt;

&lt;p&gt;We break this statement down:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tests must fail&lt;/strong&gt;&lt;br&gt;
Our feature has not been implemented yet, so why on earth would we expect a test to pass?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test must pass&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hey Marv, I wrote down that cool little feature. What next? Simple; the test must pass. The test whose feature we just wrote should pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code must be refactored&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the same piece of code is edited later, does the code still pass? Can this component or code be edited and still let the test pass gracefully? &lt;/p&gt;

&lt;p&gt;Do we get the 'It broke everything else!' exclamation?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2u218gyugbl9rcvyksu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2u218gyugbl9rcvyksu.jpeg" alt="photo_2021-05-03_19-27-42.jpg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests must fail, tests must pass and the code must be refactored.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We could go further with this test and specify what element we wanted to have the title:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;titleFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;titleFound&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;welcomeMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get the same result. Ignore the warning for UI element registration, incase you are already using it within your code, for now, we'll fix this in a while.&lt;/p&gt;

&lt;p&gt;Let's not just make our application, but let's make a great UI. Adjust your code to look as below:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Home component&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;TheGreenCodes&lt;/span&gt; &lt;span class="nx"&gt;awesome&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;list-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/b-card&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="nx"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;170&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/style&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor the routes: (This would mean another component under views with the name &lt;code&gt;Completed&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* webpackChunkName: "about" */&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../views/Completed.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our application entry component would also have a link to the completed. section, either as a replacement to the about page or an add-on&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Completed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/router-link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end, we should have something similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsgsfb7koq8flgylmclo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsgsfb7koq8flgylmclo.png" alt="awesome-todo-llanding.png" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a basic layout up, and a first taste of what testing involves. To dive or not to dive is the question I pose to you.&lt;/p&gt;

&lt;p&gt;Hush for a moment and let it settle. We will proceed with our application in an upcoming article.&lt;/p&gt;

&lt;p&gt;Be sure to check the code, if need be, from &lt;a href="https://github.com/TheGreenCodes/awesome-todo/releases/tag/v0.1.0" rel="noopener noreferrer"&gt;TheGreenCodes&lt;/a&gt; repo. Specifically, the project tag &lt;code&gt;awesome-todo v0.1.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Stick around for a while as we delve more into the internals; and yes, we can continue this conversation on tech twitter, where Potato, oh, my bad, &lt;a href="https://twitter.com/miamilarry78" rel="noopener noreferrer"&gt;Larry&lt;/a&gt; and I, &lt;a href="https://twitter.com/marvinus_j" rel="noopener noreferrer"&gt;Marvin&lt;/a&gt;, talk everything between code and smelling flowers over the weekends. &lt;/p&gt;

&lt;p&gt;Peace out.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A small laugh, in case &lt;a href="https://lewiskori.com/" rel="noopener noreferrer"&gt;Lewis&lt;/a&gt;, finds himself here again:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;'Kuingia kimahuru'&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>vue</category>
      <category>webdev</category>
      <category>testing</category>
    </item>
    <item>
      <title>Unit testing in Vue</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Tue, 27 Apr 2021 15:08:50 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/unit-testing-in-vue-3en5</link>
      <guid>https://forem.com/marvinkweyu/unit-testing-in-vue-3en5</guid>
      <description>&lt;p&gt;Hold up! I got a confession to make. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I pushed my code to the master branch without tests. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Until I stumbled upon TDD, I had never really understood the purpose or relevance of tests. I remember writing a whole project without tests and publishing it. Can you believe it? Was I out of my mind blind? &lt;/p&gt;

&lt;p&gt;Thinking about this still gives me heartache. Did the project work? Of course, it did. Until it didn't and I had to spend 3 whole weeks staring into the screen wondering what on earth had gone wrong. I mean, I just added a mini-feature, it should work! Sound familiar?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv69db9n0tkualsioyfgx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv69db9n0tkualsioyfgx.jpeg" alt="software-crash.jpg" width="800" height="715"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This could be us ... but we are writing tests now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We are going to split this up into the fundamental building blocks of all tests, which are; Tests must fail, tests must pass, and the code must be refactored. Let's dive in, shall we?&lt;/p&gt;

&lt;p&gt;First of all, we have outlined the pain that comes from not testing, but not really as to the importance of testing in itself. For a view of this, we would summarize into the below off-the-batt pointers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Giving the developer an understanding of the project requirements from the client's point of view.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this sense, a developer who writes tests following the principles outlined earlier in this piece is made to think in terms of the project requirements earlier on. Which in short says; &lt;em&gt;programming is more thinking than coding&lt;/em&gt;. Once you visualize what you want to achieve before doing it, it significantly reduces the chances of veering off the project in itself. You know this part of the page should display what, where this data comes from and expected results should the fetch not happen. You get the project's aerial view; writing, in the end, smaller modular code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The confidence in shipping without fear of breaking other features of your code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Small project? Sure, fine. Can this scale? How certain are you? What about that last little piece the project manager requested? Will it mean my service or call or method will not work? What about when the project grows larger and we change something? Will we go page by page checking whether each part still works and shows the expected message? Do we have this time?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shorter feedback loop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Shorten the 'x y and x pieces need w z k' feedback loops. When you can tell directly from the onset that this piece of code will not work as it is given how the backend team has refactored the API, you shorten the time it takes for the QA team to notice it, the time it gets to get to you and the time it takes to figure out where in the code you need to fix. You have, at this point, already identified it.&lt;/p&gt;

&lt;p&gt;These, are some of the reasons we write tests. &lt;/p&gt;

&lt;p&gt;So what are some of the ways we can use to get this done? Where do we get started here? Glad you asked.&lt;/p&gt;

&lt;p&gt;To kick us off, we highlight the tools and options.&lt;br&gt;
PS: We are not installing the internet of node_modules in our project, you can breathe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Jest
&lt;/h3&gt;

&lt;p&gt;Created by Facebook, &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt; is an out-of-the-box package that comes bundled with assertion. Plainly, it shows not only that the test fails, but also where it failed; whether variable Y was not equal to X, and so forth. This is necessary more so when you find a test comparing, for instance, an arithmetic sum 5 to a test data of 5, failing, only later to realize that you passed the string '5' instead of an integer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mocha
&lt;/h3&gt;

&lt;p&gt;As an elder brother to its counterpart, &lt;a href="https://mochajs.org/" rel="noopener noreferrer"&gt;Mocha&lt;/a&gt; works just the same way, but with a little bit more configuration. To be precise, you have to include an assertion library separately. Most commonly used as a partner her, would be &lt;a href="https://www.chaijs.com/" rel="noopener noreferrer"&gt;Chai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Whichever of the two most used packages you use is up to preference. It all depends on how customizable your tests need to be and or what you are more comfortable with.&lt;/p&gt;

&lt;p&gt;The two mentioned are global across javascript frameworks. What about the specific framework of choice here in our case (Vuejs)? We could say, we have libraries that make it much easier to test in Vuejs. Specifically, we are talking about &lt;a href="https://vue-test-utils.vuejs.org/" rel="noopener noreferrer"&gt;Vue test utils&lt;/a&gt;, which is the official unit testing utility library for Vue.js and the &lt;a href="https://testing-library.com/docs/vue-testing-library/intro/" rel="noopener noreferrer"&gt;Vue testing library&lt;/a&gt;, an abstraction of the previous. &lt;/p&gt;

&lt;p&gt;So, first, we decide whether we want to use Mocha + Chai or jest, then we go ahead with what works for us between Vue test utils and the vue testing library or perhaps both.&lt;/p&gt;

&lt;p&gt;To engrave this knowledge on testing, we intend to build a simple web application; a ToDo list. With this, we can track items, check them off as done, see what was done, edit items, delete these items, and so forth. Along the way, we use different approaches of testing and ping what one approach has to offer vs the other. Every step of the way will be guided by a systematic approach, to give a clear outline of the intent beforehand. So pause here, for a while at least, as we get our tools ready for the next section of this series.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>testing</category>
    </item>
    <item>
      <title>ColorDetect: Python Image processing algorithms</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Mon, 29 Mar 2021 10:33:14 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/colordetect-python-image-processing-algorithms-494b</link>
      <guid>https://forem.com/marvinkweyu/colordetect-python-image-processing-algorithms-494b</guid>
      <description>&lt;p&gt;It's been a &lt;a href="https://thegreencodes.com/colordetection-python-colordetect-package" rel="noopener noreferrer"&gt;while&lt;/a&gt; since we touched on &lt;a href="https://colordetect.readthedocs.io/en/master/" rel="noopener noreferrer"&gt;ColorDetect&lt;/a&gt;. Having taken an overview of what exactly we could achieve in the past, between getting colors from both images and video and in different formats and counts. We went ahead and described some of the use-cases of such a package, just to mention but a few.&lt;/p&gt;

&lt;p&gt;In this piece, we highlight the improvements we have so far made, along with some notable &lt;a href="https://github.com/MarvinKweyu/ColorDetect#hall-of-code" rel="noopener noreferrer"&gt;contributors&lt;/a&gt; since the piece rolled out. Most notable, &lt;a href="https://twitter.com/onyonkaclifford" rel="noopener noreferrer"&gt;Clifford&lt;/a&gt;, whose algorithms have helped push from v1.1 ... to v1.4. Hurray Cliff!&lt;br&gt;
Let's get down with it.&lt;/p&gt;

&lt;p&gt;In case you still haven't done so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ColorDetect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll take it from the new features and enhancements. Specifically, text customization and color segmentation (which, I realized, came in at just the right time)&lt;br&gt;
In the use of ColorDetect, we faced two to three challenges.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We now have the ability to get the colors off media files, but we want this text in a customizable format. The ability to have our own font and or styling to this text. This comes in handy especially in instances where we have a dark image. We cannot write black text on this and still maintain readability now, can we?&lt;/li&gt;
&lt;li&gt;Hey there, what does an RGB code &lt;code&gt;5.0, 211.0, 212.0&lt;/code&gt; even mean? Can the algorithm give me a more friendly color to decipher?&lt;/li&gt;
&lt;li&gt;Okay great, I can get the percentage colors and dominance off the files I have, but can I tell what this color code or percentage refers to on the image? Can I mark the image to make it visible without guessing?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These, among others, are what we got to tackle. Let's do a quick overview of each. &lt;/p&gt;

&lt;p&gt;To start with, In our virtual environment, we create a file &lt;code&gt;custom_styling.py&lt;/code&gt;, and write our colors and text differently, from the defacto configurations.&lt;/p&gt;

&lt;p&gt;For this, we will use &lt;a href="https://unsplash.com/@nowyouknowgini?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;virginia lackinger's photo&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/flower?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1615216102316%2FUOnemsEiv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1615216102316%2FUOnemsEiv.jpeg" alt="flowers.jpg" width="800" height="532"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;colordetect&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ColorDetect&lt;/span&gt;

&lt;span class="c1"&gt;# parse the image.
&lt;/span&gt;&lt;span class="n"&gt;flowers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ColorDetect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./images/flowers.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;flowers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_color_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human_readable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;flowers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_color_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top_margin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;flowers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./images&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processed-human-image.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output you might ask?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617002212379%2FUt9PK1Eob.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617002212379%2FUt9PK1Eob.jpeg" alt="processed-human-image.jpg" width="640" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A human-readable color display. We gave some space between the text and top section of the image, as well as implicitly clarify that we want a human-friendly color format for the output. We may go further into specification of the font color to write in by parsing &lt;code&gt;font_color=(0,255, 0)&lt;/code&gt; (for green), for instance, to the method &lt;code&gt;write_color_count&lt;/code&gt;. Along with this, comes the &lt;em&gt;font_size, font_thickness, line_type&lt;/em&gt; and &lt;em&gt;left_margin&lt;/em&gt;, among other configurable options.&lt;/p&gt;

&lt;p&gt;Let's take a look at how we separate our colors from the image. With this, we refer to color segmentation. How do we tell which sections, no matter how small, from the given image, are color XYZ? &lt;/p&gt;

&lt;p&gt;We parse in the color ranges we want to grab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;colordetect&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ColorDetect&lt;/span&gt;

&lt;span class="c1"&gt;# parse the image.
&lt;/span&gt;&lt;span class="n"&gt;flowers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ColorDetect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./images/flowers.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# provide a lower and upper range for our target colors
&lt;/span&gt;&lt;span class="n"&gt;monochromatic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;segmented&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flowers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_segmented_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lower_bound&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;upper_bound&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Segmented&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;segmented&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;monochromatic&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;monochromatic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mask image&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grey image&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get four results. For brevity, we show three, assuming you know what gray looks like in an image; more of black and white.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Segmented image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617008333295%2FvbofSI8ni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617008333295%2FvbofSI8ni.png" alt="segmented-image.png" width="640" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;masked image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617008372043%2FRtW1vttTs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617008372043%2FRtW1vttTs.png" alt="mask-image.png" width="640" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;monochromatic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just highlight the color I need. Turn the rest of the image into black white &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617008414022%2Ffm2uxI3ez.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1617008414022%2Ffm2uxI3ez.png" alt="monochromatic.png" width="640" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yatza! It works!&lt;/p&gt;

&lt;p&gt;As of now, we have color codes of the images, in the format we want, and a return of images with our target color-highlighted. The same could be applied to videos, without the segmentation and one or two features, for now.&lt;/p&gt;

&lt;h3&gt;
  
  
  A call to action
&lt;/h3&gt;

&lt;p&gt;We, however, know that much more could be achieved; and that is why we have a call to action. What features would you want to be implemented? What bug did you find? &lt;/p&gt;

&lt;p&gt;For one, &lt;strong&gt;we need more tests&lt;/strong&gt;. Do you feel an aspect of the codebase has not undergone sufficient testing? Let it be known. Get the ColorDetect repo,&lt;br&gt;
take a look at the contribution guidelines and make a pull. &lt;/p&gt;

&lt;p&gt;We can leave it here for a while. Do feel free to go through the &lt;a href="https://colordetect.readthedocs.io/en/latest/index.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; as we update it with one or two features down the road.&lt;/p&gt;

&lt;p&gt;As for this articles code, we have it on &lt;a href="https://github.com/TheGreenCodes/ColorDetectEnhancements" rel="noopener noreferrer"&gt;TheGreenCode's&lt;/a&gt; page&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>python</category>
      <category>datascience</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Launching Django applications</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Sun, 21 Feb 2021 16:29:58 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/launching-django-applications-53ji</link>
      <guid>https://forem.com/marvinkweyu/launching-django-applications-53ji</guid>
      <description>&lt;p&gt;Deployment day, and it's Django. Where to start. We got a server we can SSH into, we got our code and endpoints - if any- ready to be consumed.&lt;/p&gt;

&lt;p&gt;Right here, we are going to look into the best practices in terms of developing our backend applications, or SSRs(if we were using Django templating). Through the process, we elaborate on the whys of having a production-ready application as soon as we create our project as opposed to waiting on the completion of the whole development process.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why now?
&lt;/h4&gt;

&lt;p&gt;For one, a good product is never really finished. There is always that one UI change, that one bug or logic discrepancy, or better yet, user feedback prompting a feature addition - our application must be getting some traction. Look at this in this way, would we wait till we got all our user feedback before optimizing our application for production? What about how we serve our media files? Would we still be serving it directly all through? Would we have passwords to our databases hardcoded? What if I add a feature or adjust a UI on my local setup? Would it break the main production app right off the batt?&lt;/p&gt;

&lt;p&gt;A pointer we are getting to is this: launch your application and make small incremental changes as you go. There is no 'Tadaaa! It works and will never break or be changed!' moment. If you were simply coding as though it was on your machine all through and waiting for the 'perfect' opportunity, you have to STOP. Stop it. Get your application and pipelines up as soon as you start the project. Be production-ready with 'hello world'.&lt;/p&gt;

&lt;p&gt;Enough talk. Let us have something we can work with here. We create a virtual environment, install our dependencies, and have our boilerplate project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GreenCodes ➤ &lt;span class="nb"&gt;mkdir &lt;/span&gt;launch-ready                                                                                                                                       
GreenCodes ➤ &lt;span class="nb"&gt;cd &lt;/span&gt;launch-ready                                                                                                                                          
launch-ready ➤ python &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv                                                                                                                                   
launch-ready ➤ &lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate                                                                                                                              
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; launch-ready ➤
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've made the directory called &lt;code&gt;launch-ready&lt;/code&gt;, our intended application name. We've also created and activated the virtual environment. Go ahead and install Django and create the project while at it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;django
django-admin startproject LaunchReady &lt;span class="nb"&gt;.&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our directory should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; launch-ready ➤ &lt;span class="nb"&gt;ls                                                                                                                                             
&lt;/span&gt;LaunchReady  manage.py
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; launch-ready ➤ &lt;span class="nb"&gt;ls &lt;/span&gt;LaunchReady                                                                                                                                 
asgi.py  __init__.py  settings.py  urls.py  wsgi.py
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; launch-ready ➤
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;python manage.py runserver&lt;/code&gt; will give the default launch page for Django.&lt;/p&gt;

&lt;p&gt;Our application is up and running. To prepare for production, however, we have a couple of things to configure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create production and development settings.
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;LaunchReady&lt;/code&gt; directory has one setting file. Within this directory, we create yet another directory named &lt;code&gt;settings&lt;/code&gt; and move our settings file into it, renaming it in the process to &lt;code&gt;base.py&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;settings
&lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; settings.py settings/base.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create two additional files within the &lt;code&gt;settings&lt;/code&gt; directory and name them &lt;code&gt;dev.py&lt;/code&gt; - to contain development settings - and &lt;code&gt;prod.py&lt;/code&gt; - to have production settings. Our directory ends up looking as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; settings ➤ &lt;span class="nb"&gt;ls                                                                                                                                                 
&lt;/span&gt;base.py  dev.py  prod.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Locally, on our development machine, we will opt for our local installation of MySQL. Go ahead and create a database and user then head over back for the next step. &lt;/p&gt;

&lt;p&gt;As with best practice in terms of version control, &lt;strong&gt;never store your passwords in code&lt;/strong&gt;. Opt at all times, for the environment variables. To manage this, we create a &lt;code&gt;.env&lt;/code&gt; file that will never make it past our local machine. Just to be sure, we add it to the &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; .env &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then, go ahead and install  &lt;code&gt;python-dotenv&lt;/code&gt; (to read the variables from the .evn file )and &lt;code&gt;mysqlclient&lt;/code&gt; (a wrapper  to interact with MySQL from Django).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;python-dotenv mysqlclient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our development settings will look as below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dev.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;LaunchReady.settings.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# since it's running on my machine, show me the errors
&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ENGINE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django.db.backends.mysql&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABASE_NAME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;USER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABASE_USER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABASE_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HOST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABASE_HOST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# show mail messages on the terminal
&lt;/span&gt;&lt;span class="n"&gt;EMAIL_BACKEND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django.core.mail.backends.console.EmailBackend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# run on every host.
&lt;/span&gt;&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we have our environment variables being read from within the development settings, but where do we set these items. Simple. We create a &lt;code&gt;.env&lt;/code&gt; file next to our &lt;code&gt;dev&lt;/code&gt; settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; settings ➤ &lt;span class="nb"&gt;ls&lt;/span&gt;  &lt;span class="nt"&gt;-a&lt;/span&gt;                                                                                                                                               
base.py  dev.py  prod.py .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file content?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SECRET_KEY = 'django-generated-secret-key'
DATABASE_NAME=database_name
DATABASE_USER=database_user
DATABASE_PASSWORD=database_password
DATABASE_HOST=localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: We can have multiple ways with the database and secret key configuration. It is not linear.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For our production application, we take the example off of Heroku. This works the same as with any other server we might get, with one or two tweaks.&lt;/p&gt;

&lt;p&gt;We install &lt;code&gt;dj-database-url&lt;/code&gt; - a python package that lets us read and perform actions on the database in the event it was on a separate platform or other from our main application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;dj-database-url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This, we use in our production-ready settings as below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;prod.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dj_database_url&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;LaunchReady.settings.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;


&lt;span class="n"&gt;ADMINS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Developer name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Developer email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),)&lt;/span&gt;

&lt;span class="c1"&gt;# always set this to false in production
&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;launch-ready-domain.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;server-ip-address&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;DATABASES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dj_database_url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn_max_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ssl_require&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# ToDo: get an email host provider
&lt;/span&gt;&lt;span class="n"&gt;EMAIL_BACKEND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django.core.mail.backends.smtp.EmailBackend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;EMAIL_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;smtp.gmail.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;EMAIL_HOST_USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMAIL_HOST_USER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;EMAIL_HOST_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMAIL_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;EMAIL_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;587&lt;/span&gt;
&lt;span class="n"&gt;EMAIL_USE_TLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As our &lt;code&gt;DEBUG&lt;/code&gt; is set to &lt;code&gt;False&lt;/code&gt;, we, instead of getting the &lt;em&gt;not found&lt;/em&gt; error, want to get a notification via mail. This is especially so when one of our views returns an exception. In this case, we set the developer(s) responsible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ADMINS &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"Developer name"&lt;/span&gt;, &lt;span class="s2"&gt;"Developer email"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we have our Linux server up. We create persistent environment variables, this time, read from the bash configuration files, setting them in either, &lt;code&gt;/etc/environment&lt;/code&gt; (for system-wide environment configuration), or in &lt;code&gt;~/.bashrc&lt;/code&gt;- for per-user configuration in case we have multiple.&lt;/p&gt;

&lt;p&gt;** /etc/environment**&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="c"&gt;# this is common with heroku and can be set via the console or dashboard interface&lt;/span&gt;
&lt;span class="nv"&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="nv"&gt;EMAIL_HOST_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="nv"&gt;EMAIL_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only major difference from the previous development setting would be how we read our database configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;DATABASES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dj_database_url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn_max_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ssl_require&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would be how we configure our application to read from an external database from our application server location.&lt;/p&gt;

&lt;p&gt;Let's try this run. Go to your shell and run your development server. Remember, we nested and split our settings. So to run anything while in development, we have to remind Django which settings we want to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py runserver &lt;span class="nt"&gt;--settings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;LaunchReady.settings.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymrfy7bleaorlfzv1nbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymrfy7bleaorlfzv1nbv.png" alt="Screenshot_20210221_170356.png" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our application default template is back up. &lt;br&gt;
For production, we would have it run as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py runserver 0.0.0.0:8000 &lt;span class="nt"&gt;--settings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;LaunchReady.settings.prod

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Launch your browser and head to &lt;code&gt;http://launch-ready-domain.com:8000&lt;/code&gt;. You should get the very same page as with your development environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  What next?
&lt;/h3&gt;

&lt;p&gt;Of course, there's more in terms of deployment server settings and configuration, especially in terms of serving static files. This, however, can be left for the next hour. We touch base with this rather lengthy piece as we fuel up and do this further in the next, and yes, the code can be accessed right off &lt;a href="https://github.com/TheGreenCodes/LaunchReady" rel="noopener noreferrer"&gt;TheGreenCodes&lt;/a&gt; repository.&lt;/p&gt;

&lt;p&gt;Till next time,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegreencodes.com/" rel="noopener noreferrer"&gt;TheGreenCodes&lt;/a&gt; &lt;/p&gt;

</description>
      <category>django</category>
      <category>tutorial</category>
      <category>python</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Data structures: The linear non-primitives</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Wed, 16 Dec 2020 11:16:42 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/data-structures-the-linear-non-primitives-24ll</link>
      <guid>https://forem.com/marvinkweyu/data-structures-the-linear-non-primitives-24ll</guid>
      <description>&lt;p&gt;On our first set of data structures, we get into the definition and scope of non-primitive structures. Have a look at the previous read on  &lt;a href="https://thegreencodes.com/the-power-of-data-structures" rel="noopener noreferrer"&gt;The Power of Data structures&lt;/a&gt; in case you feel a little lost. Right off the batt, we define what it means to be a non-primitive set, and how this can be further broken down.&lt;/p&gt;

&lt;p&gt;Let's get right into it. A non-primitive structure is what happens when you combine two or more primitives. What we mean is simple. A &lt;code&gt;char&lt;/code&gt; and  &lt;code&gt;int&lt;/code&gt; , for instance,  are primitives. The simplest representations of data. &lt;/p&gt;

&lt;p&gt;Broadly speaking, linear non-primitives can be grouped further as below:&lt;/p&gt;

&lt;h2&gt;
  
  
  Linear non-primitives
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Stacks&lt;/li&gt;
&lt;li&gt;Queues&lt;/li&gt;
&lt;li&gt;LInked lists&lt;/li&gt;
&lt;li&gt;Arrays&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, as stated before, data is sequential - one after another. Some of these structures might &lt;a href="https://thegreencodes.com/memory-management-deep-and-shallow-copying" rel="noopener noreferrer"&gt;ring a bell&lt;/a&gt;, stackify, is that you?. &lt;/p&gt;

&lt;h3&gt;
  
  
  Arrays
&lt;/h3&gt;

&lt;p&gt;These are what we call stores of homogenous (meaning similar) data. So one might have an array like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my_array = [1,2,3,4,5,6,7,8,9] ;

vowels = [' a', 'e', 'i' , 'o', 'u' ] ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how &lt;code&gt;my_array&lt;/code&gt; has only integers while &lt;em&gt;vowels&lt;/em&gt; has &lt;em&gt;char&lt;/em&gt;. In both instances, our array has a collection of primitives - &lt;strong&gt;one type of primitive per array&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Arrays are of a fixed size. Once declared, the computer knows the amount of memory reserved for items to be stored there.  You might ask:&lt;/p&gt;

&lt;p&gt;*"But what if the type of data I have changes in size greater than the array?" *&lt;/p&gt;

&lt;p&gt;Well, you might need to consider a different type of structure to store this data. &lt;br&gt;
Use arrays, for instance, to store months of the year. We will not be changing this count anytime.&lt;/p&gt;

&lt;p&gt;Above declared, the sizes of the arrays are inferred. Meaning the types, since not defined per se, are  'figured out' based on the values and how we use them.&lt;/p&gt;

&lt;p&gt;We might as well have this:&lt;/p&gt;

&lt;p&gt;For python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;

&lt;span class="n"&gt;count_down&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;i&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# where *i* stands for int (an array of integers).
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Types may go on as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;c&lt;/code&gt; for &lt;em&gt;char&lt;/em&gt;&lt;br&gt;
&lt;code&gt;f&lt;/code&gt; for &lt;em&gt;float&lt;/em&gt;&lt;br&gt;
&lt;code&gt;d&lt;/code&gt; for &lt;em&gt;double&lt;/em&gt;&lt;br&gt;
&lt;code&gt;u&lt;/code&gt; for &lt;em&gt;unicode&lt;/em&gt; and so forth.&lt;/p&gt;

&lt;p&gt;Have a look at the &lt;a href="https://docs.python.org/3/library/array.html?highlight=arrays" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more insight into this. AS well, take note that the &lt;code&gt;array module&lt;/code&gt; has different functions to enable array manipulation.&lt;/p&gt;

&lt;p&gt;Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;count_down&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// where *i32* is signed integers, and *5* in *[i32; 5]* is the size of the array. i.e have five integers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Important pointer:&lt;br&gt;
    Python lists and arrays are not the same!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Operations on an array will be based on the &lt;code&gt;index&lt;/code&gt; of the array element, with indexing starting from &lt;em&gt;0&lt;/em&gt;. Hence, the first item, in either case, would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;count_down[0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result from the above is 5 (the semi-colon has been left out for brevity but should be used based on the language you are using).&lt;/p&gt;

&lt;p&gt;Let's take a look at another structure that looks similar, but is not the same - &lt;strong&gt;Linked lists&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linked lists
&lt;/h3&gt;

&lt;p&gt;Unlike arrays, linked lists store data in a non-contiguous form. This implies one piece of data is not placed side by side to the other as: &lt;code&gt;[1,2,3,4,5]&lt;/code&gt;, rather it is stored in form of nodes with pointers to the next as so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[data1, pointer_to_data2] ...  [data1, pointer_to_data3] ... and so on

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhsfd6ozls3e7he28azn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhsfd6ozls3e7he28azn.png" alt="linked_list.png" width="511" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last item in our linked list, since there is no pointer to the next, would have &lt;code&gt;null&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;As well, linked lists are dynamic-  their size is not fixed at initialization. &lt;/p&gt;

&lt;p&gt;Linked lists will be further broken to:&lt;/p&gt;

&lt;p&gt;a) Singular linked lists (used in the elaboration of linked lists above)&lt;/p&gt;

&lt;p&gt;b) Circular linked lists&lt;/p&gt;

&lt;p&gt;c) Doubly linked lists&lt;/p&gt;

&lt;h4&gt;
  
  
  Circular linked lists
&lt;/h4&gt;

&lt;p&gt;These have three items in a node: the previous data, the data, and finally, the next data in the sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[null, data1, pointer_to_data2] ...  [pointer_to_data_1 ,data1, pointer_to_data3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first item (the head), has a &lt;code&gt;null&lt;/code&gt; as the previous pointer while the last node has &lt;code&gt;null&lt;/code&gt; on the next pointer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Doubly linked lists
&lt;/h4&gt;

&lt;p&gt;Similar to circular linked lists, these have two pointers as well. The only difference would be the last node, instead of a &lt;code&gt;null&lt;/code&gt;, has a pointer back to the first item in the list. 1 + 1 = circular.&lt;/p&gt;

&lt;p&gt;In most of what we implement through code, we have implementations of linked lists. You will hardly get yourself doing this manually, but understanding that some of the things we call 'mutable arrays ' are actually implementations or wrappers around more complex structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
If navigating through my directory, my computer needs to know where I am, where I'm from, and possibly have the correct link/structure to the nested directory I'm navigating to. So to the top-level directory, I cannot go any higher, no previous node. Likewise to the last directory or file, there is no 'next' option.&lt;/p&gt;

&lt;p&gt;Till now, we have come to understand the importance of data structures, the groups they have been placed into, and we have an idea of what some of the linear data structures involved. We could go on and on on the details of each, but that is a tale for another day. A breather for us both at this point.  Go read something non-algorithm-like for a moment. We'll still meet here, same time,  same drive. &lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>datastructures</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>The Power of Data Structures</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Wed, 18 Nov 2020 12:38:38 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/the-power-of-data-structures-1aj2</link>
      <guid>https://forem.com/marvinkweyu/the-power-of-data-structures-1aj2</guid>
      <description>&lt;p&gt;A trip down memory lane avid reader. Let's take a walk through the core of it all: data structures. What are they and why are they so important? A 'hello' to a reader that might have missed our talk on &lt;a href="https://thegreencodes.com/memory-management-deep-and-shallow-copying" rel="noopener noreferrer"&gt;Memory management&lt;/a&gt;, where we delved into what happens to our code in variable assignment. Do take a look, even if it's a refresher you're looking for.&lt;/p&gt;

&lt;p&gt;Alright then. What is a data structure?&lt;/p&gt;

&lt;p&gt;It's a way of organizing data. Say we have a couple of friends coming over for our fortnightly game night( ah...the things on our to-do list). We need snacks, a number of people expected to be there, a list of activities to partake. I can go on and on. So how do we organize this in say a program we want to implement to fix the hustle of planning? How do we store the things to be done or the items to be purchased? It's all data in the end. We need structure. We need data structures. The how of getting our data and manipulating it from these structures are our algorithms.&lt;/p&gt;

&lt;p&gt;Right back to our game, who will do what? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn49pf1x11ey9o4wtcxs5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn49pf1x11ey9o4wtcxs5.jpeg" alt="adeolu-eletu-DqWEAOHsAvc-unsplash.jpg" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do we decide what comes before what in terms of structuring this data? Does our simple program make it easy to retrieve this information? Is it fast enough? What about efficiency?&lt;/p&gt;

&lt;p&gt;Whatever kind of application we are talking about, we need a data structure(s) that will allow traversing, insertion, searching, deletion( in case the last casserole was outright nasty), sorting, or merging of bits of data. Call it CRUD with extra steps.&lt;/p&gt;

&lt;p&gt;As from the Memory management article, we got data, then collections of data. It's all data. While memory allocation might not be something we think of with javascript of even Python, it holds water when doing &lt;strong&gt;C&lt;/strong&gt; or &lt;strong&gt;C++&lt;/strong&gt;. So keep this in mind. &lt;/p&gt;

&lt;p&gt;Broadly speaking, we group data structures, much like data types in itself, as:&lt;/p&gt;

&lt;p&gt;a) Primitive&lt;/p&gt;

&lt;p&gt;b) Non-primitive&lt;/p&gt;

&lt;p&gt;Primitive structures would hold primitive data types; that is the &lt;em&gt;chars&lt;/em&gt;, the &lt;em&gt;int&lt;/em&gt; the &lt;em&gt;float&lt;/em&gt;. Basically, data types that hold a single value.&lt;/p&gt;

&lt;p&gt;Non-primitive structures, on the other hand, break down to &lt;strong&gt;linear&lt;/strong&gt; (which holds data in a sequence) and of course &lt;strong&gt;non-linear&lt;/strong&gt;. Hold your breath in case you lost it a moment there. We'll go into the details soon enough.&lt;/p&gt;

&lt;p&gt;As of now, you have a general idea, a scope if you may, of what structures involve.&lt;br&gt;
They are quite a number.&lt;/p&gt;

&lt;p&gt;Over the course of the next couple of weeks, we'll be covering some of these structures. Unraveling them to bits and pieces. Finding what makes them tick as so and getting why many a time, developers new and old alike, have challenges addressing them. Stick a while, I cannot wait for our next piece in this!&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ColorDetection - Python ColorDetect package</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Mon, 28 Sep 2020 07:04:11 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/colordetection-python-colordetect-package-12li</link>
      <guid>https://forem.com/marvinkweyu/colordetection-python-colordetect-package-12li</guid>
      <description>&lt;p&gt;Images. That's it. Images. As a point of practicality, take a fashion designer (as a forum member vividly described to me at one point). You are given an image or have an image at your disposal that simply tickles your curiosity and want to incorporate it in one of your new lines. Let's swerve a little into the genetics section. Given a petri dish image for instance, with pigmented bacteria or similar organisms, and you would like to find the abundance of that organism or organisms in this specific image. Get the gist?&lt;/p&gt;

&lt;p&gt;That's why we have &lt;a href="https://colordetect.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;ColorDetect&lt;/a&gt;. Letting you knab those colors right from the image, or if you were a tad bit crazy, a video. For an overview, we'll kick it off by installation.&lt;/p&gt;

&lt;p&gt;As all Pythonistas have it, create a virtual environment, and install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;ColorDetect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this demonstration, we'll borrow Greyson Joralemon's photo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frva6pek2jvjdzo9wr771.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frva6pek2jvjdzo9wr771.jpeg" alt="random_balls.jpg" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A program that gets the colors in this specific image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;colordetect&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ColorDetect&lt;/span&gt;

&lt;span class="n"&gt;user_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ColorDetect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;media/random_balls.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_color_count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ColorDetect will go, do its thing and return this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python get_colors.py

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'[59.0, 70.0, 198.0]'&lt;/span&gt;: 7.63, &lt;span class="s1"&gt;'[245.0, 155.0, 186.0]'&lt;/span&gt;: 9.0, &lt;span class="s1"&gt;'[232.0, 22.0, 103.0]'&lt;/span&gt;: 11.98, &lt;span class="s1"&gt;'[207.0, 143.0, 3.0]'&lt;/span&gt;: 35.54, &lt;span class="s1"&gt;'[88.0, 70.0, 34.0]'&lt;/span&gt;: 35.85&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A color description of the image, breaking down the relevant most abundant colors to say, hey, this image has &lt;code&gt;7.63 %&lt;/code&gt; of it occupied by this &lt;strong&gt;RGB&lt;/strong&gt; color: &lt;code&gt;'[59.0, 70.0, 198.0]'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we wanted the &lt;strong&gt;hex&lt;/strong&gt; for this instead, we'd pass that as the parameter to &lt;code&gt;get_color_count()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_color_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#colors
# {'#3b46c6': 7.63, '#f59bba': 9.0, '#e81667': 11.99, '#cf8f03': 35.56, '#584622': 35.83}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could, of course, look for more color than just five of the most dominant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;user_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_color_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the size or ratio of the image, it may take a moment. A case in point, a low graphic image, say 2MP vs a high definition top of the line camera image. These two images, despite pointing to the same object or scene, have very different pixel ratios.&lt;/p&gt;

&lt;p&gt;Let's go ahead, and instead of getting the color as a variable, write this color onto the image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="n"&gt;user_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_color_count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# save the image after writing the color count to it
&lt;/span&gt;&lt;span class="n"&gt;user_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;media&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processed.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We save this image in the media directory with a name &lt;code&gt;processed.jpg&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qbvz6t55y4jegwnjssf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qbvz6t55y4jegwnjssf.jpeg" alt="processed.jpg" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfecto!&lt;/p&gt;

&lt;p&gt;we did have something about the crazy people with videos, didn't we?&lt;br&gt;
Now, where is that video...oh, &lt;a href="https://github.com/TheGreenCodes/ColorDetectPreview/blob/master/media/earth.mp4" rel="noopener noreferrer"&gt;here it is&lt;/a&gt;. Our &lt;em&gt;earth.mp4&lt;/em&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;colordetect&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VideoColor&lt;/span&gt;


&lt;span class="n"&gt;my_video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;VideoColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;media/earth.mp4&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;video_colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_video_frames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;video_colors&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{'[137.0, 165.0, 182.0]': 0.92, '[71.0, 84.0, 95.0]': 2.16, '[24.0, 30.0, 50.0]': 11.17, '[7.0, 10.0, 26.0]': 17.59, '[0.0, 0.0, 0.0]': 68.83, '[143.0, 170.0, 187.0]': 0.84, '[76.0, 89.0, 101.0]': 2.09, '[26.0, 32.0, 52.0]': 11.18, '[8.0, 11.0, 28.0]': 16.69, '[135.0, 163.0, 181.0]': 0.95, '[76.0, 88.0, 98.0]': 2.05, '[8.0, 11.0, 27.0]': 15.43, '[127.0, 160.0, 179.0]': 0.94, '[71.0, 83.0, 94.0]': 2.38, '[7.0, 11.0, 27.0]': 15.72, '[124.0, 160.0, 181.0]': 0.9, '[69.0, 84.0, 96.0]': 2.26, '[26.0, 32.0, 53.0]': 13.12, '[125.0, 160.0, 182.0]': 0.89, '[68.0, 82.0, 95.0]': 2.27, '[132.0, 166.0, 186.0]': 0.79, '[71.0, 87.0, 100.0]': 2.1, '[25.0, 32.0, 52.0]': 14.18, '[132.0, 164.0, 183.0]': 0.89, '[70.0, 85.0, 97.0]': 2.08, '[132.0, 165.0, 183.0]': 0.9, '[73.0, 88.0, 99.0]': 2.06, '[26.0, 33.0, 53.0]': 12.11, '[8.0, 10.0, 27.0]': 16.76, '[134.0, 166.0, 184.0]': 0.88, '[132.0, 165.0, 185.0]': 0.86, '[74.0, 88.0, 100.0]': 2.0, '[26.0, 33.0, 52.0]': 10.65, '[7.0, 10.0, 27.0]': 16.93, '[124.0, 157.0, 178.0]': 0.99, '[68.0, 82.0, 93.0]': 2.14, '[25.0, 31.0, 50.0]': 10.66, '[124.0, 160.0, 182.0]': 0.88, '[67.0, 82.0, 94.0]': 2.19, '[25.0, 31.0, 49.0]': 10.68, '[124.0, 160.0, 183.0]': 0.85, '[67.0, 83.0, 95.0]': 2.0, '[25.0, 30.0, 49.0]': 11.04, '[123.0, 160.0, 182.0]': 0.87, '[24.0, 29.0, 47.0]': 11.15, '[23.0, 29.0, 47.0]': 10.6, '[6.0, 9.0, 26.0]': 19.34, '[67.0, 83.0, 97.0]': 2.0, '[24.0, 29.0, 48.0]': 9.31, '[125.0, 161.0, 184.0]': 0.85, '[67.0, 84.0, 97.0]': 1.98, '[127.0, 162.0, 183.0]': 0.87, '[67.0, 83.0, 96.0]': 1.96, '[23.0, 29.0, 46.0]': 8.58, '[5.0, 8.0, 25.0]': 17.77, '[125.0, 161.0, 183.0]': 0.88, '[68.0, 84.0, 98.0]': 1.9, '[24.0, 29.0, 46.0]': 6.95, '[67.0, 84.0, 99.0]': 1.89, '[133.0, 166.0, 186.0]': 0.81, '[67.0, 86.0, 99.0]': 1.85, '[23.0, 28.0, 45.0]': 6.83, '[5.0, 8.0, 24.0]': 22.22, '[135.0, 165.0, 186.0]': 0.85, '[69.0, 86.0, 100.0]': 1.79, '[22.0, 27.0, 43.0]': 7.22, '[5.0, 7.0, 24.0]': 22.48, '[73.0, 91.0, 105.0]': 1.69, '[129.0, 163.0, 185.0]': 0.85, '[69.0, 85.0, 98.0]': 1.9, '[21.0, 27.0, 44.0]': 7.25, '[4.0, 7.0, 24.0]': 21.7, '[68.0, 86.0, 101.0]': 1.9, '[22.0, 27.0, 45.0]': 7.91, '[126.0, 160.0, 181.0]': 0.94, '[66.0, 83.0, 96.0]': 1.91, '[22.0, 27.0, 46.0]': 9.19, '[129.0, 164.0, 185.0]': 0.84, '[69.0, 86.0, 99.0]': 1.96, '[21.0, 27.0, 46.0]': 10.65, '[133.0, 165.0, 185.0]': 0.85, '[23.0, 29.0, 48.0]': 10.61, '[7.0, 9.0, 26.0]': 17.7, '[135.0, 165.0, 185.0]': 0.85, '[73.0, 88.0, 100.0]': 1.96, '[24.0, 29.0, 50.0]': 11.34, '[139.0, 164.0, 177.0]': 0.92} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We may find the colors are too much for our use case. So let's shorten this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;color_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{'[0.0, 0.0, 0.0]': 68.83, '[5.0, 7.0, 24.0]': 22.48, '[5.0, 8.0, 24.0]': 22.22, '[4.0, 7.0, 24.0]': 21.7, '[6.0, 9.0, 26.0]': 19.34, '[5.0, 8.0, 25.0]': 17.77}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return the top 6 most dominant colors from the whole video, having taken a frame for every second. Looks much better! Unless you want to use all the colors, that is.&lt;/p&gt;

&lt;p&gt;I'll iterate on this. This all depends on the quality of the input media file, and length if it is a video in this case. take it this way, a video 5 minutes long, showing a wide variety of colors from all sorts of crayons vs a short video as just shown. Remember, the process is per frame of every second. I'm certain this will be addressed in a future &lt;a href="https://colordetect.readthedocs.io/en/latest/contributing.html#contributing" rel="noopener noreferrer"&gt;release&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can hold off here and let the steam cool off.&lt;br&gt;
Do keep up to date with the &lt;a href="https://github.com/MarvinKweyu/ColorDetect" rel="noopener noreferrer"&gt;package&lt;/a&gt; as more features and performance improvements come to light. &lt;/p&gt;

&lt;p&gt;Yours, &lt;/p&gt;

&lt;p&gt;&lt;a href="https://thegreencodes.com/" rel="noopener noreferrer"&gt;TheGreencodes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>datascience</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Memory management - Deep and Shallow Copying</title>
      <dc:creator>Marvin</dc:creator>
      <pubDate>Sat, 22 Aug 2020 16:58:00 +0000</pubDate>
      <link>https://forem.com/marvinkweyu/memory-management-deep-and-shallow-copying-2h78</link>
      <guid>https://forem.com/marvinkweyu/memory-management-deep-and-shallow-copying-2h78</guid>
      <description>&lt;p&gt;Let's go back one moment. A little further down to our data structures. The dear heaps and stacks of them.Quite literally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens when I assign a variable? What about when I pass it as a parameter?&lt;br&gt;
How does the program know this is what I'm talking about?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before we go to a higher level of abstraction, that is, looking at it like a note title taken on a piece of paper so that you can flip the page and just look at the variable value, we should look at how the machine 'thinks' about it. &lt;/p&gt;

&lt;p&gt;Close your eyes for a moment and declare a variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my_variable = "random";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See, when you do this, you're adding to the list of things the program has to remember. It's like one on top of another of 'cart' lists. A stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598087724622%2FcxRROkqIl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598087724622%2FcxRROkqIl.png" alt="basic_stack.png" width="201" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As it stands, your program will store your string as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598088168386%2FriNQRru31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598088168386%2FriNQRru31.png" alt="memory_management.png" width="601" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where the first diagram with the pointer(location of the variable in memory), len(for the length of the string) and capacity(the amount of memory, in bytes, the machine gives to this variable for use) is a stack and the other is a heap. Whatever we do with this variable, be it a mutation, concatenation, making a substring or whatever there is, refers to the stack.&lt;br&gt;
In the stack, the pointer holds the location of where the actual data is stored. So we are just given a reference to it.&lt;/p&gt;

&lt;p&gt;Why do we do this? Why do we store it in different data structures?&lt;/p&gt;

&lt;p&gt;Simple. It's about the speed.&lt;/p&gt;

&lt;p&gt;Stacks are faster compared to heaps. So instead of moving around a whole chunk of data(the heap) while mutating it, just carry the reference to it. I mean, the program is already doing its tasks (whether heavy or not), so there is no need to add overhead here.&lt;/p&gt;

&lt;p&gt;A point to remember, not all data is assigned as such. For &lt;strong&gt;static data types&lt;/strong&gt;, that is, &lt;em&gt;boolean, integers, floats&lt;/em&gt;, and &lt;em&gt;chars&lt;/em&gt;, variables are added directly onto the stack. So we would have no heap to store a simple &lt;em&gt;456.98&lt;/em&gt; because the sizes of these types are already known by the program except in the rare case it is user input! &lt;/p&gt;

&lt;p&gt;The size of these types, more so numbers(integers and floats), are determined based on whether they can be negative (signed) or exclusively positive(unsigned). This should remind you of how you declare your variables in math. You would say that any number in your paper is positive unless stated otherwise, or as we call it here unless signed. &lt;/p&gt;

&lt;p&gt;So this assignment would work with &lt;strong&gt;compound data types&lt;/strong&gt; - the result of combining two or more &lt;em&gt;static types&lt;/em&gt;*. &lt;/p&gt;

&lt;p&gt;Example: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;string (a combination of chars)&lt;/li&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;tuples
... and so forth, depending on how your language of choice calls it, for instance, dictionary vs javascript object.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Back to copying.
&lt;/h4&gt;

&lt;p&gt;You want two variables to refer to the same thing and you want to edit one of the variables without affecting the other.&lt;br&gt;
I suppose you could assume a simple re-assignment, right?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my_variable = "random"

my_other_variable = my_variable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether it's &lt;code&gt;console.log()&lt;/code&gt;, &lt;code&gt;print()&lt;/code&gt; or &lt;code&gt;printf()&lt;/code&gt;, (choose your weapon and let's make the battle legendary!), anything that your muscle memory has right now. The two will show &lt;code&gt;random&lt;/code&gt; in stdout/ output. The caveat?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598089540489%2F3RvVS6He1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598089540489%2F3RvVS6He1.png" alt="memory_management3.png" width="621" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, you've duplicated the stack, &lt;strong&gt;not the heap&lt;/strong&gt;. Being as it is, every language's goal at optimum performance. Keeping it as tidy and efficient as possible. No overhead. Pointing to the same memory space.&lt;/p&gt;

&lt;p&gt;So what happens if I mutate one variable?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;my_other_variable&lt;/span&gt;  &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ramblings&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; 

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My second variable: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;my_other_variable&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My variable: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;my_variable&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both cases, the output is a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;random
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get completely two different items with the same data, in that both can be mutated independently, you have to take a different approach; &lt;strong&gt;deep copy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A warning&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As far as memory is concerned, deep copying is memory consuming as it has to get the pointer and follow it to where the data is stored then duplicate this heap.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Depending on what language you are using, we have the inbuilt &lt;code&gt;copy&lt;/code&gt; module in python,  javascript and or copy for lower-level languages and so on and so forth (We cannot simply list all the ways to deep copy across the multiverse)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;

&lt;span class="n"&gt;my_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;random&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;my_other_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deepcopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_variable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Love javascript much?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;my_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ramblings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;


&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;my_second_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;my_variable&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;


&lt;span class="nx"&gt;my_second_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;random &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;my_second_variable&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My first variable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;my_variable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My second variable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;my_second_variable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are, of course, other multiple ways of doing this. It is, after all, javascript.&lt;br&gt;
A point to mark, especially with objects, [lodash](&lt;a href="https://lodash.com/" rel="noopener noreferrer"&gt;https://lodash.com/&lt;/a&gt;], dearest &lt;a href="https://ramdajs.com/" rel="noopener noreferrer"&gt;ramda&lt;/a&gt; or &lt;a href="https://github.com/davidmarkclements/rfdc]" rel="noopener noreferrer"&gt;rfdc&lt;/a&gt; work perfectly. Custom method for your implementation? Go ahead, just not &lt;code&gt;JSON.stringify()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The mad rustacean?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;my_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"random"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;my_other_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_variable&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having done this, you can manipulate your new variables in any way you want. Go to the moon if need be. Just need a couple of dollars more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598093390452%2Fa362yWnpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1598093390452%2Fa362yWnpn.png" alt="memory_management_deep_copy.png" width="657" height="657"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is this same principle that governs the passing of variables across functions and objects. Passing a pointer to the original data and not the whole &lt;code&gt;heap&lt;/code&gt;. Comprende? I sure hope so. So go forth and choose wisely.&lt;/p&gt;

&lt;p&gt;Let's leave this piece at that, and chat in the comments if need be. &lt;/p&gt;

&lt;p&gt;And yes, we can chat tech on twitter too. &lt;a href="https://twitter.com/marvinus_j" rel="noopener noreferrer"&gt;marvinus_j&lt;/a&gt;&lt;/p&gt;

</description>
      <category>datastructures</category>
      <category>management</category>
      <category>memorymanagement</category>
      <category>memory</category>
    </item>
  </channel>
</rss>
