<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Effy L.H.</title>
    <description>The latest articles on DEV Community by Effy L.H. (@effylh).</description>
    <link>https://dev.to/effylh</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%2F361032%2Fc8dd078a-fff8-43dd-9016-5653b7818ebc.jpeg</url>
      <title>DEV Community: Effy L.H.</title>
      <link>https://dev.to/effylh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/effylh"/>
    <language>en</language>
    <item>
      <title>'Queendom2Data' -A data visualization web app built by React+Flask</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Mon, 09 May 2022 14:52:38 +0000</pubDate>
      <link>https://dev.to/effylh/queendom2data-a-data-visualization-app-bulilt-by-reactflask-4300</link>
      <guid>https://dev.to/effylh/queendom2data-a-data-visualization-app-bulilt-by-reactflask-4300</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Queendom2data is a data visualization app displays the YouTube views count of the ongoing K-pop reality survival show &lt;strong&gt;‘Queendom2’&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Link:&lt;/strong&gt; &lt;a href="http://www.qd2data.xyz"&gt;www.qd2data.xyz&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/monkeyapple/queendom2data"&gt;https://github.com/monkeyapple/queendom2data&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Techstack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Programming Languages:  Python, Javascript,SQL,CSS,HTML&lt;/li&gt;
&lt;li&gt;Frameworks:  React(Front-end),Flask(Back-end),Bootstrap(CSS)&lt;/li&gt;
&lt;li&gt;Database:  PostgreSQL&lt;/li&gt;
&lt;li&gt;Automation:  HerokuScheduler&lt;/li&gt;
&lt;li&gt;Data API:  YouTube Data API&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  WorkFlow
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Preview
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Current Version
&lt;/h2&gt;

&lt;p&gt;v1.0.0&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical details about this project
&lt;/h2&gt;

&lt;p&gt;I also wrote two articles for this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@effylh/create-a-data-visualization-web-page-with-react-flask-postgresql-bootstrap-4ec4f080309e"&gt;Create a data visualization app for the K-pop TV show ‘Queendom2’ with React+Flask+PostgreSQL+Bootstrap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@effylh/create-a-data-scraper-for-the-ongoing-k-pop-tv-program-queendom2-with-python-youtube-data-d74103a3d074"&gt;Create a data scraper with Python+YouTube Data API+PostgreSQL+HerokuScheduler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>python</category>
    </item>
    <item>
      <title>New Features Updated: Udemy Syllabus Scraper v1.0.2</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Wed, 06 Apr 2022 08:50:29 +0000</pubDate>
      <link>https://dev.to/effylh/new-features-updated-udemy-syllabus-scraper-v102-3a6a</link>
      <guid>https://dev.to/effylh/new-features-updated-udemy-syllabus-scraper-v102-3a6a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Syllabus-Scraper is a web application for generating the Markdown syllabus of Udemy courses by using Flask, jQuery, UdemyAPI, and PostgreSQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App link&lt;/strong&gt;: &lt;a href="http://www.syllabuscraper.com"&gt;www.syllabuscraper.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dyjo19w2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8frjral14lhqym3wzozb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dyjo19w2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8frjral14lhqym3wzozb.gif" alt="preview" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Version
&lt;/h2&gt;

&lt;p&gt;v1.0.2&lt;/p&gt;

&lt;h2&gt;
  
  
  New Features
&lt;/h2&gt;

&lt;p&gt;A data table added at the bottom of the page, which is a convenient way for users to check the 10 most recent searched courses by other users. Users can choose interested courses and copy the MarkDown syllabus directly inside the table.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Technical details
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/monkeyapple/Syllabus-Scraper"&gt;https://github.com/monkeyapple/Syllabus-Scraper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I also wrote a article with all the details about this Web App, please check:
&lt;a href="https://medium.com/@effylh/building-an-online-course-syllabus-scraper-with-flask-udemyapi-postgresql-on-heroku-262b727e228b"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Display recent queries on Web Page from PostgreSql database with Flask+psycopg2+Bootstrap</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Wed, 06 Apr 2022 08:25:12 +0000</pubDate>
      <link>https://dev.to/effylh/display-recent-queries-on-web-page-from-postgresql-database-with-flaskpsycopg2bootstrap-3of4</link>
      <guid>https://dev.to/effylh/display-recent-queries-on-web-page-from-postgresql-database-with-flaskpsycopg2bootstrap-3of4</guid>
      <description>&lt;p&gt;This is a simple tutorial for people who is just stepping into Flask framework and trying to display database queries on the screen. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub repo for this tutorial:&lt;/strong&gt;&lt;a href="https://medium.com/pythonistas/display-recent-queries-on-web-page-from-postgresql-database-with-flask-psycopg2-bootstrap-467ced8583c5" rel="noopener noreferrer"&gt;Display recent queries on Web Page from PostgreSql database with Flask+psycopg2+Bootstrap&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample dataset
&lt;/h2&gt;

&lt;p&gt;Here we have a sample database contains a table called ‘game’ which stores 18 games and their last visit records.&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%2Fcdn-images-1.medium.com%2Fmax%2F2240%2F1%2Ahqh6rGhLOHvUPwKyZOFI-w.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-images-1.medium.com%2Fmax%2F2240%2F1%2Ahqh6rGhLOHvUPwKyZOFI-w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;Our goal is to display the 5 most recent queries on the screen&lt;/p&gt;

&lt;h3&gt;
  
  
  Preview of the result
&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%2Fcdn-images-1.medium.com%2Fmax%2F4112%2F1%2A7mn0cMd1sc0NTstiJ5ScRg.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-images-1.medium.com%2Fmax%2F4112%2F1%2A7mn0cMd1sc0NTstiJ5ScRg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create an HTML file called &lt;strong&gt;index.html&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Display recent database queries&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a file called &lt;strong&gt;run.py&lt;/strong&gt;, then define a route to render the &lt;strong&gt;index.html&lt;/strong&gt; file we just created
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;render_template&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;############################################
&lt;/span&gt;        &lt;span class="c1"&gt;# Routes
##########################################
&lt;/span&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Run in the command line and the result is shown as below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 run.py&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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-images-1.medium.com%2Fmax%2F3212%2F1%2AGOyxqGPJuBQycXFBmEJrkw.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-images-1.medium.com%2Fmax%2F3212%2F1%2AGOyxqGPJuBQycXFBmEJrkw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s get started!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Back-End
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a file called **database.ini **in order to safely store database configurations:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[postgresql]
host=localhost
database=games
user=postgres
password=123456
port=5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a file called &lt;strong&gt;config.py&lt;/strong&gt; in order to safely call the configurations defined inside the &lt;strong&gt;database.ini&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/Users/Project/DisplayQueries_With_Flask_jQuery_Bootstrap_PostgreSQL/database.ini&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;postgresql&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ConfigParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;db&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="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_section&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;param&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;param&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="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Section {0} not found in the {1} file&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Let’s update  the &lt;strong&gt;run.py&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Import needed modules: &lt;strong&gt;config&lt;/strong&gt;(we just created in step 1) , &lt;strong&gt;psycopg2&lt;/strong&gt; (psycopg2 is a popular PostgreSQL database adapter )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect with our local database by using the &lt;strong&gt;config&lt;/strong&gt; module we defined before, then execute a SQL statement to extract the 5 most recent rows from the database(&lt;strong&gt;sort the records according to the ‘last_visit’ column in descending order&lt;/strong&gt;)&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;render_template&lt;/span&gt;
&lt;span class="c1"&gt;#1.
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;###########################################
&lt;/span&gt;        &lt;span class="c1"&gt;#Route
#########################################
&lt;/span&gt;
&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;rowResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="c1"&gt;#2.
&lt;/span&gt;    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;order_statement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM game ORDER BY last_visit DESC LIMIT 5;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;rowResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rowResults&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;except&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
            &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database connection is now closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check the results we got&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 5 records we need are as below:&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%2Fcdn-images-1.medium.com%2Fmax%2F2156%2F1%2AAggtqr1HuUg2DJ46B_l6BQ.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-images-1.medium.com%2Fmax%2F2156%2F1%2AAggtqr1HuUg2DJ46B_l6BQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 5 records we actually got:&lt;/p&gt;

&lt;p&gt;(Which means our SQL operations successfully executed!)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Outputs:
[
(4, 'The Legend of Zelda: Breath of the Wild', datetime.datetime(2021, 4, 14, 22, 6, 12)), 
(3, 'Horizon Forbidden West', datetime.datetime(2021, 4, 5, 2, 43, 2)), 
(8, 'The Elder Scrolls V: Skyrim', datetime.datetime(2021, 3, 27, 21, 31, 4)), 
(5, 'The Witcher 3: Wild Hunt', datetime.datetime(2021, 3, 25, 6, 8, 23)), 
(16, 'Final Fantasy', datetime.datetime(2021, 3, 21, 17, 52, 47))
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Since now, we’ve finished all the back-end scripts, let’s move on to the front-end and display the results on the web page:&lt;/p&gt;

&lt;h3&gt;
  
  
  Front-End
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add a line at the end of the &lt;strong&gt;index()&lt;/strong&gt; function in the &lt;strong&gt;run.py&lt;/strong&gt;, the &lt;strong&gt;render_template&lt;/strong&gt; method will help us to render the defined &lt;strong&gt;index.html&lt;/strong&gt; on the web page, meanwhile, we pass in a variable called &lt;strong&gt;“recentRecords”&lt;/strong&gt; and assign the &lt;strong&gt;‘rowResults’&lt;/strong&gt; (query results we retreived from the databse) onto it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;render_template&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;###########################################
&lt;/span&gt;        &lt;span class="c1"&gt;#Route
#########################################
&lt;/span&gt;
&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;rowResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;order_statement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM game ORDER BY last_visit DESC LIMIT 5;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_statement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;rowResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;except&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
            &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database connection is now closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;recentRecords&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rowResults&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Render query results &lt;strong&gt;“recentRecords”&lt;/strong&gt; by using Jinja’s &lt;strong&gt;for loops&lt;/strong&gt; syntax&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Control flow: if the &lt;strong&gt;“recentRecords”&lt;/strong&gt; is equals to an empty array &lt;strong&gt;[]&lt;/strong&gt;, displaying a text “Not enough data” on the screen. Otherwise, displaying a bootstrap table with values we got from the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;About the style of table, I just simply copy&amp;amp;paste the bootstrap default CSS classes: &lt;strong&gt;“table-hover table-dark table-striped”&lt;/strong&gt;, or you can reference the official document to choose the style you like: &lt;a href="https://getbootstrap.com/docs/5.1/content/tables/" rel="noopener noreferrer"&gt;https://getbootstrap.com/docs/5.1/content/tables/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;DOCTYPE&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;CSS&lt;/span&gt; &lt;span class="n"&gt;stylesheet&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stylesheet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;integrity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;crossorigin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anonymous&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;table table-hover table-dark table-striped&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;cellspacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;thead&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;#&amp;lt;/th&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-align:left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Game&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;col&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Visit&lt;/span&gt; &lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;thead&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tbody&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;recentRecords&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;Not&lt;/span&gt; &lt;span class="n"&gt;enough&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;row&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="n"&gt;i&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;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="n"&gt;recentRecords&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="n"&gt;recentRecords&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endfor&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endif&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;tbody&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Local Test
&lt;/h2&gt;

&lt;p&gt;Let’s run the script and access the address  &lt;a href="http://127.0.0.1:5000" rel="noopener noreferrer"&gt;http://127.0.0.1:5000&lt;/a&gt; on your browser:&lt;br&gt;
&lt;code&gt;python3 run.py&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It works!🥳
&lt;/h2&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-images-1.medium.com%2Fmax%2F4112%2F1%2A7mn0cMd1sc0NTstiJ5ScRg.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-images-1.medium.com%2Fmax%2F4112%2F1%2A7mn0cMd1sc0NTstiJ5ScRg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Project Example
&lt;/h2&gt;

&lt;p&gt;Another motivation I wrote this tutorial is: I just extended my launched Web App with the same functionality mentioned in this tutorial, which you can check it at:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App link&lt;/strong&gt;: &lt;a href="http://www.syllabuscraper.com/" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;And I wrote an article about the Web App:&lt;/strong&gt; &lt;a href="https://medium.com/@effylh/building-an-online-course-syllabus-scraper-with-flask-udemyapi-postgresql-on-heroku-262b727e228b?source=your_stories_page----------------------------------------" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's all for this tutorial. Thanks!&lt;/strong&gt;&lt;br&gt;
If you have any questions, feel free to comment.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>python</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Udemy Syllabus Scraper Released</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Sun, 02 Jan 2022 08:29:58 +0000</pubDate>
      <link>https://dev.to/effylh/udemy-syllabus-scraper-released-5f4d</link>
      <guid>https://dev.to/effylh/udemy-syllabus-scraper-released-5f4d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Syllabus-Scraper is a web application for generating the Markdown syllabus of Udemy courses by using Flask, jQuery, UdemyAPI, and PostgreSQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App link&lt;/strong&gt;: &lt;a href="http://www.syllabuscraper.com" rel="noopener noreferrer"&gt;www.syllabuscraper.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;GitHub repo&lt;/strong&gt;:&lt;a href="https://github.com/monkeyapple/Syllabus-Scraper" rel="noopener noreferrer"&gt;https://github.com/monkeyapple/Syllabus-Scraper&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Version
&lt;/h2&gt;

&lt;p&gt;V1.0&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;Generating Markdown syllabus of Udemy courses&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Copy the course link from Udemy&lt;/li&gt;
&lt;li&gt;Paste the course link in the search box
&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%2Fme0h1aarh81azt0equb5.png" alt="Instruction"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Preview
&lt;/h2&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%2F8frjral14lhqym3wzozb.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%2F8frjral14lhqym3wzozb.gif" alt="preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical details about this project
&lt;/h2&gt;

&lt;p&gt;I wrote a article for this project:&lt;a href="https://medium.com/@effylh/building-an-online-course-syllabus-scraper-with-flask-udemyapi-postgresql-on-heroku-262b727e228b" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Internal Implementations of List.extend() and List.append() operations in Python</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Sun, 09 Aug 2020 12:28:26 +0000</pubDate>
      <link>https://dev.to/effylh/internal-implements-of-list-extend-and-list-append-operations-in-python-4p8j</link>
      <guid>https://dev.to/effylh/internal-implements-of-list-extend-and-list-append-operations-in-python-4p8j</guid>
      <description>&lt;p&gt;Let’s take a deep dive into the internal implementation of &lt;strong&gt;List.extend()&lt;/strong&gt; &amp;amp; &lt;strong&gt;List.append()&lt;/strong&gt; operations:&lt;/p&gt;

&lt;p&gt;Suppose the list &lt;strong&gt;nums[]&lt;/strong&gt; contains 7 integer elements, and we're about to execute lines as below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result=[]
    for i in range(n):
        result.append(nums[0])
        result.append(nums[1])
return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sample 2&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result=[]
    for i in range(n):
        result.extend([nums[0],nums[1]])
return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Analysis of Internal Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Sample 1
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When we execute &lt;strong&gt;result.append(nums[0]),result.append(nums[1])&lt;/strong&gt;, the internal implementation will be like as below:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FX_-w3Rf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0nhnqa08b4k1up5nxum6.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;List &lt;strong&gt;result&lt;/strong&gt; get reference to num[0]which actually pointed to the integer instance 'int1'&lt;/li&gt;
&lt;li&gt;Then list &lt;strong&gt;result&lt;/strong&gt; get reference to num[1]which actually pointed to the integer instance 'int2'&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Sample 2
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When we execute &lt;strong&gt;result.extend([nums[0],nums[1]])&lt;/strong&gt;, the internal implementation will be like as below:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pCc287vp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0tims2z0wb5vfiv6hywv.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Contents inside the parentheses of &lt;strong&gt;.extend()&lt;/strong&gt; function can be treated as a &lt;strong&gt;temp list&lt;/strong&gt; which actually pointed to the same integer objects as list &lt;strong&gt;nums&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Then, the list &lt;strong&gt;result&lt;/strong&gt; receive those references to those integers through that &lt;strong&gt;temp list&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This post is also a complement to my previous post:&lt;br&gt;
&lt;a href="https://dev.to/effylh/leetcode-1470-shuffle-the-array-3ok5"&gt;https://dev.to/effylh/leetcode-1470-shuffle-the-array-3ok5&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>LeetCode:442. Find All Duplicates in an Array</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Sun, 09 Aug 2020 04:20:38 +0000</pubDate>
      <link>https://dev.to/effylh/leetcode-442-find-all-duplicates-in-an-array-4a2m</link>
      <guid>https://dev.to/effylh/leetcode-442-find-all-duplicates-in-an-array-4a2m</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/find-all-duplicates-in-an-array/"&gt;https://leetcode.com/problems/find-all-duplicates-in-an-array/&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;set&lt;/strong&gt; is an collection of elements without duplicates, we use this property to solve the problem:&lt;/p&gt;

&lt;p&gt;Execute an iteration cross the given array, meanwhile:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;check the length of current &lt;strong&gt;set&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;add current element from the array into the &lt;strong&gt;set&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;go back to &lt;strong&gt;1.&lt;/strong&gt;, if there is no change in the length, then it indicates that the added element is duplicated &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Submissions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;faster than 87.10%
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def findDuplicates(self, nums: List[int]) -&amp;gt; List[int]:
        myset=set()
        result=[]
        for i in nums:
            length=len(myset)
            myset.add(i)
            if length==len(myset):
                result+=[i]
        return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>leetcode</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>LeetCode:680. Valid Palindrome II</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Sun, 09 Aug 2020 03:38:51 +0000</pubDate>
      <link>https://dev.to/effylh/leetcode-680-valid-palindrome-ii-1nf5</link>
      <guid>https://dev.to/effylh/leetcode-680-valid-palindrome-ii-1nf5</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/valid-palindrome-ii/submissions/"&gt;https://leetcode.com/problems/valid-palindrome-ii/submissions/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution:Array
&lt;/h2&gt;

&lt;p&gt;The goal of this problem is to find the 'the character which needs to be deleted',let's denote it as 'key'. The given string will be shown as a pattern of Palindrome after located and deleted the 'key',&lt;/p&gt;

&lt;h3&gt;
  
  
  Find the 'key'
&lt;/h3&gt;

&lt;p&gt;We try to check the comparison of head &amp;amp; tail elements of the string, if they are identical characters, check the next pair, otherwise, one of them will be the 'key' we want to find.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kiWae8dw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyedctdgdanvdmf9zx56.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kiWae8dw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyedctdgdanvdmf9zx56.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
(if the length of string is &lt;strong&gt;n&lt;/strong&gt;, in this way, the time complexity can be reduced to &lt;strong&gt;n/2&lt;/strong&gt; )&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exception&lt;/strong&gt;:but here is a special scenario will break the algorithm of 'head-tail- comparison',for example: &lt;strong&gt;'abbaa'&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;thus we design flow control as: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;if&lt;/strong&gt; the 'key' located at head or tail, return True
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;else&lt;/strong&gt; we begin to execute our 'head-tail-comparison'.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Details of head-tail-comparison
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(psuedocode)
if head!=tail:
  Construct a named 'List1'(removded head) 
  Construct a named 'List2'(removded tail)

then:
if ConstructList1==(in reversed ordered)ConstructList1--&amp;gt;return True
if ConstructList2==(in reversed ordered)ConstructList2--&amp;gt;return True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Submission
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;faster than 91.08%
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def validPalindrome(self, s: str) -&amp;gt; bool:
#Step1:
        if s[1:] == s[1:][::-1] or s[0:-1] == s[0:-1][::-1]:
            return True
#Step2:
        else:
            for i in range((len(s) + 1) // 2):
                if s[i] != s[-(i + 1)]:
                    check1 = s[0:i] + s[(i + 1):]
                    check2 = s[0: -(i + 1)] + s[-i:]
                    if check1 == check1[::-1] or check2 == check2[::-1]:
                        return True
                    else:
                        return False
            return True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>algorithms</category>
      <category>leetcode</category>
    </item>
    <item>
      <title>LeetCode:125. Valid Palindrome</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Fri, 07 Aug 2020 12:53:34 +0000</pubDate>
      <link>https://dev.to/effylh/leetcode-125-valid-palindrome-1292</link>
      <guid>https://dev.to/effylh/leetcode-125-valid-palindrome-1292</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/valid-palindrome/"&gt;https://leetcode.com/problems/valid-palindrome/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;step1:&lt;/strong&gt; apply .isalnum() on each character for filtering out all the alphanumeric characters in the given string .&lt;br&gt;
&lt;strong&gt;step2:&lt;/strong&gt; compare filtered list with the one in reversed order, if they're identical with each other, we got the string with pattern of palindrome&lt;/p&gt;

&lt;h2&gt;
  
  
  Submissions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;faster than 98.95%
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def isPalindrome(self, s: str) -&amp;gt; bool:
        result=''
        for i in s:
            if i.isalnum():
                result+=i.lower()
        if result==result[::-1]:
            return True
        return False
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>leetcode</category>
      <category>algorithms</category>
      <category>python</category>
    </item>
    <item>
      <title>TOC-generator of Bear Note</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Tue, 04 Aug 2020 14:04:22 +0000</pubDate>
      <link>https://dev.to/effylh/toc-generator-of-bear-note-4g6h</link>
      <guid>https://dev.to/effylh/toc-generator-of-bear-note-4g6h</guid>
      <description>&lt;p&gt;I'm a person who relies deeply on notes app, mostly I use Bear Note for taking notes for tech books or courses. When a note became huge and included enormous topics and headings inside, TOC(Table Of Contents) will be very useful for an efficient searching. So I created this simple tool for generating TOC in Bear Note.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d8P1fwEF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyj0r6hg0xevdzdxiuei.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d8P1fwEF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyj0r6hg0xevdzdxiuei.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  User Interface
&lt;/h2&gt;

&lt;p&gt;Cause it's just a simple tool, I quickly built the UI with simple settings in QtDesigner without any further edits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7YWcusNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n2i0prdqvo9p3rakurr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7YWcusNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n2i0prdqvo9p3rakurr7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev Workflow
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step1:&lt;/strong&gt; Export identifier &amp;amp; html page of that note.[operations inside Bear Note]&lt;/p&gt;

&lt;p&gt;Reference to Bear Note API document, we define a method to generate TOC with valid jump links inside Bear Note.&lt;br&gt;
Ref:&lt;a href="https://bear.app/faq/X-callback-url%20Scheme%20documentation/"&gt;https://bear.app/faq/X-callback-url%20Scheme%20documentation/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def textFormat(self, aster, insert, factor):
    return '\t' * factor+aster+' '+'[' + insert + ']' + '(' + self.bearNoteUrl(insert) + ')\n'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step2:&lt;/strong&gt; Hit 'Run' button to trigger the scraping process&lt;/p&gt;

&lt;p&gt;Use beautifulSoup to extract Headings from HTML file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cause the HTML code exported from Bear Note is very clean, so html.parser is enough to reach our goal, and no need to import extra module library such as 'lxml'&lt;/li&gt;
&lt;li&gt;Search all lines of the html code and generate appropriate links which matched with the conditions (here conditions are all types of Headings,from'h1'to'h5')
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def scraping(self): 
    self.ui.textBrowser.clear()
    self.scrapResult = ''
    self.asteriskAdd()
    if self.htmlFilePath[0] != '' and len(self.ui.identifier.text()) != 0:
        url = open(self.htmlFilePath[0], encoding='utf-8', errors='ignore')
        bs = BeautifulSoup(url, 'html.parser')
        self.collectList = bs.find_all(['h1', 'h2', 'h3', 'h4'])
        self.scrapResult = "# Table of Contents\n"

        for i in self.collectList:
            if i.name == 'h1':
                insert = i.get_text()
                self.scrapResult+=self.textFormat(self.aster1,insert,0)
            elif i.name == 'h2':
                insert = i.get_text()
                self.scrapResult+=self.textFormat(self.aster2,insert,1)
            elif i.name == 'h3':
                insert = i.get_text()
                self.scrapResult+=self.textFormat(self.aster3,insert,2)
            elif i.name == 'h4':
                insert = i.get_text()
                self.scrapResult+=self.textFormat(self.aster4,insert,3)
            elif i.name == 'h5':
                insert = i.get_text()
                self.scrapResult+=self.textFormat(self.aster5,insert,4)
        self.scrapResult += '***\n'

        self.ui.textBrowser.append(self.scrapResult)

    else:
        QMessageBox.warning(self, 'Warning', 'identifier or html file needed!')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step3:&lt;/strong&gt; Markdown texts of TOC will be shown in text browser at the bottom, then users could copy &amp;amp; paste them into Bear Note &lt;/p&gt;

&lt;h2&gt;
  
  
  Operation Screenshot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CsNmaHCI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yv8rq8rbz1n1g5plqr31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CsNmaHCI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yv8rq8rbz1n1g5plqr31.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Sample of generated TOC in Bear Note&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4Jcf6Haq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/la013byov20685uuc4o7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4Jcf6Haq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/la013byov20685uuc4o7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;I use Pyinstaller to create distributable .EXE file for Windows users and .app for Mac users(find them in "dist" folder). But there is one thing we needs to pay attention: The default .spec setting generated from Pyinstaller will lead to low resolution rendering in Mac Retina. We need to add one more line into .spec file to solve this problem.&lt;br&gt;
Reference:&lt;a href="https://pyinstaller.readthedocs.io/en/stable/spec-files.html"&gt;https://pyinstaller.readthedocs.io/en/stable/spec-files.html&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;info_plist={'NSHighResolutionCapable': 'True'}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pOB9so_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v4427xgoilth6kj2erlj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pOB9so_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v4427xgoilth6kj2erlj.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project link
&lt;/h2&gt;

&lt;p&gt;You can find the source code and executable files here:&lt;br&gt;
&lt;a href="https://github.com/monkeyapple/TOC-Generator-for-Bear-Note"&gt;https://github.com/monkeyapple/TOC-Generator-for-Bear-Note&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;provide more customization options like:ordered Lists&lt;/li&gt;
&lt;li&gt;seek better solution for packaging:
Pyinstaller generated 70M executable file for Mac seems too much, compare with the Windows version which is 33M.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>github</category>
      <category>showdev</category>
    </item>
    <item>
      <title>LeetCode 1470. Shuffle the Array</title>
      <dc:creator>Effy L.H.</dc:creator>
      <pubDate>Fri, 24 Jul 2020 13:46:39 +0000</pubDate>
      <link>https://dev.to/effylh/leetcode-1470-shuffle-the-array-3ok5</link>
      <guid>https://dev.to/effylh/leetcode-1470-shuffle-the-array-3ok5</guid>
      <description>&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/shuffle-the-array/"&gt;link&lt;/a&gt;&lt;br&gt;
The logic of this problem is quite simple: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;treat the given array which is divided at the position &lt;strong&gt;n&lt;/strong&gt; as two parts.&lt;/li&gt;
&lt;li&gt;use &lt;strong&gt;n&lt;/strong&gt; as the iterator(reduce the cost of For Loop to O(len(array)/2)), then add each element into the result array&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I made two submissions to solve this problem, all the lines are the same except one line inside the For Loop , which made a huge difference in the time complexity. &lt;/p&gt;
&lt;h2&gt;
  
  
  Submissions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;faster than 39.93%:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def shuffle(self, nums: List[int], n: int) -&amp;gt; List[int]:
        result=[]
        for i in range(n):
            result+=[nums[i],nums[i+n]]
        return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;faster than 95.78%:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def shuffle(self, nums: List[int], n: int) -&amp;gt; List[int]:
        result=[]
        for i in range(n):
            result+=[nums[i]]+[nums[i+n]]
        return result

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

&lt;/div&gt;

&lt;h2&gt;
  
  
  Analysis
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;result+=[nums[i],nums[i+n]]&lt;/code&gt; has the same effect as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result.extend([nums[i],nums[i+n]])
# O(k),k is the number of elements inside the extending list 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;result+=[nums[i]]+[nums[i+n]]&lt;/code&gt;has the same effect as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result.append(nums[i]) # O(1)
result.append(nums[i+1]) # O(1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;I wrote a complement post to this topic:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.to/effylh/internal-implements-of-list-extend-and-list-append-operations-in-python-4p8j"&gt;https://dev.to/effylh/internal-implements-of-list-extend-and-list-append-operations-in-python-4p8j&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We're familiar with those methods, but we still need to pay attention about the time complexity and make the most appropriate choice.&lt;br&gt;
&lt;strong&gt;Method    Time Complexity:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;append()  O(1)&lt;/code&gt;&lt;br&gt;
&lt;code&gt;insert()  O(n)&lt;/code&gt;&lt;br&gt;
&lt;code&gt;extend()  O(k)&lt;/code&gt; &lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>python</category>
      <category>algorithms</category>
    </item>
  </channel>
</rss>
