create account

Control Structures and Errors By albro by albro

View this thread on: hive.blogpeakd.comecency.com
· @albro ·
$14.70
Control Structures and Errors By albro
<center>![Control Structures and Errors](https://files.peakd.com/file/peakd-hive/albro/EoibW8i1TMdR9esizdnfWcaXQYZd4KtLKMZkXywytusqxEj8Y6QV8bkTQAmgLbtvBpn.jpg)</center>
<p>Control structures are structures that control the execution logic of your program. The simplest of these structures is the <code>if</code> statement! One of the problems that occurs in writing clean code is the excessive use of these control structures (especially nested). Pay attention to the following code:</p>
<pre><code>if (rowCount > rowIdx)
    {
      if (drc[rowIdx].Table.Columns.Contains("avalId"))
      {
        do
        {
          if (Attributes[attrVal.AttributeClassId] == null)
          {
            // do stuff
          }
          else
          {
            if (!(Attributes[attrVal.AttributeClassId] is ArrayList))
            {
              // do stuff
            }
            else
            {
              if (!isChecking)
              {
                // do stuff
              }
              else
              {
                // do stuff
              }
            }
          }
          rowIdx++;
        }
        while (rowIdx < rowCount && GetIdAsInt32(drc[rowIdx]) == Id);
      }
      else
        rowIdx++;
    }
    return rowIdx;
  }</code></pre>
<p>Codes that have loops and different conditions and are written in this way are at the lowest level in terms of readability because it will take a lot of time to read and understand them. The above codes are called arrow code because their general appearance is similar to the tips of arrows:</p>
<pre><code>if
  if
    if
      if
        do something
      endif
    endif
  endif
endif</code></pre>
<p>In this post, I want to cover two main topics: preventing nested control structures and handling errors. The topics of this post are such that we will deal less with theory and directly enter into coding and edit our own codes many times, so try to be patient and study step by step. To write clean code related to control structures, you should remember the following points:</p>
<ul>
<li>Avoid deep nesting. Deep nesting means excessive nesting. Doing this will usually create the same arrow codes that I showed you earlier.</li>
<li>Use techniques such as factory functions and polymorphism.</li>
<li>Try to use positive terms. For example, use isEmpty instead of isNotEmpty. Positive terms are always easier to read than negative terms.</li>
<li>Use error messages to organize your control structures.</li>
</ul>
<h3>What is Guard?</h3>
<p>One of the best ways to shorten arrow code is to use a theme called Guards. To understand guards, it is better to use a practical example:</p>
<pre><code>if (email.includes('@')) {
  // Do Anything
}</code></pre>
<p>This code is a very simple code that only checks for the @ sign in the email variable. I have specified possible operations in the form of a comment (perform specific operations); That is, it doesn't matter what kind of operation we want to do, but we assume that the desired operation is very long and requires many control structures. In this case, we can use a guard; It means to reverse the condition:</p>
<pre><code>if (!email.includes('@')) {
  return;
}<br /><br /><br />
// perform special operations</code></pre>
<p>Can we understand the working mechanism of the code from the code above? Here we have reversed the <code>if</code> condition and call it guard. Why? If the desired email does not have the @ symbol, the condition is established, so we enter it. At this time, the <code>return</code> statement causes us to exit the function and the rest of the code (the "perform special operations" section) will never be executed. The <code>if</code> condition is a guard because it protects its subsequent parts. Doing this will make us have consecutive codes instead of nested codes. The more nested the codes are, the harder it will be to read them. For example:</p>
<pre><code>if (user.active) {
  if (user.hasPurchases()) {
    // perform special operations
  }
}</code></pre>
<p>In this example, we have two nested <code>if</code> conditions and it is annoying to read them. If we turn the inner condition into a guard, we can increase the readability of the code:</p>
<pre><code>if (!user.hasPurchases()) {
  return;
}<br /><br /><br />
if (user.active) {
  // perform special operations
}</code></pre>
<p>By doing this we have avoided nested <code>if</code> conditions. Our assumption is that this code is part of a function, so when we reach the <code>return</code> statement, we exit the function and we will never reach the <code>user.active</code> condition. To understand better, let's solve a simple exercise together. For this post, I've chosen a very busy code with several levels of nesting for you to work on:</p>
<pre><code>main();<br /><br /><br />
function main() {
  const transactions = [
    {
      id: "t1",
      type: "PAYMENT",
      status: "OPEN",
      method: "CREDIT_CARD",
      amount: "23.99",
    },
    {
      id: "t2",
      type: "PAYMENT",
      status: "OPEN",
      method: "PAYPAL",
      amount: "100.43",
    },
    {
      id: "t3",
      type: "REFUND",
      status: "OPEN",
      method: "CREDIT_CARD",
      amount: "10.99",
    },
    {
      id: "t4",
      type: "PAYMENT",
      status: "CLOSED",
      method: "PLAN",
      amount: "15.99",
    },
  ];<br /><br /><br />
  processTransactions(transactions);
}<br /><br /><br />
function processTransactions(transactions) {
  if (transactions && transactions.length > 0) {
    for (const transaction of transactions) {
      if (transaction.type === "PAYMENT") {
        if (transaction.status === "OPEN") {
          if (transaction.method === "CREDIT_CARD") {
            processCreditCardPayment(transaction);
          } else if (transaction.method === "PAYPAL") {
            processPayPalPayment(transaction);
          } else if (transaction.method === "PLAN") {
            processPlanPayment(transaction);
          }
        } else {
          console.log("Invalid transaction type!");
        }
      } else if (transaction.type === "REFUND") {
        if (transaction.status === "OPEN") {
          if (transaction.method === "CREDIT_CARD") {
            processCreditCardRefund(transaction);
          } else if (transaction.method === "PAYPAL") {
            processPayPalRefund(transaction);
          } else if (transaction.method === "PLAN") {
            processPlanRefund(transaction);
          }
        } else {
          console.log("Invalid transaction type!", transaction);
        }
      } else {
        console.log("Invalid transaction type!", transaction);
      }
    }
  } else {
    console.log("No transactions provided!");
  }
}<br /><br /><br />
function processCreditCardPayment(transaction) {
  console.log(
    "Processing credit card payment for amount: " + transaction.amount
  );
}<br /><br /><br />
function processCreditCardRefund(transaction) {
  console.log(
    "Processing credit card refund for amount: " + transaction.amount
  );
}<br /><br /><br />
function processPayPalPayment(transaction) {
  console.log("Processing PayPal payment for amount: " + transaction.amount);
}<br /><br /><br />
function processPayPalRefund(transaction) {
  console.log("Processing PayPal refund for amount: " + transaction.amount);
}<br /><br /><br />
function processPlanPayment(transaction) {
  console.log("Processing plan payment for amount: " + transaction.amount);
}<br /><br /><br />
function processPlanRefund(transaction) {
  console.log("Processing plan refund for amount: " + transaction.amount);
}</code></pre>
<p>We will work with this code several times in this post. If you look carefully, the <code>if</code> conditions are calling the methods defined in this file, but for now, focus on the big <code>if</code> condition in the <code>processTransactions</code> function. I want you to improve these nested bets by using guards. Note that even after using guards you will still have a small number of nested conditions.</p>
<p>The answer to this exercise is simple. In the first step, we must convert the first <code>if</code> condition in the <code>processTransactions</code> function into a guard. If you have read the code, you can assume that the <code>transaction</code> parameter is an array. With this account, we can reverse the condition as follows: there are no <code>transactions</code> or its length is equal to zero. Once you've done that, you can condition the contents of the <code>else</code> block, which is a <code>console.log</code> (by reversing the condition, the <code>else</code> block itself will be the condition). After doing this there is still one more part that can become a guard. Where? This part of the code:</p>
<pre><code>if (transaction.status === "OPEN") {
  if (transaction.method === "CREDIT_CARD") {
    processCreditCardPayment(transaction);
  } else if (transaction.method === "PAYPAL") {
    processPayPalPayment(transaction);
  } else if (transaction.method === "PLAN") {
    processPlanPayment(transaction);
  }
} else {
  console.log("Invalid transaction type!");
}</code></pre>
<p>We have a big condition here that has a lot of code inside it, and then we have an <code>else</code> condition for it that shows the error message. Anywhere in any program you see such code (a big <code>if</code> and an <code>else</code> to display an error), you should immediately realize that it is possible to use guards in it. The important issue here is that this condition is written in a <code>for</code> loop, and if we <code>return</code>, we will exit this loop by mistake, which is not a good thing. The solution to this problem is to use <code>continue</code> instead of <code>return</code>. Also, don't forget to put the <code>console.log</code> message before <code>continue</code>.</p>
<p>Now, for more convenience, I move the condition related to <code>transaction.status !== 'Open'</code> to the beginning of the conditions of this function. With a little correction and doing this operation, you get the following result:</p>
<pre><code>main();<br /><br /><br />
function main() {
  const transactions = [
    {
      id: "t1",
      type: "PAYMENT",
      status: "OPEN",
      method: "CREDIT_CARD",
      amount: "23.99",
    },
    {
      id: "t2",
      type: "PAYMENT",
      status: "OPEN",
      method: "PAYPAL",
      amount: "100.43",
    },
    {
      id: "t3",
      type: "REFUND",
      status: "OPEN",
      method: "CREDIT_CARD",
      amount: "10.99",
    },
    {
      id: "t4",
      type: "PAYMENT",
      status: "CLOSED",
      method: "PLAN",
      amount: "15.99",
    },
  ];<br /><br /><br />
  processTransactions(transactions);
}<br /><br /><br />
function processTransactions(transactions) {
  if (!transactions || transactions.length === 0) {
    console.log("No transactions provided!");
    return;
  }<br /><br /><br />
  for (const transaction of transactions) {
    if (transactions.status !== "OPEN") {
      console.log("Invalid transaction type!");
      continue;
    }
    if (transaction.type === "PAYMENT") {
      if (transaction.method === "CREDIT_CARD") {
        processCreditCardPayment(transaction);
      } else if (transaction.method === "PAYPAL") {
        processPayPalPayment(transaction);
      } else if (transaction.method === "PLAN") {
        processPlanPayment(transaction);
      }
    } else if (transaction.type === "REFUND") {
      if (transaction.method === "CREDIT_CARD") {
        processCreditCardRefund(transaction);
      } else if (transaction.method === "PAYPAL") {
        processPayPalRefund(transaction);
      } else if (transaction.method === "PLAN") {
        processPlanRefund(transaction);
      }
    } else {
      console.log("Invalid transaction type!", transaction);
    }
  }
}<br /><br /><br />
function processCreditCardPayment(transaction) {
  console.log(
    "Processing credit card payment for amount: " + transaction.amount
  );
}<br /><br /><br />
function processCreditCardRefund(transaction) {
  console.log(
    "Processing credit card refund for amount: " + transaction.amount
  );
}<br /><br /><br />
function processPayPalPayment(transaction) {
  console.log("Processing PayPal payment for amount: " + transaction.amount);
}<br /><br /><br />
function processPayPalRefund(transaction) {
  console.log("Processing PayPal refund for amount: " + transaction.amount);
}<br /><br /><br />
function processPlanPayment(transaction) {
  console.log("Processing plan payment for amount: " + transaction.amount);
}<br /><br /><br />
function processPlanRefund(transaction) {
  console.log("Processing plan refund for amount: " + transaction.amount);
}</code></pre>
<p>In the future, we will work more on this code, but for now, we have been able to improve the readability of the code by using guards.</p>
<h3>Extraction of control structures</h3>
<p>As I explained in the previous post, one of the issues that cause the codes to be unreadable is the difference in the levels of the codes in the same block. In the previous post, we introduced breaking the code into different functions as a solution to deal with such problems, and this solution is also applicable in this section. For example, the first part of the <code>processTransactions</code> function is an <code>if</code> condition as follows:</p>
<pre><code>if (!transactions || transactions.length === 0) {
    console.log("No transactions provided!");
    return;
  }</code></pre>
<p>We can extract the two conditions that are checked in this <code>if</code> (<code>transaction</code> and its non-zero length (<code>transaction.length</code>)) in the form of another function. Doing this, in addition to shortening the <code>if</code> condition, allows us to use positive conditions (not using the <code>!</code> sign in the condition), and as I said, the readability of positive conditions is more than the readability of negative conditions. With this account, we define a new function and say:</p>
<pre><code>function isEmpty(transactions) {
  return !transactions || transactions.length === 0;
}</code></pre>
<p>Now this function takes our transaction and checks our condition on it. To use it, you must call it inside the <code>if</code> condition:</p>
<pre><code>function processTransactions(transactions) {
  if (isEmpty(transactions)) {
    console.log("No transactions provided!");
    return;
  }
// other codes</code></pre>
<p>By doing this, we have made our code more readable, but the difference in the code levels in the if condition is still clear. We have a <code>console.log</code> statement that is more verbose than the rest of the code. Again, I say that changing this section is up to you and the needs of your programs. Usually, less than <code>console.log</code> is used in real programs, and this <code>log</code> statement is usually statements for error management. So I like to define it as a separate method so that if we want to edit it later, we don't need to edit 10 different parts of the program:</p>
<pre><code>function showErrorMessage(message) {
  console.log(message);
}</code></pre>
<p>Now we can use it in the <code>if</code> condition:</p>
<pre><code>function processTransactions(transactions) {
  if (isEmpty(transactions)) {
    showErrorMessage("No transactions provided!");
    return;
  }</code></pre>
<p>Next, I want to keep the <code>for</code> loop in its place because the name of the function is <code>processTransactions</code>, so it should be able to circulate between transactions, but inside this loop we have a big <code>if</code> condition that performs different operations based on the types of transactions. to give In my opinion, it is better to extract all this code and put it inside a completely new function. I'll name the new function <code>processTransaction</code> (without the plural s):</p>
<pre><code>function processTransaction(transaction) {
  if (transactions.status !== "OPEN") {
    console.log("Invalid transaction type!");
    return;
  }
  if (transaction.type === "PAYMENT") {
    if (transaction.method === "CREDIT_CARD") {
      processCreditCardPayment(transaction);
    } else if (transaction.method === "PAYPAL") {
      processPayPalPayment(transaction);
    } else if (transaction.method === "PLAN") {
      processPlanPayment(transaction);
    }
  } else if (transaction.type === "REFUND") {
    if (transaction.method === "CREDIT_CARD") {
      processCreditCardRefund(transaction);
    } else if (transaction.method === "PAYPAL") {
      processPayPalRefund(transaction);
    } else if (transaction.method === "PLAN") {
      processPlanRefund(transaction);
    }
  } else {
    console.log("Invalid transaction type!", transaction);
  }
}</code></pre>
<p>Since we will receive the transaction as a parameter, the <code>if</code> condition inside it will still work and can access the <code>type</code> or <code>method</code> properties. Note that I've also separated our own guard (<code>transaction.status !== 'OPEN</code>) from the main loop and put it inside the <code>processTransaction</code> function. Of course, when we do this, there is no need to <code>continue</code> and we have returned it to the same <code>return</code>. Why? Because now the scope of the code is different. Previously, this guard was located directly inside a loop, but now it is located directly inside a function and is exited from the function with <code>return</code>.</p>
<p>With this account, we can go back to the <code>processTransactions</code> method (with a plus s) and call <code>processTransaction</code> inside it:</p>
<pre><code>function processTransactions(transactions) {
  if (isEmpty(transactions)) {
    showErrorMessage("No transactions provided!");
    return;
  }<br /><br /><br />
  for (const transaction of transactions) {
    processTransaction(transaction);
  }
}</code></pre>
<p>Now, as you can see, the <code>processTransactions</code> method is much shorter and more readable. We have kept the same <code>for</code> loop, but instead of writing the partial code line by line inside it, we have transferred the code to another independent function that takes one of the transactions in each round and processes it.</p>
<p>So that you can keep up with me, compare all your codes with all of mine. Your code should look exactly like this:</p>
<pre><code>main();<br /><br /><br />
function main() {
  const transactions = [
    {
      id: "t1",
      type: "PAYMENT",
      status: "OPEN",
      method: "CREDIT_CARD",
      amount: "23.99",
    },
    {
      id: "t2",
      type: "PAYMENT",
      status: "OPEN",
      method: "PAYPAL",
      amount: "100.43",
    },
    {
      id: "t3",
      type: "REFUND",
      status: "OPEN",
      method: "CREDIT_CARD",
      amount: "10.99",
    },
    {
      id: "t4",
      type: "PAYMENT",
      status: "CLOSED",
      method: "PLAN",
      amount: "15.99",
    },
  ];<br /><br /><br />
  processTransactions(transactions);
}<br /><br /><br />
function processTransactions(transactions) {
  if (isEmpty(transactions)) {
    showErrorMessage("No transactions provided!");
    return;
  }<br /><br /><br />
  for (const transaction of transactions) {
    processTransaction(transaction);
  }
}<br /><br /><br />
function isEmpty(transactions) {
  return !transactions || transactions.length === 0;
}<br /><br /><br />
function showErrorMessage(message) {
  console.log(message);
}<br /><br /><br />
function processTransaction(transaction) {
  if (transactions.status !== "OPEN") {
    console.log("Invalid transaction type!");
    return;
  }
  if (transaction.type === "PAYMENT") {
    if (transaction.method === "CREDIT_CARD") {
      processCreditCardPayment(transaction);
    } else if (transaction.method === "PAYPAL") {
      processPayPalPayment(transaction);
    } else if (transaction.method === "PLAN") {
      processPlanPayment(transaction);
    }
  } else if (transaction.type === "REFUND") {
    if (transaction.method === "CREDIT_CARD") {
      processCreditCardRefund(transaction);
    } else if (transaction.method === "PAYPAL") {
      processPayPalRefund(transaction);
    } else if (transaction.method === "PLAN") {
      processPlanRefund(transaction);
    }
  } else {
    console.log("Invalid transaction type!", transaction);
  }
}<br /><br /><br />
function processCreditCardPayment(transaction) {
  console.log(
    "Processing credit card payment for amount: " + transaction.amount
  );
}<br /><br /><br />
function processCreditCardRefund(transaction) {
  console.log(
    "Processing credit card refund for amount: " + transaction.amount
  );
}<br /><br /><br />
function processPayPalPayment(transaction) {
  console.log("Processing PayPal payment for amount: " + transaction.amount);
}<br /><br /><br />
function processPayPalRefund(transaction) {
  console.log("Processing PayPal refund for amount: " + transaction.amount);
}<br /><br /><br />
function processPlanPayment(transaction) {
  console.log("Processing plan payment for amount: " + transaction.amount);
}<br /><br /><br />
function processPlanRefund(transaction) {
  console.log("Processing plan refund for amount: " + transaction.amount);
}</code></pre>
<p>As you can see by looking at the code above, the <code>processTransactions</code> function is readable, but the nested if conditions that we transferred to the <code>processTransaction</code> function are still very crowded and unreadable. I want you to try to solve this problem yourself using the tips I explained in this post and then look at my answer.</p>
<p>If you look at the big <code>if</code> condition, you'll see the following two <code>if</code> and <code>else</code> clauses:</p>
<ul>
<li><strong>Payment</strong> section: This section is for paying money by customers to buy our goods or services.</li>
<li><strong>Refund</strong> Section: This section is dedicated to returning customers' money in case of dissatisfaction with goods and services.</li>
</ul>
<p>Accordingly, we can have two functions, each of which is responsible for processing one of these two types of transactions. I'll start with the first category and call this method <code>processPayment</code>:</p>
<pre><code>function processPayment(paymentTransaction) {
  if (paymentTransaction.method === "CREDIT_CARD") {
    processCreditCardPayment(paymentTransaction);
  } else if (paymentTransaction.method === "PAYPAL") {
    processPayPalPayment(paymentTransaction);
  } else if (paymentTransaction.method === "PLAN") {
    processPlanPayment(paymentTransaction);
  }
}</code></pre>
<p>As you can see, half of the big <code>if</code> condition related to Payments is placed inside this function. Since I want the received parameter of the function to be clear and explicit, I have changed its name from <code>transaction</code> to <code>paymentTransaction</code>. For this reason, you must change the name of the <code>transaction</code> to <code>paymentTransaction</code> in all this code.</p>
<p>In the next step, we do the same for the second half of the <code>if</code> condition. This time I have chosen the name <code>processRefund</code> for this function:</p>
<pre><code>function processRefund(refundTransaction) {
  if (refundTransaction.method === "CREDIT_CARD") {
    processCreditCardRefund(refundTransaction);
  } else if (refundTransaction.method === "PAYPAL") {
    processPayPalRefund(refundTransaction);
  } else if (refundTransaction.method === "PLAN") {
    processPlanRefund(refundTransaction);
  }
}</code></pre>
<p>Finally, we return to the <code>processTransaction</code> function (without s plus) and use these two functions in it:</p>
<pre><code>function processTransaction(transaction) {
  if (transactions.status !== "OPEN") {
    console.log("Invalid transaction type!");
    return;
  }
  if (transaction.type === "PAYMENT") {
    processPayment(transaction);
  } else if (transaction.type === "REFUND") {
    processRefund(transaction);
  } else {
    console.log("Invalid transaction type!", transaction);
  }
}</code></pre>
<p>By doing this, the code has become more readable, but there is still room for improvement. For example, we have two commands <code>console.log</code> in this function, which caused the level difference in the codes. One of these two commands, in addition to printing a message in the console, also prints the transaction itself and its data (the second argument for <code>console.log</code>), so if we want to use our own <code>showErrorMessage</code> function, we have to edit it a little:</p>
<pre><code>function showErrorMessage(message, item) {
  console.log(message);
  if (item) {
    console.log(item);
  }
}</code></pre>
<p>This is a very simple way to do this. We print the error message first, and if a second argument (item) is sent, we also print it separately. Naturally, there are many ways to do this, and the above function is just one of several possible modes. Now we can use this function instead of console.logs:</p>
<pre><code>function processTransaction(transaction) {
  if (transactions.status !== "OPEN") {
    showErrorMessage("Invalid transaction type!");
    return;
  }<br /><br /><br />
  if (transaction.type === "PAYMENT") {
    processPayment(transaction);
  } else if (transaction.type === "REFUND") {
    processRefund(transaction);
  } else {
    showErrorMessage("Invalid transaction type!", transaction);
  }
}</code></pre>
<p>I don't suggest breaking this code any further because almost everything you do from here on is overhead, but if you insist you can also specify the status of a transaction through another function. For example, I define the following three functions for three different states:</p>
<pre><code>function isOpen(transaction) {
  return transaction.status === "OPEN";
}<br /><br /><br />
function isPayment(transaction) {
  return transaction.type === "PAYMENT";
}<br /><br /><br />
function isRefund(transaction) {
  return transaction.type === "REFUND";
}</code></pre>
<p>As you can see, these three functions are responsible for checking the type of transaction (<code>Refund</code> or <code>Payment</code>) and whether the transaction status is open. Now, using these three functions, we can rewrite the <code>processTransaction</code> function as follows:</p>
<pre><code>function processTransaction(transaction) {
  if (!isOpen(transaction)) {
    showErrorMessage("Invalid transaction type!");
    return;
  }
  if (isPayment(transaction)) {
    processPayment(transaction);
  } else if (isRefund(transaction)) {
    processRefund(transaction);
  } else {
    showErrorMessage("Invalid transaction type!", transaction);
  }
}</code></pre>
<p>In my opinion, this type of writing is also acceptable and readable, although we may have gone too far in the opinion of many people.</p>
<p>[hive: @albro]</p>
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 269 others
properties (23)
authoralbro
permlinkcontrol-structures-and-errors-by-albro
categoryhive-169321
json_metadata{"app":"peakd/2023.10.1","format":"markdown","author":"albro","tags":["development","programming","gosh","threads","chessbrothers","neoxian","stem","bee","tricks","leofinance"],"users":["albro"],"image":["https://files.peakd.com/file/peakd-hive/albro/EoibW8i1TMdR9esizdnfWcaXQYZd4KtLKMZkXywytusqxEj8Y6QV8bkTQAmgLbtvBpn.jpg"]}
created2023-11-05 11:18:27
last_update2023-11-05 11:18:27
depth0
children2
last_payout2023-11-12 11:18:27
cashout_time1969-12-31 23:59:59
total_payout_value7.304 HBD
curator_payout_value7.395 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length26,825
author_reputation30,477,419,385,789
root_title"Control Structures and Errors By albro"
beneficiaries
0.
accounthive-169321
weight200
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id128,594,310
net_rshares30,005,226,575,584
author_curate_reward""
vote details (333)
@poshthreads ·
https://inleo.io/threads/albro/re-leothreads-26u4ske2n
<sub> The rewards earned on this comment will go directly to the people ( albro ) sharing the post on LeoThreads,LikeTu,dBuzz.</sub>
properties (22)
authorposhthreads
permlinkre-albro-control-structures-and-errors-by-albro19514
categoryhive-169321
json_metadata"{"app":"Poshtoken 0.0.2","payoutToUser":["albro"]}"
created2023-11-05 19:20:24
last_update2023-11-05 19:20:24
depth1
children0
last_payout2023-11-12 19:20:24
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length188
author_reputation415,471,585,053,248
root_title"Control Structures and Errors By albro"
beneficiaries
0.
accountnomnomnomnom
weight10,000
max_accepted_payout1,000,000.000 HBD
percent_hbd0
post_id128,604,545
net_rshares0
@stemsocial ·
re-albro-control-structures-and-errors-by-albro-20231106t031425961z
<div class='text-justify'> <div class='pull-left'>
 <img src='https://stem.openhive.network/images/stemsocialsupport7.png'> </div>

Thanks for your contribution to the <a href='/trending/hive-196387'>STEMsocial community</a>. Feel free to join us on <a href='https://discord.gg/9c7pKVD'>discord</a> to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support.&nbsp;<br />&nbsp;<br />
</div>
👍  
properties (23)
authorstemsocial
permlinkre-albro-control-structures-and-errors-by-albro-20231106t031425961z
categoryhive-169321
json_metadata{"app":"STEMsocial"}
created2023-11-06 03:14:24
last_update2023-11-06 03:14:24
depth1
children0
last_payout2023-11-13 03:14:24
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length565
author_reputation22,918,491,691,707
root_title"Control Structures and Errors By albro"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id128,614,222
net_rshares6,940,900,382
author_curate_reward""
vote details (1)