(Cover Image: The 'drum kit' I created for the first project in the 'JavaScript30' course)
I'm thrilled to participate in Women Who Code's '100 Days of Code Challenge'. I've wanted to get more involved with Women Who Code for a while now (I've attended a few workshops in the past, which have all been wonderful), and so far, this challenge has been a great way to connect with a fantastic community while getting some much-needed practice with a) consistently coding every day and b) talking about what I'm working on (which I'll put into practice here now!).
I picked up much of what I've learned so far about programming over 15 weeks in Flatiron School's Full-Stack Software Engineering bootcamp (which I started a year ago, a fact that boggles my mind). I learned a lot very quickly, but because of the fast pace of the program, there wasn't much time for me to reflect and go deeper to make sure I really understood the fundamentals. Remedying that will be my main area of focus over the next 100 days.
What I've Worked On This Week
Quick Links
- JavaScript—JavaScript30 Project #1: Drum Kit
- Python—GMail Web Scraping Tool
- Python—'Days of Code' Challenge
- Linux Command Line—OverTheWire's 'Bandit'
- React Native—Random Acts of Kindness App
JavaScript—JavaScript30 Project #1: Drum Kit
The WWCode Front End track is working through Wes Bos's free 'JavaScript30' course, which aims to strengthen programmers' vanilla JavaScript skills through 30 projects. I spent time last week tackling the first project in the course, a JavaScript drum kit!
This was an entertaining exercise that got me reacquainted with event listeners and query selectors in JavaScript and introduced me to working with embedded audio. I've provided a detailed explanation of the approach I took to solve this exercise alongside my code on GitHub.
As a bonus exercise, I also added functionality for playing the sounds and animations when the on-screen buttons are clicked (as opposed to pressed on the keyboard). The biggest challenge with the click event was figuring out how to grab the parent .key
<div>
even when one of its children (<kbd>
, <span>
) got clicked. I added some logic to check whether event.target
was one of the child nodes and grab the parentElement
value instead.
I'll be coming back to this project because another feature I'd like to add some time in the future is a built-in metronome (every musician's friend)!
Python
GMail Web Scraping Tool
I've been on the post-bootcamp job search for several months now. One thing that would make my life ever-so-slightly easier is if there was a way to compile all the job leads I get emailed from LinkedIn and Indeed together in one place that is not my email (competing for attention among all the spammy promotional emails that crowd into my inbox all day, every day).
I figured I could:
- set up filters to forward job alert emails into one folder
- write an automation that extracts relevant information (i.e., job title, location, link to posting) from the body of each email
- deposit those results into a lovely, distraction-free spreadsheet (I <3 spreadsheets)
Perhaps there are services already established that could do something like this in my GMail inbox (for a fee), but I've wanted to get some experience with web scraping, automation, and Google's APIs, so I figured, "Why not build something myself for fun?" (It's definitely not a way to procrastinate on sending out more job applications.)
I'll probably expand more on this project in a future blog post, but so far, here are some new things I've learned:
- Google has documentation and 'getting started' resources for the GMail API, but the sample script implemented in their 'Python Quickstart' guide is using syntax that is documented separately in the Google API Python Client docs and GMail API docs.
- Email messages are stored as binary data (base64) and need to be decoded into a human-readable format (ASCII) before we can parse them with web-scraping libraries like
BeautifulSoup
. Python has a built-in base64 library for this purpose. - Messages have multiple parts arranged in a tree (similar to the DOM in the browser), and these parts have different formats (one branch is for plain text; another is for HTML; there are others associated with various attachment types). I need to do more reading into Multipurpose Internet Mail Extensions (MIME) for a better understanding of how this works.
Other than that, I've done a lot of debugging with ipdb
to zero in on key HTML structures in each email that I could incorporate into a scraping script.
'Days of Code' Python Challenge
I've also been participating in the WWCode Python track's ongoing Python 'Days of Code' challenge, with a new prompt posted daily. I've been posting code and commentary on the approach I took and what I learned along the way in this GitHub repository: WWCode-Python-DaysOfCode-2024
Beyond solving the challenges at a basic level and then adapting my code to various use cases and edge cases, I've also been using this challenge as an opportunity to get some practice with writing unit tests (using Pytest), applying concepts I learned in the Introduction to Test and Behavior Driven Development course I took last year.
Something that has struck me throughout this first week of challenges is how a seemingly straightforward task can quickly become more complex once you start thinking about other ways people might use the program or the errors that could arise.
For example, the day four prompt, Write a program to find the sum of all elements in a list
, was relatively straightforward to implement, assuming a smaller list comprised only of integers, but once floats (decimals) were added to the mix, things became much more complicated because the anticipated result (0.6
) was not what Python returned (0.6000000000000001
). This led me down a rabbit hole to figure out what was happening, which turned up this tutorial from the Python documentation, Floating Point Arithmetic: Issues and Limitations. This is a nuance related to how computers represent floating-point numbers. As humans, we typically calculate decimal fractions using base 10 notation, but computers calculate using base 2 (binary). If you're curious about what the difference is between the two, this tutorial on Binary Representation from University of California, Berkeley provides a good primer.
To cut a long story short, the nice, relatively short value we're used to seeing when calculating decimals is often being rounded, but the value stored in memory is often many decimal places longer. To resolve this, I updated the code to return a manually rounded result, adding an optional parameter to specify how many decimal places to round to (which defaults to 2).
Linux Command Line—OverTheWire's 'Bandit'
I'm a Mac user, and macOS is a UNIX-based system, so working from the terminal has already given me experience with some of the most common commands (primarily cd
, ls
, touch
, and mkdir
). However, now that I'm working more with Linux and Ubuntu to maintain a cloud-based server for ongoing projects, I'm realizing I've still got a lot to learn to harness the full power of the command line.
When talking with a friend about this learning curve, he recommended I check out the "wargames" offered by the OverTheWire community, starting with a game called "Bandit"., which is the entry point for "absolute beginners" to get acquainted with the basic concepts needed to play other games in the collection. I'm currently on Level 7 of 34, and it's been a fun challenge so far that has me feeling like a secret agent.
I don't want to give too much away because a core part of the experience is figuring out what to do with limited background information (other than a list of commands you may or may not need to solve each level). Some things I've learned so far (which may or may not have been used in the course of the game):
- The Linux man-pages project is an incredible resource.
-
cat
is not a command to summon a feline friend (drat!), but it can print file contents in your terminal (among many other things; see Geeks4Geeks' cat Command article for examples). -
find
is a potent tool for searching for files in a directory, with a wide variety of criteria you can specify to narrow your search (see Geeks4Geeks' Find Command article for examples).
React Native—'Random Acts of Kindness' App
In addition to the above activities, which have helped me strengthen fundamentals I picked up during my coding bootcamp, I've also been collaborating with a friend to build a 'random acts of kindness' app to practice a new framework for both of us, React Native. Having focused primarily on web development over the last year, this first foray into mobile programming has definitely been a learning experience. However, the nice thing about having a React background already is that a lot of the concepts and syntax we've encountered so far with React Native are very similar.
This week, we spent some time troubleshooting why we were getting errors when using React Navigation "drawers" (which allow you to have a navigation menu that opens from the side of your screen, like a drawer). The message is similar to the one below:
ERROR in ./node_modules/@react-navigation/drawer/lib/module/views/legacy/Drawer.js 84:25-39
export 'default'.'Value' (imported as 'Animated') was not found in 'react-native-reanimated' (possible exports: FlatList, Image, ScrollView, Text, View, addWhitelistedNativeProps, addWhitelistedUIProps, createAnimatedComponent
Upon further investigation, we found out from a closer review of the React Navigation Drawer Navigator docs that, in order to use the latest version of the 'React Native Reanimated' dependency, it needs to be configured a certain way, as described in its installation guide. In the end, all we needed to do in addition to installing the requisite packages was add the React Native Reanimated plugin to our Babel configuration file.
module.exports = {
presets: [
],
plugins: [
'react-native-reanimated/plugin',
],
};
Looking Ahead
That's a wrap for this week. For the upcoming week, I'm planning to work more with:
- Continuing the JavaScript30 course
- Building out my 'Job Alert Scraper' tool
- Continuing to solve the daily Python code challenges
- Finishing up the OverTheWire 'Bandit' game
- Experimenting with React Native calendar views
I'll check in again next week to let you know how it all goes—stay tuned!
Top comments (0)