<?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: Gavi Schneider</title>
    <description>The latest articles on DEV Community by Gavi Schneider (@gschnei).</description>
    <link>https://dev.to/gschnei</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%2F354342%2Ff95b24f1-a4ca-4fdc-8cad-3957792a0097.jpg</url>
      <title>DEV Community: Gavi Schneider</title>
      <link>https://dev.to/gschnei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gschnei"/>
    <language>en</language>
    <item>
      <title>IsraBrew: A Craft Beer Scraper</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Wed, 24 Feb 2021 09:01:33 +0000</pubDate>
      <link>https://dev.to/gschnei/israbrew-a-craft-beer-scraper-5d4l</link>
      <guid>https://dev.to/gschnei/israbrew-a-craft-beer-scraper-5d4l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CjysNp5Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AEBylAzIHFWd1RWjR9_uh6Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CjysNp5Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AEBylAzIHFWd1RWjR9_uh6Q.png" alt="" width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We may be small in size geographically, but the craft beer scene in Israel is booming. New beers are appearing on shelves on a weekly (if not daily) basis, and I’m not just talking about beers brewed locally. New beers from countries all over the world, some of them landing in Israel for the very first time are also popping up left and right. Last month (January ’21) was a particularly historic time for Israeli craft beer enthusiasts, with over 15 new beers from &lt;a href="https://www.brewdog.com/uk/"&gt;BrewDog&lt;/a&gt; (and their experimental brewery, &lt;a href="https://www.brewdog.com/uk/locations/brewery/overworks"&gt;OverWorks&lt;/a&gt;) making their debut appearance in Israeli stores all on the same day.&lt;/p&gt;

&lt;p&gt;As someone who likes to stay up to date with all the latest beers making their way to our country, I was looking for a way to see everything that’s available from all the different stores and suppliers in one place. I could have just visited every store’s website and scrolled through their inventory, but I’d essentially be doing the same thing over and over again, only on different sites (assuming I even know where to look — something that might pose as a challenge to new Israeli beer enthusiasts).&lt;/p&gt;

&lt;p&gt;When you want repeat some process over and over again, automation is your best friend. Specifically, in my case I turned to automating a web scraper. By writing a program that would visit all the websites for me, pull in their inventories and aggregate them into one location I wouldn’t need to bounce from site to site to know what beers are currently available.&lt;/p&gt;

&lt;p&gt;This is how IsraBrew was born: The need for a website to view what craft beers are currently available from all the major Israeli suppliers. If you’re as obsessive as me and want to try every beer that you can get your hands on, you’re going to love this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HZNfCYPE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/892/1%2AgEhRyF7fMZD8LV_lINQlGQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HZNfCYPE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/892/1%2AgEhRyF7fMZD8LV_lINQlGQ.png" alt="" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The IsraBrew project is made up of four main components:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Web Scraper: The app that visits the websites and populates the database.
&lt;/li&gt;
&lt;li&gt;The API: Responds to requests with beers it retrieves from the database.
&lt;/li&gt;
&lt;li&gt;The Client: Web interface to view the beers.
&lt;/li&gt;
&lt;li&gt;Deployment: Infrastructure and services that aided in deploying the app.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Web Scraper
&lt;/h4&gt;

&lt;p&gt;Although I really like using &lt;a href="https://developers.google.com/web/tools/puppeteer"&gt;Puppeteer&lt;/a&gt; when building projects that utilize web scraping in JavaScript / Node.js, I decided that this time I’d go with Python for my web scraping needs. Selenium would have been an obvious choice, and I’ve even used it previously in both Python and Java, however I decided to go with &lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/"&gt;Beautiful Soup&lt;/a&gt; — its simplicity and speed (relative to Selenium) were what won me over. I was looking to build a lightweight scraper that I could deploy on a server and run a few times a day, and Beautiful Soup did that perfectly. Well, almost perfectly, there was one thing it couldn’t do: scrape content that was generated via JavaScript after the page loaded. This initially became a problem, as a few of the suppliers used JS to load their content. After countless Stack Overflow and Reddit threads, I finally discovered &lt;a href="https://github.com/Nykakin/chompjs"&gt;ChompJS&lt;/a&gt;, which solved this exact problem.&lt;/p&gt;

&lt;p&gt;With ChompJS, I was able to target script tags in the DOM and get the content that they would eventually produce. Problem solved. Using both Beautiful Soup and ChompJS, I was able to scrape all the desired websites without actually having to open a browser (headless or otherwise).&lt;/p&gt;

&lt;p&gt;Once scraped, the beers were then stored in an in-memory SQLite database. &lt;a href="https://gavischneider.medium.com/watchlist-your-new-movie-tracker-48ef05abed4b"&gt;Last time&lt;/a&gt; I had worked with a Flask backend I wrote out all the SQL commands inside of my Python code, but this time I decided to use the &lt;a href="https://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt; ORM package, which allowed me to do CRUD operations in Python without any need for raw SQL.&lt;/p&gt;

&lt;p&gt;The web scraper is deployed with the Flask server and is scheduled to run multiple times throughout the day, so whenever you’re browsing the site the products will be up to date.&lt;/p&gt;

&lt;h4&gt;
  
  
  API
&lt;/h4&gt;

&lt;p&gt;This part turned out to be the shortest and easiest to implement. I created a barebones Flask server that had a ‘/beers’ route and would retrieve beers from the database and send them to the requesting client. In my opinion, Flask’s simplicity is both it’s strength and it’s weakness — for smaller projects that require a web server, Flask is super easy to get started with and very easy to understand. For larger projects however, its lack of structure may cause uncertainty and confusion when choosing how to properly build out your application (similar to Express in the Node.js ecosystem, it’s not very opinionated, leaving the developer with many decisions to be made). I personally prefer using Django when building larger web applications with Python, but for this particular project Django seemed like overkill.&lt;/p&gt;

&lt;h4&gt;
  
  
  Client
&lt;/h4&gt;

&lt;p&gt;A simple Frontend built with my usual stack: React, TypeScript and TailwindCSS. I discovered &lt;a href="http://reactcommunity.org/react-tabs/"&gt;this&lt;/a&gt; NPM package which made implementing different tabs for different suppliers super easy. You all know about React, I’m not going to go into much detail here. What I will say is — if you’re using React but not using &lt;a href="https://tailwindcss.com/"&gt;Tailwind&lt;/a&gt; to style your components, you should be. I still use old school CSS (or SASS) for specific things, but for me Tailwind has become almost as invaluable as React — If I’m building a React project, I’ll be styling it with TailwindCSS.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deployment
&lt;/h4&gt;

&lt;p&gt;If you’re even remotely interested in the Flask world, you’ve probably heard of &lt;a href="https://blog.miguelgrinberg.com/index"&gt;Miguel Grinberg&lt;/a&gt;, who’s books I consider to be our Flask Bible. His blog is just as informative, and I found &lt;a href="https://blog.miguelgrinberg.com/post/how-to-deploy-a-react--flask-project"&gt;this&lt;/a&gt; article that really helped me understand how to properly deploy a Flask project on a server.&lt;/p&gt;

&lt;p&gt;Essentially, Nginx is what holds everything together: It proxies all traffic starting with ‘/api’ to the backend (which is running on a Gunicorn server), and everything else to the React frontend. Not only does Nginx make this really easy to set up, but because my frontend and backend are deployed on the same machine, I never had to deal with any CORS issues in this project, which was… new. The server itself is a DigitalOcean Droplet, which are super easy to deploy and configure.&lt;/p&gt;

&lt;p&gt;Serving my app over HTTPS turned out be a breeze thanks to Cloudflare. I’m not entirely sure how they’re staying business with their ridiculously good free tier, but I’m very thankful for it.&lt;/p&gt;

&lt;p&gt;One feature that I really wanted to add was search — the ability to search for a specific beer and have results from all the different suppliers appear. Unfortunately, there was a slight language barrier — some of the suppliers named their beers in English while some named them in Hebrew. It’s possible that three suppliers are all carrying the same beer, but if two of them are named in Hebrew and you searched in English, you’d only get one result. I can implement the search with both English and Hebrew options and make it clear that searching in a certain language will only yield partial results, but I’d really like to find a way to overcome the language obstacle so that I can implement a proper search bar that can really show you all your different options when searching for a particular beer.&lt;/p&gt;

&lt;p&gt;If you’re into programming, you can check out the repo &lt;a href="https://github.com/gavischneider/israbrew"&gt;here&lt;/a&gt;. If you’re in Israel and looking for some good beer, you can check out IsraBrew &lt;a href="https://israbrew.ml/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cheers 🍻&lt;/p&gt;

</description>
      <category>flask</category>
      <category>react</category>
      <category>craftbeer</category>
      <category>python</category>
    </item>
    <item>
      <title>bandDotRand: A Random Artist Generator</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Mon, 07 Dec 2020 10:38:28 +0000</pubDate>
      <link>https://dev.to/gschnei/banddotrand-a-random-artist-generator-281k</link>
      <guid>https://dev.to/gschnei/banddotrand-a-random-artist-generator-281k</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m8mTG2FC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/943/1%2ABATSey_O6vjMgMaRC5DO6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m8mTG2FC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/943/1%2ABATSey_O6vjMgMaRC5DO6A.png" alt="" width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After completing my &lt;a href="https://medium.com/@gavischneider/my-capstone-project-for-udacitys-cloud-devops-engineer-nanodegree-b83c4e733cd5"&gt;DevOps project&lt;/a&gt; last month, I wanted to take the app I had built and turn it into something more permanent, something with a graphical user interface that could be used outside of the terminal. I had built the app for my capstone project, but there the main focus was on the infrastructure, not on the app itself. I quickly created a program that exposed an API endpoint and returned a random song when it received a request. The song was generated through the Musixmatch API, and would include basic song properties, such as the song ID, name, album, artist, etc.&lt;/p&gt;

&lt;p&gt;Instead of getting a random song, my new idea was to create an app that would get a random artist and display it alongside the artists discography and related artists. Every artist or album on the page would include a link to that artist / album on a music streaming service, so you could actually listen to anything you found interesting. Refreshing the page (or clicking on the next button) would load another artist, so the website could be used as a random artist generator.&lt;/p&gt;

&lt;p&gt;After initially building out a prototype for the website that would eventually become bandDotRand, I realized that the Musixmatch API wasn’t going to cut it, and I had to find a music API that would better suit my needs. Spotify was my next choice, and after diving into their API documentation, it seemed like the right choice. The one thing Spotify didn’t have was an API endpoint to access a random artist, but after reading &lt;a href="https://medium.com/@perryjanssen/getting-random-tracks-using-the-spotify-api-61889b0c0c27"&gt;this&lt;/a&gt; article on how to get random tracks using the Spotify API, I realized I could do something similar in order to get a random artist. Once I had my random artist, I’d need to make one more API call to get the artist’s albums, and then I’d be set.&lt;/p&gt;

&lt;p&gt;I had the artist data, now all that was left to do was to create a frontend that would display all that data nicely. I created all the React components that I needed, added some styles and tied it all together.&lt;/p&gt;

&lt;p&gt;Lastly, I deployed the app on Heroku. Getting the frontend to communicate with the backend turned out to be way more time consuming than I thought it would be (I swear it ran on my machine), but in the end it ran just fine. “In the end”, meaning seven hours of debugging later, but nonetheless, the app is deployed.&lt;/p&gt;

&lt;p&gt;The website is built with React on the frontend, and Node.js with Express on the backend. Both frontend and back are written in TypeScript — after watching some Pluralsight courses on the topic, I was looking for an excuse to try it out. Turns out if you’re coming from a C/C++ (or any statically typed language) background, it really isn’t that difficult to transition to from JavaScript.&lt;/p&gt;

&lt;p&gt;All of the styling was done with TailwindCSS, which is my new favorite utility-class library. The combination of React components and utility-class styling makes building reusable components that look good really simple.&lt;/p&gt;

&lt;p&gt;Looking ahead, I’d love to be able to integrate other streaming service API’s so that the user can be redirected to the service of their choice, instead of just Spotify. I’d have to figure out a way to match the artist on multiple platforms, like taking an artist I received from the Spotify API and finding it’s counterpart on Apple Music or Tidal. Getting the artists website and social accounts would also make a great addition, giving you more access to that new favorite (or not so favorite) band you just discovered.&lt;/p&gt;

&lt;p&gt;You can try out bandDotRand &lt;a href="https://band-dot-rand.herokuapp.com/"&gt;here&lt;/a&gt;. Let &lt;a href="https://twitter.com/gschnei"&gt;me&lt;/a&gt; know what you think, and tell me which new bands you’ve discovered.&lt;/p&gt;

</description>
      <category>express</category>
      <category>react</category>
      <category>music</category>
      <category>node</category>
    </item>
    <item>
      <title>My Capstone Project for Udacity’s Cloud DevOps Engineer Nanodegree</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Thu, 12 Nov 2020 14:10:06 +0000</pubDate>
      <link>https://dev.to/gschnei/my-capstone-project-for-udacity-s-cloud-devops-engineer-nanodegree-58o2</link>
      <guid>https://dev.to/gschnei/my-capstone-project-for-udacity-s-cloud-devops-engineer-nanodegree-58o2</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F500%2F1%2AcAB3Zkg7VhhbeF90NaO7RQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F500%2F1%2AcAB3Zkg7VhhbeF90NaO7RQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After three months of various DevOps related courses and smaller projects, I had reached the end of my Nanodegree, and it was time to build out my capstone project.&lt;/p&gt;

&lt;p&gt;My project can be broken down into two parts: the application itself, and the infrastructure that deploys and hosts it.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Application: Random Song
&lt;/h4&gt;

&lt;p&gt;Random Song is a simple web app built using TypeScript, Node.js and Express. It serves as a web service that can send you a random song, using the Musixmatch API. To test out the app, simply go to the /random route, and you'll receive a random song object in JSON.&lt;/p&gt;

&lt;p&gt;Going to the / route will return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to my capstone project! To get a random song, go to the '/random' route.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And going to the /random route will return a random song:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  track_id: 160557034,
  track_name: 'Get Up and Fight',
  track_name_translation_list: [],
  track_rating: 26,
  commontrack_id: 86880624,
  instrumental: 0,
  explicit: 0,
  has_lyrics: 1,
  has_subtitles: 1,
  has_richsync: 1,
  num_favourite: 62,
  album_id: 30545841,
  album_name: 'Simulation Theory (Super Deluxe)',
  artist_id: 1248,
  artist_name: 'Muse',
  track_share_url: 'https://www.musixmatch.com/lyrics/Muse/Get-Up-and-Fight?utm_source=application&amp;amp;utm_campaign=api&amp;amp;utm_medium=Student+Developer%3A1409620630471',
  track_edit_url: 'https://www.musixmatch.com/lyrics/Muse/Get-Up-and-Fight/edit?utm_source=application&amp;amp;utm_campaign=api&amp;amp;utm_medium=Student+Developer%3A1409620630471',
  restricted: 0,
  updated_time: '2020-05-19T15:42:03Z',
  primary_genres: { music_genre_list: [[Object], [Object] ] }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The Infrastructure
&lt;/h4&gt;

&lt;p&gt;After the application was built, the next task was deploying it. In this project I decided to go with a Rolling Deployment. My goal was to write out the necessary configuration files and required build commands, and then create a pipeline to automate the process of actually building the application and deploying the infrastructure. This way, it could be executed in the exact same manner every time I added new code or infrastructure to the project. I needed a server to host Jenkins, my CI/CD technology of choice for this project. After provisioning an AWS EC2 instance and installing Jenkins, it was time to start defining the tasks that I’d want Jenkins to run. After accessing my application’s code, here are the tasks that I created for Jenkins to run:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Node dependencies
Simply running npm install would do the trick.&lt;/li&gt;
&lt;li&gt;Build the application
My application is written in TypeScript, so I needed to run npm run build to build out the JavaScript distribution folder.&lt;/li&gt;
&lt;li&gt;Lint the code
Running npm run lint to make sure everything is up to tslint's standards.&lt;/li&gt;
&lt;li&gt;Build the Docker image
Here Jenkins would build a Docker container based on the Dockerfile that I created. It was based off a simple Node image, and would copy my application code into the container and start it.&lt;/li&gt;
&lt;li&gt;Upload the container to Docker Registry
After being containerized, my application would then be uploaded to the Docker Registry for further availability.&lt;/li&gt;
&lt;li&gt;Create the Kubernetes configuration file
Here I needed to create a Kubernetes deployment file that would be used in the next step to actually deploy my application into a cluster. I used Kubernetes via AWS EKS.&lt;/li&gt;
&lt;li&gt;Deploy application
With the help of my Kubernetes deployment file and my Docker container that I uploaded to the registry, I was now able to deploy my application to my AWS EKS cluster. I also ran a kubectl get pods and kubectl get services to make sure everything was running as expected.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the end, the app is deployed to the cluster and accessible to users. Random songs for days.&lt;/p&gt;

&lt;p&gt;Unfortunately, the app is not currently deployed due to EKS not being a cheap service for a student to continuously pay for. However, I’m planning on taking the Random Song application and turning it into something that will be more permanently hosted in a future project. As far as the infrastructure goes, these are also things that can be repurposed in future projects — Docker containers, Kubernetes clusters and Jenkins pipelines are tools that can help build any software related project.&lt;/p&gt;

&lt;p&gt;If you’d like to see the code, you can take a look at the project’s repo on &lt;a href="https://github.com/gavischneider/cloud-devops-engineer-nanodegree-capstone-project" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>jenkins</category>
      <category>docker</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Watchlist: Your New Movie Tracker</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Thu, 02 Jul 2020 14:20:16 +0000</pubDate>
      <link>https://dev.to/gschnei/watchlist-your-new-movie-tracker-1374</link>
      <guid>https://dev.to/gschnei/watchlist-your-new-movie-tracker-1374</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVbv2JJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/420/1%2AsxqkE11Immf-cdAkLSUyUA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVbv2JJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/420/1%2AsxqkE11Immf-cdAkLSUyUA.png" alt="" width="420" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Watchlist is my final project for CS50’s Introduction to Computer Science, by Harvard University.&lt;/p&gt;

&lt;p&gt;Watchlist is your new to-do list for movies. Instead of trying to remember what movies you’d like to watch, just add them to Watchlist, where you can view them anywhere with an internet connection.&lt;/p&gt;

&lt;p&gt;Watchlist is super simple: register, and you’ll be taken to your watchlist, which will initially be empty. Click on the ‘Add’ button in the navbar to start adding movies. Type in the movie you’d like to search for, and it will be added to your list.&lt;/p&gt;

&lt;p&gt;Can’t remember the name of that movie you wanted to watch? Just log into Watchlist!&lt;/p&gt;

&lt;p&gt;Finally got around to watching that movie? Click the button at the end of the movie’s row to delete it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watchlist was built with the following technologies:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Bootstrap&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Flask&lt;/li&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Watchlist’s movie data is from iTunes via their API, which technically means that a movie has to be on iTunes in order to add it to your Watchlist. As of April 2020, there are 65,000 movies in the iTunes store, so hopefully you won’t feel too limited when searching.&lt;/p&gt;

&lt;p&gt;Lastly, I’d like to thank the CS50 staff who have put together a tremendous course. I took an Intro to Computer Science course in college over two years ago, yet by the end of this course I realized I had learnt so many new things that I hadn’t previously learned in my CS degree. I’m looking forward to taking my next CS50 course.&lt;/p&gt;

&lt;p&gt;You can check out Watchlist here: &lt;a href="https://gavischneider.pythonanywhere.com/login"&gt;https://gavischneider.pythonanywhere.com/login&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>watchlist</category>
      <category>cs50</category>
      <category>html</category>
    </item>
    <item>
      <title>Full Stack Certification</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Sat, 06 Jun 2020 22:38:37 +0000</pubDate>
      <link>https://dev.to/gschnei/full-stack-certification-4agf</link>
      <guid>https://dev.to/gschnei/full-stack-certification-4agf</guid>
      <description>&lt;p&gt;Super proud of this one. Today I finished FreeCodeCamp's curriculum and earned the Full Stack Developer certificate. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freecodecamp.org/certification/gavischneider/full-stack"&gt;https://www.freecodecamp.org/certification/gavischneider/full-stack&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>freecodecamp</category>
      <category>webdev</category>
      <category>fullstack</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Music Genres: My Second NPM Package</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Sat, 23 May 2020 18:53:49 +0000</pubDate>
      <link>https://dev.to/gschnei/music-genres-my-second-npm-package-3bh</link>
      <guid>https://dev.to/gschnei/music-genres-my-second-npm-package-3bh</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LFjA8jU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AgLBig78AOTrgfu3uxwX3kQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LFjA8jU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AgLBig78AOTrgfu3uxwX3kQ.png" alt="" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you haven’t already noticed, I love music. Not the way everyone says they do, I &lt;strong&gt;actually&lt;/strong&gt; love it. So after yesterdays SLAAAYER rush, I quickly dove into my next music-related NPM project: Music Genres.&lt;/p&gt;

&lt;p&gt;The package is simple: install and require it, and then you’ll have access to three functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;getAllGenres()&lt;/li&gt;
&lt;li&gt;getRandomGenre()&lt;/li&gt;
&lt;li&gt;getRandomSubgenre()&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first will return all the stored genres and sub-genres (of which there are currently 13 and 222, respectively) in a JavaScript Object. The second will Return a random genre, an array holding sub-genres. Lastly, the third will return a random sub-genre, which is a string.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;musicGenres&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;music-genres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;musicGenres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAllGenres&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Returns all genres - an object holding genres&lt;/span&gt;

&lt;span class="nx"&gt;musicGenres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomGenre&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Returns random genre - an array holding sub-genres&lt;/span&gt;

&lt;span class="nx"&gt;musicGenres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomSubgenre&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Returns random sub-genre - a string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can install the package here: &lt;a href="https://www.npmjs.com/package/music-genres"&gt;https://www.npmjs.com/package/music-genres&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d love any and all feedback. Say hi on twitter &lt;a href="https://twitter.com/gschnei"&gt;@gschnei&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>music</category>
      <category>javascript</category>
      <category>npm</category>
    </item>
    <item>
      <title>My Very First NPM Package: SLAAAYER!</title>
      <dc:creator>Gavi Schneider</dc:creator>
      <pubDate>Fri, 22 May 2020 19:10:04 +0000</pubDate>
      <link>https://dev.to/gschnei/my-very-first-npm-package-slaaayer-7j9</link>
      <guid>https://dev.to/gschnei/my-very-first-npm-package-slaaayer-7j9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on my &lt;a href="https://medium.com/@gavischneider/my-very-first-npm-package-slaaayer-5d829342c613"&gt;blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No, it doesn’t do much, as you probably guessed from the name. But it’s my first NPM package, and it works. A tiny piece of software that has my name on it. That’s good enough for me.&lt;/p&gt;

&lt;p&gt;The package is simple: add it to your dependencies, require and name it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;slaaayer&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The name of the variable doesn’t actually have to be slayer, name it whatever you’d like.&lt;/p&gt;

&lt;p&gt;Once you’ve done that, call slayer and pass it a number. The result is “SLAAAYER! 🤘🏻”, where the number you pass the function is the number of “A”s in the word slayer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;slayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will log: SLAAAAAAAAAAYER! 🤘🏻&lt;/p&gt;

&lt;p&gt;You can install the package here: &lt;a href="https://www.npmjs.com/package/slaaayer"&gt;https://www.npmjs.com/package/slaaayer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for future NPM packages. I think Cannibal Corpse has a good ring to it…&lt;/p&gt;

</description>
      <category>npm</category>
      <category>javascript</category>
      <category>node</category>
      <category>slayer</category>
    </item>
  </channel>
</rss>
