<?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>DEV Community: Sihan Tawsik</title>
    <description>The latest articles on DEV Community by Sihan Tawsik (@sihantawsik).</description>
    <link>https://dev.to/sihantawsik</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%2F342399%2F85ac9bf0-0ac4-48c9-abef-1cca08514f57.jpg</url>
      <title>DEV Community: Sihan Tawsik</title>
      <link>https://dev.to/sihantawsik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sihantawsik"/>
    <language>en</language>
    <item>
      <title>Junior Dev Mistakes: What I Wish I Knew Sooner</title>
      <dc:creator>Sihan Tawsik</dc:creator>
      <pubDate>Sun, 30 Mar 2025 08:43:21 +0000</pubDate>
      <link>https://dev.to/sihantawsik/junior-dev-mistakes-what-i-wish-i-knew-sooner-amd</link>
      <guid>https://dev.to/sihantawsik/junior-dev-mistakes-what-i-wish-i-knew-sooner-amd</guid>
      <description>&lt;p&gt;As they say, "The expert in anything was once a beginner." However, no one tells you how messy that beginning can be. You must experience it firsthand to grasp its depth.&lt;/p&gt;

&lt;p&gt;When I started my career as a software engineer, I thought I had to prove myself by figuring everything out on my own. I spent hours debugging issues that turned out to be silly mistakes, nodded along in meetings while secretly Googling terms, and somehow managed to break things I didn't even touch. At one point, I seriously considered adding 'professional Stack Overflow user' to my résumé.&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%2Fkamb7x4jbsc9biz1sik7.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%2Fkamb7x4jbsc9biz1sik7.png" alt="professional Stack Overflow user" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're feeling overwhelmed, second-guessing yourself, or wondering if you even belong, buckle up and hop on the bandwagon. We've all been there, and trust me, the ride gets easier. Here’s what I wish I had known sooner!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Code for humans, not just machines
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”&lt;/em&gt; - Martin Fowler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As developers, it's tempting to flex—writing clever one-liners, cramming logic into fewer characters, or over-engineering for the sake of it. But code isn’t just for machines—it’s for future you, your teammates, and anyone stuck maintaining it. Trust me, it’s not worth it in the long run.&lt;br&gt;
If your code looks like an ancient spellbook, you’re doing it wrong. No one should need a decoder ring or a PhD in hieroglyphics just to figure out what you wrote.&lt;br&gt;
Instead of writing code that’s &lt;em&gt;impressive&lt;/em&gt;, write code that’s &lt;em&gt;clear&lt;/em&gt;.&lt;br&gt;
You should always:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep it simple – Clear names and straightforward logic &amp;gt; clever hacks.&lt;/li&gt;
&lt;li&gt;Break it down – Small functions, modular code, readable flow.&lt;/li&gt;
&lt;li&gt;Avoid over-engineering – If it needs a diagram to understand, you might want to rethink it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good code isn’t just about making computers understand—it’s about making life easier for the next person who reads it (which is probably you).&lt;/p&gt;

&lt;p&gt;Write less spaghetti, embrace readability, and return to monke.&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%2Fgpfdb0wk5i2s5f6v7kaq.jpg" 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%2Fgpfdb0wk5i2s5f6v7kaq.jpg" alt="Return to monke" width="607" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. RTFM: Read the Docs or Debug Forever
&lt;/h2&gt;

&lt;p&gt;I’ve been there, staring at my screen, convinced my code is flawless, yet somehow it refuses to work. Hours pass, Stack Overflow tabs multiply, frustration builds—only to realize the answer was sitting in the documentation all along.&lt;/p&gt;

&lt;p&gt;Skipping the docs feels faster at first. Who needs official guides when you can just “figure it out”? But then, three hours later, you’re questioning your career choices, rewriting half your codebase, and preparing to submit yourself to the dark art of print debugging.&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%2Fp8xy1jgd45b1trqqasto.jpg" 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%2Fp8xy1jgd45b1trqqasto.jpg" alt="read documentation" width="800" height="921"&gt;&lt;/a&gt;&lt;br&gt;
Before engaging in some hacky, overcomplicated solution, pause and read the docs. Chances are, someone has already solved your problem—and documented it. Reading first saves time, pain, and your last shred of sanity.&lt;br&gt;
The reality? Reading the docs first saves time, pain, and your last shred of sanity. The moment you finally open the documentation and everything just works—it’s like finding the cheat code to development. A true ‘Why didn’t I do this sooner?’ moment.&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%2Fcnk96tzizo4ykjthwfx1.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%2Fcnk96tzizo4ykjthwfx1.png" alt="hacky solution" width="576" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Future-Proof Mode: Code That Adapts
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The right man in the wrong place can make all the difference in the world."&lt;/em&gt; – G-Man, Half-Life&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You might think your code works perfectly today, but what happens when requirements change? Hardcoded values, rigid logic, and inflexible structures will turn even the smallest update into a nightmare-level boss fight.&lt;/p&gt;

&lt;p&gt;Instead of writing code that barely survives the current sprint, build with &lt;em&gt;&lt;strong&gt;Future-Proof Mode&lt;/strong&gt;&lt;/em&gt; enabled. I always remember the three golden rules of futureproofing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Configurations Over Hardcoding – Instead of burying values deep in your code, make them easily adjustable through env variables, config files, or database settings. One small change shouldn't require a full-scale refactor.&lt;/li&gt;
&lt;li&gt;Embrace Modularity – Write self-contained functions and reusable components. Future-you (or your teammates) will thank you when features need updating without breaking everything else.&lt;/li&gt;
&lt;li&gt;Plan for Change – Assume things will change—because they always do. Write flexible logic that can adapt without rewriting half the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good devs solve problems. &lt;strong&gt;Great devs make future problems easy to fix.&lt;/strong&gt;. Keep your code adaptable, and you won’t have to grind through endless bug-fixing quests.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Art of Debugging: Think Before You Do
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Speed is good. Precision is better. Panic is death."&lt;/em&gt; – Some wise dev, probably&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The room is quiet. Keys clack rhythmically. All is well. Then—bam. The bug appears. Chaos unfolds. The Slack notifications pile up. Your PM is breathing down your neck. The instinct? Type fast. Push something. Hope for the best.&lt;/p&gt;

&lt;p&gt;But a true dev does not panic. A true dev transcends the console, merges with the stack trace, and debugs in the astral plane.&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%2Fnhztncap9ywlokz1vjpi.jpg" 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%2Fnhztncap9ywlokz1vjpi.jpg" alt="Zen debugging" width="750" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When crisis strikes, activate Zen Debugging Mode™. Calm your mind—the code is broken, but you are not. Breathe. Raging at your keyboard will not summon a solution. Observe the chaos—read the error message, follow the logs, and ask yourself: What would Stack Overflow do? See beyond the bug. Adapt, don’t react—a quick hack today is a production outage tomorrow.&lt;br&gt;
Fix the problem, not just the symptom. Master the art of debugging—the impatient dev fights the bug, the wise dev understands the bug, but the true dev? &lt;strong&gt;The true dev makes the bug fix itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stay calm, analyze, and execute with precision. A wise dev doesn’t just code. A wise dev waits, thinks… and then wins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At its core, great development isn’t about writing code that just works—it’s about writing code that lasts. Keep it simple so others (and future you) can understand it. Read the docs before reinventing the wheel. Design for the future, because change is inevitable. And when chaos strikes, don’t react—analyze, adapt, and debug with wisdom.&lt;/p&gt;

&lt;p&gt;Because beyond every clean commit, every well-placed log, and every thoughtful refactor lies something greater—the undiscovered possibility of what you’ll build next.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>beginners</category>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>Working with sigmoid in Solidity</title>
      <dc:creator>Sihan Tawsik</dc:creator>
      <pubDate>Sun, 18 Sep 2022 07:05:38 +0000</pubDate>
      <link>https://dev.to/sihantawsik/working-with-sigmoid-in-solidity-3g38</link>
      <guid>https://dev.to/sihantawsik/working-with-sigmoid-in-solidity-3g38</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;While working on a project in solidity, I needed to make a calculation with sigmoid. Now, anyone who has already worked with sigmoid will know that it involves the irrational number &lt;strong&gt;e&lt;/strong&gt;. In this article, I will describe what problems I faced and how I tried to approach the problem from a mathematical and programming concept.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Solidity does not have native support for fractional operations, rather it uses scaled version of numbers (i.e: &lt;code&gt;uint256&lt;/code&gt; and &lt;code&gt;int256&lt;/code&gt;) to make operations for fractional calculation. for example, if you are to do an operation like this:&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In pure solidity the result needs to be scaled to adjust precision similar to this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint256 x = (10**18)/3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On top of that the natural exponential function makes it harder to calculate in pure solidity.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(x)=11+e−x
    f(x) = \frac{1}{1+e^{-x}}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution Approach
&lt;/h2&gt;

&lt;p&gt;I tried to make the solution for this problem using observation and estimations using the graph.&lt;br&gt;
Let's look at the graph for sigmoid function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fimna51mwpxlycr1mmko0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fimna51mwpxlycr1mmko0.png" alt="Sigmoid graph" width="800" height="444"&gt;&lt;/a&gt;&lt;br&gt;
As x approaches 5 and goes to infinity, the function result tends to reach 1.&lt;br&gt;
And as x approaches -5 and goes to -infinity, the function results in 0.&lt;/p&gt;

&lt;p&gt;The first observation that I got from this is that the graph is symmetric for positive and negative x.&lt;br&gt;
If we shift the graph by 0.5 units below the y-axis, we will see that x and -x yield the same result but in opposite directions on the y-axis.&lt;/p&gt;

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

&lt;p&gt;So, we can calculate the values for negative x by adding/subtracting some offset value with the positive x value. From the shifted graph, we can calculate the value for this offset.&lt;br&gt;
We shifted the y values by 0.5, and we got relation for positive and negative x like this:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(−x)−0.5=−(f(x)−0.5)
f(-x) - 0.5 = -(f(x) - 0.5)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.5&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.5&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;
From this equation we get:&lt;br&gt;

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(−x)=1−f(x)
f(-x) = 1 - f(x)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;We can now use the positive x to calculate the values for negative x.&lt;/p&gt;

&lt;h2&gt;
  
  
  Polynomial estimations
&lt;/h2&gt;

&lt;p&gt;We have reduced the problem domain in half, but the irrational number and the fractional calculations are still not solved.&lt;br&gt;
What if we could express the function in some simpler polynomial function? We could use the Maclaurin series to achieve this.&lt;br&gt;
Taking the first 6 terms for the Maclaurin expansion for sigmoid function, we get:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;g(x)=12+x4−x348+x5480−17x780640+31x91451520
g(x) = \frac{1}{2} + \frac{x}{4} - \frac{x^3}{48} + \frac{x^5}{480} - \frac{17x^7}{80640} + \frac{31x^9}{1451520}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;48&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;480&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;80640&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;17&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1451520&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;31&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;9&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;
If we plot &lt;strong&gt;&lt;em&gt;g(x)&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;f(x)&lt;/em&gt;&lt;/strong&gt; in the graph, we will see something like this:

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni1w31tqdp5myw1seww0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni1w31tqdp5myw1seww0.png" alt="Polynomial estimation of sigmoid" width="800" height="399"&gt;&lt;/a&gt;&lt;br&gt;
The green curve is &lt;strong&gt;&lt;em&gt;g(x)&lt;/em&gt;&lt;/strong&gt; and the blue curve is &lt;strong&gt;&lt;em&gt;f(x)&lt;/em&gt;&lt;/strong&gt;. We can see that the estimation does very well from 0 to 2 but diverges from the original curve after that. So, we can use this for values from -2 to 2 in our code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Linear estimations
&lt;/h2&gt;

&lt;p&gt;After that, I used linear estimations for the rest of the values. I found that from 2 to 5 i needed a linear estimation and from 5 to 9 to smooth out the results. Anything greater than 9 or less than -9, I assumed to be 1 and 0 respectively.&lt;/p&gt;
&lt;h2&gt;
  
  
  Polinomial estimation code
&lt;/h2&gt;

&lt;p&gt;To implement the curve in solidity in simple terms, I processed the mathematical term a bit. It made it easier to write the solidity code.&lt;br&gt;
The denominator of the term was 1451520. I also calculated the modifiers for the x nominators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function buildModifiers() internal pure returns (uint256[] memory) {
        uint256[] memory modifiers = new uint256[](5);
        modifiers[0] = uint256(362880);
        modifiers[1] = uint256(30240);
        modifiers[2] = uint256(3024);
        modifiers[3] = uint256(306);
        modifiers[4] = uint256(31);
        return modifiers;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I have scaled the numbers by &lt;code&gt;10^18&lt;/code&gt; I used a power function to scale down. One observation from the polynomial term is that all the power of x is odd, and thus the next x term can be obtained by multiplying the previous x term with &lt;code&gt;x^2&lt;/code&gt;. I incorporated that into my code as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function power(uint256 base, uint256 scale)
        internal
        pure
        returns (uint256[] memory)
    {
        uint256 square = (base * base) / scale;
        uint256[] memory result = new uint256[](5);
        result[0] = base;
        for (uint i = 1; i &amp;lt; 5; i++) {
            result[i] = (result[i - 1] * square) / scale;
        }
        return result;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, I multiplied the result with the modifiers and add/subtract the terms to get the answer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function polynomial(
        uint256 base,
        uint256 scale,
        uint256[] memory modifiers,
        uint256 addition
    ) internal pure returns (uint256) {
        uint256 result = 0;
        uint256[] memory powers = power(base, scale);
        for (uint i = 0; i &amp;lt; 5; i += 2) {
            result += modifiers[i] * powers[i];
        }
        for (uint i = 1; i &amp;lt; 5; i += 2) {
            result -= modifiers[i] * powers[i];
        }
        return result / denominator + addition;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;addition&lt;/code&gt; variable is the value for &lt;strong&gt;&lt;em&gt;f(0)&lt;/em&gt;&lt;/strong&gt; which is 0.5 scaled by &lt;code&gt;10^18&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;As I used fixed polynomials and linear approximations to calculate the sigmoid, I was able to calculate the result in constant time. So, the time complexity for this function was &lt;code&gt;O(k)&lt;/code&gt; or &lt;code&gt;O(1)&lt;/code&gt;. And with 10000 different inputs for sigmoid, the final result had s mean absolue error of &lt;code&gt;0.00013193236860416846&lt;/code&gt; or &lt;code&gt;0.013193236860416846%&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I had a lot of fun working on this particular problem. It was exciting to use high school math along with observations to implement something that is natively not available in solidity. I wish to do more exciting stuff like this in the future as well. Happy coding!&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>web3</category>
      <category>programming</category>
      <category>math</category>
    </item>
  </channel>
</rss>
