<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: vejendla</title>
    <description>The latest articles on Forem by vejendla (@nithinv).</description>
    <link>https://forem.com/nithinv</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%2F927144%2Fd0ff2d6b-6553-4a60-ba11-b273980198c2.jpeg</url>
      <title>Forem: vejendla</title>
      <link>https://forem.com/nithinv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nithinv"/>
    <language>en</language>
    <item>
      <title>Day 1: Learning full-stack development</title>
      <dc:creator>vejendla</dc:creator>
      <pubDate>Tue, 18 Apr 2023 02:13:16 +0000</pubDate>
      <link>https://forem.com/nithinv/day-1-learning-full-stack-development-4aik</link>
      <guid>https://forem.com/nithinv/day-1-learning-full-stack-development-4aik</guid>
      <description>&lt;p&gt;Hello! One of the &lt;a href="https://dev.tourl"&gt;technical skills&lt;/a&gt; I want to learn in 2023 is full-stack development. More precisely, I want to continue learning full-stack development. &lt;/p&gt;

&lt;p&gt;I started my career as a junior engineer at Floyd, a d2c e-commerce brand based in Detroit. When I was in college, I did not expect that I was going to go down this path. I only did a minor in Computer Science in college and most of my friends were in the business school. Because of that, I assumed I was going to be a consultant of some kind, or a similar analytical or business role.&lt;/p&gt;

&lt;p&gt;Because of my background, and the fact that I had very few friends who were in software engineering, I have always felt like an imposter in technical roles. I found myself feeling like I didn't know enough to consider myself an engineer, and that I wasn't good enough to continue down the career path. After my role at Floyd ended, I didn't think I was cut out for another software engineering role and that I should look towards roles that are adjacent to software engineering or tech, but tend to flex softer skills (I'm still open to that career path as well, especially in the long term).&lt;/p&gt;

&lt;p&gt;I want to prove to myself that I can learn a framework from scratch, and I want to blog about my experience to help other people who don't come from a traditional pure Computer Science background. Hopefully, you can relate to some of the feelings I'm going through, and it helps you work through similar challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I'm starting from
&lt;/h2&gt;

&lt;p&gt;I am not starting this challenge as a beginner, because I have worked as a software engineer (for close to two years) using a modern front-end framework. Specifically, I worked with Solidus, which was built on Ruby on Rails, and a Vue.js heavy front-end. Our app also worked with a content management system, called Contentful (the organization has since switched to using a different set of tools). &lt;/p&gt;

&lt;p&gt;Also, I have been hobby programming since I was 11 or 12. I got my start with HTML/CSS, and then graduated to messing around with Wordpress. I completed an undergraduate minor in Computer Science at the University of Michigan, which shares core classes with the major, and is a well-reputed computer science program more generally. Those have given me a strong base of knowledge to approach this course.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1
&lt;/h2&gt;

&lt;p&gt;Let's begin! To teach myself Full Stack I'll be using this &lt;a href="https://fullstackopen.com/en/"&gt;website&lt;/a&gt;, which is a free resource. They recommend doing one part at a time. I'm starting with &lt;a href="https://fullstackopen.com/en/part1"&gt;Part 1 - Introduction to React&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The first challenge with any new framework is figuring out how to get the d**** thing running. This is by far the most frustrating part of development. &lt;/p&gt;

&lt;p&gt;Specifically, I'm trying to run the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app part1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npx&lt;/code&gt; is a command that you can use to install npm package binaries (&lt;a href="https://www.npmjs.com/package/npx"&gt;link I Googled&lt;/a&gt;). &lt;code&gt;npm&lt;/code&gt; is a package manager for Javascript. I always thought it stood for Node Package Manager but technically that's &lt;a href="https://en.wikipedia.org/wiki/Npm_(software)"&gt;not true&lt;/a&gt; (though that was the name of the original commit). &lt;/p&gt;

&lt;p&gt;I'm not sure how to run this command - I think I need to install npm, and use that to install npx. I already have nvm installed. Based on &lt;a href="https://github.com/facebook/create-react-app#creating-an-app"&gt;this section&lt;/a&gt; of &lt;code&gt;create-react-app&lt;/code&gt; docs, I &lt;em&gt;think&lt;/em&gt; I can use nvm to use npx/npm. Let's try following &lt;a href="https://github.com/facebook/create-react-app#creating-an-app"&gt;these steps&lt;/a&gt; to see if that works. I ran the following command to install node:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now let's see if I can use &lt;code&gt;npx&lt;/code&gt;. I followed the &lt;a href="https://fullstackopen.com/en/part1/introduction_to_react"&gt;commands here&lt;/a&gt;, and it worked! Excellent. &lt;/p&gt;

&lt;p&gt;I'm not going to replicate every step in the tutorial, but will outline any cool things I notice, or any problems I run into as time goes on.&lt;/p&gt;

&lt;p&gt;Here are some things&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React dynamically updates the content - I didn't have to refresh my react app after saving code, unlike Vue.js&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reflections
&lt;/h2&gt;

&lt;p&gt;I spent probably one to two hours on this. I'm starting a part-time job soon, and that took up the remainder of my day. I think to be successful with this, I should focus on doing it at the beginning of the day, and setting a goal of 2 hours of learning. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Geocoding addresses</title>
      <dc:creator>vejendla</dc:creator>
      <pubDate>Thu, 06 Apr 2023 04:12:30 +0000</pubDate>
      <link>https://forem.com/nithinv/geocoding-addresses-2a3l</link>
      <guid>https://forem.com/nithinv/geocoding-addresses-2a3l</guid>
      <description>&lt;p&gt;I want to teach myself Leaflet.js, so I’m working on a project to rebuild &lt;a href="https://www.shtetlhood.com/map.htm"&gt;this map&lt;/a&gt; as a Leaflet.js app. If you’re curious why I picked a website cataloguing old synagogues in Detroit as a project, read &lt;a href="https://github.com/vejendla/shtetlhood-map-leaflet"&gt;the readme&lt;/a&gt; on my GitHub to learn more.&lt;/p&gt;

&lt;p&gt;So far, I’ve scraped the names and addresses of each former synagogue from the website, and have a .csv of them all that looks like this:&lt;/p&gt;

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

&lt;p&gt;Some of the locations are listed as addresses (2625 Tyler), while some are listed as cross streets (Holbrook at Brush). A few are listed as general locations like “Curtis just west of Livernois”.&lt;/p&gt;

&lt;p&gt;The next step in my project is to convert these addresses to coordinates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which service?
&lt;/h2&gt;

&lt;p&gt;To do so, I need to geocode these locations. Geo-coding is the process of transforming a description of a location (like 2625 Tyler or Holbrook at Brush) to a set of coordinates referring to a specific place on the Earth.&lt;/p&gt;

&lt;p&gt;There are several geo-coding services out there. While researching geocoding services, I found this &lt;a href="https://gis.stackexchange.com/questions/21890/does-leaflet-js-api-provide-a-geocoding-service"&gt;StackExchange&lt;/a&gt; thread which lists a few options for geocoding. There’s also this &lt;a href="https://www.natasshaselvaraj.com/a-step-by-step-guide-on-geocoding-in-python/"&gt;article&lt;/a&gt; for Python which lists Google Maps. Here are some of the options I found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wiki.openstreetmap.org/wiki/Nominatim"&gt;Nominatim from OpenStreetMaps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a Leaflet Bing Geocoder&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toMapBox%20Geocoding%20API"&gt;MapBox Geocoding API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toGoogle%20Maps%20Place%20Autocomplete"&gt;Google Maps Place Autocomplete&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, I thought of using Nominatim (an Open Street Maps API), since it’s free. However, Open Street Maps (not the API) doesn’t recognize “Holbrook at Brush, Detroit, MI” as an address. I’m assuming that the API wouldn’t recognize it either, which is a problem.&lt;/p&gt;

&lt;p&gt;Next, I thought about using Google Maps, which does recognize the address. However, their API requires me to get a key, which is a lot of work and may require me to set up a billing account. There’s one more place I can look…&lt;/p&gt;

&lt;h2&gt;
  
  
  Census to the rescue
&lt;/h2&gt;

&lt;p&gt;The Census Bureau offers a &lt;a href="https://geocoding.geo.census.gov/geocoder/locations/addressbatch?form"&gt;free tool&lt;/a&gt; to geocode a .csv of addresses or locations in bulk. It works best for fully formed addresses (i.e., 400 Main St, Anywhere, NY). I can try uploading my .csv, and then filling in the missing addresses manually. Let’s give that a try:&lt;/p&gt;

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

&lt;p&gt;It worked! Only 14 of the addresses didn’t have matches, which should be easy to fill in. Next, I copied the coordinates column back into my original spreadsheet. I ran into a roadblock here because it turns out that Numbers (on Mac) doesn’t actually have a SPLIT function. That seems like a tomorrow problem (it’s 9pm as of writing this), so I’ll move forward on filling in the missing values.&lt;/p&gt;

&lt;p&gt;Using Google Maps, I found the first missing value, and right-clicked on the map to get the coordinates. It turns out that the Census and Google Maps return their coordinates in a different order. This also sounds like a tomorrow problem, so I’ll just copy them as is. 10 minutes later – I have a spreadsheet full of coordinates.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Next, I need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reverse the order of the coordinates I copied from Google Maps&lt;/li&gt;
&lt;li&gt;split the coordinates into their own columns&lt;/li&gt;
&lt;li&gt;refer to this &lt;a href="https://github.com/HandsOnDataViz/leaflet-map-csv"&gt;GitHub repo&lt;/a&gt; to read the .csv into my Leaflet.js map&lt;/li&gt;
&lt;li&gt;figure out how to add both the name and the address of the each lost synagogue as part of the title card&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Plotting ZIP Codes using Kepler.gl</title>
      <dc:creator>vejendla</dc:creator>
      <pubDate>Mon, 03 Apr 2023 18:44:56 +0000</pubDate>
      <link>https://forem.com/nithinv/plotting-zip-codes-using-keplergl-4gde</link>
      <guid>https://forem.com/nithinv/plotting-zip-codes-using-keplergl-4gde</guid>
      <description>&lt;p&gt;Do you have a set of data that contains ZIP Codes, and want to display that data using a free, open-source tool?&lt;/p&gt;

&lt;p&gt;Then read on to learn how I did exactly that to help a non-profit in my hometown understand their visitor data over a three year period.&lt;/p&gt;

&lt;p&gt;This article contains three sections. First, I'll generate a list of vists by ZIP Codes using Pivot Tables. &lt;/p&gt;

&lt;p&gt;Second, I'll describe how I used a free dataset and Python to convert the ZIP Codes into geographic coordinates. &lt;/p&gt;

&lt;p&gt;Finally, I'll upload the data to Kepler.gl.&lt;/p&gt;

&lt;p&gt;Here's what the final data looked like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5GtnjmV7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a48wyyxo726w31y63tw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5GtnjmV7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a48wyyxo726w31y63tw9.png" alt="A visualization of data points" width="880" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Creating a pivot table of Zip Codes
&lt;/h2&gt;

&lt;p&gt;First, I previewed my data using Google Sheets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kX3p1zKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/561if6v0z196o9patsls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kX3p1zKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/561if6v0z196o9patsls.png" alt="A spreadsheet in Google Sheets" width="880" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, I used pivot tables to display the count of visitors by ZIP Code. See the result (left) and settings (right) below. You can access this view by highlighting your data range and clicking "Insert &amp;gt; Pivot Tables".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--myT59W0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ra5u8dvj2vua2a77q91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--myT59W0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ra5u8dvj2vua2a77q91.png" alt="A screenshot of Google Sheets displaying a pivot table and its configuration settings" width="880" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Converting the Zip Codes to latitudes and longitudes
&lt;/h2&gt;

&lt;p&gt;Since Kepler.gl requires coordinates to plot data, I had to find a way to convert ZIP Codes into latitudes and longitudes (As an aside, ZIP Codes aren't always the best datatype for business purposes. See &lt;a href="https://carto.com/blog/zip-codes-spatial-analysis/"&gt;this post&lt;/a&gt; for more.)&lt;/p&gt;

&lt;p&gt;There are a number of ways to convert ZIP Codes to coordinates. One free way is to download &lt;a href="https://www.kaggle.com/datasets/joeleichter/us-zip-codes-with-lat-and-long"&gt;this dataset&lt;/a&gt; from Kaggle, and use a VLOOKUP style operation in Pandas. That's exactly what I did. Below is the code that I used. You will need to have pandas and geopy installed prior to using this code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
import geopy
import math

# replace this with your input csv
df = pd.read_csv('20-21/20-21pv.csv')

# this is the name of the column in your input CSV that contains the ZIP Codes
df['Zip Code'] = df['Zip Code'].astype('int')

# replace this with the URL to the Kaggle csv
zipdf = pd.read_csv('zip_lat_long.csv')

def geocode_lat(row):
    if math.isnan(row['Zip Code']):
        return None

    searchZip = int(row['Zip Code'])
    tempRow = zipdf.loc[zipdf.ZIP == searchZip, "LAT"]
    if tempRow.empty:
        return None
    else:
        return tempRow.values[0]

def geocode_long(row):
    if math.isnan(row['Zip Code']):
        return None

    searchZip = int(row['Zip Code'])
    tempRow = zipdf.loc[zipdf.ZIP == searchZip, "LNG"]
    if tempRow.empty:
        return None
    else:
        return tempRow.values[0]

df['lat'] = df.apply(lambda row: geocode_lat(row), axis=1)
df['long'] = df.apply(lambda row: geocode_long(row), axis=1)

# replace this with the name of your output file
df.to_csv('20-21pv_with_latlong.csv')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and here's the result (see the coordinate columns):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TP9jHpBW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y5fo8c263lqxdmgu6sx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TP9jHpBW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y5fo8c263lqxdmgu6sx5.png" alt="A table containing ZIP Codes and coordinates" width="880" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note 1: I did some mild data cleaning between step 1 and 2 that involved removing invalid ZIP Codes from the dataset. This included foreign ZIP Codes, and improperly formatted US ZIP Codes.&lt;/p&gt;

&lt;p&gt;Note 2: The free dataset I used only contains ZIP Codes up to 2010. The US Postal Service has added a small number since then that weren't included in my final visualization.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Plotting visits in Kepler.gl
&lt;/h2&gt;

&lt;p&gt;The final step is the easiest. With our .csv, I simply uploaded it into &lt;a href="https://kepler.gl/demo"&gt;Kepler.gl&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The user interface should be self-explanatory, but there's a &lt;a href="https://docs.kepler.gl/docs/user-guides"&gt;helpful guide&lt;/a&gt; if you get stuck.&lt;/p&gt;

</description>
      <category>pandas</category>
      <category>keplergl</category>
      <category>tutorial</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
