<?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: Marco Pasqua</title>
    <description>The latest articles on DEV Community by Marco Pasqua (@pasqua101).</description>
    <link>https://dev.to/pasqua101</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%2F1154394%2Fd1ecaad8-52fa-4401-ac14-f7fb76004d9c.jpeg</url>
      <title>DEV Community: Marco Pasqua</title>
      <link>https://dev.to/pasqua101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pasqua101"/>
    <language>en</language>
    <item>
      <title>Releasing my First Tachiyomi Contribution</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Fri, 05 Jan 2024 01:46:15 +0000</pubDate>
      <link>https://dev.to/pasqua101/releasing-my-first-tachiyomi-contribution-2b6j</link>
      <guid>https://dev.to/pasqua101/releasing-my-first-tachiyomi-contribution-2b6j</guid>
      <description>&lt;p&gt;Hi everyone, if you've been reading my blog posts about Tachiyomi, then you would have known that in my &lt;a href="https://dev.to/pasqua101/working-on-my-first-tachiyomi-contribution-1p6"&gt;last blog post&lt;/a&gt; I created a &lt;a href="https://github.com/tachiyomiorg/website/pull/1099"&gt;pull request&lt;/a&gt; for the issue I was working on for Tachiyomi's website. All I had to do was wait for the repo owner to accept or request a change to the contribution I made. Well, they got back to me and did request a few changes to make things clearer. &lt;/p&gt;

&lt;h3&gt;
  
  
  What Changes were Requested
&lt;/h3&gt;

&lt;p&gt;These are the two requests: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://github.com/tachiyomiorg/website/pull/1099#discussion_r1433410581"&gt;first request&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/tachiyomiorg/website/pull/1099#discussion_r1433411227"&gt;second request&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see from the links, they're both very simple changes that I had to make. &lt;/p&gt;

&lt;h3&gt;
  
  
  Working on the Requested Changes
&lt;/h3&gt;

&lt;p&gt;After I read through the requests, and asked a question to clear up some confusion on the first request. I got to work on updating my contribution to match them. I continued my work in the same branch from my previous contribution and once I as done, I committed it. The repo owner, then accepted my contribution and had it merged with the website. You can see this change right now on their &lt;a href="https://tachiyomi.org/docs/guides/local-source/"&gt;website&lt;/a&gt; right now. I enjoyed working on this contribution and I'm looking forward to perhaps continuing to contribute to Tachiyomi in the future. &lt;/p&gt;

&lt;h3&gt;
  
  
  What About the Android App?
&lt;/h3&gt;

&lt;p&gt;If you recall I was also working on an &lt;a href="https://github.com/tachiyomiorg/tachiyomi/issues/9154"&gt;issue&lt;/a&gt; for their Android app. Unfortunately, I wasn't able to get past the previous issue I faced, which was the duplicate description from when the Markdown function was used. The repo owner did tell me what I would have to update for it to properly work, but I unfortunately had a hard time trying to do so, I didn't really understand how I would write out in the code. I tried looking it up, but couldn't find much. I did also look at how the developers used the Markdown function in their own code, and tried replicating it but with no success. I think that this was probably due to me still not knowing enough about Kotlin and how it works. So unfortunately, this was an issue that I was not able to complete. I'm hoping that maybe in the future, once I've used Kotlin enough and become familiar with it I can create a contribution for the issue. But for now this is something that I wasn't able to complete and will require a lot more practice than I anticipated, as I bit off more than I could chew.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overall
&lt;/h3&gt;

&lt;p&gt;Moving past the unfortunate news, I'm glad that at I have a couple things that I could take away from this. The most notable being that I now have a general knowledge of Kotlin now, one which I for sure have to practice more with. I also was able to make a small contribution to Tachiyomi, which is certainly a start to what I initially planned to do with Tachiyomi.&lt;/p&gt;

&lt;p&gt;So for now, I'll end it off here. I appreciate you all for following my Tachiyomi contribution journey, and I'll catch you all in the next blog post.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Working on My First Tachiyomi Contribution</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Fri, 05 Jan 2024 01:29:19 +0000</pubDate>
      <link>https://dev.to/pasqua101/working-on-my-first-tachiyomi-contribution-1p6</link>
      <guid>https://dev.to/pasqua101/working-on-my-first-tachiyomi-contribution-1p6</guid>
      <description>&lt;p&gt;Hi everyone, if you've seen my &lt;a href="https://dev.to/pasqua101/planning-my-first-tachiyomi-contribution-4d57"&gt;previous blog post&lt;/a&gt;, you would have read about my plans to make my first two contributions to &lt;a href="https://github.com/tachiyomiorg"&gt;Tachiyomi&lt;/a&gt;. In short, I had to update the documentation of their &lt;a href="https://tachiyomi.org/"&gt;website&lt;/a&gt; to state that 1 EPUB file = 1 chapter. As well as make sure that the description of a series supported Markdown, which you can find &lt;a href="https://github.com/tachiyomiorg/tachiyomi/issues/9154"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working on the Website Issue
&lt;/h3&gt;

&lt;p&gt;As I mention in my planning phase, I asked a contributor where this change should be made. Well, he responded and showed me where this change should be made, which is &lt;a href="https://tachiyomi.org/docs/guides/local-source/"&gt;here&lt;/a&gt;. So I got to work. I first, forked the repo, then cloned it to my computer. After that I opened it on VS Code and in my command line, I created a branch for this issue. I then made the documentation changes required. I ended up doing this below the part of the page where supported file formats are mentioned. After I wrote the change, I read it over to make sure it sounded right, and created a &lt;a href="https://github.com/tachiyomiorg/website/pull/1099"&gt;pull request&lt;/a&gt;. Now I just have to wait for any changes requested by the repo owner. &lt;/p&gt;

&lt;h3&gt;
  
  
  Working on the Android App Issue
&lt;/h3&gt;

&lt;p&gt;If you remember in my previous blog post, I mentioned how for this &lt;a href="https://github.com/tachiyomiorg/tachiyomi/issues/9154"&gt;issue&lt;/a&gt; I would have to learn Kotlin. Well, I did end up learning it and to be honest Kotlin, doesn't seem too hard. I actually enjoyed learning it, I like how its syntax is deferent from Java;&lt;/p&gt;

&lt;p&gt;Java functions are created like this, &lt;code&gt;private String name()&lt;/code&gt;, whereas Kotlin creates them like so, &lt;code&gt;fun name(): String&lt;/code&gt;. Also, printing is different. Java is &lt;code&gt;System.out.println()&lt;/code&gt; and Kotlin is simply &lt;code&gt;println()&lt;/code&gt;. There is much less that you have to type with Kotlin, and I like it. &lt;/p&gt;

&lt;p&gt;I also like that you can create &lt;a href="https://www.geeksforgeeks.org/kotlin-extension-function/"&gt;extension functions&lt;/a&gt; in Kotlin. &lt;/p&gt;

&lt;p&gt;After I learn Kotlin and created a few test apps modeled after code I made in my Android Java development class, I left a comment on the issue expressing my interest in working on it and which file I must work in. This prompted for the repo owner to reply and tell me where this change must be done. Which resulted in me creating a fork, cloning it, and making a branch for it. The repo owner also told me about a open source Markdown converter that they use for a similar feature in the app, which is displaying updates for their app. &lt;/p&gt;

&lt;p&gt;I did a few test with the function, and tried my own thing. I actually managed to get the links to display on the description of the manga/comic, which meant that it was parsing the Markdown correctly. However, these links were clickable, and someone commented saying that we should make them unclickable as we shouldn't be trusting links from websites. This was something that I agreed with, and then looked at how I can remove the hyperlink. I found out that I can simply use the comment syntax &lt;code&gt;&amp;lt;!-- --&amp;gt;&lt;/code&gt; for HTML to remove the hyperlink. All I had to do was insert the start and the end of the comment between the &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt; of the link. I was able to do this using Regex, so I had it figured out on that end. &lt;/p&gt;

&lt;p&gt;However, there was one problem. The Markdown function was returning null with the text, which it shouldn't be doing. I asked a question about it, and was told that I was using the function incorrectly. I then realized that I was using the wrong function altogether. I double checked the file where they use the markdown function and made this realization. So for now, I'm trying to use the function correctly, and while I see that it does parse the description, it produces a duplicate of the description. So this is something that I'll have to figure out for the next blog post.&lt;/p&gt;

&lt;p&gt;So for now, that concludes this blog post. Thanks for reading, and I'll see in you in the next one.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Planning my First Tachiyomi Contribution</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Fri, 05 Jan 2024 01:14:36 +0000</pubDate>
      <link>https://dev.to/pasqua101/planning-my-first-tachiyomi-contribution-4d57</link>
      <guid>https://dev.to/pasqua101/planning-my-first-tachiyomi-contribution-4d57</guid>
      <description>&lt;p&gt;Hi everyone, if you've been following me for a while you may know that I use a comic/manga reader on my phone called &lt;a href="https://tachiyomi.org/"&gt;Tachiyomi&lt;/a&gt;. I've been wanting to contribute to this project for a while and started looking at open issues that might be good for a first timer like me. So I did some searching between the repos used for their &lt;a href="https://github.com/tachiyomiorg/tachiyomi"&gt;Android App&lt;/a&gt; and their &lt;a href="https://github.com/tachiyomiorg/website"&gt;Website&lt;/a&gt;. I eventually settled for  two issues, this [issue] here (&lt;a href="https://github.com/tachiyomiorg/website/issues/1093"&gt;https://github.com/tachiyomiorg/website/issues/1093&lt;/a&gt;) that I found on the repo meant for their &lt;a href="https://github.com/tachiyomiorg/website"&gt;website&lt;/a&gt;. As well as an &lt;a href="https://github.com/tachiyomiorg/tachiyomi/issues/9154"&gt;issue&lt;/a&gt; I found on the repo for their &lt;a href="https://github.com/tachiyomiorg/tachiyomi"&gt;Android app&lt;/a&gt;. I'll talk about them below.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's the Issue on their Website?
&lt;/h4&gt;

&lt;p&gt;This website issue is fairly simple. It's really just making a minor update to their website's documentation. The update that I have to make is in regards to how the app processes locally read files. In short, the app will count the number of files in a folder for a series. Each file is counted as a chapter. However, for a file type, such as EPUB, where all of the chapters are usually in one file. The app is unable to count each chapter, unless the EPUB is broken up into separate files for each chapter of the book/series. So this must be documented on their website.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's the Issue for their Android App
&lt;/h4&gt;

&lt;p&gt;The issue for their Android App seems somewhat simple, essentially I have to make sure that the description of a manga/comic is able to support Markdown. So I really just have to make, sure that things like links, bolds, or italics are properly displayed on the screen for the user to see. Whereas they previously were not being displayed correctly. For example, a link would look like this &lt;code&gt;[link](www.example.com)&lt;/code&gt; meanwhile it should look like this &lt;a href="//www.example.com"&gt;link&lt;/a&gt;. As you may know, I worked on creating a Python Application that converts Markdown into HTML. So I figured that with my previous Android knowledge with Java, I could learn Android development with Kotlin and tackle this issue. Since there shouldn't be too many differences between Android development with Java and Kotlin.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's the Plan for the Website?
&lt;/h4&gt;

&lt;p&gt;As I said before, this is a fairly simple issue, and kind of serves as a small introduction to contributing to Tachiyomi. So my plan is to ask one of the contributors were this change should be made, and then make a fork of the repo, clone it and create a branch for the issue. This seems fairly straight forward, and shouldn't take too long. &lt;/p&gt;

&lt;h4&gt;
  
  
  What's the Plan for the Android App?
&lt;/h4&gt;

&lt;p&gt;To tackle this issue, I'm going to try learning Kotlin, which I think should be pretty easy to pick up considering that it isn't too different from Java. To learn it, I'll split it up into two different parts. I'll first learn some of the features, and syntax differences between Java and Kotlin. Then I'll try to create an app or two with Kotlin that should function the same as the Java versions that I created for assignments in class. This should probably take a day or two. After that, I'll leave a comment on the issue saying I'd like to work on this, and ask which file the related code is located in. Then, I can just fork it, clone and create a branch to work on it, and hopefully things go smooth. &lt;/p&gt;

&lt;p&gt;So I'll get to work on this and see you guys in the post talking about my progress. Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Releasing my First Open Source Project</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Sun, 03 Dec 2023 02:03:58 +0000</pubDate>
      <link>https://dev.to/pasqua101/releasing-my-first-open-source-project-bj6</link>
      <guid>https://dev.to/pasqua101/releasing-my-first-open-source-project-bj6</guid>
      <description>&lt;p&gt;Hi everyone, if you've been following my blog posts for a while, you may know that I have been working on an open source project called &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;TXT to HTML Converter&lt;/a&gt;. Well, I recently released it. You can find it here, on &lt;a href="https://pypi.org/project/text-to-html-converter/"&gt;PyPI&lt;/a&gt;. I'll talk about the release process below.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Platform did I use to Release my project
&lt;/h3&gt;

&lt;p&gt;As mentioned above, I used &lt;a href="https://pypi.org/"&gt;PyPI&lt;/a&gt;. PyPI is a service used to host packages or projects made by you. It's used by open source projects like &lt;a href="https://pypi.org/project/black/"&gt;Black&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What was the Release Process Like?
&lt;/h3&gt;

&lt;p&gt;The release process was a little bit complicated for me, as I originally had a hard time with having it run on PC. I'll talk about part of the setup process below, to hopefully help out others releasing their first project on PyPI.&lt;/p&gt;

&lt;p&gt;PyPI provides a &lt;a href="https://packaging.python.org/en/latest/tutorials/packaging-projects/"&gt;tutorial&lt;/a&gt; that you can use when you're getting ready to release a package. I based majority of the setup process off of this tutorial. I created a new file called &lt;code&gt;__init__.py&lt;/code&gt;. I also moved all of my source code, including &lt;code&gt;__init__.py&lt;/code&gt;, into a folder that has the name of my package. I left &lt;code&gt;__init__.py&lt;/code&gt; empty. I also made changes to my toml file called &lt;code&gt;pyproject.toml&lt;/code&gt;. As you may know, I've used this toml file to configure my formatter, &lt;a href="https://pypi.org/project/black/"&gt;Black&lt;/a&gt;, and linter, &lt;a href="https://docs.astral.sh/ruff/linter/"&gt;Ruff&lt;/a&gt;. Now I'm also using it to configure the release of my package, I'll show what the file looks like for me.&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="nn"&gt;[build-system]&lt;/span&gt;
&lt;span class="py"&gt;requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"hatchling"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;build-backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hatchling.build"&lt;/span&gt;

&lt;span class="nn"&gt;[project]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"text-to-html-converter"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0.2"&lt;/span&gt;
&lt;span class="py"&gt;authors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Marco Pasqua"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;email&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email@gmail.com"&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"A package that allows for txt and md conversion to HTML files."&lt;/span&gt;
&lt;span class="py"&gt;readme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"README.md"&lt;/span&gt;
&lt;span class="py"&gt;requires-python&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;3.11&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;classifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"Programming Language :: Python :: 3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"License :: OSI Approved :: MIT License"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Operating System :: OS Independent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[project.urls]&lt;/span&gt;
&lt;span class="py"&gt;Homepage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/Pasqua101/txt-to-HTML-converter"&lt;/span&gt;
&lt;span class="py"&gt;Issues&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/Pasqua101/txt-to-HTML-converter/issues"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PyPI provides a good explanation in their &lt;a href="https://packaging.python.org/en/latest/tutorials/packaging-projects/"&gt;tutorial&lt;/a&gt;. However, I'll explain some of the things I did. While most of it is self-explanatory, you can see that I've stated that my program requires Python 3.11 and above. This is due to a library I used called &lt;a href="https://docs.python.org/3/library/tomllib.html"&gt;TOMLlib&lt;/a&gt;, which is built into Python 3.11 and above. You can also see that I've provided a version number, which I can update for each release, as well as a description. The build system part is something that is necessary for uploading the package to PyPI. Other than that, I did make changes to my import statements. Instead of doing something like &lt;code&gt;from helper import extension_checker&lt;/code&gt;, my imports now looked like this &lt;code&gt;from . import helper as h&lt;/code&gt;. According to my peer, I had to do this to get my code to be able to work with PyPI. Even if it didn't work on my computer in the end. Moving on, when I did all that, I then made sure to set my PyPI token. The tutorial should mention how to get and use this token for releasing your package. Afterwards, I ran this command &lt;code&gt;python -m build&lt;/code&gt;. This command builds my program, and puts the required files to be uploaded in a dist folder. To upload the dist files, I first had to install Twine by doing this &lt;code&gt;python -m pip install --upgrade twine&lt;/code&gt;. I was then ready to upload it with this command &lt;code&gt;py -m twine upload --repository pypi dist/*&lt;/code&gt;. This is where the token comes into play. The token is able to create a project on my account for the files to be hosted and downloaded from as a package. If I needed to fix my code, I could make my changes, then change the version number in the &lt;code&gt;pyproject.toml&lt;/code&gt; file and run the same upload command from earlier. &lt;/p&gt;

&lt;h3&gt;
  
  
  Testing my Package
&lt;/h3&gt;

&lt;p&gt;I had a peer testing my work, who also helped me solve most of the problem with my code not being able to run. They seemed to have no problems with running my package, during the testing phase. However, I did notice that since I moved my source code into a new folder, I had to make some changes to my testers. This is something that I set as an issue for myself on my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter/issues/25"&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Install my Program
&lt;/h3&gt;

&lt;p&gt;To install my program, you can navigate to this &lt;a href="https://pypi.org/project/text-to-html-converter/"&gt;link&lt;/a&gt; that it's hosted at. Here, you can choose to learn more about it, or run this command, &lt;code&gt;pip install text-to-html-converter&lt;/code&gt;, to get started. Once the package is installed, you should then be able to run it like so &lt;code&gt;python -m text-to-html.text_to_html -h&lt;/code&gt;. This will display some information about the app, and how to use it. After that, you're all set! Enjoy using my program and feel free to report any bugs or problems you come across by going to my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you all for following my journey of creating and publishing this program! I hope it has some use to you all, despite the simple problem it accomplishes. See you in the next blog post.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>Reinforcing my ReactJS Knowledge</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Sat, 25 Nov 2023 04:54:08 +0000</pubDate>
      <link>https://dev.to/pasqua101/reinforcing-my-reactjs-knowledge-5b03</link>
      <guid>https://dev.to/pasqua101/reinforcing-my-reactjs-knowledge-5b03</guid>
      <description>&lt;p&gt;Hi everyone, this should be a much shorter post, but I just want to talk about the recent contribution I made to the &lt;a href="https://github.com/SarthakKeshari/calc_for_everything"&gt;Calculator for Everything&lt;/a&gt; repo. This contribution is very much like the one I made in my last blog post titled, &lt;a href="https://dev.to/pasqua101/expanding-on-my-reactjs-knowledge-1bli"&gt;Expanding on My ReactJS Knowledge&lt;/a&gt;. So most of this blog post won't be as detailed as the previous one. However, I'll talk about what I did below.&lt;/p&gt;

&lt;h3&gt;
  
  
  What was the Issue I Worked on?
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/SarthakKeshari/calc_for_everything/issues/647"&gt;issue&lt;/a&gt; I created was to update another calculator that I made for the repo. The difference being that this time instead of &lt;a href="https://github.com/SarthakKeshari/calc_for_everything/issues/645"&gt;updating my momentum calculator&lt;/a&gt;, I was updating the density calculator that I made for Hacktoberfest.&lt;/p&gt;

&lt;p&gt;Going into this issue, I already knew what had to be done. I had to create a dropdown menu using the &lt;code&gt;&amp;lt;InputLabel&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Select&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;MenuItem&amp;gt;&lt;/code&gt; tags. As well as a new functions and variables to track the selected unit of measurement for both mass and volume. If you are interested in having a more comprehensive explanation of what I did, I highly suggest that you read my &lt;a href="https://dev.to/pasqua101/expanding-on-my-reactjs-knowledge-1bli"&gt;previous blog post&lt;/a&gt;. Since this contribution and the previous one as pretty much identical. That being said, I will briefly describe how I used these tags with the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InputLabel&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;absolute&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Unit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;InputLabel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Select&lt;/span&gt;
&lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Mass Unit"&lt;/span&gt;
&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;massUnit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleMassUnitChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;fullWidth&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"kg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Kilograms (kg)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"g"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Grams (g)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Milligram (mg)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"oz"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Ounces (oz)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"lb"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Pounds (lb)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Metric Tons (t)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see above, I used &lt;code&gt;&amp;lt;InputLabel&amp;gt;&lt;/code&gt; to name the menu, While I used &lt;code&gt;&amp;lt;Select&amp;gt;&lt;/code&gt; to create it, and &lt;code&gt;&amp;lt;MenuItem&amp;gt;&lt;/code&gt; to give the menu options. With this, I was able to use the &lt;code&gt;onChange={handleMassUnitChange}&lt;/code&gt; to track the unit of measurement selected by the user. I also had a similar setup for my volume. This would allow me to then convert the provided input back into kilograms (kg) or cubic meters (m&lt;sup&gt;3&lt;/sup&gt;). &lt;/p&gt;

&lt;p&gt;After I created the menu, and updated my functions to support converting mass and volume back to kg and m&lt;sup&gt;3&lt;/sup&gt;. I got to testing my code. To do this, I compared my results with an online calculator. I saw that the results were the same, which allowed me to push this and create a &lt;a href="https://github.com/SarthakKeshari/calc_for_everything/pull/649"&gt;pull request (pr)&lt;/a&gt; on the repo. This pr was tested by the continuous integration (ci) set up by the owner, which basically made sure my code would work when deployed and there were no errors. If you would like a more in depth explanation of the ci, I would suggest to read my &lt;a href="https://dev.to/pasqua101/expanding-on-my-reactjs-knowledge-1bli"&gt;previous blog post&lt;/a&gt;. Moving on, my code passed these tests just fine, and it allowed for the repo owner to merge it. This contribution allowed me to reinforce some of my ReactJS knowledge, as well as test my memory on how drop down menus are made. &lt;/p&gt;

&lt;h3&gt;
  
  
  The Honest Truth
&lt;/h3&gt;

&lt;p&gt;There is something I must tell you about my actual plans for this blog post. Truth is, I didn't really plan on contributing to this repo again. I did some searching yesterday and came across this really interesting repo called &lt;a href="https://github.com/ollm/OpenComic"&gt;OpenComic&lt;/a&gt;. OpenComic is essentially a JavaScript app designed to run on your computer to read comics, manga and graphic novels. I was actually thrilled by the idea of contributing to this repo, because if you remember from some older blog posts, I use an open source Android app called &lt;a href="https://github.com/tachiyomiorg/tachiyomi"&gt;Tachiyomi&lt;/a&gt; which works in a similar way, except instead of just reading the files locally, it also pulls them from websites. I thought that by contributing to this I may have a good start on contributing to Tachiyomi in the future, despite me not knowing Kotlin. &lt;/p&gt;

&lt;p&gt;Moving back to OpenComic, I came across an &lt;a href="https://github.com/ollm/OpenComic/issues/172"&gt;issue created by a Mac user&lt;/a&gt;. Basically, when a Mac user would go the about section of the app, it would open an alert window with no buttons to close the window causing the user to be stuck on the screen. This seemed like a pretty easy bug fix, as I have had experience with alerts in both JavaFx and Java for Android so I was expecting it to be similar for JavaScript. My main idea was to create the buttons to close a window, instead of the 'x' that would be present at the top of it,  like in most OSs. I had this idea, because since I'm not a Mac user there's no actual way for me to be 100% sure that on Mac the x button would appear above the alert window. With this idea in mind, I left a comment on the issue. While I did see that this was already self-assigned to the repo owner, I also saw a lot of other issues that were self-assigned. So I was hoping that I could lighten the load for the owner. Unfortunately, when the owner responded to me, they said that they already took care of the issue. Fortunately for me, they said that this feature would be in the next beta version of the app, and invited me to test it and make sure it was working. At the time of writing this, that beta version has already been released. So I might try to go through it and see if I can find any bugs.&lt;/p&gt;

&lt;p&gt;Anyways, that is the honest truth, I was hoping that I could have had the chance to contribute to &lt;a href="https://github.com/ollm/OpenComic"&gt;OpenComic&lt;/a&gt; instead of to &lt;a href="https://github.com/SarthakKeshari/calc_for_everything"&gt;Calculator for Everything&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's my Plan Moving Forward?
&lt;/h3&gt;

&lt;p&gt;Moving forward, I'm planning to potentially test the &lt;a href="https://github.com/ollm/OpenComic/releases"&gt;OpenComic &lt;br&gt;
v1.0.0-beta.5&lt;/a&gt; and see if I can spot any bugs. If I don't find any bugs then I'll take a look at the issues that occasionally come into the repo. That's not all, I'm also planning to teach myself the basics of Kotlin in the coming days. I'm hoping that with my Android development experience  in Java, I can quickly grasp the fundamentals of Kotlin Android development and possibly make my first ever contribution to &lt;a href="https://github.com/tachiyomiorg/tachiyomi"&gt;Tachiyomi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That concludes my blog post for now. Thank you to everyone who continues to read and follow my story through the open source world. I'll catch you all in the next post, where I possibly make my first release of my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;Text to HTML Converter&lt;/a&gt;! Take care!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>react</category>
    </item>
    <item>
      <title>Expanding on My ReactJS Knowledge</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Thu, 23 Nov 2023 22:48:53 +0000</pubDate>
      <link>https://dev.to/pasqua101/expanding-on-my-reactjs-knowledge-1bli</link>
      <guid>https://dev.to/pasqua101/expanding-on-my-reactjs-knowledge-1bli</guid>
      <description>&lt;p&gt;Hi everyone, I recently expanded on my ReactJS knowledge through a contribution I made to a repo called &lt;a href="https://github.com/SarthakKeshari/calc_for_everything"&gt;Calculator for Everything&lt;/a&gt;. Some of you may know about this repo through my previous HacktoberFest contribution blogs. I won't cover majority of what I did in those contributions. So if you're interested in learning about those contributions, you can read my blog posts &lt;a href="https://dev.to/pasqua101/second-pr-of-hacktoberfest-5929"&gt;Second PR of Hacktoberfest&lt;/a&gt; and &lt;a href="https://dev.to/pasqua101/last-pr-of-hacktoberfest-5dce"&gt;Last PR of Hacktoberfest&lt;/a&gt;, which talk about this repo.&lt;/p&gt;

&lt;p&gt;Anyways, the contribution I made to the repo this time was to expand on the Momentum Calculator I made in a &lt;a href="https://github.com/SarthakKeshari/calc_for_everything/issues/531"&gt;previous issue&lt;/a&gt;. In that issue, I created a calculator to solve for Momentum, using mass and velocity. However, in that contribution, mass and velocity were only using one unit of measurement, which was kilograms (kg) for mass and meters per second (m/s) for velocity. I wanted to expand on this so it could use more than one unit of measurement for mass and velocity.&lt;/p&gt;

&lt;p&gt;To start, I created an &lt;a href="https://github.com/SarthakKeshari/calc_for_everything/issues/645"&gt;issue&lt;/a&gt; on the repo stating the changes I would like to make. Once it got approved by the repo owner I got to work. I'll talk about it below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working on the Issue
&lt;/h3&gt;

&lt;p&gt;In the &lt;a href="https://github.com/SarthakKeshari/calc_for_everything/issues/645"&gt;issue&lt;/a&gt; I mentioned the idea I had to get this working. I wanted to created a dropdown menu that would allow for the user to select from a list of different units of measurement for both mass and velocity. I already had a general idea of how this could work, thanks to previous applications I made with JavaFX and for Android using FXML. However, for both methods were different. For JavaFX to make a dropdown, I have to use the &lt;code&gt;combobox&lt;/code&gt; UI element, whereas for Android development with Java I had to use the &lt;code&gt;Spinner&lt;/code&gt; tag in an XML file. With ReactJS, this method was also different. After doing some research I found out that in order to make a dropdown menu, I would have to do something like this in the area of my code  where I wanted the menu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;InputLabel style={{ position: 'absolute', top: -20 }}&amp;gt;Unit&amp;lt;/InputLabel&amp;gt;
&amp;lt;Select
label="Mass Unit"
value={massUnit}
onChange={handleMassUnitChange}
fullWidth
&amp;gt;
&amp;lt;MenuItem value="kg"&amp;gt;Kilograms&amp;lt;/MenuItem&amp;gt;
&amp;lt;MenuItem value="g"&amp;gt;Grams&amp;lt;/MenuItem&amp;gt;
&amp;lt;MenuItem value="oz"&amp;gt;Ounces&amp;lt;/MenuItem&amp;gt;
&amp;lt;MenuItem value="lb"&amp;gt;Pounds&amp;lt;/MenuItem&amp;gt;
&amp;lt;/Select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the code it's pretty easy to see how the dropdown menu is made from a UI perspective. If I wanted to label the menu, I can use &lt;code&gt;&amp;lt;InputLabel&amp;gt;&lt;/code&gt; to give a title to the menu, and then use the style attribute to position the label. To create the actual menu, I had to use the &lt;code&gt;&amp;lt;Select&amp;gt;&lt;/code&gt; tag. Here I can assign it a &lt;code&gt;label&lt;/code&gt;, and a &lt;code&gt;value&lt;/code&gt;. I'll talk about the &lt;code&gt;onChange&lt;/code&gt; attribute in a bit. After that, I could then populate the inside of the tag with the &lt;code&gt;&amp;lt;MenuItem&amp;gt;&lt;/code&gt; tag.  From here, I could assign each &lt;code&gt;&amp;lt;MenuItem&amp;gt;&lt;/code&gt; tag with a &lt;code&gt;value&lt;/code&gt; that is respective to the text/option in the tag. As you can see above, for the Grams option, I have assigned it the &lt;code&gt;value&lt;/code&gt; "g". This brings me to the &lt;code&gt;onChange&lt;/code&gt; attribute in my &lt;code&gt;&amp;lt;Select&amp;gt;&lt;/code&gt; tag. The &lt;code&gt;onChange&lt;/code&gt; attribute is linked to a function I created in my code called handleMassUnitChange. This function is used only when the user selects an option from the menu, and affects the &lt;code&gt;useState&lt;/code&gt; value set for the massUnit variable, which changes the unit of measurement being used. By default this value is set to "kg", but if grams was selected it would then switch to "g". This affects the way the value entered for the mass is used and I have a similar method for the velocity. &lt;/p&gt;

&lt;p&gt;Since the unit of measurement used for Momentum is kg m/s, I would need to make sure that the measurement selected for both mass and velocity gets converted back to kg and m/s. This is where something like my convertMass and convertVelocity functions come into play. When the user clicks the button to solve the equation, it will run the functions that check the unit of measurement being used for both variables and convert their values to kg and m/s which I then multiply to solve for the momentum. I tested this out a few times, and compared it to an actual Momentum calculator online. After verifying the product I received for momentum with my calculator and compared it to the one I found online, I saw that the results were the same. This was a good sign for me, so I moved onto the second last step.&lt;/p&gt;

&lt;p&gt;The second last step, I had to accomplish was to update the info file for the calculator. The changes I had to make were very simple. I just had to state the new units of measurement that both Mass and Velocity would use. This brought me to the final step.&lt;/p&gt;

&lt;p&gt;Lastly, I just had to push my contributions to my fork and create a pull request for the changes I made. As you may remember in my previous contributions to this repo, the owner has setup a template for all contributors. I followed the template and then sent in my request. After I created the request, I noticed something new. The repo owner has implemented continuous integration into contributions made to their repo. This was done to not only test my code for deployment to their &lt;a href="https://calc-for-everything-psi.vercel.app/"&gt;website&lt;/a&gt;, but to detect and fix vulnerabilities in my contribution. I actually found this to be really interesting, this application they used for this is called &lt;a href="https://github.com/apps/gitguardian"&gt;GitGuardian&lt;/a&gt;, if you wanted to check it out. I think I should learn more about it, and see if it's something I would like to use in future products.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overall
&lt;/h3&gt;

&lt;p&gt;This contribution is meant to be a step up from my previous Hacktoberfest contributions, and while it was as I did learn more about ReactJS. I knew I could do better to improve. However, for now this isn't that bad of a step up. Since I did have a take away, which was learning dropdown menus in React and using that to improve old code. I'm hoping that for my next contribution I can help out a larger repo. I did have that in mind for this contribution, but most repos that interested me where for languages I have little to no knowledge of, and for the repos I was interested in when I tried to clone it and run it locally I had a hard time installing certain prerequisites. Hopefully for a future contribution, I can change this and actually make a more significant contribution as that was my original goal for one of my Hacktoberfest contributions. &lt;/p&gt;

&lt;p&gt;Anyways, that concludes this blog post for now. Once again thank you all for reading. I also noticed that I recently gained quite a few new followers. Thank you for following me and watching my journey to improve my coding abilities. I'll catch you all in the next post!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Using GitHub Actions with my Project</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Fri, 17 Nov 2023 03:29:11 +0000</pubDate>
      <link>https://dev.to/pasqua101/using-github-actions-with-my-project-434o</link>
      <guid>https://dev.to/pasqua101/using-github-actions-with-my-project-434o</guid>
      <description>&lt;p&gt;Hi everyone, I recently had the chance to integrate a CI workflow into &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;TXT to HTML Converter&lt;/a&gt; project. I'll talk about it below.&lt;/p&gt;

&lt;h3&gt;
  
  
  What was the Set up Process Like?
&lt;/h3&gt;

&lt;p&gt;Setting up the workflow for my project was very simple. I followed the steps from the &lt;a href="https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python"&gt;tutorial posted by GitHub&lt;/a&gt; and basically created a workflow to test my project. GitHub created template for me, and the directories to store the YAML file in. &lt;/p&gt;

&lt;h3&gt;
  
  
  What Does my Workflow Look Like?
&lt;/h3&gt;

&lt;p&gt;After the YAML file was created, I continued to follow &lt;a href="https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python"&gt;GitHub's tutorial&lt;/a&gt;. It was very simple and direct, it told me how I can run my code on different versions of Python as well as different OSs. Here is the YAML file I used that tests with different Python versions and OSs.&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="c1"&gt;# This workflow will install Python dependencies, run tests and lint with a single version of Python&lt;/span&gt;
&lt;span class="c1"&gt;# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python&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;Python application&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&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;build&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;${{ matrix.os }}&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.11"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.12"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;windows-latest&lt;/span&gt;&lt;span class="pi"&gt;]&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&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;Set up Python ${{ matrix.python-version }}&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/setup-python@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;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.python-version }}&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;Install dependencies&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;python -m pip install --upgrade pip&lt;/span&gt;
        &lt;span class="s"&gt;pip install ruff&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;Lint with Ruff&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;ruff --output-format-github .&lt;/span&gt;
      &lt;span class="na"&gt;continue-on-error&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;Test with unittest&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;python -m unittest discover tests&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Thankfully, my project has no dependencies so I don't have to make pip install anything other than &lt;a href="https://docs.astral.sh/ruff/"&gt;Ruff&lt;/a&gt; to lint my code, which you can see above. I only make my program run the testers with two versions of Python, 3.11 and 3.12. I chose these versions in particular because there is a library my program uses called &lt;a href="https://docs.python.org/3/library/tomllib.html"&gt;tomllib&lt;/a&gt;. Tomllib is built into Python 3.11 and above, which means that my program does not support 3.10 and below. So I've only made it test with the two most recent versions of Python. I also wanted to attempt running my program on different OSs, like Ubuntu and MacOS, but I believe way those two OSs handle file paths differently from Windows. So when I was trying to handle file paths, it was expecting it in the Windows way and not the Linux way. So for now, it looks like my program does not work with Linux and MacOS. That concludes what I did for my workflow, next I'll talk about writing a test for a peer's program.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing a Test for a Peer's Program
&lt;/h3&gt;

&lt;p&gt;I made a contribution to my peer's program called &lt;a href="https://github.com/rabroldan/Waypoint"&gt;Waypoint&lt;/a&gt;. I made a contribution to their testers. The way they had it setup was different from mine. I had my program store all the testers in a tests folder for organizational reasons. I also split up the testers for each file, for example my testers for my helpers.py would have its own tester file. While my peer combined all their testers into one file. However, we both used unittest so I could just look at their code and jump right into creating a unittest. Thanks to my prior knowledge of making unittests for my program, this was simple. I created a tester to test the output of the function that handles Markdown conversion. I tested it, then committed and then made a PR. The tester worked with the CI my peer made and so they merged it. This leads me to my final thoughts about CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  What do I think of CI?
&lt;/h3&gt;

&lt;p&gt;I think that CI is a pretty handy tool for development, and I found the setup process to be really simple (for Python at least). I liked how I can use it to test my PRs on GitHub to make sure that the code I'm contributing works issue free. I also think that if I were to make another project, I would use CI in it. So, I'm definitely looking forward to how I can use it more in my programs, and what I can take advantage of to help me.&lt;/p&gt;

&lt;p&gt;That's all for now. As always thank you for reading, and I'll catch you all in the next blog post.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>github</category>
    </item>
    <item>
      <title>Testing Python Code Using UnitTest</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Thu, 09 Nov 2023 18:49:30 +0000</pubDate>
      <link>https://dev.to/pasqua101/testing-python-code-using-unittest-32ah</link>
      <guid>https://dev.to/pasqua101/testing-python-code-using-unittest-32ah</guid>
      <description>&lt;p&gt;Hey everyone, I recently had to create testers for my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;TXT to HTML Converter&lt;/a&gt; program. To do this I used the built-in UnitTest framework, which I'll talk about below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why did I Choose the UnitTest Library?
&lt;/h3&gt;

&lt;p&gt;Like I said above, I chose the &lt;a href="https://docs.python.org/3/library/unittest.html"&gt;UnitTest&lt;/a&gt; framework because it is built into Python, which should make things easier for contributors as it reduces the number of libraries they need to install in order to get started on the program. I also have a little experience with reading the syntax for the library due to a Data Structures and Algorithms class I took in a previous semester, where my professor had us write data structures and algorithms in Python which we had to test with testers they wrote with the UnitTest framework.&lt;/p&gt;

&lt;p&gt;Aside from that the UnitTest framework is quite simple to understand and works very well with my IDE, &lt;a href="https://www.jetbrains.com/pycharm/"&gt;PyCharm&lt;/a&gt;, since I can run the tests in the IDE without having to use the command-line. I'll talk about the setup and how I got them to work with my program next&lt;/p&gt;

&lt;h3&gt;
  
  
  Using UnitTest with my Program
&lt;/h3&gt;

&lt;p&gt;To set up the framke work, I had to import the unit test library into a python file that starts with &lt;code&gt;test_&lt;/code&gt;, as well as the function you want to test. Then you must define a class that uses &lt;code&gt;unittest.TestCase&lt;/code&gt; and create a function in the class that also has the &lt;code&gt;test_&lt;/code&gt; prefix. To better explain it, I'll show a brief example below for a function I have that returns true or false based on the file extension.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;helper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;extension_checker&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestExtensionChecker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&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;test_extension_checker_txt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extension_checker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extension_checker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extension_checker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&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;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using self.assertTrue or False allows the tester to make sure that the return value is what it is supposed to be. There is also self.assertEqual which you can use to directly compare the return value with a string or another value. An example is provided below;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&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;test_convert_bold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;converted_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_md&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;**Hello World**&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;converted_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;strong&amp;gt;Hello World&amp;lt;/strong&amp;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;test_convert_hr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;converted_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_md&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;converted_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;hr&amp;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;test_convert_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;converted_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_md&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[YouTube](https://www.youtube.com/)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;converted_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;a href=https://www.youtube.com/&amp;gt;YouTube&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Tests conversion result for both 1 and 3 backticks
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_convert_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;converted_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_md&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;`\``Hello world`\``&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Note: In my actual code the backslash isn't in the string. 
&lt;/span&gt;        &lt;span class="c1"&gt;# I did this to prevent Markdown from reading "Hello world" as another code block.
&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;converted_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;code&amp;gt;Hello world&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;converted_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_md&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;`Hello world`&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;converted_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;code&amp;gt;Hello world&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was with this test that I made that I was able to test my &lt;code&gt;parse_md&lt;/code&gt; function, previously called &lt;code&gt;check_md_and_write&lt;/code&gt;, and locate a bug that I uncovered a last week. I noticed this bug when I was using the linter, &lt;a href="https://docs.astral.sh/ruff/"&gt;Ruff&lt;/a&gt;, and formatter, &lt;a href="https://black.readthedocs.io/en/stable/"&gt;Black&lt;/a&gt;, I set up for my project. If you're interested in reading about the linter and formatter I chose and the setup process you can read &lt;a href="https://dev.to/pasqua101/picking-out-a-formatter-and-linter-for-my-open-source-project-1gj2"&gt;last week's blog&lt;/a&gt;. Essentially the problem was that I could not parse any Markdown in my program. I wasn't sure what the problem was, but I think it had something to do with when I refactored my code and tried to clean things up. Luckily, I still has the branches where I worked on improved the function to parse markdown and the refactoring branch. To make note of it, I made an &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter/issues/21"&gt;issue&lt;/a&gt; for myself and specified which branches to take a look at. &lt;/p&gt;

&lt;p&gt;To fix the solution I compared the code I had with the branch I made for &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter/issues/16"&gt;issue-16&lt;/a&gt; since this had the completed version of my function, just without the refactoring changes. I ended up falling back on this function and changed the way it gets called. Which was by checking if the file had the md extension before entering the function, whereas before I would enter the function and then check if it was an md file. I did this because when I ran the tester I noticed that it would not return anything, so I suspected that it wasn't able to check the file extension and would return nothing as a result. This change worked and got the function working properly again. I made sure to commit this just in case, I messed up the function again in the future.&lt;/p&gt;

&lt;p&gt;The next tester I made was for my main program logic. This one was a little more complex for me, as I was initially stuck on how to use it and thought I had to make mock files and folders to get it work. However, it was simpler than I thought. Unittest has two functions that worked for my program, called &lt;a href="https://docs.python.org/3/library/unittest.html#unittest.TestCase.setUp"&gt;setUp&lt;/a&gt; and &lt;a href="https://docs.python.org/3/library/unittest.html#unittest.TestCase.tearDown"&gt;tearDown&lt;/a&gt;. &lt;code&gt;setUp&lt;/code&gt; is called before the test is executed and is meant to prepare the test call for the test function. &lt;code&gt;tearDown&lt;/code&gt; is called once the test ends and cleans up any files or folders that were made from the test. Using these two functions I was able to build this test to test the result of txt to html conversion;&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;file_processors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;text_to_html&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestTextToHtmlTxtConversion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&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;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Creating a temporary input file with some text content
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NamedTemporaryFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This is a test file.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_file&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="c1"&gt;# Creating a temporary output directory
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TemporaryDirectory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Defining the stylesheet, language, and sidebar
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stylesheet&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/water.css@2/out/water.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&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-CA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&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;def&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Deleting the temporary input file and output directory
&lt;/span&gt;        &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_file&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cleanup&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;test_text_to_html_txt_conversion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertRaises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;SystemExit&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;cm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Calling the text_to_html function and store the HTML content
&lt;/span&gt;            &lt;span class="n"&gt;html_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;text_to_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_file&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stylesheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dir&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&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="c1"&gt;# Defining the expected HTML content
&lt;/span&gt;            &lt;span class="n"&gt;expected_html_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;html lang=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;meta charset=&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="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;title&amp;gt;This is a test file&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;meta name=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;viewport&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; content=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;width=device-width, initial-scale=1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;link rel=&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="s"&gt; type=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; href=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stylesheet&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;p&amp;gt; This is a test file.&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# Check if the HTML content matches the expected HTML content
&lt;/span&gt;            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_html_content&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;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that in the &lt;code&gt;setUp&lt;/code&gt; function I prepare the variables and files that will be used in the &lt;code&gt;text_to_html&lt;/code&gt; function, and in &lt;code&gt;tearDown&lt;/code&gt; I make sure to remove the temp file and folder that were made in &lt;code&gt;setUp&lt;/code&gt;. Also, since I've created my program to exit with a code of 0 when successfully executed I had to wrap the entire test function in &lt;code&gt;with self.assertRaises(SystemExit) as cm:&lt;/code&gt;. This line can be used to determine when the code exits when an exception is raised or if it exits with a code. In this case, I wanted to make sure that the function exits with a code of 0. So after the function runs, I put this line &lt;code&gt;self.assertEqual(cm.exception.code, 0) right after the function to make sure it worked properly before comparing the return value with the&lt;/code&gt;expected_html_content` variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  What did I learn From Testing and What do I Think of it?
&lt;/h3&gt;

&lt;p&gt;Overall, since I have had no real testing experience, other than looking at testing code my professors would write for my class. I feel that I learned quite a bit from the testers I wrote. I learned how I could make temporary files and folders to work with the function I made. Which I could then use on any functions that handle file or folder input in any future Python applications I make. Additionally, I know how to test the return value of other functions that I make, whether they return a value or a bool. Based on this, I think that I would create testers for any projects I would make in the future, as while it was somewhat time consuming, I still enjoyed it as to me, it added another layer of confidence that the code was working.&lt;/p&gt;

&lt;p&gt;Well, that concludes today's post. Thank you all for reading and continuing to follow my journey through programming. I'll catch you in the next post!&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Picking out a Formatter and Linter for my Open Source Project</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Fri, 03 Nov 2023 01:13:37 +0000</pubDate>
      <link>https://dev.to/pasqua101/picking-out-a-formatter-and-linter-for-my-open-source-project-1gj2</link>
      <guid>https://dev.to/pasqua101/picking-out-a-formatter-and-linter-for-my-open-source-project-1gj2</guid>
      <description>&lt;p&gt;Hey everyone, I recently had the chance to install a linter and formatter for my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;TXT to HTML Converter&lt;/a&gt; program. For formatting I went with &lt;a href="https://pypi.org/project/black/"&gt;Black&lt;/a&gt; and for linting, I chose &lt;a href="https://docs.astral.sh/ruff/"&gt;Ruff&lt;/a&gt;. I'll talk about why I chose them, how they work, and what changes they made to my code below.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Black?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/black/"&gt;Black&lt;/a&gt; is a Python code formatter that will format your code on the fly to match the code style set by the developers. For example, if a line of code is too long, Black will split it up into 2 or more lines for readability. If there are several arguments in a function, Black will also split that up into 2 or more lines. I chose Black, as I liked its code style and the way I can configure it. It was also a project I stumbled across during &lt;a href="https://hacktoberfest.com/"&gt;Hacktoberfest&lt;/a&gt;, but since I never used the formatter before I didn't really know how it works so I wouldn't be able to contribute to issues as easily. So I figured I should learn it now, and maybe contribute to it in the future.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Ruff?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.astral.sh/ruff/"&gt;Ruff&lt;/a&gt; is both a formatter and linter written in Rust that promises to be faster than alternative Python linters out there. Now, you may be thinking to yourself, why not chose Ruff for both linting and formatting? It would make things much easier. Well, I mainly chose for Ruff to be just a linter, as like I said above, I wanted to learn how Black works and try to contribute to it in the future. I can also do the same with Ruff, if I learn how their linter works, I can technically learn how two open source projects work and try to contribute to them both. Additionally, Ruff provides the same method for configuration as Black, which is another benefit I'll talk about later.&lt;/p&gt;

&lt;h4&gt;
  
  
  How was Black and Ruff set up?
&lt;/h4&gt;

&lt;p&gt;Both Black and Ruff had very simple installation processes. I'll talk about how I set them up for Windows running PyCharm as my IDE.&lt;/p&gt;

&lt;h5&gt;
  
  
  Black:
&lt;/h5&gt;

&lt;p&gt;To install Black, all I had to was type &lt;code&gt;pip install black&lt;/code&gt; into my terminal. Black is designed to run on Python 3.8 or newer, and since I'm running my project with Python 3.11.4, it had no problem installing. What was nice about Black is that it worked straight after downloading, there was no setup involved. I could type &lt;code&gt;black  .&lt;/code&gt; into my terminal and have it format all of my Python files immediately. However, there were some files I did not want it to format, specifically a Python file I'm using for reading a Dictionary from for a sidebar feature I'm developing. So while I could run &lt;code&gt;black file1.py file2.py file3.py&lt;/code&gt;. I would rather configure it to ignore one file and format the rest with &lt;code&gt;black .&lt;/code&gt; instead. Here's how I did it. To &lt;a href="https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file"&gt;configure Black&lt;/a&gt; you have to create a pyproject.toml file. From there you have to specify the tool that reads configuration, and then tell the tool what to exclude by using regex. Like the example I made below&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="nn"&gt;[tool.black]&lt;/span&gt;

&lt;span class="py"&gt;extend-exclude&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'^/sidebar.py'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since I was using PyCharm as my IDE, Black added itself as a tool without me having to do anything. This gave me the option to configure my IDE to use Black when I save the file or reformat it, which I took advantage of. Since it saves me time from typing it into my terminal. To change the settings for Black on PyCharm, I had to go to &lt;code&gt;Preferences or Settings -&amp;gt; Tools -&amp;gt; Black&lt;/code&gt;. That's pretty much it for the set up process, it was quick and easy and Ruff was about the same.&lt;/p&gt;

&lt;h5&gt;
  
  
  Ruff:
&lt;/h5&gt;

&lt;p&gt;Setting up Ruff was roughly the same as Black. I had to paste this line of code &lt;code&gt;pip install ruff&lt;/code&gt; into PowerShell. Then once it installed I could use it without having to configure anything, which is something I appreciated. Before I got to using it, I had to configure it. Just like Black, Ruff also uses a pyproject.toml file for configuration. So I was able to use the same configuration file for Black with Ruff. All I had to do was specify that Ruff will be reading the information after a certain line. With the configuration I was able to tell Ruff what kind of code style it should look for, what warnings it should ignore and what to exclude from linting. You can see the configuration I used for Ruff below, which I was able to put right under the configuration for Black.&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="nn"&gt;[tool.ruff.lint]&lt;/span&gt;
&lt;span class="py"&gt;select&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c"&gt;# pycodestyle&lt;/span&gt;
  &lt;span class="s"&gt;"E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c"&gt;# Pyflakes&lt;/span&gt;
  &lt;span class="s"&gt;"F"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c"&gt;# pyupgrade&lt;/span&gt;
  &lt;span class="s"&gt;"UP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c"&gt;# flake8-bugbear&lt;/span&gt;
  &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c"&gt;# flake8-simplify&lt;/span&gt;
  &lt;span class="s"&gt;"SIM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c"&gt;# isort&lt;/span&gt;
  &lt;span class="s"&gt;"I"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c"&gt;# Asking ruff to ignore the number of characters per line. PyCharm IDE already takes care of it.&lt;/span&gt;
&lt;span class="py"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"E501"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c"&gt;#Exclude certain files and folders from linting&lt;/span&gt;
&lt;span class="py"&gt;exclude&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;".git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;".examples"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;".app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"sidebar.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"til"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;".ruff_cache"&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;Originally, I did not have the ignore there, but I'll talk about why I used it later. Unlike Black, Ruff was not already added as a tool to PyCharm. There is a way to add it as an &lt;a href="https://docs.astral.sh/ruff/integrations/#pycharm-external-tool"&gt;external tool&lt;/a&gt;, but it didn't work for me. Thankfully, there on Ruff's website they mentioned a member in the community who created a &lt;a href="https://plugins.jetbrains.com/plugin/20574-ruff"&gt;PyCharm plugin&lt;/a&gt; for Ruff and according to reviews they commonly updates it. So it was something I could rely on. Downloading the plugin was really simple, I just had to go to &lt;code&gt;Preferences or Settings -&amp;gt; Plugins&lt;/code&gt; and search for Ruff on PyCharm. I found it and download it to my IDE. Then to configure it I had to go to &lt;code&gt;Preferences or Settings -&amp;gt; Tools -&amp;gt; Ruff&lt;/code&gt;. Doing this greeted me to very similar option that Black had, I could run Ruff when I saved the file or reformatted it. Since I'm using Black for formatting, I made sure to configure the Ruff plugin to not be used when reformatting. If you did want to run Ruff on the terminal you could just type &lt;code&gt;ruff check .&lt;/code&gt; to lint all the files in the current directory. If Ruff finds any issues, you could have it attempt to fix them by using &lt;code&gt;ruff check . --fix&lt;/code&gt;. Ruff also has some &lt;a href="https://docs.astral.sh/ruff/linter/"&gt;other linting options&lt;/a&gt; you can use to help out. That was pretty much it.&lt;/p&gt;

&lt;h4&gt;
  
  
  What did Black and Ruff Find and Change in my Code and How Did I Use Them?
&lt;/h4&gt;

&lt;p&gt;Black:&lt;br&gt;
When I used Black, I first tried it out from by using this line of code &lt;code&gt;black  .&lt;/code&gt; on PowerShell, after I configured it to ignored one of my files. Black found out that a lot of my lines were too long for the Python standard. This is something that I kind of knew, since PyCharm makes highlights this issue for me. I mainly do on all my programming on a monitor that is connected to my laptop. So I tend to write longer lines of code. However, if I drag the IDE window to my laptop's display, it can be harder to read some of the lines of code. So, Black fixed that for me. I also noticed that with some lines where I do string concatenation Black split up each part of the string on separate lines. I didn't mind it, as it felt like my code looked a little neater and easier to read. The easy to read part is something I strive for with my code, so I was thankful for it. When I integrated Black into my IDE with the steps I mentioned above, I also tested it make sure it was working by handing it an unformatted line of code, which it fixed.&lt;/p&gt;

&lt;p&gt;Ruff:&lt;br&gt;
Just like Black, I used Ruff on PowerShell first with the command &lt;code&gt;ruff check .&lt;/code&gt; to lint my files, I of course did this after I configured Ruff. Ruff seemed to think that some of line of code and comments were still to long, which was something that PyCharm was also suggesting to me. Before I tried fixing it myself I did try to use &lt;code&gt;ruff check . --fix&lt;/code&gt;, and it was able to fix a handful of the 20+ problems it found. It was helpful, but I had to go fix some by hand, and thankfully my IDE provided me suggestions on how to change my lines of code, which I let it do for me. However, a lot of the lines seemed both fine to me and my IDE, which was when I configured Ruff to &lt;code&gt;ignore = ["E501"]&lt;/code&gt; (it's a rule that states how many characters long my lines should be). PyCharm already seems to handle part of this for me, and if I did want to check with Ruff I can always uncomment the line. One other issue, Ruff picked up was that I was importing everything (*) from my helper.py file into my file_processors.py file. I didn't really see an issue with this until I realized I had a function from helpers.py that was not used in the file_processors.py, that function being the one that handles sidebar creation. Realizing that I did not need to import a function that would not be used in file_processors.py I changed up my import for the helper.py file to import only the functions I need, which I then formatted with Black. I also tried out the Ruff extension on my code and it worked just fine.&lt;/p&gt;

&lt;h4&gt;
  
  
  What did I learn?
&lt;/h4&gt;

&lt;p&gt;Other than the fact that I got to learn how to use a very helpful formatter and linter, I also got to learn a little more about the proper way to style my code in Python since I feel like my code is now a look more easier to read and digest. Which should make future revisions easier not just for me, but anyone else modifying my code.&lt;/p&gt;

&lt;p&gt;That concludes this post. Thank you all for reading, and I hope you found my little setup tutorial helpful! Catch you in the next post!&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Summary of Hacktoberfest</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Tue, 31 Oct 2023 19:09:16 +0000</pubDate>
      <link>https://dev.to/pasqua101/summary-of-hacktoberfest-45ke</link>
      <guid>https://dev.to/pasqua101/summary-of-hacktoberfest-45ke</guid>
      <description>&lt;p&gt;Hi everyone, seeing as how today is the last day of Hacktoberfest I figured it would be appropriate to make a recap of my Hacktoberfest experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did I do During Hacktoberfest and How did I progress?
&lt;/h4&gt;

&lt;p&gt;During Hacktoberfest, I made four PRs to other repos. You can learn about them in the blog posts below, but I'll also summarize some of them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/pasqua101/first-pull-request-of-hacktoberfest-1c1j"&gt;First Pull Request of Hacktoberfest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/pasqua101/second-pr-of-hacktoberfest-5929"&gt;Second PR of Hacktoberfest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/pasqua101/third-hacktoberfest-pr-3978"&gt;Third Hacktoberfest PR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/pasqua101/last-pr-of-hacktoberfest-5dce"&gt;Last PR of Hacktoberfest&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before I started making my contributions, I had a hard time finding a repo to contribute to as I was coming across a lot of big repos that made me nervous to work on. I knew that I had to start off small and work my way up to make myself more comfortable. I first started off by updating the documentation on a repo to have a table of contents, which is my first post. The next contributions I made were enhancements to repos I found. These enhancements ranges from adding in new calculators to a project, as seen in my second and fourth blog post. To updating the logos used for X (formerly Twitter) that were used in the repo I selected for my third blog post.  &lt;/p&gt;

&lt;h4&gt;
  
  
  What did I learn?
&lt;/h4&gt;

&lt;p&gt;I learned a few things about Docker, which I had to use in my third contribution. I also learned that people in the open source community can be really friendly when assigning an issue to you and will offer to help you where they can. Since in my &lt;a href="https://github.com/seths10/Quotes-Generator/issues/188"&gt;third issue&lt;/a&gt;, I struggled with getting the logo to display in its respective colour for dark and light mode. The repo owner gave me some advice, but I decided to try something that I found online which managed to work for me and the owner. Going forward I know that I don't have to be so shy when it comes to working on other repos and solving their issues, since the owners are also in it to make sure that their project can be the best it can be.&lt;/p&gt;

&lt;p&gt;That concludes this blog post, once again thank you for reading this post and following my journey through Hacktoberfest. It means a lot and I'll catch you all in the next post.&lt;/p&gt;

</description>
      <category>hacktoberfest23</category>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Adding a Table of Contents Feature to my Project</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Mon, 30 Oct 2023 20:15:40 +0000</pubDate>
      <link>https://dev.to/pasqua101/adding-a-table-of-contents-feature-to-my-project-2973</link>
      <guid>https://dev.to/pasqua101/adding-a-table-of-contents-feature-to-my-project-2973</guid>
      <description>&lt;p&gt;Hi everyone, as mentioned in my &lt;a href="https://dev.to/pasqua101/learning-about-docusaurus-2fmo"&gt;last blog post&lt;/a&gt;. I mentioned that I wanted to add in a sidebar feature to my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;txt to html convertor&lt;/a&gt; project. Well, I did just that, the new feature is up and running in my program, and while it is still more in its prototype phase. It's still working. However, instead of a sidebar it's a table of contents, for now.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the Sidebar Feature?
&lt;/h3&gt;

&lt;p&gt;The sidebar feature in my program works very similarly to the same feature offered by Docusaurus. However, instead of generating a sidebar it just makes table of contents, as mentioned above. This works in my program, by reading the contents of a dictionary stored in a file called sidebar.py that exists within the root of the txt to html convertor's folder. The dictionary looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;table_of_contents&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TIL How to Get Command Line Arguments in Python&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TIL How to Get Command Line Arguments in Python.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TIL rmtree and os Library&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TIL rmtree and os Library.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 It works by taking in the URL or path of a file and writing that path to an HTML &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag while also giving it a label based on the user's choice. In this case, I chose to name it after the files I wanted to include in the table of contents. This feature basically aims to save the user some time from creating a table of contents, as for example if they wanted to process a folder made up of txt or md files, they can not only process them but also link them all together with the use of the sidebar feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  How did I Make it?
&lt;/h3&gt;

&lt;p&gt;To implement this feature, I first added in a new optional argument to be entered from the command line. This argument being &lt;code&gt;--sidebar&lt;/code&gt; and &lt;code&gt;-sb&lt;/code&gt;. When invoked, the user provides the path of their sidebar.py file (which is something that I don't want them to do. I just want them to be able to use the optional argument without having to provide the file path. So I would need to fix this in a future commit). After they provide the file, the program begins creation of the HTML file. But before that, it starts by processing the content from the dictionary in the sidebar.py file into a table of contents to be used in the body of the HTML file. I tested this out and found it was working, but noticed a issue existing in my code that I have found before. When processing a Markdown file with the bold (**) syntax, the code was supposed to convert the text in the syntax to the &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; HTML tag. However, this wasn't working anymore. So I left a comment for myself and created a new issue identifying which branches and issues to look at when I decide to tackle the bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  How did Docusaurus Inspire my Feature?
&lt;/h3&gt;

&lt;p&gt;When using Docusaurus, I liked the sidebar feature. As mentioned above, this feature is meant to be a little bit of the time saver for the user when generating a website with several pages. That's exactly how I saw this feature in Docusaurus, so that's the feature I wanted to implement in my project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison with Docusaurus' Sidebar and txt to HTML Convertor Sidebar
&lt;/h3&gt;

&lt;p&gt;There are some similarities and differences between my implementation of the sidebar and Docusaurus' version. Similarly with both implementations, they read a dictionary from a sidebar file and get the information from the dictionary by importing it to a function that handles the generation of the sidebar. They both rely on keys from the dictionary when creating certain parts of sidebar. The differences are, that at the moment my sidebar implementation only makes a table of contents, and I don't need a config file that requires the path of the sidebar file in order to generate it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Steps for the Feature
&lt;/h3&gt;

&lt;p&gt;As you might be able to tell, my next big step for the feature is to make an actual sidebar. I think I might be able to just use some CSS to get this done, but I may have to look into it more as web development is not my strong suit, so I could be underestimating this. If you're good with web development and might have an idea of how I can implement this idea, feel free to leave a comment on the &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter/issues/22"&gt;issue&lt;/a&gt; I made for it. There is one other thing I want to figure out. I mentioned earlier that when using the sidebar argument I don't want the code to require a file path input from the user. Since right now I have the code hardcoded to read the dictionary from the sidebar file, and I think that it's fine to read it like that. I might just leave this problem on the backburner for now as I just see the problem as more of a minor inconvenience to the user. So my main next step to tackle to creating an actual sidebar.&lt;/p&gt;

&lt;p&gt;That about sums up my feature and what I plan to do improve it in the future. As always, thank you for reading and I'll catch you in the next post.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Learning About Docusaurus</title>
      <dc:creator>Marco Pasqua</dc:creator>
      <pubDate>Mon, 30 Oct 2023 15:47:06 +0000</pubDate>
      <link>https://dev.to/pasqua101/learning-about-docusaurus-2fmo</link>
      <guid>https://dev.to/pasqua101/learning-about-docusaurus-2fmo</guid>
      <description>&lt;p&gt;Hi everyone, today I'm going to be talking about Docusaurus. Docusaurus is an open source project backed by Meta, which allows developers to build a documentation website, portfolio or blog website entirely from Markdown and/or React JS. It can be really handy for those who aren't fans of web development (like me), or those who just want to push out a quick and simple website. There are several other features that it provides, but I'll be talking about one of those features that I would like to implement in my &lt;a href="https://github.com/Pasqua101/txt-to-HTML-converter"&gt;txt to html convertor&lt;/a&gt; project and how I tried to examine the code implementation of the feature on Docusaurus.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's the Feature I want to Implement?
&lt;/h4&gt;

&lt;p&gt;Docusaurus has the ability to generate a sidebar for your site, which can act like a table of contents to help the user navigate through the pages of your site. To create a sidebar with Docusaurus you must make sidebars.js file in the root of your website folder. In the sidebars.js file, you must make a dictionary that links to the pages of your website. Docusaurus makes one by default, however you can also make your own or remove it if you'd like. To make you own, you can do something like this;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sidebars = {
  tutorialSidebar: [
    'intro',
    {
      type: 'category',
      label: 'Getting Started',
      items: ['tutorial-basics/create-a-document', 'tutorial-basics/create-a-blog-post'],
    },
    'hello',
    'tutorial-basics/create-a-page'
  ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Words in the dictionary like intro and hello link to Markdown files in the root of the docs folder. Doing something like 'tutorial-basics/create-a-page' also links a file that is in the docs directory, but gets the file from the tutorial-basics directory that is within the docs directory. You can also make a nested part of the side bar with the&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
      type: 'category',
      label: 'Getting Started',
      items: ['tutorial-basics/create-a-document', 'tutorial-basics/create-a-blog-post'],
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 part. You can assign a &lt;code&gt;label&lt;/code&gt; like "Getting Started" and then inside of the label, you can have several different links to other pages within the &lt;code&gt;items&lt;/code&gt; tag. I also forgot to mention, that in the markdown files, you can assign a position of the file to the sidebar. For example, in my intro.md file I could do something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;sidebar_position&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 to say that I want this file to appear first in the sidebar. If I wanted to change the position, I can give it a value of 2 or more.&lt;/p&gt;

&lt;h4&gt;
  
  
  Strategies used to Find the Official Implementation
&lt;/h4&gt;

&lt;p&gt;With that out of the way, we can get to the strategies I used to try to find the official implementation of the feature. I did a couple of ideas on how the developers could have made it, based on the sidebars.js file that needs to be created. But they were more of vague ideas and I needed a better idea of what was done. I used a few strategies, so I'll list them out below.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I first tried using git grep on my repo to try to find any sign of how sidebars are handled within the files of the website. I found out that the sidebar file must be mentioned in the docusaurus.config.js file, this was a good start. Since I then followed the &lt;code&gt;sidebarPath&lt;/code&gt; key from the dictionary which brought me to a new file called &lt;code&gt;plugin-content-docs.js&lt;/code&gt;. The file contained a lot about side bars, so I search the file for instances of where the word "sidebar" is mentioned and found a function called SidebarItemsGeneratorOption that links to a file called types in a sidebars folder. This was a good I was able to find what might be the folder containing most of the sidebar logic. I followed the path to the folder that Visual Studio provided. I ended up finding a file called generator.ts which included a generateSidebar function. Reading through the file was a little confusing for me (since JavaScript isn't my strong suit), but from my understanding the way the sidebar is generated is split into 4 steps based on comments provided by the developers;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Step 1: The code extracts docs in the autogenerated directory.&lt;/li&gt;
&lt;li&gt;Step 2: The code then turns the extracted files into a tree structure.&lt;/li&gt;
&lt;li&gt;Step 3: The code then recursively transforms the tree to sidebar items, which is where the generateSidebar function comes in. It looks like the function handles the naming of the items in the sidebar, the creation of the category and assigning a position and id.&lt;/li&gt;
&lt;li&gt;Step 4: The code finally recursively sorts through the categories/docs and removed the position attribute from the final output, as it is only used for the sorting. It then returns the generated and sorted sidebar to be displayed.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I also tried to use GitHub's code search feature, but perhaps I was using it incorrectly, as searching for the feature implementation only brought me to other people's websites on my first search. I did one more search, which was this time formatted to look specifically at repos owned by Meta that include the works "Docusaurus" and "sidebars" which brought me to the code I found with git grep in my first step. So I basically found the same thing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I finally used ChatGPT to try to help me. I already had the idea that everything relevant to the sidebar was being handled in the sidebar folder, so I can always look there for help. But I did kind of want a simplified idea and I could also use it in case I needed an explanation of the code written by the developers. The simplified idea was more of just making a basic table of contents, since that's basically what the sidebar is, I could maybe make the actually sidebar with some CSS. It helped me refine the idea of making an optional argument for a table of contents (sidebar) that takes in an additional python file that includes a dictionary keys and values that link to other pages in the website.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Based off of the 3 methods that I used to help me understand the way sidebars are handled. Using git grep probably helped me the most, as I was able to find out how the feature is implemented. It also helped a little with figuring out how to make proper comments.  Most of the variables and functions names are somewhat self explanatory, but the comments left within the files mainly provide a walk through of everything that was done, while also explaining what values certain variables contain. I already do the latter, but not the former when I make comments. I find that I make too many comments some times, as I find myself occasionally making comments on most variables names. However, making comments in a walkthrough type of way can be very helpful to me and the person reading my code. ChatGPT also helped me, as I used it to help simplify some of the ideas I had in my head for the implementation. Although, I can also use it for explaining the dev's code, which may prove useful in the future when I work on the feature.&lt;/p&gt;

&lt;p&gt;That's it for now. Thank you all for reading! I'm going to get to work and see if I can make a prototype for a table of contents to be generated in my project.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
