<?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: Jonah Lawrence</title>
    <description>The latest articles on Forem by Jonah Lawrence (@denvercoder1).</description>
    <link>https://forem.com/denvercoder1</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%2F499624%2Ff4265e69-fb08-45ce-a52e-fd03f5409ca2.png</url>
      <title>Forem: Jonah Lawrence</title>
      <link>https://forem.com/denvercoder1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/denvercoder1"/>
    <language>en</language>
    <item>
      <title>Create and Elevate Your GitHub Profile README</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Sun, 13 Aug 2023 12:42:32 +0000</pubDate>
      <link>https://forem.com/denvercoder1/create-and-elevate-your-github-profile-readme-4mom</link>
      <guid>https://forem.com/denvercoder1/create-and-elevate-your-github-profile-readme-4mom</guid>
      <description>&lt;h2&gt;
  
  
  Create and Elevate Your GitHub Profile README
&lt;/h2&gt;

&lt;p&gt;Your GitHub profile isn't just a place to showcase your repositories and contributions. It's an opportunity to leave a lasting impression on visitors. One way to do that is by creating an engaging profile README. In this article, I will show you how to get started with your profile README and add some dynamic components to make it stand out!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Getting Started&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To begin, you'll need to create a public repository with the same name as your username (e.g., &lt;code&gt;yourusername/yourusername&lt;/code&gt;) and add a README file.&lt;/p&gt;

&lt;p&gt;Create a new repository 👉 &lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;https://github.com/new&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to add a README to the repository. This can be done in the initial creation page by checking the box that says "Add a README file" If you've already created the repository, you can add a README by clicking the "README" link on the setup page or by uploading a file named &lt;code&gt;README.md&lt;/code&gt; to the repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;&lt;img src="https://media.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%2Fblvxj1xccxwyenn7i8zd.png" alt="Create a readme profile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All that's left to do is to add content to your README. You can use the &lt;a href="https://github.github.com/gfm/" rel="noopener noreferrer"&gt;GitHub Flavored Markdown&lt;/a&gt; syntax to format your text, add images, and create links. You can also add emojis to your README by using the emoji code (e.g., &lt;code&gt;:smile:&lt;/code&gt;). You can find a list of supported emojis &lt;a href="https://gist.github.com/rxaviers/7360908" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Adding Dynamic Content&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Typing Animation with Readme Typing SVG
&lt;/h4&gt;

&lt;p&gt;&lt;a href="(https://github.com/DenverCoder1/readme-typing-svg)"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fqj8opOT.gif" alt="Typing SVG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/DenverCoder1/readme-typing-svg" rel="noopener noreferrer"&gt;Readme Typing SVG&lt;/a&gt; project enables you to create an SVG animation that simulates typing and deleting text. You can use this to display a quick bio, witty taglines, favorite quotes, or any text you'd like to highlight on your profile. You can customize the text, speed, color, and more at the demo site (link below).&lt;/p&gt;

&lt;p&gt;🎨 Customization and Demo Site: &lt;a href="https://readme-typing-svg.demolab.com" rel="noopener noreferrer"&gt;https://readme-typing-svg.demolab.com&lt;/a&gt;&lt;br&gt;
🐙 GitHub Repo: &lt;a href="https://github.com/DenverCoder1/readme-typing-svg" rel="noopener noreferrer"&gt;https://github.com/DenverCoder1/readme-typing-svg&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Contribution Streak with GitHub Readme Streak Stats
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/github-readme-streak-stats" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstreak-stats.demolab.com%2Fdemo%2Fpreview.php%3Fuser%3DDenverCoder1%26type%3Dpng" alt="Contribution Streak"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/DenverCoder1/github-readme-streak-stats" rel="noopener noreferrer"&gt;GitHub Readme Streak Stats&lt;/a&gt; project lets you showcase your contribution streak. It displays your total contributions, current streak, and longest streak in a visually appealing way. This feature can be a great motivator and adds a sense of accomplishment to your profile. If you prefer not having a daily commitment, you can also display a weekly contribution streak or exclude certain days such as weekends.&lt;/p&gt;

&lt;p&gt;🎨 Customization and Demo Site: &lt;a href="https://streak-stats.demolab.com" rel="noopener noreferrer"&gt;https://streak-stats.demolab.com&lt;/a&gt;&lt;br&gt;
🐙 GitHub Repo: &lt;a href="https://github.com/DenverCoder1/github-readme-streak-stats" rel="noopener noreferrer"&gt;https://github.com/DenverCoder1/github-readme-streak-stats&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Badges and Custom Icon Badges
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/badges/shields" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FDenverCoder1%2FDenverCoder1%2Fassets%2F20955511%2Fcfa5f8dc-4d76-470e-a89a-248005ffa6ff" alt="Interest Badges"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shields.io/badges/" rel="noopener noreferrer"&gt;Shields.io&lt;/a&gt; allows you to create badges for your profile README. You can use these badges to display your skills, interests, and accomplishments. You can also create dynamic badges to show off stats such as your GitHub followers, YouTube subscribers, and more.&lt;/p&gt;

&lt;p&gt;📕 Docs and list of available dynamic badges: &lt;a href="https://shields.io/badges/" rel="noopener noreferrer"&gt;https://shields.io/badges/&lt;/a&gt;&lt;br&gt;
🐙 GitHub Repo: &lt;a href="https://github.com/badges/shields" rel="noopener noreferrer"&gt;https://github.com/badges/shields&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/custom-icon-badges" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FDenverCoder1%2FDenverCoder1%2Fassets%2F20955511%2Fb9d87a6c-1b09-4eed-b9a9-c9a3dc5f8502" alt="Custom Icon Badges"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To use custom icons other than brand names, you can use the project &lt;a href="https://github.com/DenverCoder1/custom-icon-badges" rel="noopener noreferrer"&gt;Custom Icon Badges&lt;/a&gt; which allows you to use GitHub's Octicons and your own icons on shields.io badges. This visual enhancement makes your profile more informative and visually pleasing.&lt;/p&gt;

&lt;p&gt;🔼 Icon Uploader: &lt;a href="https://custom-icon-badges.demolab.com/" rel="noopener noreferrer"&gt;https://custom-icon-badges.demolab.com/&lt;/a&gt;&lt;br&gt;
🐙 GitHub Repo: &lt;a href="https://github.com/DenverCoder1/custom-icon-badges" rel="noopener noreferrer"&gt;https://github.com/DenverCoder1/custom-icon-badges&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgngq6ejjzxoy97flnyiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgngq6ejjzxoy97flnyiy.png" alt="Hit.sh"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you'd like to display a visitor counter on your profile, there are many options. One such option is &lt;a href="https://hits.sh/" rel="noopener noreferrer"&gt;Hit.sh&lt;/a&gt; by &lt;a href="https://github.com/silentsoft" rel="noopener noreferrer"&gt;silentsoft&lt;/a&gt;. It's a free service that allows you to track visitors to your pages and repos including your profile README. You can customize the badge to match your profile and add it to your README.&lt;/p&gt;

&lt;p&gt;🎨 Hit.sh: &lt;a href="https://hits.sh/" rel="noopener noreferrer"&gt;https://hits.sh/&lt;/a&gt;&lt;br&gt;
🐙 GitHub Repo: &lt;a href="https://github.com/silentsoft/hits" rel="noopener noreferrer"&gt;https://github.com/silentsoft/hits&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. YouTube Video Cards with GitHub Readme YouTube Cards
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/github-readme-youtube-cards" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FDenverCoder1%2FDenverCoder1%2Fassets%2F20955511%2F35c31e43-d3e1-43cc-aae4-bffd3b257e77" alt="YouTube Video Cards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://ytcards.demolab.com/" rel="noopener noreferrer"&gt;GitHub Readme YouTube Cards&lt;/a&gt; workflow enables you to showcase your recent YouTube videos as SVG cards in your README. If you're a content creator or simply share informative videos, this feature can attract visitors to explore your videos right from your profile.&lt;/p&gt;

&lt;p&gt;🎨 Customization and Demo Site: &lt;a href="https://ytcards.demolab.com/" rel="noopener noreferrer"&gt;https://ytcards.demolab.com/&lt;/a&gt;&lt;br&gt;
🐙 GitHub Repo: &lt;a href="https://github.com/DenverCoder1/github-readme-youtube-cards" rel="noopener noreferrer"&gt;https://github.com/DenverCoder1/github-readme-youtube-cards&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. GitHub Stats with GitHub Readme Stats
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FDenverCoder1%2FDenverCoder1%2Fassets%2F20955511%2F03f4593d-5342-437a-aa89-674a8a7cf630" alt="GitHub Stats"&gt;&lt;/a&gt; &lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FDenverCoder1%2FDenverCoder1%2Fassets%2F20955511%2F3f053873-bd39-49ce-b7dd-e587215bc4ed" alt="Top Languages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;GitHub Readme Stats&lt;/a&gt; project by &lt;a href="https://github.com/anuraghazra/" rel="noopener noreferrer"&gt;Anurag Hazra&lt;/a&gt; generates dynamic statistics about your GitHub activities. This includes your top languages, total contributions, and more. You can use these stats to showcase your skills and dedication.&lt;/p&gt;

&lt;p&gt;🐙 GitHub Repo: &lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;https://github.com/anuraghazra/github-readme-stats&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Activity Graph with GitHub Readme Activity Graph
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/ashutosh00710/github-readme-activity-graph" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FDenverCoder1%2FDenverCoder1%2Fassets%2F20955511%2F7ca61fcd-fa77-4820-8a13-9cb29c2c0c31" alt="Activity Graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ashutosh00710/" rel="noopener noreferrer"&gt;Ashutosh Kumar&lt;/a&gt;'s &lt;a href="https://github.com/ashutosh00710/github-readme-activity-graph" rel="noopener noreferrer"&gt;GitHub Readme Activity Graph&lt;/a&gt; generates an activity graph representing your GitHub activities over the past month. It's a visually appealing way to demonstrate your commitment and involvement in open-source projects.&lt;/p&gt;

&lt;p&gt;🐙 GitHub Repo: &lt;a href="https://github.com/ashutosh00710/github-readme-activity-graph" rel="noopener noreferrer"&gt;https://github.com/ashutosh00710/github-readme-activity-graph&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Putting It All Together
&lt;/h3&gt;

&lt;p&gt;Now that you've seen some of the dynamic components you can add to your profile README, let's put it all together. Click the link below to see a sample (my own) profile README with all the components mentioned in this article.&lt;/p&gt;

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

&lt;p&gt;It's also always a good idea to credit the creators of the projects you use in your README. You can do this by making the dynamic images link back to the project's GitHub repository, or by including a section at the bottom of your README. This is entirely optional, but it's a great way to show your appreciation for the creators of these projects. Leaving a star on their GitHub repository is another great way to show your support.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I hope this article has inspired you to create your own profile README. It's a great way to showcase your skills and interests. If you have any questions or suggestions, feel free to leave a comment below. I'd love to hear your thoughts!&lt;/p&gt;

&lt;p&gt;Feel free to join my &lt;a href="https://discord.gg/fPrdqh3Zfu" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt; to discuss this article and other topics.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hosting a Python Discord Bot for Free with Fly.io</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Mon, 29 Aug 2022 01:11:00 +0000</pubDate>
      <link>https://forem.com/denvercoder1/hosting-a-python-discord-bot-for-free-with-flyio-3k19</link>
      <guid>https://forem.com/denvercoder1/hosting-a-python-discord-bot-for-free-with-flyio-3k19</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;As Heroku is no longer going to be free after November 28, 2022, I am sharing another way to host a Discord bot 24/7 for free.&lt;/p&gt;

&lt;p&gt;You will be able to host any kind of bot on Fly.io with few limitations by following the steps below. You can also optionally attach a PostgreSQL database for storing data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying a Python Discord Bot to &lt;a href="https://fly.io/"&gt;Fly.io&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This article was originally a video tutorial, which you can check out here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/J7Fm7MdZn_E"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install the &lt;code&gt;flyctl&lt;/code&gt; command line tool
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Mac OS
&lt;/h4&gt;

&lt;p&gt;If you have the &lt;a href="https://brew.sh"&gt;Homebrew&lt;/a&gt; package manager installed, flyctl can be installed by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install flyctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If not, you can run the install script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -L https://fly.io/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Windows
&lt;/h4&gt;

&lt;p&gt;Run the Powershell install script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iwr https://fly.io/install.ps1 -useb | iex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Arch Linux
&lt;/h4&gt;

&lt;p&gt;Run the package installer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; flyctl-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Linux
&lt;/h4&gt;

&lt;p&gt;Run the install script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -L https://fly.io/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More info: &lt;a href="https://fly.io/docs/getting-started/installing-flyctl/"&gt;https://fly.io/docs/getting-started/installing-flyctl/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create an account by running &lt;code&gt;flyctl auth signup&lt;/code&gt; and finishing through the browser
&lt;/h3&gt;

&lt;p&gt;After installing flyctl, you should now be able to use it in the command line. Use &lt;code&gt;flyctl auth signup&lt;/code&gt; to launch your browser and complete the account creation steps. If you already have an account, you can use &lt;code&gt;flyctl auth login&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Add a &lt;code&gt;Dockerfile&lt;/code&gt; with the Python version and dependency install method
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method 1: requirements.txt
&lt;/h4&gt;

&lt;p&gt;Create a list of your dependencies in a &lt;code&gt;requirements.txt&lt;/code&gt;. You can find out what you have installed using &lt;code&gt;pip freeze&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Discord.py example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;discord.py&amp;gt;=2.0.0,&amp;lt;3
python-dotenv==0.20.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nextcord example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nextcord&amp;gt;=2.1.0,&amp;lt;3
python-dotenv==0.20.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To tell Fly.io to install these dependencies, create a file called &lt;code&gt;Dockerfile&lt;/code&gt; (no file extension) with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.11&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /bot&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt /bot/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /bot&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; python bot.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case &lt;code&gt;python bot.py&lt;/code&gt; is the command used to run the bot. If your bot starts in a different file, you should change that here.&lt;/p&gt;

&lt;h4&gt;
  
  
  Method 2: Using Poetry
&lt;/h4&gt;

&lt;p&gt;If you are using Poetry for dependencies, your &lt;code&gt;Dockerfile&lt;/code&gt; will look more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.11&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;poetry
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /bot&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /bot/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; poetry.lock pyproject.toml /bot/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;poetry config virtualenvs.create &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; poetry &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &lt;span class="nt"&gt;--no-ansi&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; python bot.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Poetry Dockerfile is based on &lt;a href="https://replicate.com/blog/build-a-robot-artist-for-your-discord-server-with-stable-diffusion"&gt;this tutorial&lt;/a&gt; by Replicate.com. Thanks Abraham Murciano for the correction.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;flyctl launch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In the project folder, run &lt;code&gt;flyctl launch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Give your project a name, type Y or N depending on if you want a Postgresql database or not, type N to not have it deploy.&lt;/p&gt;

&lt;p&gt;This will create a &lt;code&gt;fly.toml&lt;/code&gt;, but you can delete most of it so that it looks similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"my-bot-name"&lt;/span&gt;  &lt;span class="c"&gt;# your bot's app name&lt;/span&gt;
&lt;span class="py"&gt;primary_region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"den"&lt;/span&gt;  &lt;span class="c"&gt;# a region of your choice&lt;/span&gt;

&lt;span class="nn"&gt;[[services]]&lt;/span&gt;
  &lt;span class="py"&gt;internal_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;
  &lt;span class="py"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tcp"&lt;/span&gt;
  &lt;span class="py"&gt;auto_start_machines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="py"&gt;auto_stop_machines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;  &lt;span class="c"&gt;# prevent automatic suspension&lt;/span&gt;
  &lt;span class="py"&gt;min_machines_running&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="c"&gt;# keep a machine running at all times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. &lt;code&gt;flyctl deploy&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Type &lt;code&gt;flyctl deploy&lt;/code&gt; to deploy the first version!&lt;/p&gt;

&lt;p&gt;Once it is completed, your bot will be running on Fly.io!&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Set the environment vars
&lt;/h3&gt;

&lt;p&gt;If you will be deploying your bot without your &lt;code&gt;.env&lt;/code&gt; or configuration files, you will need to set secrets for fly.io to know about.&lt;/p&gt;

&lt;p&gt;This will include all environment variables, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flyctl secrets set DISCORD_TOKEN=My.TOken.3213.example LOG_CHANNEL_ID=1234567890
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;a href="https://fly.io/docs/reference/secrets/#setting-secrets"&gt;https://fly.io/docs/reference/secrets/#setting-secrets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You're done!&lt;/p&gt;

&lt;p&gt;To deploy further versions, you can run &lt;code&gt;flyctl deploy&lt;/code&gt; or see below for automatic deploys from GitHub.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your bot is responding to commands twice, this may mean your bot is running on multiple machines. To fix this, try running the command &lt;code&gt;fly scale count 1&lt;/code&gt; in order to remove the extra machine(s). Also, you should ensure your bot is only running in one location; you should not run the bot on fly.io and locally or on another host at the same time.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Continuous deployment from GitHub
&lt;/h2&gt;

&lt;p&gt;You can find the video for this part here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/6u9BrDaSHJc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;flyctl auth token&lt;/code&gt; to get a Fly API token&lt;/li&gt;
&lt;li&gt;Go to your repo's &lt;code&gt;Settings &amp;gt; Secrets &amp;gt; Actions&lt;/code&gt; and click &lt;code&gt;New repository secret&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enter &lt;code&gt;FLY_API_TOKEN&lt;/code&gt; as the name and your token from step 1 as the value&lt;/li&gt;
&lt;li&gt;Create a folder, &lt;code&gt;.github/workflows/&lt;/code&gt; and inside create a file that uses the flyctl action on push. You may name it what you like, for example, &lt;code&gt;fly.yml&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example &lt;code&gt;fly.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fly Deploy&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;FLY_API_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FLY_API_TOKEN }}&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy app&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;superfly/flyctl-actions/setup-flyctl@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flyctl deploy --remote-only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure the branch name is correct for your default branch.&lt;/p&gt;

&lt;p&gt;More info: &lt;a href="https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/"&gt;https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;I hope you found this tutorial useful.&lt;/p&gt;

&lt;p&gt;Check out the full video for further explanations and be sure to like and subscribe!&lt;/p&gt;

&lt;p&gt;Part 1 (Setup and Hosting) - &lt;a href="https://youtu.be/J7Fm7MdZn_E"&gt;https://youtu.be/J7Fm7MdZn_E&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part 2 (Continuous Deployment) - &lt;a href="https://youtu.be/6u9BrDaSHJc"&gt;https://youtu.be/6u9BrDaSHJc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/DenverCoder1"&gt;DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YouTube: &lt;a href="https://www.youtube.com/channel/UCipSxT7a3rn81vGLw9lqRkg"&gt;Jonah Lawrence - Dev Pro Tips&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Discord server: &lt;a href="https://discord.gg/fPrdqh3Zfu"&gt;https://discord.gg/fPrdqh3Zfu&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>discord</category>
      <category>bot</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Why Most Wordle Clones are Wrong!</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Mon, 07 Feb 2022 19:27:09 +0000</pubDate>
      <link>https://forem.com/denvercoder1/why-most-wordle-clones-are-wrong-390c</link>
      <guid>https://forem.com/denvercoder1/why-most-wordle-clones-are-wrong-390c</guid>
      <description>&lt;p&gt;Wordle, the new online viral game everyone's talking about, at first glance, seems to be not such a difficult feat for an average programmer.&lt;/p&gt;

&lt;p&gt;In this post, I will be talking about a mistake that even experienced developers make when coding Wordle and how it can be fixed.&lt;/p&gt;

&lt;p&gt;The rules of Wordle are straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guess the secret word wihin 6 tries.&lt;/li&gt;
&lt;li&gt;Each guess must be a valid 5-letter word.&lt;/li&gt;
&lt;li&gt;After each guess, the color of the tiles will change to show how close your guess was to the word:
GREEN: The letter is in the word and in the correct spot.
YELLOW: The letter is in the word but in the wrong spot.
GRAY: The letter is not in the word in any spot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So why are most hobbyists and even content creators such as &lt;a href="https://www.youtube.com/watch?v=Wak7iN4JZzU"&gt;Web Dev Simplified&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=eXow_OxrAeE"&gt;Burke Holland from Visual Studio Code&lt;/a&gt; getting it wrong?*&lt;/p&gt;

&lt;h2&gt;
  
  
  The mistake
&lt;/h2&gt;

&lt;p&gt;The common mistake that nearly all Wordle clone creators make is by oversimplifying the algorithm by misunderstanding an ambiguity in the rules.&lt;/p&gt;

&lt;p&gt;During my attempt at creating a Wordle clone, I admit to have fallen for this trap initially myself until I realized that for some inputs, the most obvious solution is not a correct one.&lt;/p&gt;

&lt;p&gt;Consider the following code snippet used for determining which color should be assigned to each letter in the guess. Can you spot the mistake?&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;function&lt;/span&gt; &lt;span class="nx"&gt;colorRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&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;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GREEN&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YELLOW&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GRAY&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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;colors&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;The mistake here is that if the guess contains multiple of the same letter, they would all be marked with at least yellow, even if there was only one of them in the answer!&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;

&lt;p&gt;Consider the correct answer is &lt;code&gt;"THOSE"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If a player were to guess the word &lt;code&gt;"GEESE"&lt;/code&gt;, the algorithm above would produce the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SDhv4jjc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7jyqngllovjhw1tr4jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SDhv4jjc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7jyqngllovjhw1tr4jt.png" alt="'GRAY', 'YELLOW', 'YELLOW', 'GREEN', 'GREEN'" width="169" height="31"&gt;&lt;/a&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GRAY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;'&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 imply that the correct answer has two E's in the wrong location and one E in the correct location (a total of three E's).&lt;/p&gt;

&lt;p&gt;A correct algorithm, however, working the same as Wordle itself, would produce the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nrgfUQy6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2hmn7w9chgso63tectj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nrgfUQy6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2hmn7w9chgso63tectj.png" alt="'GRAY', 'GRAY', 'GRAY', 'GREEN', 'GREEN'" width="169" height="31"&gt;&lt;/a&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GRAY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GRAY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GRAY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  As another example:
&lt;/h3&gt;

&lt;p&gt;If the answer is &lt;code&gt;"DREAD"&lt;/code&gt;, and &lt;code&gt;"ADDED"&lt;/code&gt; is guessed, the result produced would be:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3w2qp5rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8qnb698dwvt8ys7tc83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3w2qp5rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8qnb698dwvt8ys7tc83.png" alt="'YELLOW', 'YELLOW', 'YELLOW', 'YELLOW', 'GREEN'" width="169" height="31"&gt;&lt;/a&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implies no letters are missing, but in fact, one of the D's is wrong and the R is missing. Only &lt;em&gt;one&lt;/em&gt; of the wrongly placed D's should be marked Yellow.&lt;/p&gt;

&lt;p&gt;A correct algorithm would produce the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j69hmzis--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7rwe7j9orb4u6azptpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j69hmzis--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7rwe7j9orb4u6azptpa.png" alt="'YELLOW', 'YELLOW', 'GRAY', 'YELLOW', 'GREEN'" width="169" height="32"&gt;&lt;/a&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GRAY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to take a moment to challenge yourself to come up with a correct algorithm before continuing to the last section of the article.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;A single for-loop is not enough as the colors of the tiles will change depending on the colors of other tiles in the same row.&lt;/p&gt;

&lt;p&gt;We always want correct letters in the correct spot to be green, so we will score those first and remove them from the answer so they cannot be scored again later as a yellow letter.&lt;/p&gt;

&lt;p&gt;Next, we want to score the correct letters in the wrong spot as yellow. Again we need to remove them from the answer so they cannot be scored again later by an additional yellow letter (as in the case of &lt;code&gt;"DREAD"&lt;/code&gt; and &lt;code&gt;"ADDED"&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Finally, all the remaining letters that are not in the answer are gray.&lt;/p&gt;

&lt;p&gt;Here is an example of an algorithm that has been corrected for this mistake (there is more than one possible solution):&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;function&lt;/span&gt; &lt;span class="nx"&gt;colorRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// initialize all colors to GRAY&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GRAY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// loop through guess and mark green if fully correct&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// remove letter from answer, so it's not scored again&lt;/span&gt;
            &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &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="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// loop through guess and mark yellow if partially correct&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// remove letter from answer, so it's not scored again&lt;/span&gt;
            &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;colors&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;In this algorithm, the &lt;em&gt;first occurrence&lt;/em&gt; of a letter in the answer is replaced with a &lt;em&gt;space&lt;/em&gt;, so that it still takes up an index in the answer string, but it is no longer able to be scored again.&lt;/p&gt;

&lt;p&gt;After the first line, we will have an array containing "GRAY" for each letter in the guess.&lt;/p&gt;

&lt;p&gt;Once we have completed the first loop, we will have an array containing "GREEN" for each letter in the guess that is fully correct, and "GRAY" for all other letters. The answer will now no longer have letters that have been scored as green.&lt;/p&gt;

&lt;p&gt;After the second loop, we will have an array still containing the greens, but now also including all "YELLOW" tiles that have been scored. All letters that do not appear in the word will remain as "GRAY". &lt;code&gt;colors[i] !== "GREEN"&lt;/code&gt; must be checked in the second loop since we don't want to change letters that were scored as "GREEN" into "YELLOW".&lt;/p&gt;

&lt;p&gt;Finally, we will have an array containing all the colors for each letter in the guess and we can return it!&lt;/p&gt;

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

&lt;p&gt;I hope you found this tutorial useful. Maybe it will help you to make or fix a Wordle Clone of your own!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;*I do not mean in any way to say that any creators or their tutorials are bad in any way. The creators who made these tutorials have great educational content and I do not think one should think less of them due to a commonly made error. Always remember to &lt;em&gt;be nice&lt;/em&gt; when approaching creators in comments.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're interested in learning how to make a Discord Bot in Python to play Wordle, check out &lt;a href="https://www.youtube.com/watch?v=0p_eQGKFY3I"&gt;my tutorial&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;🐙 GitHub: &lt;a href="https://github.com/DenverCoder1"&gt;DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📺 YouTube: &lt;a href="https://youtube.com/c/DevProTips"&gt;Jonah Lawrence - Dev Pro Tips&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🐦 Twitter: &lt;a href="https://twitter.com/DenverCoder1"&gt;@DenverCoder1&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Update (2022-03-01): Anonymous#9495 pointed out on Discord that there was a slight error in the code (checking &lt;code&gt;guess[i] !== answer[i]&lt;/code&gt; in the second loop instead of &lt;code&gt;colors[i] !== "GREEN"&lt;/code&gt;). The code did not work in some cases such as where the answer is "MAXIM" and "MAMMA" is guessed, since the &lt;code&gt;answer&lt;/code&gt; string has been changed to have spaces, so the guess and answer will no longer match.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Using GitHub Actions to Publish Doxygen Docs to GitHub Pages</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Mon, 06 Dec 2021 06:34:03 +0000</pubDate>
      <link>https://forem.com/denvercoder1/using-github-actions-to-publish-doxygen-docs-to-github-pages-177g</link>
      <guid>https://forem.com/denvercoder1/using-github-actions-to-publish-doxygen-docs-to-github-pages-177g</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/doxygen-github-pages-deploy-action" rel="noopener noreferrer"&gt;&lt;img src="https://media.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%2Fkxxu8dgjat4dmlrz1pde.png" alt="Marketplace screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/doxygen-github-pages-action" rel="noopener noreferrer"&gt;&lt;strong&gt;Doxygen GitHub Pages Deploy Action&lt;/strong&gt;&lt;/a&gt; is a new GitHub action for automating the process of making documentation using &lt;a href="https://www.doxygen.nl/index.html" rel="noopener noreferrer"&gt;Doxygen&lt;/a&gt; and publishing it to &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This action is a composite action using shell scripts for installing necessary tools and preparing docs and makes use of &lt;a href="https://github.com/JamesIves/github-pages-deploy-action" rel="noopener noreferrer"&gt;JamesIves/github-pages-deploy-action&lt;/a&gt; for deploying the docs to a GitHub Pages branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Doxygen GitHub Pages Deploy Action&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DenverCoder1/doxygen-github-pages-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gh-pages&lt;/span&gt;
          &lt;span class="na"&gt;folder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;DIY Deployments&lt;/p&gt;
&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DenverCoder1" rel="noopener noreferrer"&gt;
        DenverCoder1
      &lt;/a&gt; / &lt;a href="https://github.com/DenverCoder1/doxygen-github-pages-action" rel="noopener noreferrer"&gt;
        doxygen-github-pages-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      GitHub Action for deploying Doxygen documentation to a GitHub pages branch
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Doxygen GitHub Pages Deploy Action&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;GitHub Action for making and deploying Doxygen documentation to a GitHub pages branch&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Basic Usage&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;To deploy docs on every push to the &lt;code&gt;main&lt;/code&gt; branch, create a new file in the &lt;code&gt;.github/workflows/&lt;/code&gt; directory called &lt;code&gt;doxygen-gh-pages.yml&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Doxygen GitHub Pages Deploy Action&lt;/span&gt;

&lt;span class="pl-ent"&gt;on&lt;/span&gt;:
  &lt;span class="pl-ent"&gt;push&lt;/span&gt;:
    &lt;span class="pl-ent"&gt;branches&lt;/span&gt;:
      - &lt;span class="pl-s"&gt;main&lt;/span&gt;

&lt;span class="pl-ent"&gt;jobs&lt;/span&gt;:
  &lt;span class="pl-ent"&gt;deploy&lt;/span&gt;:
    &lt;span class="pl-ent"&gt;runs-on&lt;/span&gt;: &lt;span class="pl-s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="pl-ent"&gt;permissions&lt;/span&gt;:
      &lt;span class="pl-ent"&gt;contents&lt;/span&gt;: &lt;span class="pl-s"&gt;write&lt;/span&gt;
    &lt;span class="pl-ent"&gt;steps&lt;/span&gt;:
      - &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;DenverCoder1/doxygen-github-pages-action@v2.0.0&lt;/span&gt;
        &lt;span class="pl-ent"&gt;with&lt;/span&gt;:
          &lt;span class="pl-ent"&gt;github_token&lt;/span&gt;: &lt;span class="pl-s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Options&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;code&gt;github_token&lt;/code&gt; (required): GitHub token for pushing to repo. See the &lt;a href="https://git.io/passing-token" rel="nofollow noopener noreferrer"&gt;docs&lt;/a&gt; for more info.&lt;/li&gt;

&lt;li&gt;

&lt;code&gt;branch&lt;/code&gt; (optional): Branch to deploy to. Defaults to &lt;code&gt;gh-pages&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;

&lt;code&gt;folder&lt;/code&gt; (optional): Folder where the docs are built. Defaults to &lt;code&gt;docs/html&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;

&lt;code&gt;config_file&lt;/code&gt; (optional): Path of the Doxygen configuration file. Defaults to &lt;code&gt;Doxyfile&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;

&lt;code&gt;target_folder&lt;/code&gt; (optional): Directory within the deployment branch to push to. Defaults to empty (root).&lt;/li&gt;

&lt;li&gt;

&lt;code&gt;doxygen_version&lt;/code&gt; (optional): Version…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DenverCoder1/doxygen-github-pages-action" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  In the Making
&lt;/h3&gt;

&lt;p&gt;First I needed to create a new repo with an &lt;code&gt;action.yml&lt;/code&gt; to start making the composite action.&lt;/p&gt;

&lt;p&gt;This action is the first action I have listed on the &lt;a href="https://github.com/marketplace/actions/doxygen-github-pages-deploy-action" rel="noopener noreferrer"&gt;Marketplace&lt;/a&gt;. In order to set up the listing properly, the following data appears at the top of the action file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Doxygen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Pages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Action'&lt;/span&gt;
&lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Jonah&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Lawrence'&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Make&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;docs&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Doxygen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;then&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generated&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HTML&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pages'&lt;/span&gt;
&lt;span class="na"&gt;branding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;upload-cloud"&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purple"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the &lt;code&gt;github_token&lt;/code&gt;, &lt;code&gt;folder&lt;/code&gt;, and &lt;code&gt;branch&lt;/code&gt; used for deployment should be configurable, these three inputs were added to the action to allow these to be set in a workflow using the &lt;code&gt;with:&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pushing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;repo.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Example:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;https://git.io/passing-token'&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Branch&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pushing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;files'&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gh-pages"&lt;/span&gt;
  &lt;span class="na"&gt;folder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Folder&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;where&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Doxygen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;will&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HTML&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;files'&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docs/html"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This action is a composite action. First we add a &lt;code&gt;runs&lt;/code&gt; property using &lt;code&gt;composite&lt;/code&gt;, then we add the steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;using&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;composite"&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following are the steps added to the action:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Checkout repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;submodules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/actions/checkout" rel="noopener noreferrer"&gt;actions/checkout&lt;/a&gt; step is used to checkout the repository with any submodules.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Install Doxygen
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Doxygen&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sudo apt-get install doxygen -y&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doxygen is installed by running &lt;code&gt;apt-get install&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Generate Doxygen Documentation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate Doxygen Documentation&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;doxygen&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doxygen documentation is generated by running &lt;code&gt;doxygen&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Create .nojekyll
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create .nojekyll&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;touch ${{ inputs.folder }}/.nojekyll&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating a .nojekyll file ensures pages with underscores work on GitHub Pages.&lt;/p&gt;

&lt;p&gt;The folder where the documentation is built is where the &lt;code&gt;.nojekyll&lt;/code&gt; file will be created. The &lt;code&gt;folder&lt;/code&gt; input is used for this purpose.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Deploy to GitHub Pages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to GitHub Pages&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JamesIves/github-pages-deploy-action@3.7.1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.github_token }}&lt;/span&gt;
        &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.branch }}&lt;/span&gt;
        &lt;span class="na"&gt;folder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.folder }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/JamesIves/github-pages-deploy-action" rel="noopener noreferrer"&gt;JamesIves/github-pages-deploy-action&lt;/a&gt; action is used to deploy the documentation to GitHub Pages.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;folder&lt;/code&gt; input option determines which folder to deploy. By default, it is &lt;code&gt;docs/html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;branch&lt;/code&gt; input option determines which branch to deploy to. By default, it is &lt;code&gt;gh-pages&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;To see it in action, I have set up the action to run on my &lt;a href="https://github.com/DenverCoder1/C-Workshop" rel="noopener noreferrer"&gt;C-Workshop&lt;/a&gt; GitHub repository.&lt;/p&gt;

</description>
      <category>actionshackathon21</category>
      <category>productivity</category>
      <category>github</category>
    </item>
    <item>
      <title>GitHub Action for Updating Your Readme with a Download Button</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Mon, 06 Dec 2021 01:37:41 +0000</pubDate>
      <link>https://forem.com/denvercoder1/github-action-for-updating-your-readme-with-a-download-button-2o11</link>
      <guid>https://forem.com/denvercoder1/github-action-for-updating-your-readme-with-a-download-button-2o11</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/readme-download-button-action" rel="noopener noreferrer"&gt;&lt;strong&gt;Readme Download Button Action&lt;/strong&gt;&lt;/a&gt; is a new workflow that allows you to keep a direct download link of the latest version of your repo in your README file.&lt;/p&gt;

&lt;p&gt;Example download button generated by the workflow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/readme-download-button-action/archive/1.0.1.zip" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcustom-icon-badges.herokuapp.com%2Fbadge%2F-Download-blue%3Fstyle%3Dfor-the-badge%26logo%3Ddownload%26logoColor%3Dwhite" title="Download zip" alt="Download zip"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The steps for setting up the workflow are explained in detail on the &lt;a href="https://github.com/DenverCoder1/readme-download-button-action/" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting started
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Download&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Button&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Action"&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;published&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get latest release&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get-latest-release&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InsonusK/get-latest-release@v1.0.1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;myToken&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.token }}&lt;/span&gt;
          &lt;span class="na"&gt;view_top&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Readme Download Button Action&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DenverCoder1"&lt;/span&gt;
          &lt;span class="na"&gt;REPO&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;readme-download-button-action"&lt;/span&gt;
          &lt;span class="na"&gt;FORMAT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;zip"&lt;/span&gt;
          &lt;span class="na"&gt;VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.get-latest-release.outputs.tag_name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
          &lt;span class="na"&gt;COLOR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blue"&lt;/span&gt;
          &lt;span class="na"&gt;BEGIN_TAG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BEGIN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;LATEST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DOWNLOAD&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BUTTON&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--&amp;gt;"&lt;/span&gt;
          &lt;span class="na"&gt;END_TAG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;END&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;LATEST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DOWNLOAD&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BUTTON&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--&amp;gt;"&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;UPDATE=$(cat README.md | perl -0777 -pe 's#(${{ env.BEGIN_TAG }})(?:.|\n)*?(${{ env.END_TAG }})#${1}\n[![Download ${{ env.FORMAT }}](https://custom-icon-badges.herokuapp.com/badge/-Download-${{ env.COLOR }}?style=for-the-badge&amp;amp;logo=download&amp;amp;logoColor=white "Download ${{ env.FORMAT }}")](https://github.com/${{ env.GITHUB_USER }}/${{ env.REPO }}/archive/${{ env.VERSION }}.${{ env.FORMAT }})\n${2}#g')&lt;/span&gt;
          &lt;span class="s"&gt;echo "${UPDATE}" &amp;gt; README.md&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EndBug/add-and-commit@v7&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docs(readme):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Bump&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;download&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;button&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.get-latest-release.outputs.tag_name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
          &lt;span class="na"&gt;default_author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github_actions&lt;/span&gt;
          &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves&lt;/p&gt;
&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DenverCoder1" rel="noopener noreferrer"&gt;
        DenverCoder1
      &lt;/a&gt; / &lt;a href="https://github.com/DenverCoder1/readme-download-button-action" rel="noopener noreferrer"&gt;
        readme-download-button-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      GitHub Action workflow configuration for keeping a direct download link to the latest version on your repo's readme
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Readme Download Button Action&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;GitHub Action workflow configuration for keeping a direct download link of the latest version in your README.md file.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Example&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;With a single click of the button below, a zip of this repository will start downloading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/readme-download-button-action/archive/1.0.2.zip" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b921c0cfed4429784d6c72d980ca6407c85b652b25df4f981c38de986831851e/68747470733a2f2f637573746f6d2d69636f6e2d6261646765732e64656d6f6c61622e636f6d2f62616467652f2d446f776e6c6f61642d626c75653f7374796c653d666f722d7468652d6261646765266c6f676f3d646f776e6c6f6164266c6f676f436f6c6f723d7768697465" alt="Download zip" title="Download zip"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The URL this button leads to is automatically updated on each release by this &lt;a href="https://github.com/DenverCoder1/readme-download-button-action.github/workflows/download-button.yml" rel="noopener noreferrer"&gt;workflow&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Basic Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;This workflow consists mainly of four parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checkout the latest version of the repo with &lt;a href="https://github.com/actions/checkout" rel="noopener noreferrer"&gt;actions/checkout&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Get the latest release with &lt;a href="https://github.com/InsonusK/get-latest-release" rel="noopener noreferrer"&gt;InsonusK/get-latest-release&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Insert a download button for the latest version in the readme using a custom shell script&lt;/li&gt;
&lt;li&gt;Update the readme with &lt;a href="https://github.com/EndBug/add-and-commit" rel="noopener noreferrer"&gt;EndBug/add-and-commit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Step 1&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Add the following snippet within your README.md file anywhere you want the button to appear:&lt;/p&gt;

&lt;div class="highlight highlight-text-md notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;&amp;lt;!--&lt;/span&gt; BEGIN LATEST DOWNLOAD BUTTON &lt;span class="pl-c"&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;&amp;lt;!--&lt;/span&gt; END LATEST DOWNLOAD BUTTON &lt;span class="pl-c"&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Step 2&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Create a workflow by placing the following in a &lt;code&gt;.yml&lt;/code&gt; file in your &lt;code&gt;.github/workflows/&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Download&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DenverCoder1/readme-download-button-action" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Background
&lt;/h3&gt;

&lt;p&gt;This project was created due to the fact that many users may come to a repository to download a project but are not familiar enough with the site to navigate the repository and find a proper download link.&lt;/p&gt;

&lt;p&gt;This workflow aims to simplify the process, by putting a download button front and center in the Readme so it can't be missed.&lt;/p&gt;

&lt;p&gt;Having a download button on the Readme allows visiting users to quickly download your source code with &lt;strong&gt;just a single click&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does this require a workflow?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to make the process a single click away, a direct download link must be included.&lt;/p&gt;

&lt;p&gt;For example, a link to download the source code of version 1.0.1 of &lt;a href="https://github.com/DenverCoder1/readme-download-button-action" rel="noopener noreferrer"&gt;readme-download-button-action&lt;/a&gt; will look like this: &lt;code&gt;https://github.com/DenverCoder1/readme-download-button-action/archive/1.0.1.zip&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Notice that the url contains &lt;strong&gt;1.0.1&lt;/strong&gt;, the &lt;em&gt;version&lt;/em&gt;. This number changes with every new version released, so in order to keep the download button up-to-date, we will have to update the readme to change the link.&lt;/p&gt;

&lt;p&gt;That's where this workflow comes in. With just a few seconds of one-time configuration, your button will be generated and automatically kept up to date whenever you make a new release.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making of this workflow
&lt;/h3&gt;

&lt;p&gt;First, we need to set the trigger event. A good choice here is when we publish a release. Additionally &lt;code&gt;workflow_dispatch:&lt;/code&gt; is added so that it can be manually triggered from the Actions tab in case you want to re-run it without creating a new release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;published&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we create some steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checkout&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to be able to read and overwrite the files in the repo such as the readme, we will need to first checkout the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Get Latest Release&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following workflow by InsonusK allows us to get info on the latest release. We can access the tag name later using &lt;code&gt;${{ steps.get-latest-release.outputs.tag_name }}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get latest release&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get-latest-release&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InsonusK/get-latest-release@v1.0.1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;myToken&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.token }}&lt;/span&gt;
    &lt;span class="na"&gt;view_top&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The custom shell script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The actual replacement of the button is done with a shell step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Readme Download Button Action&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;GITHUB_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DenverCoder1"&lt;/span&gt;
    &lt;span class="na"&gt;REPO&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;readme-download-button-action"&lt;/span&gt;
    &lt;span class="na"&gt;FORMAT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;zip"&lt;/span&gt;
    &lt;span class="na"&gt;VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.get-latest-release.outputs.tag_name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
    &lt;span class="na"&gt;COLOR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blue"&lt;/span&gt;
    &lt;span class="na"&gt;BEGIN_TAG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BEGIN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;LATEST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DOWNLOAD&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BUTTON&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--&amp;gt;"&lt;/span&gt;
    &lt;span class="na"&gt;END_TAG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!--&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;END&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;LATEST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DOWNLOAD&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;BUTTON&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;UPDATE=$(cat README.md | perl -0777 -pe 's#(${{ env.BEGIN_TAG }})(?:.|\n)*?(${{ env.END_TAG }})#${1}\n[![Download ${{ env.FORMAT }}](https://custom-icon-badges.herokuapp.com/badge/-Download-${{ env.COLOR }}?style=for-the-badge&amp;amp;logo=download&amp;amp;logoColor=white "Download ${{ env.FORMAT }}")](https://github.com/${{ env.GITHUB_USER }}/${{ env.REPO }}/archive/${{ env.VERSION }}.${{ env.FORMAT }})\n${2}#g')&lt;/span&gt;
    &lt;span class="s"&gt;echo "${UPDATE}" &amp;gt; README.md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;perl&lt;/code&gt; is used here to make a multiline replacement using regular expressions. At first I was going to try &lt;code&gt;sed&lt;/code&gt; but it deals with lines one at a time, so it's much more complicated when dealing with multiline matches.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;env&lt;/code&gt; section also appears to make configuring the download button as simple as possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add and commit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally we can use EndBug's add-and-commit to make the change persist!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EndBug/add-and-commit@v7&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docs(readme):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Bump&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;download&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;button&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.get-latest-release.outputs.tag_name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
    &lt;span class="na"&gt;default_author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github_actions&lt;/span&gt;
    &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;This action works great in combination with several open-source workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/InsonusK/get-latest-release" rel="noopener noreferrer"&gt;InsonusK/get-latest-release&lt;/a&gt; - Determine the tag for the latest release&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/EndBug/add-and-commit" rel="noopener noreferrer"&gt;EndBug/add-and-commit&lt;/a&gt; - Commit your changes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tvdias/github-tagger" rel="noopener noreferrer"&gt;tvdias/github-tagger&lt;/a&gt; - Create new tags to push to&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/fregante/release-with-changelog" rel="noopener noreferrer"&gt;fregante/release-with-changelog&lt;/a&gt; - generate changelogs for your releases&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>actionshackathon21</category>
      <category>productivity</category>
      <category>github</category>
    </item>
    <item>
      <title>Keeping your dependencies updated automatically with Dependabot</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Wed, 19 May 2021 12:28:39 +0000</pubDate>
      <link>https://forem.com/denvercoder1/keeping-your-dependencies-updated-automatically-with-dependabot-299g</link>
      <guid>https://forem.com/denvercoder1/keeping-your-dependencies-updated-automatically-with-dependabot-299g</guid>
      <description>&lt;p&gt;In this tutorial, you will learn how to use the GitHub dependency bot to make sure your packages stay up to date without breaking your code.&lt;/p&gt;

&lt;p&gt;I will be showing you how to add versions to Python dependencies and how to set up Dependabot to run on your GitHub repository to make sure you always have the latest version in your requirements.txt. Dependabot will send Pull Requests to your repo whenever a package is out of date so you can easily check the changelog, test the new version, and update your requirements file with a single click.&lt;/p&gt;

&lt;p&gt;The Dependabot configuration steps can be applied to dependencies of many types and in many languages including &lt;code&gt;github-actions&lt;/code&gt;, &lt;code&gt;docker&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt; (Python), &lt;code&gt;npm&lt;/code&gt; (JavaScript), &lt;code&gt;composer&lt;/code&gt; (PHP), and &lt;a href="https://docs.github.com/en/code-security/supply-chain-security/configuration-options-for-dependency-updates#package-ecosystem" rel="noopener noreferrer"&gt;many others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article was originally a video tutorial, which you can check out here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/22XrqdIe8oQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Make sure your packages have version numbers
&lt;/h2&gt;

&lt;p&gt;When using a &lt;code&gt;requirements.txt&lt;/code&gt; in a Python project, version numbers are optional. If they are not provided, running the command to install the packages will always get the latest version of the package.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So why should we add version numbers?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is very risky to install dependencies without specifying version numbers. Often times packages will receive updates that break or alter existing functionality and require the dependent to update their code to continue using the package. In the case of a new major release, your code may all of a sudden break just because you wrote it for a different version of a package you are using.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do you add version numbers?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In your &lt;code&gt;requirements.txt&lt;/code&gt;, you can specify version numbers by appending &lt;code&gt;==&lt;/code&gt; followed by the version to the package name. To find out what version of each package your are using, you can run &lt;code&gt;pip freeze&lt;/code&gt; in your terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fn57rr8iihgar0uaixjut.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fn57rr8iihgar0uaixjut.gif" alt="pip freeze"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This is an example &lt;code&gt;requirements.txt&lt;/code&gt; with version numbers included:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ftmvq6fv0yguea70s83op.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftmvq6fv0yguea70s83op.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic updates with Dependabot
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 - Click on Insights
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fohlse9tl3jujtmhru7cq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fohlse9tl3jujtmhru7cq.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Click "Dependency graph", then "Dependabot"
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.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%2F73uy9ju56boi9g195c94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F73uy9ju56boi9g195c94.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Enable Dependabot and create a config file
&lt;/h3&gt;

&lt;p&gt;Make sure to insert the name of your package ecosystem on the line that is highlighted below. See &lt;a href="https://docs.github.com/en/code-security/supply-chain-security/configuration-options-for-dependency-updates#package-ecosystem" rel="noopener noreferrer"&gt;this link&lt;/a&gt; for the list of possible options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmdgjmrnrir1dyt8kv949.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmdgjmrnrir1dyt8kv949.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 - Push the configuration file to your main branch and wait for pull requests
&lt;/h3&gt;

&lt;p&gt;Within a few minutes, you should start receiving PRs (possibly longer if you already have everything up to date 😄)&lt;/p&gt;

&lt;h2&gt;
  
  
  Reviewing Dependabot PRs
&lt;/h2&gt;

&lt;p&gt;Here's what a Dependabot PR looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxg2e2f5essero76172xq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxg2e2f5essero76172xq.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will give you details about the changes to the package and allow you run tests if that is applicable to your repo.&lt;/p&gt;

&lt;p&gt;Once your code is tested and seems to be working with the new version, you can update your requirements by simply clicking "Merge Pull Request".&lt;/p&gt;

&lt;p&gt;Whenever a change is made to the requirements, Dependabot will automatically rebase all of it's open PRs to ensure there are never any merge conflicts.&lt;/p&gt;

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

&lt;p&gt;I hope you found this tutorial useful.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://www.youtube.com/watch?v=22XrqdIe8oQ" rel="noopener noreferrer"&gt;the full video&lt;/a&gt; for further explanations and be sure to like and subscribe!&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;Twitter: &lt;a href="https://twitter.com/DenverCoder1" rel="noopener noreferrer"&gt;@DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YouTube: &lt;a href="https://youtube.com/c/DevProTips" rel="noopener noreferrer"&gt;Jonah Lawrence - Dev Pro Tips&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Discord server: &lt;a href="https://discord.gg/fPrdqh3Zfu" rel="noopener noreferrer"&gt;https://discord.gg/fPrdqh3Zfu&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>productivity</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to run an HTML/PHP website on Localhost</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Wed, 17 Feb 2021 14:46:26 +0000</pubDate>
      <link>https://forem.com/denvercoder1/how-to-run-an-html-php-website-on-localhost-2fk3</link>
      <guid>https://forem.com/denvercoder1/how-to-run-an-html-php-website-on-localhost-2fk3</guid>
      <description>&lt;p&gt;In this tutorial, I'm going to show you how to run your website locally with XAMPP. This is especially useful when writing PHP since you will be able to test your site without putting it on a web server!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/K-qXW9ymeYQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;The first thing you'll need to do is install PHP. My preferred way of doing that is by installing XAMPP from &lt;a href="https://www.apachefriends.org" rel="noopener noreferrer"&gt;https://www.apachefriends.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzym1bmy5seq2buh3rsmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzym1bmy5seq2buh3rsmh.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the download button for your operating system to get the latest version.&lt;/p&gt;

&lt;p&gt;Once it's finished installing, you should be able to access all of the PHP features from your command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open a command prompt in your working directory
&lt;/h2&gt;

&lt;p&gt;You'll need to open a command prompt in the directory containing your root directory or index file.&lt;/p&gt;

&lt;p&gt;There are a few ways to do that on Windows:&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1
&lt;/h3&gt;

&lt;p&gt;Open a File Explorer to the directory and click on the bar containing the path&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F745mz9yutx27a0oydbms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F745mz9yutx27a0oydbms.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter "cmd" in the bar and press enter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6l71kw8xbkiv9a538f5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6l71kw8xbkiv9a538f5y.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2
&lt;/h3&gt;

&lt;p&gt;Open a command prompt by searching for the application "Command Prompt" or "Terminal".&lt;/p&gt;

&lt;p&gt;Run the "change directory" command by typing &lt;code&gt;cd&lt;/code&gt; followed by the path of your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1ik1rksf7eo1m0svduip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1ik1rksf7eo1m0svduip.png" alt="image"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Method 3
&lt;/h3&gt;

&lt;p&gt;If you have Visual Studio Code installed, you can press &lt;strong&gt;Ctrl + `&lt;/strong&gt; to open a terminal within the editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fo4vi1zs9nz4k0te49wxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fo4vi1zs9nz4k0te49wxr.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running your code on localhost
&lt;/h2&gt;

&lt;p&gt;Type the command &lt;code&gt;php -S localhost:8000&lt;/code&gt; to run your site on port 8000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmqax7himqo2tfey2ydk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmqax7himqo2tfey2ydk8.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: If you get an error that 'php' is not recognized, you likely will need to add it to your path manually. To do that, locate &lt;code&gt;php.exe&lt;/code&gt; (for me it is in the directory &lt;code&gt;C:\xampp\php\&lt;/code&gt;). Search for "Edit system environment variables", at the bottom of the window that comes up, click "Environment variables", then click the row for "Path" and click the "Edit..." button. Add a row containing the directory you found earlier (ex. &lt;code&gt;C:\xampp\php\&lt;/code&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  See your site live!
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="http://localhost:8000/" rel="noopener noreferrer"&gt;http://localhost:8000/&lt;/a&gt; in your browser to see your site live!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F3eirokwt2vrn0gghf4ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3eirokwt2vrn0gghf4ny.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to keep the command prompt open while you want your site to stay live!&lt;/p&gt;

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

&lt;p&gt;If you found this useful, consider leaving a like and subscribing to &lt;a href="https://www.youtube.com/channel/UCipSxT7a3rn81vGLw9lqRkg" rel="noopener noreferrer"&gt;my YouTube channel&lt;/a&gt;! 😎&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;🐦 &lt;a href="https://twitter.com/DenverCoder1" rel="noopener noreferrer"&gt;@DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📺 &lt;a href="https://www.youtube.com/channel/UCipSxT7a3rn81vGLw9lqRkg" rel="noopener noreferrer"&gt;Jonah Lawrence • Dev Pro Tips&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>webdev</category>
      <category>php</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Easily Bulk Rename Files on Windows</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Mon, 15 Feb 2021 21:00:22 +0000</pubDate>
      <link>https://forem.com/denvercoder1/easily-bulk-rename-files-on-windows-2leb</link>
      <guid>https://forem.com/denvercoder1/easily-bulk-rename-files-on-windows-2leb</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/DCP1elBAy_U"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In this tutorial, I will show you how to rename several files at once in Windows 10. You not only can append text to filenames, but you can even create advanced regular expressions or enumerate your files. There are also text transformations available to make your filenames all uppercase or lowercase.&lt;/p&gt;

&lt;p&gt;To get started, I will be using PowerRename which is part of Microsoft PowerToys.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/microsoft"&gt;
        microsoft
      &lt;/a&gt; / &lt;a href="https://github.com/microsoft/PowerToys"&gt;
        PowerToys
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Windows system utilities to maximize productivity
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Microsoft PowerToys&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/microsoft/PowerToysdoc/images/overview/PT_hero_image.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OK8M0meS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/microsoft/PowerToysdoc/images/overview/PT_hero_image.png" alt="Hero image for Microsoft PowerToys"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/powertoys-docs" rel="nofollow"&gt;How to use PowerToys&lt;/a&gt; | &lt;a href="https://aka.ms/installPowerToys" rel="nofollow"&gt;Downloads &amp;amp; Release notes&lt;/a&gt; | &lt;a href="https://github.com/microsoft/PowerToys#contributing"&gt;Contributing to PowerToys&lt;/a&gt; | &lt;a href="https://github.com/microsoft/PowerToys#whats-happening"&gt;What's Happening&lt;/a&gt; | &lt;a href="https://github.com/microsoft/PowerToys#powertoys-roadmap"&gt;Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Build status&lt;/h2&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Architecture&lt;/th&gt;
&lt;th&gt;Solution (Main)&lt;/th&gt;
&lt;th&gt;Solution (Stable)&lt;/th&gt;
&lt;th&gt;Installer (Main)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;x64&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&amp;amp;branchName=main&amp;amp;jobName=Build%20x64%20Release" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4f22179470501726e2caf505fea156f55c1d1d39c3ee6c9f0d17f6667c4c769e/68747470733a2f2f6465762e617a7572652e636f6d2f6d732f506f776572546f79732f5f617069732f6275696c642f7374617475732f6d6963726f736f66742e506f776572546f79733f6272616e63684e616d653d6d61696e266a6f624e616d653d4275696c6425323078363425323052656c65617365" alt="Build Status for Main"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&amp;amp;branchName=stable" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/7067fcca0c885d07d2f6c47300ac2cbff7fa3985fdb87464605801e9c651d161/68747470733a2f2f6465762e617a7572652e636f6d2f6d732f506f776572546f79732f5f617069732f6275696c642f7374617475732f6d6963726f736f66742e506f776572546f79733f6272616e63684e616d653d737461626c65266a6f624e616d653d4275696c6425323078363425323052656c65617365" alt="Build Status for Stable"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.azure.com/microsoft/Dart/_build/latest?definitionId=76541&amp;amp;branchName=main" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/ff67719bd40e4050f2a8dc63f8b874f43e1d4a0cba98d4523fa3eafca2352712/68747470733a2f2f6465762e617a7572652e636f6d2f6d6963726f736f66742f446172742f5f617069732f6275696c642f7374617475732f506f776572546f79732f506f776572546f79732532305369676e656425323059414d4c25323052656c656173652532304275696c643f6272616e63684e616d653d6d61696e266a6f624e616d653d4275696c6426636f6e66696775726174696f6e3d4275696c6425323052656c656173655f783634" alt="Build Status Installer pipeline"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARM64&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&amp;amp;branchName=main" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/f473a06943a3323f287352d512fa0e6956d6cfc92211e49c01d25a2835898bba/68747470733a2f2f6465762e617a7572652e636f6d2f6d732f506f776572546f79732f5f617069732f6275696c642f7374617475732f6d6963726f736f66742e506f776572546f79733f6272616e63684e616d653d6d61696e266a6f624e616d653d4275696c6425323061726d363425323052656c65617365" alt="Build Status for Main"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&amp;amp;branchName=stable" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/f473a06943a3323f287352d512fa0e6956d6cfc92211e49c01d25a2835898bba/68747470733a2f2f6465762e617a7572652e636f6d2f6d732f506f776572546f79732f5f617069732f6275696c642f7374617475732f6d6963726f736f66742e506f776572546f79733f6272616e63684e616d653d6d61696e266a6f624e616d653d4275696c6425323061726d363425323052656c65617365" alt="Build Status for Main"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.azure.com/microsoft/Dart/_build/latest?definitionId=76541&amp;amp;branchName=main" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/60b9880baafe2d4a07abfa00ee3c7b87c4dc01fd453bb659d755ef6954fd135a/68747470733a2f2f6465762e617a7572652e636f6d2f6d6963726f736f66742f446172742f5f617069732f6275696c642f7374617475732f506f776572546f79732f506f776572546f79732532305369676e656425323059414d4c25323052656c656173652532304275696c643f6272616e63684e616d653d6d61696e266a6f624e616d653d4275696c6426636f6e66696775726174696f6e3d4275696c6425323052656c656173655f61726d3634" alt="Build Status Installer pipeline"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
About&lt;/h2&gt;
&lt;p&gt;Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. For more info on &lt;a href="https://aka.ms/powertoys-docs" rel="nofollow"&gt;PowerToys overviews and how to use the utilities&lt;/a&gt;, or any other tools and resources for &lt;a href="https://learn.microsoft.com/windows/dev-environment/overview" rel="nofollow"&gt;Windows development environments&lt;/a&gt;, head over to &lt;a href="https://aka.ms/powertoys-docs" rel="nofollow"&gt;learn.microsoft.com&lt;/a&gt;!&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Current utilities:&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_AoT" rel="nofollow"&gt;Always on Top&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_Awake" rel="nofollow"&gt;PowerToys Awake&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_ColorPicker" rel="nofollow"&gt;Color Picker&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_FancyZones" rel="nofollow"&gt;FancyZones&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_FileExplorerAddOns" rel="nofollow"&gt;File Explorer Add-ons&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_FileLocksmith" rel="nofollow"&gt;File Locksmith&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_HostsFileEditor" rel="nofollow"&gt;Hosts File Editor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_ImageResizer" rel="nofollow"&gt;Image Resizer&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_KeyboardManager" rel="nofollow"&gt;Keyboard Manager&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_MouseUtilities" rel="nofollow"&gt;Mouse utilities&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_PowerRename" rel="nofollow"&gt;PowerRename&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_PowerToysRun" rel="nofollow"&gt;PowerToys Run&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_QuickAccent" rel="nofollow"&gt;Quick Accent&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_ScreenRuler" rel="nofollow"&gt;Screen Ruler&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_ShortcutGuide" rel="nofollow"&gt;Shortcut Guide&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_TextExtractor" rel="nofollow"&gt;Text Extractor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aka.ms/PowerToysOverview_VideoConference" rel="nofollow"&gt;Video Conference Mute&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
Installing and running Microsoft PowerToys&lt;/h2&gt;
&lt;h3&gt;
Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Windows 11 or Windows 10 version 2004 (code name 20H1 / build number 19041) or newer.&lt;/li&gt;
&lt;li&gt;Our installer will install the following items
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dotnet.microsoft.com/download/dotnet/6.0#runtime-desktop-6.0.10" rel="nofollow"&gt;.NET 6.0.10&lt;/a&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/microsoft/PowerToys"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You can install PowerToys by heading to &lt;a href="https://github.com/microsoft/PowerToys/releases/"&gt;this link&lt;/a&gt; and downloading the executable for the latest release (as of writing this, it's called &lt;code&gt;PowerToysSetup-0.31.2-x64.exe&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Once it's installed, you should be able to see PowerRename as an option in your Right-click menu when selecting files in your File Explorer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QsdYulks--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kdxvvuq0dbcp5ajpa72q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QsdYulks--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kdxvvuq0dbcp5ajpa72q.png" alt="image" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you click that, you should see a popup come up with a search box, replace box, some options, and a preview.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TgAkiRqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oydu680h2ltuv88hmoh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TgAkiRqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oydu680h2ltuv88hmoh9.png" alt="image" width="735" height="801"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make a simple word replacement, you can type the word to search for in the first box, the word to replace it with in the second box, preview the results, and click "Rename".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7btNa0RUYa5E7iiQ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7btNa0RUYa5E7iiQ/giphy.gif" alt="easy gif" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want more complex replacements, such as matching several different words or characters, reordering parts of the filename, or duplicating sections, you can do that with &lt;a href="https://www.youtube.com/playlist?list=PL9YUC9AZJGFGB7qnffZD0Iu7kntOSgfS7"&gt;Regular Expressions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, to match the words "Lab" or "Lecture" in a filename, we can use &lt;code&gt;(Lab|Lecture)&lt;/code&gt; in our search text. Just make sure to click the box for "Use Regular Expressions."&lt;/p&gt;

&lt;p&gt;To rearrange parts of a filename, you can reference capturing groups in the replace text.&lt;/p&gt;

&lt;p&gt;For example, if you had files that all ended with a 2-digit number and you wanted to move it to the beginning, your search text may be in the form &lt;code&gt;(.*)(\d\d)&lt;/code&gt; and you could replace it with &lt;code&gt;$2$1&lt;/code&gt; where &lt;code&gt;$2&lt;/code&gt; is the second capturing group, &lt;code&gt;(\d\d)&lt;/code&gt;, and &lt;code&gt;$1&lt;/code&gt; is the first capturing group, &lt;code&gt;(.*)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In my video, &lt;a href="https://www.youtube.com/watch?v=DCP1elBAy_U"&gt;How to Bulk Rename Files Easily on Windows&lt;/a&gt;, I show how it is possible to reorder parts of a filename, add padding zeroes, and change date formats with just a few simple replacements.&lt;/p&gt;

&lt;p&gt;Be sure to check it out and subscribe for more tips!&lt;/p&gt;

&lt;p&gt;Thanks for your support!&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;🐦 &lt;a href="https://twitter.com/DenverCoder1"&gt;@DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📺 &lt;a href="https://www.youtube.com/channel/UCipSxT7a3rn81vGLw9lqRkg"&gt;Jonah Lawrence • Dev Pro Tips&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>From Developer to Dev Content Creator - My 2020 Story</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Sun, 03 Jan 2021 15:31:49 +0000</pubDate>
      <link>https://forem.com/denvercoder1/from-developer-to-dev-content-creator-my-2020-story-9no</link>
      <guid>https://forem.com/denvercoder1/from-developer-to-dev-content-creator-my-2020-story-9no</guid>
      <description>&lt;p&gt;Here is my review of 2020 and the story of how I became a content creator from being just a quiet developer.&lt;/p&gt;

&lt;p&gt;2020 was a very interesting year. Staying inside and not having so many commitments gave me more time to learn new things and begin teaching what I love!&lt;/p&gt;

&lt;p&gt;Before 2020, I mostly worked alone on personal projects, but this past year, many things changed and I became a content creator!&lt;/p&gt;

&lt;p&gt;Without further ado, here are my highlights from 2020...&lt;/p&gt;

&lt;h3&gt;
  
  
  Made some online friends
&lt;/h3&gt;

&lt;p&gt;Although I haven't been extremely social online, I found a few developers on Twitter, YouTube, and Discord who I look up to and would consider my new friends.&lt;/p&gt;

&lt;p&gt;Here are just a few of the many awesome developers &amp;amp; content creators who I've connected with on social media:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://twitter.com/catalinmpit"&gt;Catalin Pit&lt;/a&gt; &lt;/li&gt;
&lt;li&gt; &lt;a href="https://twitter.com/jamesqquick"&gt;James Q. Quick&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/FrancescoCiull4"&gt;Francesco Cuilla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/eddiejaoude"&gt;Eddie Jaoude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/MaxProgramming1"&gt;Max Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/codeSTACKr"&gt;CodeSTACKr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/DThompsonDev"&gt;Danny Thompson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/BatsouElef"&gt;Eleftheria Batsou&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/Tyler_Potts_"&gt;Tyler Potts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/SimonHoiberg"&gt;Simon Høiberg&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out their content! These are all amazing people I hope to get to know better in 2021!&lt;/p&gt;

&lt;h3&gt;
  
  
  YouTube
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/DevProTips"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tzh6FE1X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1609680774570/HV2C1R-Tt.png" alt="image.png" width="679" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On May 31, 2020, I made my first real YouTube video which has since been unlisted due to the change in plans for my channel.&lt;/p&gt;

&lt;p&gt;About a month later, I realized my channel could become a resource for people who want to learn programming.&lt;/p&gt;

&lt;p&gt;On July 20, 2020, I made my first programming tutorial where you can hear me speak (before July 20 I only used background music).&lt;/p&gt;

&lt;p&gt;I now have been teaching web development and other coding tips about once a week.&lt;/p&gt;

&lt;p&gt;Since I started, I have made a total of &lt;strong&gt;28 public tutorials&lt;/strong&gt; and gained &lt;strong&gt;786 subscribers!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Including my unlisted and public videos, I achieved over 104,000 views this year!&lt;/p&gt;

&lt;p&gt;Check out my channel 👉 &lt;a href="https://www.youtube.com/c/DevProTips"&gt;https://www.youtube.com/c/DevProTips&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/DevProTips"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--htnf8289--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1609680666459/4hceERQq8.png" alt="image.png" width="880" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Twitter
&lt;/h3&gt;

&lt;p&gt;Starting in September, I have been posting JavaScript tips and quizzes every week.&lt;/p&gt;

&lt;p&gt;I also post any programming resources I find useful.&lt;/p&gt;

&lt;p&gt;Check it out 👉 &lt;a href="https://twitter.com/DenverCoder1"&gt;https://twitter.com/DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/DenverCoder1"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WdvVHXJt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1609680747562/jPg5Bjn34.png" alt="image.png" width="593" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="http://dev.to"&gt;Dev.to&lt;/a&gt; and Hashnode
&lt;/h3&gt;

&lt;p&gt;I only very recently started writing articles/blog posts (this is my 6th one). In 2020, my posts on DEV community have gotten 6800 views and 169 reactions.&lt;/p&gt;

&lt;p&gt;One of my first articles even got featured on Hashnode!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/denvercoder1"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q9RTJTqZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1609680807008/7R829kogj.png" alt="image.png" width="880" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jonahlawrence.hashnode.dev/making-a-responsive-birthday-card-with-html-and-css"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CtMObOkN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1609680811471/v_HkW3LHy.png" alt="image.png" width="880" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hacktoberfest
&lt;/h3&gt;

&lt;p&gt;Hacktoberfest was a great event this year. I learned about contributing to open source projects and even made some of my own for others to contribute to.&lt;/p&gt;

&lt;p&gt;Learning how to make a pull request on a public project was a very important skill I picked up and now I do it all the time!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hacktoberfest.digitalocean.com/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ythxZWTI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1609680842460/-ml9LPX-Z.png" alt="image.png" width="880" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub
&lt;/h3&gt;

&lt;p&gt;In 2020, I made 1220 commits, 50 pull requests, and opened 34 issues.&lt;/p&gt;

&lt;p&gt;My open source projects received a total of &lt;strong&gt;134 stars&lt;/strong&gt;! ⭐&lt;/p&gt;

&lt;p&gt;I contributed on GitHub every day from September 26 to December 17 making an 83-day streak. Hopefully, I can extend that this year! You can get this streak stats card for your profile at &lt;a href="http://git.io/streak-stats"&gt;git.io/streak-stats&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DenverCoder1/github-readme-streak-stats"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7pf2RWFa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github-readme-streak-stats.herokuapp.com/%3Fuser%3DDenverCoder1" alt="GitHub Streak" width="495" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  My top open source projects of 2020
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/DenverCoder1/LaTeX-Gboard-Dictionary"&gt;LaTeX Gboard Dictionary&lt;/a&gt; - 74 stars&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DenverCoder1/github-readme-streak-stats"&gt;GitHub Readme Streak Stats&lt;/a&gt; - 32 stars&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DenverCoder1/github-readme-youtube-stats"&gt;GitHub Readme YouTube Stats&lt;/a&gt; - 10 stars&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DenverCoder1/unicode-formatter"&gt;Unicode formatter&lt;/a&gt; - 4 stars&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Helping Computer Science Students
&lt;/h3&gt;

&lt;p&gt;As a Computer Science student finishing my degree, I had the chance to help other students who have been struggling with programming and math concepts.&lt;/p&gt;

&lt;p&gt;In 2020, I spent over 90 hours tutoring other students.&lt;/p&gt;

&lt;h3&gt;
  
  
  New Programming Skills
&lt;/h3&gt;

&lt;p&gt;I have learned many new things in 2020!&lt;/p&gt;

&lt;p&gt;Here are a few programming topics I learned and practiced in 2020:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Chrome Extensions&lt;/li&gt;
&lt;li&gt;Bootstrap and Material UI (I still prefer plain CSS though)&lt;/li&gt;
&lt;li&gt;C#&lt;/li&gt;
&lt;li&gt;Logical Programming (Prolog)&lt;/li&gt;
&lt;li&gt;Functional Programming&lt;/li&gt;
&lt;li&gt;Oracle Database Systems&lt;/li&gt;
&lt;li&gt;SQL, PL/SQL&lt;/li&gt;
&lt;li&gt;Building WordPress Plugins&lt;/li&gt;
&lt;li&gt;Interacting with WordPress Databases&lt;/li&gt;
&lt;li&gt;Introduction to Cybersecurity&lt;/li&gt;
&lt;li&gt;Software design patterns and UML&lt;/li&gt;
&lt;li&gt;OOP in Java&lt;/li&gt;
&lt;li&gt;Dynamic Programming and Memoization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know what you're interested in learning in 2021!&lt;/p&gt;




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

&lt;p&gt;2020 was a great year for me and I hope 2021 will allow me to continue to help others learn!&lt;/p&gt;

&lt;p&gt;Helping others is very rewarding and I'd recommend anyone who's considering it to give content creation a try.&lt;/p&gt;

&lt;p&gt;Making the first video or first post is the hardest, but it becomes easier from there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interested in what I'm teaching?
&lt;/h3&gt;

&lt;p&gt;You can find me on:&lt;/p&gt;

&lt;p&gt;YouTube 📺 &lt;a href="https://www.youtube.com/c/DevProTips"&gt;https://www.youtube.com/c/DevProTips&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Twitter 🐦 &lt;a href="https://twitter.com/DenverCoder1"&gt;https://twitter.com/DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

</description>
      <category>yearinreview</category>
      <category>productivity</category>
      <category>programming</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Getting the user's location with JavaScript</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Thu, 24 Dec 2020 17:07:54 +0000</pubDate>
      <link>https://forem.com/denvercoder1/getting-the-user-s-location-with-javascript-47m0</link>
      <guid>https://forem.com/denvercoder1/getting-the-user-s-location-with-javascript-47m0</guid>
      <description>&lt;p&gt;In this tutorial I will show you how to get the user's location with the JavaScript Geolocation API.&lt;/p&gt;

&lt;p&gt;You can use it to redirect them to a site in their language or on sites such as a News or &lt;a href="https://www.youtube.com/watch?v=WZNG8UomjSI"&gt;Weather App&lt;/a&gt; and use their location to adjust the home page to show content relevant for where they are.&lt;/p&gt;

&lt;p&gt;This article was originally a video tutorial, which you can check out here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/JdJ2VBbYYTQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking if the navigator API is available
&lt;/h2&gt;

&lt;p&gt;The geolocation functions are part of the &lt;code&gt;window&lt;/code&gt; object can be accessed with &lt;code&gt;window.navigator.geolocation&lt;/code&gt; or simply &lt;code&gt;navigator.geolocation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Some older browsers may not have support for the geolocation API, so you should use an if statement to check if it exists before using it:&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* use the API here */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting the user's coordinates
&lt;/h2&gt;

&lt;p&gt;If your browser supports the API, you can use its methods. The method to get the user's coordinates is &lt;code&gt;navigator.geolocation.getCurrentPosition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It requires as parameters, a success callback and optionally an error callback and options.&lt;/p&gt;

&lt;p&gt;To test it out, we can use &lt;code&gt;console.log&lt;/code&gt; as the the success callback function and &lt;code&gt;console.error&lt;/code&gt; as the error callback.&lt;/p&gt;

&lt;p&gt;One of these two functions will get called depending on whether the call is successful or not.&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getCurrentPosition&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="nx"&gt;log&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user will be prompted to allow the site to access their location the first time this is used.&lt;/p&gt;

&lt;p&gt;Once permission is granted, you should see something like this in the JavaScript console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c"&gt;/* GeolocationPosition */&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c"&gt;/* GeolocationCoordinates */&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"coords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"accuracy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"altitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"altitudeAccuracy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"heading"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"latitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;39.7501&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"longitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;-104.9957&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"speed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1608826371767&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will have a &lt;code&gt;GeolocationPosition&lt;/code&gt; object containing a &lt;code&gt;GeolocationCoordinates&lt;/code&gt; object labeled as &lt;code&gt;coords&lt;/code&gt; and a timestamp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Success function
&lt;/h2&gt;

&lt;p&gt;Instead of using &lt;code&gt;console.log&lt;/code&gt;, you can use a custom success callback to do exactly what you need to with the data.&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;function&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// extracting the latitude and longitude from the data&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your location: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getCurrentPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;success&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="nx"&gt;error&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;This will tell the &lt;code&gt;getCurrentPosition&lt;/code&gt; function to call &lt;code&gt;success&lt;/code&gt; when it successfully looks up the location and send it the Geolocation Position as the parameter.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;success&lt;/code&gt; function above will extract the latitude and longitude and make a popup telling it to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if you want to know their city or country?
&lt;/h2&gt;

&lt;p&gt;If you want to know where your user is located in a more meaningful way, you can look that up using a reverse geocoding API.&lt;/p&gt;

&lt;p&gt;There are many APIs available to do this. For this tutorial, I used the OpenCage API.&lt;/p&gt;

&lt;p&gt;Create a free account at &lt;a href="https://opencagedata.com/api"&gt;opencagedata.com&lt;/a&gt; and get an API key to use with your application.&lt;/p&gt;

&lt;p&gt;You can find a code snippet for reverse geocoding with OpenCage in their &lt;a href="https://opencagedata.com/tutorials/geocode-in-javascript"&gt;JavaScript documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can simplify it using modern JavaScript techniques:&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;apikey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your API key goes here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;51.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;7.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.opencagedata.com/geocode/v1/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;apikey&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;q=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;pretty=1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;no_annotations=1&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="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&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;span class="nx"&gt;formatted&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming you have a valid API key from OpenCage, the snippet above should make an alert that says "Grüner Kuhweg, 51061 Cologne, Germany". That is the location for the coordinates 51.0, 7.0.&lt;/p&gt;

&lt;p&gt;If you log &lt;code&gt;data.results[0]&lt;/code&gt; in the console, you will see there are a few fields in addition to just the formatted address that you can access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bounds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"northeast"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;51.0008597&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lng"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.0042934&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"southwest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;50.9973232&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lng"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.999946&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"components"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ISO_3166-1_alpha-2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ISO_3166-1_alpha-3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DEU"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"road"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"road"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cologne"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"city_district"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mülheim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"continent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Europe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Germany"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"de"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"political_union"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"European Union"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"51061"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"road"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Grüner Kuhweg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"road_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"North Rhine-Westphalia"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"state_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"suburb"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Flittard"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"formatted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Grüner Kuhweg, 51061 Cologne, Germany"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"geometry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;50.999559&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lng"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.0002524&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Accessing specific components
&lt;/h2&gt;

&lt;p&gt;You can access any component of the returned JSON object.&lt;/p&gt;

&lt;p&gt;To access the user's city, we can say &lt;code&gt;data.results[0].components.city&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To get their country, we can say &lt;code&gt;data.results[0].components.country&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse geocoding the user's location
&lt;/h2&gt;

&lt;p&gt;Now that we can access the user's coordinates and reverse geocode coordinates, we can put it all together:&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;function&lt;/span&gt; &lt;span class="nx"&gt;reverseGeocode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;apikey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your API key goes here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.opencagedata.com/geocode/v1/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;apikey&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;q=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;pretty=1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;no_annotations=1&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="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&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;span class="nx"&gt;formatted&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// extracting the latitude and longitude from the data&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// reverse geocode&lt;/span&gt;
    &lt;span class="nx"&gt;reverseGeocode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getCurrentPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;success&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="nx"&gt;error&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;The alert function at the end of the &lt;code&gt;reverseGeocode&lt;/code&gt; call can be replaced with any function you need to use the data for.&lt;/p&gt;

&lt;p&gt;In my video, &lt;a href="https://youtu.be/JdJ2VBbYYTQ"&gt;Getting the user's location with JavaScript&lt;/a&gt;, I show how this can be used in a weather app to display weather for the user's current location.&lt;/p&gt;

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

&lt;p&gt;I hope you found this tutorial useful.&lt;/p&gt;

&lt;p&gt;Check out the video for further explanations and be sure to like and subscribe!&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;Twitter: &lt;a href="https://twitter.com/DenverCoder1"&gt;@DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YouTube: &lt;a href="https://youtube.com/c/DevProTips"&gt;Jonah Lawrence - Dev Pro Tips&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>C++ Pointers and Dynamic Memory Allocation</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Wed, 23 Dec 2020 14:33:43 +0000</pubDate>
      <link>https://forem.com/denvercoder1/c-pointers-and-dynamic-memory-allocation-1emi</link>
      <guid>https://forem.com/denvercoder1/c-pointers-and-dynamic-memory-allocation-1emi</guid>
      <description>&lt;p&gt;In C and C++, pointers allow you direct control of the way you access memory. This becomes very useful when learning to use build complex data structures or trying to save space when allocating memory.&lt;/p&gt;

&lt;p&gt;One of the most basic ways pointers help is when you want to dynamically set the size of an array based on an external input not known beforehand to the compiler or you may want to change the size of the array in runtime. In C++, arrays must have a constant size which can't be changed, but with pointers, you can allocate just the space you need, allowing you to improve your program's space efficiency and make the shape of your data as flexible as the user needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  A pointer storing an address
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&amp;amp;x&lt;/code&gt; (referencing operator) = “address of”&lt;br&gt;
&lt;code&gt;int* p&lt;/code&gt; (pointer declaration) = “p is a pointer to an integer”&lt;br&gt;
&lt;code&gt;int** p&lt;/code&gt; (pointer declaration) = “p is a pointer to a pointer to an integer”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;+-----&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="o"&gt;-------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&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;span class="c1"&gt;// x is an integer with the value 6                    |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// a is a pointer that points to the address of x    |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// b is a pointer that points to the address of a   |&lt;/span&gt;
&lt;span class="o"&gt;+-------------------------------------------------------------------+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dereferencing pointers
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;*p&lt;/code&gt; (dereferencing operator) = “content at the address stored in p”&lt;br&gt;
&lt;code&gt;**p&lt;/code&gt; = “content at the address stored in the address stored in p”&lt;/p&gt;

&lt;p&gt;In the example above, &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;x&lt;/code&gt; can be used interchangeably. Modifying &lt;code&gt;*a&lt;/code&gt; (ex. &lt;code&gt;(*a)++&lt;/code&gt;) will also modify &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  A pointer storing an array
&lt;/h2&gt;

&lt;p&gt;Before you assign a value to an address in memory, you need to be sure that the memory is unused.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;new&lt;/code&gt; operator will allocate a given size in memory to store consecutive values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;+-----&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="o"&gt;---------------------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&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="c1"&gt;// numbers points to memory where 3 integers can be stored |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the first value in the memory numbers points to is now set to 5      |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;numbers&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;// using array notation, the value after the first value is now a 3    |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="c1"&gt;// using pointer notation, the value at index 2 is now a 7         |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;// The current array, 'numbers' is now storing the integers, {5, 3, 7}                |&lt;/span&gt;
&lt;span class="o"&gt;+---------------------------------------------------------------------------------------+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a two-dimensional array, the values the pointer points to are pointers pointing to arrays&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;+-----&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="o"&gt;-----------------------------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numOfRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                                                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;numArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;numOfRows&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//numArr points to memory where 4 addresses can be stored |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;numArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&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="c1"&gt;// the first row of numArr points to memory where 3 ints can be stored |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;*&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="n"&gt;numArr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&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;span class="c1"&gt;// The value at coordinates 1,2 (numArr[1][2]) is now a 3           |&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------------------------------------------------------+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Dynamic Memory Allocation
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;delete[]&lt;/code&gt; operator deallocates memory so that it can be used later.&lt;br&gt;
To deallocate the two dimensional array, &lt;code&gt;numArr&lt;/code&gt;, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&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="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;numArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// frees up the row at i of numArr&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numOfRows&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;numArr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// frees up the address numArr itself&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you change the size of the data an array points to, you need to &lt;code&gt;delete[]&lt;/code&gt; each row and the original address of the array.&lt;/p&gt;

&lt;p&gt;Then, use the new operator to allocate the amount of data you will need.&lt;/p&gt;

&lt;p&gt;If you need to keep the contents of the old array, you will need to create a temporary array to back up the values.&lt;/p&gt;

&lt;p&gt;After you change the size with the new operator, copy the values back into the array from the temporary array.&lt;/p&gt;

&lt;p&gt;You will need to do this for both shrinking and expanding an array.&lt;/p&gt;

&lt;p&gt;The example program at the end includes a pointer array which changes size using dynamic memory allocation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualization
&lt;/h3&gt;

&lt;p&gt;Below are two ways to visualize arrays and access their contents.&lt;/p&gt;

&lt;h4&gt;
  
  
  Array as a grid with subscript notation (left) and pointer dereferencing notation (right)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    +-----------+-----------+-----------+           +---------------+---------------+---------------+
    | arr[0][0] | arr[0][1] | arr[0][2] |           | *(*(arr+0)+0) | *(*(arr+0)+1) | *(*(arr+0)+2) |
    +-----------+-----------+-----------+           +---------------+---------------+---------------+
    | arr[1][0] | arr[1][1] | arr[2][2] |           | *(*(arr+1)+0) | *(*(arr+1)+1) | *(*(arr+1)+2) |
    +-----------+-----------+-----------+           +---------------+---------------+---------------+
    | arr[2][0] | arr[2][1] | arr[2][2] |           | *(*(arr+2)+0) | *(*(arr+2)+1) | *(*(arr+2)+2) |
    +-----------+-----------+-----------+           +---------------+---------------+---------------+
    | arr[3][0] | arr[3][1] | arr[3][2] |           | *(*(arr+3)+0) | *(*(arr+3)+1) | *(*(arr+3)+2) |
    +-----------+-----------+-----------+           +---------------+---------------+---------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Pointer map with subscript notation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     +--------+      +-----------+-----------+-----------+
               +---&amp;gt; | arr[0] |----&amp;gt; | arr[0][0] | arr[0][1] | arr[0][2] |
    +-----+    |     +--------+      +----- -----+-----------+-----------+     +-----------+-----------+-----------+
    | arr |----+     | arr[1] |----------------------------------------------&amp;gt; | arr[1][0] | arr[1][1] | arr[1][2] |
    +-----+          +--------+      +-----------+-----------+-----------+     +-----------+-----------+-----------+
                     | arr[2] |----&amp;gt; | arr[2][0] | arr[2][1] | arr[2][2] |
                     +--------+      +----- -----+-----------+-----------+     +-----------+-----------+-----------+
                     | arr[3] |----------------------------------------------&amp;gt; | arr[3][0] | arr[3][1] | arr[3][2] |
                     +--------+                                                +-----------+-----------+-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Pointer map with pointer dereferencing notation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     +--------+      +---------------+---------------+---------------+
               +---&amp;gt; |*(arr+0)|----&amp;gt; | *(*(arr+0)+0) | *(*(arr+0)+1) | *(*(arr+0)+2) |
    +-----+    |     +--------+      +---------------+---------------+---------------+     +---------------+---------------+---------------+
    | arr |----+     |*(arr+1)|----------------------------------------------------------&amp;gt; | *(*(arr+1)+0) | *(*(arr+1)+1) | *(*(arr+1)+2) |
    +-----+          +--------+      +---------------+---------------+---------------+     +---------------+---------------+---------------+
                     |*(arr+2)|----&amp;gt; | *(*(arr+2)+0) | *(*(arr+2)+1) | *(*(arr+2)+2) |
                     +--------+      +---------------+---------------+---------------+     +---------------+---------------+---------------+
                     |*(arr+3)|----------------------------------------------------------&amp;gt; | *(*(arr+3)+0) | *(*(arr+3)+1) | *(*(arr+3)+2) |
                     +--------+                                                            +---------------+---------------+---------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;h4&gt;
  
  
  In this program:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The user is asked for a number of rows and a value to start filling the cells with&lt;/li&gt;
&lt;li&gt;A pointer array changes size to hold the given number of rows&lt;/li&gt;
&lt;li&gt;The number of columns will be 12 throughout the program&lt;/li&gt;
&lt;li&gt;New rows are filled using the fill value provided (incrementing by 1 for each new row)&lt;/li&gt;
&lt;li&gt;The new array is printed
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;changeSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fillValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;numDigits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// declare a pointer that will point to an&lt;/span&gt;
    &lt;span class="c1"&gt;// array of pointers to integers (see diagrams above)&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fillValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"How many rows? "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// if newSize is less than current size, no rows added, so no need for fill value&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newSize&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Enter the fill value: "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fillValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fillValue&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Please enter a positive number."&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&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="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fillValue&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Loop will continue until a negative number is chosen&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newSize&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// change amount of memory 'arr' points to&lt;/span&gt;
            &lt;span class="c1"&gt;// (new amount of memory will be enough to store 'newSize' number of pointers)&lt;/span&gt;
            &lt;span class="n"&gt;changeSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fillValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// print the new array&lt;/span&gt;
            &lt;span class="n"&gt;printArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// exit the loop&lt;/span&gt;
            &lt;span class="k"&gt;break&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;// free up remaining memory which is in current array&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentNumOfRows&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// changes amount of memory arr points to&lt;/span&gt;
&lt;span class="c1"&gt;// and fills new cells starting with fillValue&lt;/span&gt;
&lt;span class="c1"&gt;// incrementing by 1 for each row&lt;/span&gt;
&lt;span class="c1"&gt;// parameters:&lt;/span&gt;
&lt;span class="c1"&gt;// arr is a pointer to pointers to integers. &lt;/span&gt;
&lt;span class="c1"&gt;// It is passed as a reference so that you can change&lt;/span&gt;
&lt;span class="c1"&gt;// the location it points to from within this function.&lt;/span&gt;
&lt;span class="c1"&gt;// currentNumOfRows is the number of rows the array has&lt;/span&gt;
&lt;span class="c1"&gt;// at the time the function is called. It will also&lt;/span&gt;
&lt;span class="c1"&gt;// change within the function.&lt;/span&gt;
&lt;span class="c1"&gt;// newSize is the new number of rows the array will point to.&lt;/span&gt;
&lt;span class="c1"&gt;// fillValue is the number to starting filling new rows with&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;changeSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fillValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// when the new operator is used, the pointer will point&lt;/span&gt;
    &lt;span class="c1"&gt;// to a new location in memory with the required size&lt;/span&gt;
    &lt;span class="c1"&gt;// therefore, if we want to keep the data, we will need&lt;/span&gt;
    &lt;span class="c1"&gt;// to back it up in a temporary array&lt;/span&gt;

    &lt;span class="cm"&gt;/* CREATE A TEMPORARY ARRAY TO STORE ARRAY'S DATA */&lt;/span&gt;

    &lt;span class="c1"&gt;// create a pointer that points to the size of the array (before we change it)&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;temporaryArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// for each row in original array (that we will backup and delete):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&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="c1"&gt;// in this example, each row in arr contains exactly 12 values&lt;/span&gt;
        &lt;span class="c1"&gt;// create a pointer to an array of 12 integers at temporaryArr[i]&lt;/span&gt;
        &lt;span class="c1"&gt;// which can be written as: *(temporaryArr + i) -- &lt;/span&gt;
        &lt;span class="c1"&gt;// i.e. content of the address, 'i' values after the address of temporaryArr&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temporaryArr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="c1"&gt;// for each of the 12 values in row i:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&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="c1"&gt;// copy data from arr into temporary array&lt;/span&gt;
            &lt;span class="o"&gt;*&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="n"&gt;temporaryArr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// original array location is no longer being used,&lt;/span&gt;
        &lt;span class="c1"&gt;// so free up the memory for current row&lt;/span&gt;
        &lt;span class="k"&gt;delete&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// free up the original address of arr&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* CHANGE THE SIZE OF ARRAY BY POINTING IT TO A LARGER AMOUNT OF MEMORY */&lt;/span&gt;
    &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="cm"&gt;/* PUT THE DATA THAT WAS REMOVED BACK INTO ARRAY */&lt;/span&gt;

    &lt;span class="c1"&gt;// for each row in temporaryArr (that we will move back into arr and delete):&lt;/span&gt;
    &lt;span class="c1"&gt;// if i becomes greater than or equal to old size (if size is increasing)&lt;/span&gt;
    &lt;span class="c1"&gt;// or new size (if size is decreasing) stop loop&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&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="c1"&gt;// create a pointer to 12 integers at *(arr + i)&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="c1"&gt;// for each of the 12 values in row i:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&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="c1"&gt;// copy data from temporaryArr back into arr&lt;/span&gt;
            &lt;span class="o"&gt;*&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&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="n"&gt;temporaryArr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// temporaryArr row is no longer being used, so free up the memory for current row&lt;/span&gt;
        &lt;span class="k"&gt;delete&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="n"&gt;temporaryArr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// free up the original address of temporaryArr&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;temporaryArr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* FILL IN SOME VALUES INTO EMPTY SPOTS */&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numOfAddedRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// original size - new size&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&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="c1"&gt;// for each new row starting at first new row&lt;/span&gt;
        &lt;span class="c1"&gt;// create a pointer to 12 integers at *(arr + i):&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="c1"&gt;// now that memory is allocated, we can set the values:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&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="c1"&gt;// for each column in row&lt;/span&gt;
            &lt;span class="c1"&gt;// set *(*(arr + i) + j),&lt;/span&gt;
            &lt;span class="c1"&gt;// i.e. arr[i][j],&lt;/span&gt;
            &lt;span class="c1"&gt;// i.e. content of j values past address stored in content of i values past address of arr&lt;/span&gt;
            &lt;span class="o"&gt;*&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fillValue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&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="cm"&gt;/* CHANGE currentNumOfRows TO NEW SIZE */&lt;/span&gt;
    &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// prints out the array's values&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;printArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// to line up numbers in columns:&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;highestNum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;32767&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&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="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;highestNum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;highestNum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxNumOfSpaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numDigits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;highestNum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// get number of digits in largest number in column&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;currentNumOfRows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&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="c1"&gt;// for each row in the array&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&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="c1"&gt;// prints the 12 pieces of data in arr[i]&lt;/span&gt;
            &lt;span class="c1"&gt;// num of spaces needed to line up text = maxNumOfSpaces - digits in currentWord&lt;/span&gt;
            &lt;span class="c1"&gt;// print spaces that many times:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;maxNumOfSpaces&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;numDigits&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="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="n"&gt;k&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="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sc"&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;// print value&lt;/span&gt;
            &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;*&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&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;// get number of digits in an integer&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numDigits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10000000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100000000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000000000&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="mi"&gt;10&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;h4&gt;
  
  
  Sample run of the program
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many rows? 5
Enter the fill value: 7
 7  7  7  7  7  7  7  7  7  7  7  7
 8  8  8  8  8  8  8  8  8  8  8  8
 9  9  9  9  9  9  9  9  9  9  9  9
10 10 10 10 10 10 10 10 10 10 10 10
11 11 11 11 11 11 11 11 11 11 11 11
How many rows? 3
7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9 9 9
How many rows? 10
Enter the fill value: 50
 7  7  7  7  7  7  7  7  7  7  7  7
 8  8  8  8  8  8  8  8  8  8  8  8
 9  9  9  9  9  9  9  9  9  9  9  9
50 50 50 50 50 50 50 50 50 50 50 50
51 51 51 51 51 51 51 51 51 51 51 51
52 52 52 52 52 52 52 52 52 52 52 52
53 53 53 53 53 53 53 53 53 53 53 53
54 54 54 54 54 54 54 54 54 54 54 54
55 55 55 55 55 55 55 55 55 55 55 55
56 56 56 56 56 56 56 56 56 56 56 56
How many rows? 15
Enter the fill value: 2
 7  7  7  7  7  7  7  7  7  7  7  7
 8  8  8  8  8  8  8  8  8  8  8  8
 9  9  9  9  9  9  9  9  9  9  9  9
50 50 50 50 50 50 50 50 50 50 50 50
51 51 51 51 51 51 51 51 51 51 51 51
52 52 52 52 52 52 52 52 52 52 52 52
53 53 53 53 53 53 53 53 53 53 53 53
54 54 54 54 54 54 54 54 54 54 54 54
55 55 55 55 55 55 55 55 55 55 55 55
56 56 56 56 56 56 56 56 56 56 56 56
 2  2  2  2  2  2  2  2  2  2  2  2
 3  3  3  3  3  3  3  3  3  3  3  3
 4  4  4  4  4  4  4  4  4  4  4  4
 5  5  5  5  5  5  5  5  5  5  5  5
 6  6  6  6  6  6  6  6  6  6  6  6
How many rows? 3
7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9 9 9
How many rows? 6
Enter the fill value: -1
Please enter a positive number.
Enter the fill value: 0
7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9 9 9
0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2
How many rows? 0
How many rows? -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you find this helpful, let me know if you find any questions or corrections.&lt;/p&gt;

&lt;p&gt;- Jonah Lawrence&lt;/p&gt;

&lt;p&gt;Twitter: &lt;a href="https://twitter.com/DenverCoder1"&gt;@DenverCoder1&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Making a Responsive (Birthday) Card with HTML and CSS</title>
      <dc:creator>Jonah Lawrence</dc:creator>
      <pubDate>Sun, 06 Dec 2020 13:04:40 +0000</pubDate>
      <link>https://forem.com/denvercoder1/making-a-responsive-birthday-card-with-html-and-css-482j</link>
      <guid>https://forem.com/denvercoder1/making-a-responsive-birthday-card-with-html-and-css-482j</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to make a responsive card using just HTML and CSS.&lt;/p&gt;

&lt;p&gt;A responsive card is one that looks good on every size screen. We can accomplish this by using &lt;code&gt;flexbox&lt;/code&gt;, relative heights and widths instead of absolute measurements, and also &lt;code&gt;@media&lt;/code&gt; rules to define CSS properties to take effect only on specific screen sizes.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/BVX7kZ4GM-g"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  The HTML
&lt;/h3&gt;

&lt;p&gt;Here we have a simple card. Inside, we have an image and some text.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./birthday.svg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"birthday"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"birthday"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Happy Birthday!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;I hope you have a wonderful birthday&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;- Jonah Lawrence&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Relative Sizes and Flexbox
&lt;/h3&gt;

&lt;p&gt;Here I have set the height to &lt;code&gt;85vh&lt;/code&gt; (85% of the viewport height) and the width to &lt;code&gt;80vw&lt;/code&gt; (80% of the viewport width). Using relative measurements like this instead of absolute measurements (ex. 800px) allows you to have elements that stretch and shrink depending on how large the screen is.&lt;/p&gt;

&lt;p&gt;Using flexbox, we can spread the elements in the card across the height or width. We can also use this to center them vertically and horizontally. I recommend checking out &lt;a href="https://flexboxfroggy.com/" rel="noopener noreferrer"&gt;Flexbox Froggy&lt;/a&gt; by Codepip for an interactive way to understand how flexboxes work.&lt;/p&gt;

&lt;p&gt;By default, the flex direction is &lt;code&gt;row&lt;/code&gt; (left to right), but you can overwrite this by using &lt;code&gt;flex-direction: column&lt;/code&gt; (top to bottom). Now our image appears on top and the text appears on the bottom.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;85vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607258435517%2FQLBRW-O0K.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607258435517%2FQLBRW-O0K.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;@media&lt;/code&gt; Rules
&lt;/h3&gt;

&lt;p&gt;When the screen is at least 1000px wide, we don't need to keep the image on top anymore, we can put it side by side with the text.&lt;/p&gt;

&lt;p&gt;Using a &lt;code&gt;@media&lt;/code&gt; rule like the one below, when the screen is a minimum width of 1000px, the &lt;code&gt;flex-direction: row-reverse&lt;/code&gt; will be applied to &lt;code&gt;.card&lt;/code&gt; causing the flexbox to place items right to left (the image on the right and the text on the left.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row-reverse&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607258457890%2FGTcwCFPZN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607258457890%2FGTcwCFPZN.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On very short devices such as phones in landscape, we may want to use this landscape layout as well, so we can use the following rule using &lt;code&gt;max-height&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The CSS properties inside this rule will only take effect on screens with a maximum height of 640px.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;640px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row-reverse&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607258722812%2F-LHpRCOAo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607258722812%2F-LHpRCOAo.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;Try running the demo in &lt;a href="https://codepen.io/eyl327/full/yLaOjqV" rel="noopener noreferrer"&gt;&lt;strong&gt;full page view&lt;/strong&gt;&lt;/a&gt; to see the effects.&lt;/p&gt;

&lt;p&gt;Resize the viewport to switch from portrait view to landscape view.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/eyl327/embed/yLaOjqV?height=600&amp;amp;default-tab=css&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch the full tutorial
&lt;/h3&gt;

&lt;p&gt;In &lt;a href="https://youtu.be/BVX7kZ4GM-g" rel="noopener noreferrer"&gt;this video&lt;/a&gt;, I walk through the full process of creating this demo from scratch.&lt;/p&gt;

&lt;p&gt;For a full understanding of how I designed this responsive birthday card, be sure to check it out!&lt;/p&gt;

&lt;h3&gt;
  
  
  About me
&lt;/h3&gt;

&lt;p&gt;My name is Jonah Lawrence and I am a full stack developer.&lt;/p&gt;

&lt;p&gt;You can find me on:&lt;/p&gt;

&lt;p&gt;YouTube 📺 &lt;a href="https://www.youtube.com/DevProTips" rel="noopener noreferrer"&gt;https://www.youtube.com/DevProTips&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Twitter ✍ &lt;a href="https://twitter.com/DenverCoder1" rel="noopener noreferrer"&gt;https://twitter.com/DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github 👨‍💻 &lt;a href="https://github.com/DenverCoder1" rel="noopener noreferrer"&gt;https://github.com/DenverCoder1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like my content, be sure to react, like, and subscribe to my channel!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>html</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
