Thursday, August 22, 2019

Day 137: Pomodoro Clock & Done w/ the Odin Project's Web Dev 101!

Wow, it's been a while since the last post. The reason this took so long was because the Pomodoro Clock project itself took so long to complete! See here for the code in all its glory.

I did the set up so that it can eventually be refactored to submit to the freeCodeCamp's version of their project. Yes, I do like my twofers.

Overall, this thing took about 19 hrs and 35 minutes to complete. Why? Because I had to do it over and I added some options that did not work out.


The project started with the styling which was my favorite part because it was so straight forward to me. That didn't take too long, probably just a handful of hours.

Then coding up the functionality began.

I started by tracking the actual time with use of the Date() object and some help from w3schools. I went this route because it is supposed to be more accurate than just using setInterval by itself. But it was really freaking hard to get a pause and resume type functionality working with the setIntervals and clearIntervals. I was able to get it paused, but not resumed, or resumed incorrectly, or there would be some bug that affected it. It was a mess.

Eventually, I decided to just straight up use setInterval() by itself without relying on Date() to track the time. So that was about 5-6 hours wasted. It was actually so much simpler this way and I was able to get the pausing and resuming up and running very quickly!

By then, it was pretty much working as intended, but I planned from the start of the project that I wanted to use a progress bar.. or rather, a progress circle. I found a neat library aptly named ProgressBar.js which seemed to fit the bill. I got it working!... but only if you do not use the pause functionality. If you do use pause, bugs start presenting itself with the progress bar by either doubling in time or some other weird stuff. So then we have another 5-6 hours spent on trying to get it working. After some searching around, it appears that others who also wanted to use a pause functionality encountered the same problems.

To fix it was to edit the library itself and I am not quite there in terms of ability yet (especially since it also uses SVG which I only just started reading about). That and I was ready to be done with the project and move on already! So I called it a close, with a promise that I will build my own built-in progress bar.

After fiddling with the project for so long, I reasoned that it would be very simple to implement my own progress bar using JS to change the styles in CSS based on the % completed. And it was! While it is not the slickest thing in the world, it does and (generally) looks like how I envisioned it.

Sometimes, you just got to Keep it Simple, Stupid. (KISS)

And lastly, I am really pleased to finally finish the Web Development 101 section in the Odin Project!


Gee, I wonder where I got that idea for the progress circle from?


Wednesday, August 14, 2019

Day 129: CodeNewbie & the Pragmatic Programmer



If you are just starting out, I feel that it is my duty to plug the CodeNewbie community and to listen to its podcasts if you aren't doing so already. I've been taking my time going through the whole catalog on my commute to and from work, from the very beginning episode 1. I am currently at episode 141, now going through the first annual Codeland Conference talks, right before they started actually numbering their seasons! (They're at season 9 now, at the time of this writing).

I must say that Saron Yitbarek is one of the best podcast hosts I've ever listened to. She has a natural talent at it. As a newbie, my favorite episodes are the ones where she interviews developers who are self taught, are career changers, or generally have a non-traditional background. It's my daily dose of inspiration.

I do also enjoy the interviews from the folks in tech that I wouldn't normally think of since I am heavily leaning to web development or interview some big names like Sandi Metz, John Resig, and Yehuda Katz (great interview). A set of episodes that really stuck out to me that I will probably keep referring back to is where she interviews the Pragmatic Programmer founder, Dave Thomas (part 1, part 2). This is a rather special interview for me as I was going through some serious doubts at that time and listening to the interview really helped encourage me.

So if you are a code newbie, give CodeNewbie a look!

Tuesday, August 6, 2019

Day 121: Javascript Calculator Project Completed!

The Javascript Calculator project with keyboard support was not as terrible in terms of bug squashing (and general frustration) as the Etch-A-Sketch Project.


Two points of interested of this project was that:

  1. When I began, I started going down this weird rabbit hole of pushing the clicked numbers into an array and then joining them for calculations. There were other funky stuff I was trying as well that I don't quite remember. It was a not insignificant (to me) amount of code written up that I ultimately ended up tossing out the whole thing and starting all over. 
  2. One of the extra credit assignments in the Odin Project is to include keyboard support. I wrote up that bit pretty quickly and it worked for the most part, but had weird bugs that included other characters that was strangely (to me) not being filtered out by the conditional. I had used "keyup" as the eventlistener and tried a few things to fix that bug. Eventually, I decided to try using "keydown" instead. Literally just switching out one word, "keyup" to "keydown" worked! I still don't quite understand why and will need to read up on the differences between the two. 
Overall, it was a really enjoyable project! FreeCodeCamp also has this project as part of their front end libraries certification, which I was planning to just submit both to TOP and FFC in one go. However, I decided to hold off on submitting to FCC since this calculator was written entirely in JS. I am still taking my time going through the React and Redux sections and eventually would like to refactor the code to use those libraries in the future since the whole point of the project for the FCC certification is to get more experience with them. 

The next project I will be working on is the Pomodoro Clock project which again is an assignment in both TOP and FCC. I will be taking the same steps, working with it in vanilla JS and then later refactoring to React/Redux. 



Wednesday, July 31, 2019

Day 115: Etch-a-Sketch Project

So I finished my etch-a-sketch project for the Odin Project a few days ago. I meant to blog about this sooner but needed a few days away from it for a bit. More on this later...

I'm happy with how it turned out!
It was a bumpy ride though... 

The requirements for the project are the following:
  • Generate a grid and allow users to choose the number of cells in the grid while conforming to the original grid size.
  • Allow users to clear the grid so they can draw something new. 
  • When the user hovers over the grid, allows them to change the colors of the cells. 
  • Optional: Allow users the option to select a random mode where each pass through a cell changes to a random RGB valu.
  • Optional: Allow users the option to select a shader mode where each pass through a cell adds another 10% of black to it so that after 10 passes is the square completely black.
  • My Extra: Allow users to have an eraser tool
  • My Extra: Allow users the option to pick their own color using a color picker.  
I pretty much got it working in a single coding session and was so gosh darned pleased with myself. "Yeah! I know how to do stuff!"

But it wasn't quite working as intended.

When you clicked the shader button, it worked as it should, but the bug was that it became persistent and continued the shader functionality (decreasing in opacity) when you switched to any other mode as well. Clearing the grid or resizing it did not help. Nothing short of ctrl+r made it go away.

Not working as intended at all!

So I spent the next THREE days trying to figure this damn thing out. I almost got it working close to intended when I switched from using opacity to straight up changing the color values themselves (i.e. hex value of #999999 => #111111). However! There were other bugs related to the shader, where when you clicked the shader (it worked), but when you clicked it again it still worked, but now instead of going through 10 passes to get to black, it was 5 passes. If clicked shader again, it was now just 2 passes to get to black. Then 1. Other bits and bobs I tried was using the removeEventListener, forcing refresh (no, no, no), and tons of refactoring.

So with my frustrated grouchy face at home, cue the husband noticing and asking to look at my code. I grumpily told him what was wrong and after a ton of console logs, we figured it out.

I was calling the mouseover eventlistener inside a function. This function was later called from the click eventlistener.

const drawShade = () => {
  sketchPad.addEventListener("mouseover", e => {
    e.target.style.backgroundColor = "black";
    let opacity = Number(e.target.style.opacity);
    if (e.target.style.opacity <= 1) {
      opacity += 0.1;
      e.target.style.opacity = opacity.toFixed(1);
    }
  });
};

const shade = document.querySelector("#shade");
shade.addEventListener("click", e => drawShade());

Yeah, you're not supposed to do that! Why? Because once you call that function, it's going to have that mouseover eventListener hanging around forever (until refresh). And when you call the function again by clicking on the button again, that evenListener is going to duplicate itself! And so on and so forth.

So this is just another case of my wanting to cram in as many things at once instead of focusing on one functionality at a time.

For something like mouseover that is persistent, that function should only be called once. And you have to work around creating something that manages the various modes.

In the end, I created an actual "mode" value that defines what the mode should be based on the user click. And the drawMode() function, being called only once and is persistent changes the mode based on the user click.

Here's the old code when I thought I was nearly done. Compare that sucker to how different it is from the final code. There was a lot of refactoring done!

Touchy Feely Stuff

Oh boy, was this project a roller coaster ride. Before I started, I was super nervous. You know the whole thing about "if I try, I might fail. If I don't try at all, I can't fail... right?" Yeah, that's why I am always nervous before starting any project. The fear of failure.

But I started it (after procrastinating a bit), I got the grid creator to work within minutes using CSS grid, fixed up the CSS to look the way I want it to (I am really pleased with it!). I got most of the functionality to work with ease and pretty minimal googling. Huzzah! I was on cloud 9.

Then that bug reared it's ugly head. Like I said, I suffered through it for 3 days. For comparison, the project took a total of 17 hours... 10 of which was bug fixing. Yeah... And this was the time where I'm thinking "This is the second, the SECOND project on the Odin Project. If I can't do this right, how the heck do I expect to do the rest of the projects which are harder!?"  SO. DAMN. FRUSTRATING.

When I understood why it was bugging out and fixed it... it was like those 3 days were erased. Total euphoria and relief. And exhaustion. Hence why I had to take a few days away from it to decompress and let it sink in a bit.

But this is how you learn and become a better developer right? Through hours and hours of frustration and when its solved, you feel like a million bucks. I am OK with that.


Friday, July 19, 2019

Day 103: First Pull Request!

It's not much but I just made my first pull request to something that is not myself and it was accepted! Huzzah!

I am so stupid excited right now. 

It's not much. It is literally just updating an .md file as a part of the Odin Project curriculum when you complete your projects to include a link to it, but it's still sooooooo exciting to see everything in action and be included!

That said, I did finish my rock, paper, scissors project last night. Give it a whirl, there's a treat if you win! (or lose). It took about 7 hours to do spread between 3 days. I wanted to do a bit more than the minimum viable product, so I spent more time on it than was necessary. The time count actually includes looking up images and sounds for it so it was not all super productive coding, but time well spent that was still important to the project. It was nice to brush up on on a tiny bit of CSS with the project as well.

The next project, doing an etch-a-sketch seems a bit more complicating, but it should be interesting! I always like to quickly peek at code from other folks... and most of them are less than 100 lines of JS. Crazy how something may seem so complicated, but can be done in much fewer lines than I always think it would be.


Wednesday, July 17, 2019

Day 101: Round 2 of the #100DaysOfCode

Yesterday was my 100th day for my #100DaysOfCode. There really wasn't much fanfare other than a post to Instagram:


And a quick tweet about it:


Honestly, I was too busy working on the latest project to really make a big deal out of it.

I am glad to have completed Angela Yu's Bootcamp and the FCC Algorithm and Data Structures certificate before day 100 though.

I have no plans to stop doing #100DaysOfCode until I actually make a career change into software development.

What's Next? 


The next few goals will be to complete the Modern Javascript Bootcamp course on Udemy with Andrew Mead.


As a quick note: my gold standard for Udemy instructors is still Angela Yu, but Andrew Mead is a really close second. They have very similar teaching styles with the demonstrations and then challenges. I also find Andrew's method in using NodeJS to teach Javascript to be unique too! Since it gets you used to the terminal (although I have been mostly going through his projects on the console with codesandbox.io so I can code on any computer). I am already making plans to purchase his NodeJS and his GraphQL courses when I finish up other courses/projects.

The other Udemy courses I also intend to go through are my already purchased Complete Web Developer in 2019: Zero to Mastery course by Andrei Neagoie (already about halfway through), the Modern React Bootcamp by Colt Steele, and Advanced CSS and Sass by Jonas Schmedtmann. For most cases, I will try to get through the parts I am already familiar with ASAP and focus on the challenges and projects in these courses. Other more advanced courses I would like to get are ones on MongoDB and D3. While I could purchase these courses now, I really don't want to get into the trap of throwing money at something just so I can feel like I am being productive. So I am forcing myself to complete the courses I already have before getting more.

For projects, I have plans to go through (most of) the projects list on The Odin Project. with the first one being a simple Rock, Paper, Scissors game. A few of these projects are also similar to the various freeCodeCamp projects or the projects in the Javascript30 course by Wes Bos, so it's like I can multi-task with my projects! Not that I am getting bonus points or anything like that from anyone (but myself) but it's nice to feel like I am being efficient, no? The whole point really is to build the damn thing already and get some projects under my belt.

In the meantime, I am going to throw some Edabit or Codewars problems in here and there as well as watching Linkedin Learning videos (formally called Lynda.com) during my down time. I usually don't code along with the LL videos because the courses are often really short (like 1-2 hours) and they really do not go as in depth as I prefer. These are usually reserved for winding down before bed or as I am commuting.

I am not doing any one specific course or set of projects in a linear fashion, but sort of all of them at once as I am going through my curriculum, which is loosely following in the order that freeCodeCamp laid out.


Saturday, July 13, 2019

Day 097: The freeCodeCamp JavaScript Algorithms and Data Structures Certificate!

Look mom! I got the thing!

This was after completing their last problem: JavaScript Algorithms and Data Structures Projects: Cash Register.

Mom, it was a harrowing ordeal to get this thing!

As you know, I track my time coding or learning to code with Toggl. How much time did I spend on this the last problem?  In total about 9 hours and 52 minutes

Holy mother... why?

The long and short of it is that you need to know the value of each of the currency item in order to solve the problem. I had set my penny to $0.1 instead of $0.01. 

I basically solved this damn thing like 3 different ways after working with that incorrect original reference data the whole time, but could not get why the heck it was not solving. Part of the reason was because I was adamant on getting it done on July 12th so I kept cranking at the problem up until around 3am in the evening until I finally gave up for the day due to sheer exhaustion. 

So roughly 9.5 hours was spent banging my head on this thing. In the end, I asked my husband for help and after a series of questions of why... that we identified that my penny was off by a decimal in like 10 mins. FML

And after that, the problem was solved as a whole pretty quickly after writing out the last bit of logic for the insufficient funds cases. 

I should have given it a rest and/or asked for help much sooner. The bulk of the solution was written out and validated in about 2-3 hours and it would have been solved by then if it wasn't for being off by the decimal. I kept hammering at why it was not working with a tired brain which worked against me. And my stubbornness (which is amplified with the tired territory) pretty much made me avoid asking for help until I became desperate. I really need to stop doing that and be better about knowing when to stop and knowing when to ask for help!

So the takeaway from working through all these algorithms is not the content itself (though I did learn lots!) but mostly about myself in how to be a better person and a better programmer.

Now that this is done and over with, I still want to solve the remainder of the Intermediate Algos that I skipped, but I want take a break from algos problems in general for a few days so I can move on to the Front End Libraries section in FCC, the more fun and creative bits.

I am pretty pleased that I manged to get the second certificate before my 100 days on Tuesday!


Wednesday, July 10, 2019

Day 094: FCC Intermediate Algorithms: Wherefore art thou

Currently, I am only about halfway through the FCC Intermediate Algos section. I had initially skipped Intermediate Algorithm Scripting: Wherefore art thou since it is dealing with objects and objects are not my cup of tea, but then I encountered another problem with objects so might as well get this one done before moving on, yes?

I really like working with challenges that have arrays. I understand it and enjoy it. But when you throw an object into the mix, I start having problems. And then you add objects into arrays or arrays into objects and nest them in some way or another, my eyes get crossed!

It is partially because the object references the location and not really the values itself (or something like that). So when you compare the following "same" objects in the below array, the result is a false. Try to iterate through that mess and you can get a sense as to why it confuses the heck out of me.

const testArr = [
  { key1: "value1", key2: "value2" },
  { key1: "value1", key2: "value2" }
];

console.log(testArr[0] === testArr[1]); // false

But objects is in part what makes Javascript OOP, so I better get used to it.

The FCC challenge requires the following:
Make a function that looks through an array of objects (first argument named "collections") and returns an array of all objects that have matching name and value pairs (second argument named "source"). Each name and value pair of the source object has to be present in the object from the collection if it is to be included in the returned array.
whatIsInAName(
  [
    { first: "Romeo", last: "Montague" }, 
    { first: "Mercutio", last: null }, 
    { first: "Tybalt", last: "Capulet" }
  ], 
  { last: "Capulet" }
);

// should return [{ first: "Tybalt", last: "Capulet" }].

Being aware of the conditions of objects and key value pairs that make it hard for me, how did I initially tackle the problem? I used Object.keys() and Object.values() to convert the array of objects into an array of arrays, combining the keys and the values as "keys+Values" with use of the for.. in loop, something like the below as an example.

const srcKey = Object.keys(source);

  for ( let i = 0 ; i < collection.length ; i++){
    for (let key in collection[i]) {
      console.log(key + ":" + collection[i][key]);
    }
  }

Midway through writing up my answer, I realized that it was probably a very inefficient and um... bad way to work with objects in getting to the solution.

So I peeked at the hints.

I was on the right path to use the Object.keys(), but I wasn't using it correctly. And filter() and Object.hasOwnProperty() also made an appearance.

I didn't quite consider using filter() because it is a method on an array, not object. Since they are objects, I kind of agonized over that and overlooked the fact that it was an array of objects. So filter will work fine in this case. It almost always does with these matching type problems.

In my own words, filter() accepts a condition and returns that which is true or "passes the test implemented by the provided function" (per MDN). You plop in a true or false function and it gives you an array of whatever values are true to the condition.

Okay, it sounds like I have to write function that checks whether any part of the source matches the submitted collections array by looping through the array (of objects). And somewhere along the way, hasOwnProperty comes into play in there. I'm not sure if I ever used hasOwnProperty and how that comes to play. So what does it do?
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it). --MDN
I am going to need to use it to check if the objects in the collection has the properties of the source. Fair enough.

So cue the many searches and hours spent on this problem and I finally gave up and took a look at their code solution.

I came close to their basic solution. Most of the bits and bobs were in the right place, but I could not get the condition statement right. /sigh Always foiled by that ! operator. Here's my completed solution after reviewing theirs:

function whatIsInAName(collection, source) {
  const sourceKey = Object.keys(source);

  function existsInArray(obj) {
    for (var i = 0; i < sourceKey.length; i++) {
      if (obj[sourceKey[i]] !== source[sourceKey[i]]) {
        return false;
      }
    }
    return true;
  }
  return collection.filter(existsInArray);
}

Why does this work? Let's deconstruct this a bit using the first test case.

Step 1. We need to use Object.keys() which will return the object's name for the key value pairs. We need this information because our task is to find the one that matches with the source. In this case, we need to match the last names (key and value).

Step 2. To simplify matters a bit, I created the "sourceKey" which is the "Object.keys(source)" to keep the code a bit cleaner. You can indeed use something like "Object.keys(source)[i]" later in the conditional part of your code, but it gets harder to read. At least for me this is the case. This code produces the following:

console.log(Object.keys(source)) 
// returns "last"

Step 3. In peeking at the hints, I found that filter() needed to be used. So in this case, it is a matter of filtering out the objects in the array that does have the same sourceKey and sourceKey value and returning the objects that match in its entirety, even the parts such as the first names and values that do not match.

I am still wrapping my head around filter(), reduce() and the like, so I rely very heavily on the documentation and the examples therein to continue. I found the Filtering invalid entries from JSON example to be particularly helpful. So I create a function to check if the source key, i.e. the last name exists in the provided collection.

Step 4. I create the "existsInArray()" function that essentially takes in an array of objects as the parameter (which is the collection) which will be run later when used in conjunction with filter(). I'm, largely following the example in MDN where were will need to call the following eventually:

return collection.filter(existsInArray)

This is the same as checking through the below:

console.log(collection[i][sourceKey[j]]); 
// is same as
console.log(collection[i].last)
// returns all the last names

It is similar to collection[i] because remember that it is built in that filter() will iterate through the arrays so there won't be an actual need to iterate through the array. Though of course it is still possible to solve this problem without filter by indeed using nested for loops to iterate through the collection and checking against the source.

Step 5. Now we write the logic so that when we iterate through the collections to check if the values of the sourceKey (the last name) match. Filter accepts a boolean value and normally outputs the items that are true to the logic and removes those that are false. In MDN's example, if the function checks for all the strings in an array greater than a length of 6, it will only return an array with those strings that are true to the function.

So I initially had in the following in my if statement:

if (obj[sourceKey[i]] === source[sourceKey[i]]) {
return true;
}

Success!.. or is it?

It solved the first and second test case but not the remaining.

Why!?


Well, my initial answer also returned any of the whole object in the collection if it matched one single key+value pair from the source, whereas it should only return the object if it matches all key+value pairs in the source. So just because I match 1 key+value pair in the source, it returned the whole object. This is obviously not what I want if there is more than one key+value pair in the source.

This is also where I spent most of the time puzzling through and could not get why it was not working. I tried a few different things that did not work out. So after an hour to trying, I peeked at the answer and saw right away... that it was reversed on their end. I applied it to my answer and of course it solved right away!

But why?

Step 6. Since filter accepts a boolean value and returns the bits that are true,  the logic should identify the objects in the collections array doesn't match all the key+value pairs in the source first and mark them as false (so it is not included in the output) then return all else as true after the for loop.

for (...){
  if (obj[sourceKey[i]] !== source[sourceKey[i]]) {
    return false;
  }
}
return true;

That's it. I have such a hard time even considering this route in using filter() or map() to define items as false first and return all else true as a way to filter more specifically. I am hoping I get better at this with time!


Tuesday, July 9, 2019

Day 093: Copy & Paste Hell, Diffchecker is Your Friend

I'm still working through the freeCodeCamp's intermediate algos. Next up was this problem Intermediate Algorithm Scripting: Convert HTML Entities which asks to convert the characters &, <, >, " (double quote), and ' (apostrophe), in a string to their corresponding HTML entities.

Easy peasy! I thought to myself since I am starting to get very comfortable with Regular Expressions and that was what I intended to use. I wrote up my code by copying and pasting the HTML entities from the of test cases below the buttons.

Huh?

I press run the tests... and for some reason, some parts did not work? I spent the next 30 mins wondering wtf I did wrong. Googled up why it didn't work as well as the solutions on how to make it work. Working through it in the console or codesandbox gave me the correct answer with what I originally wrote as well. By all accounts on StackOverflow and such, I had the right answer... but the tests were not passing on FCC. 

PS get a codesandbox.io account and you can code anywhere!

I sometimes check out the hints but I really hate looking at the solution. But after nearly an hour (my cue to start getting help) at this, I gave up and looked at how FCC did it.... and it was nearly identical to their intermediate solution. WTF?! And yes, I also checked to make sure their solution actually passed their test and it did.


And then it finally dawned on me that I might have some weird characters somewhere that FCC is not reading, so I fired up Diffchecker to confirm my suspicions..... and yep.. there's a hidden blank character that I got from when I copied and pasted the HTML entities from the FCC site.

After removing those bits from my code, the tests all passed with flying colors. /sigh


Monday, July 8, 2019

Day 092: Long Weekend Coding Retrospective, Personal Hackathon

Not that I announced it or anything, but I did another "Personal Mini Bootcamp" this past long weekend (July 4 though July 7). Since I am more precisely tracking only productive time (no break times) with Toggl, I figured it would be more reasonable to do at least 6 hours of coding or learning to code each day as opposed to the original 8hr/day. Also, if it is where I am just watching a video and not coding or trying out the examples in the videos, I count the time viewing for half (or less, depending on how much I am learning from the content).

While I knew I needed to do another one of these Personal Mini Bootcamp sessions, I only decided on July 2nd that I will be attempting it during the my long weekend since my workplace decided to give everyone a free day off on Friday, July 5th. In all, it gave me 4 whole days of coding and getting back on track.

I had a lot of courses/videos/assignments that were incomplete, so the main goal was to move on to functional programming and ES6 and asynchronous JS and wrap up those courses and videos and take occasional breaks with the FCC Intermediate Algorithms section.

As you know, I finished Angela Yu's Web Dev Bootcamp course, I also finally completed the Intro to Javascript course on Codecademy. The last few sections in this course were indeed ES6 and async JS hence the delay on completing it.

The past 2 weeks has been all about functional programming and ES6 so it was really nice doing all of these from various sources at the same time. And no surprise, a great deal of the weekend was focused on APIs, implementing them, practicing with them and creating it. I also made a very simple implementation of the Dad Joke API on Codepen (which I also need to update to include the errors and such).


For those Lynda videos that I stopped midway because I didn't want to get too ahead of myself, I finished most of them often while I was eating or on my indoor bike, counting for half time. So of course the content was further reinforcement on ES6, async JS, and functional programming. The last bits of the Angela Yu bootcamp was also all about APIs as well. It was neat how everything fell into place like that.

Another side effect of the weekend was actually finally starting to push projects onto Github and getting more comfortable with that.

I did go easy on the hours on July 4th proper (because bbqs and whatnot), but on average it does work out to be a tiny bit over 6 hours per day for the 4 day weekend. And I am also happy to say that I finally broke the 30 hour/week barrier to clock in a total of 32 hours and 13 mins for the week of July 1 through July 7 (Monday through Sunday). Woo! My general goal is to get in at least 20 hours of coding each week, which I have only achieved 2x previous to this week in the past 13ish weeks. /sigh

As an aside, I really need to think of a new name for the "Personal Mini Bootcamp" because its kind of misleading? I originally had that name because I was going through the Angela Yu Web Dev Bootcamp as my curriculum for that first weekend. I also originally chose the 8 hours so I would know what it feels like to be coding for 8+ hours a day like a full-time bootcamp student. But in reality, these weekend sessions are more like a very focused attempt to get some hours of code time in. Maybe "Personal Hackathon" might be a better name for it? Yeah, I think it makes more sense.


Sunday, July 7, 2019

Day 091: Finished Angela Yu's Complete Web Development Bootcamp

I just want to post that I finally completed the Complete 2019 Web Development Bootcamp course by Angela Yu on Udemy.


Man, it feels good to cross something big off my list.

I started on 5/12/19 and worked on it for a few hours each day, then took a long break from the course and left it at 90% for a while. But in the past 2 days, I made an effort to just finish and boom, I am done now!

It says the course is 43.5 hours, but there are 2 sections that are debatable in usefulness. The first is a 1hr 44min Q&A with Angela, while interesting, it should have been linked to a Youtube or something so it doesn't inflate the hour count towards the course. The other is a general module on design and colors, not specific to coding which was about an hour long. It has some uses, but I am not sure it belonged in this course. In all, I spent about 63 hours on the course (not counting the 2 above modules), watching it and working through the challenges. I did admittedly go very quickly through the HTML and CSS parts that I was already familiar with on 2x speed, or sometimes marked completed because it was too basic. The rest of the content, I normally watched on 1.5x speed.

Here's part of the review I submitted for the course posted on Udemy:

Pros: 

Angela is a charismatic, humorous, and gentle teacher. Her teaching style works really well for me as a visual & project based learner. She is very clear and concise in her explanations. IMO she speaks too slow, but Udemy allows you to adjust the video speed so this is no big deal. Angela will demonstrate and along the way and will frequently ask you to pause the video to complete mini challenges. I found this to be my preferred style of teaching in the video format. And since it is not 100% coding along like some other courses, I retain information much better. Whereas in the code along type courses, I find I am too focused on trying to catch up to their coding to pay as much attention to the concepts as I should.

She has some “boss level” challenges at the end of the major sections. Here you work on what you’ve learned in a big project such as creating a tinder site for dogs (cute), dice game, simon says game (this was an excellent project), creating your own blog/cms, among other projects. For these boss challenges, she prompts you to write a bit of code in each step. There are many steps along the way. By the last step, if you did everything correctly, you will have a complete and functional app. This really helps hammer in the fact that coding is basically tiny steps and not to get overwhelmed.

Not all the other instructors/courses do this, but Angela will code through the solutions after each challenge and will explain through each step. This can get repetitive if you are already comfortable with the content (which you can then totally skip her challenge reviews), but for the parts that were tricky for me, this was a godsend.

The video production values are excellent, very professional, always on par and often times above some Lynda courses. Her course also gives you access to the discord channel where you can get help from other students or even make some new coding friends (like I did!).

My favorite parts of the course was probably going through the Simon Says challenge and the Security and Authentication section (learned tons here).

Cons: 

IMO, she spends too much time on jQuery and Bootstrap, with a big project on Bootstrap itself. However, if you are just starting from the very beginning, I think Bootstrap is good to know to get practice with a framework and getting used to thinking about CSS in divs.

CSS Flexbox and CSS Grid are noticeably missing from the course, but hopefully she will add a section on these later.

Also missing are working with or at least introductions to the big JS frameworks out there: React, Angular, and Vue. I know it gets tricky to pick one framework for such a course, but they should at least be introduced at a high level. Students need to be aware they exist. I also wish she covered debugging a bit (not the sexiest thing in the world, I know). Even so, the cons do not detract from the content that is already there.

TLDR: 

Angela’s course and teaching style works perfectly with my learning style (visual & project based) as she often challenges you to complete steps after demonstrating how to do it. I recommend this course to anyone looking to learn about web development, if you are starting from scratch or even if you have some experience.

If you take your time like I did, you will learn a lot and get so much value from this course. Since Angela often updates the content based on student feedback, the ROI keeps getting better. Will taking this course turn you into a web developer and get you a dev job? Probably not because you need to practice what you learned and apply it to your own projects. But will it give you a strong foundation to do so? HECK YES!

Tuesday, July 2, 2019

Day 086: Intermediate Algorithm Scripting (FCC)

I like the new FCC redesign! (recolor?)
I just finished the Functional Programming section on FCC. It took a few days to get through. I get why it is useful, but dang, it is a lot to take in. Callbacks seriously gets me cross eyed. And then when you add all the (new to me) methods like forEach(), map(), filter(), reduce() etc., it is a lot to take in!

At any rate, I am now heading into the Intermediate Algorithm Scripting section of FCC. I am trying to apply the Functional Programming principles to solving these challenges, so it is taking a bit longer to work through the problems.

What really helped me learn in the past was to collect a massive sheet of notes that I may or may not refer back to, but the act of putting it somewhere seems to help me understand it better some how? Or at the very least, it is good reference material. So here it is.

Intermediate Algorithm Scripting: Diff Two Arrays
I solved something similar in Edabit, but like I said, I wanted to get more practice in with the methods am not yet familiar with. I got that I needed to concat() the strings and knew filter() was the likeliest method that would help me find the answer, but I had some help from the Internets and StackOverflow to get the conditional statement correctly with the use of ! and includes() which I am not yet familiar with, nor would it be something I would have thought to use right away. I also poked around with trying to figure out how to refactor it a bit into all arrow functions, but rather move on to the next problem after a few failed attempts.
function diffArray(arr1, arr2) {
  var filterUnique = arr1.concat(arr2).filter((elem) => {
   if (!arr1.includes(elem) || !arr2.includes(elem)) {
     return elem;
    }
  })
  return filterUnique;
}  








Monday, July 1, 2019

Day 085: Finding the Sum of Consecutive Numbers with Javascript (Easy Mode w/ Carl Gauss)

While I am still digesting all the information from the Functional Programming section in FCC, I started to poke around the Intermediate Algorithm Scripting section. Low and behold, the first challenge was to Sum All Numbers in a Range.

I know that FCC wants us to do a loop, but that's boring since' I've already done a type of problem like this at least twice in Edabit and Codewars. After solving the problem there I was able to review how other folks solved this problem and recall that a few have used a formula, so cue up Google to search around. Gauss on Arithmetic Sequences hit the spot! The site goes into length about the formula and why/how it works. But I found what I was looking for here:



Where n is the number of integers.

Or for the purpose of applying it to the problem, I will use the below simplified formula.




And below are two versions of the answer. (Equations created with CodeCogs)

function sumAll(arr) {
  let min = Math.min(...arr);
  let max = Math.max(...arr);
  return ((max - min + 1)/2)*(min + max)
}

const sumAllCodeGolf = (arr) => ((Math.max(...arr) - Math.min(...arr) + 1)/2)*(Math.min(...arr) + Math.max(...arr));

Easy peasy! I think it's still good to practice writing out the loop as well. However, I am at the point where I've done enough of these arithmetic challenges that I'm getting clued into the fact that there is likely a formula for most things. If it doesn't break anything in JS, why not use it?

Quick Retrospective

Since it is Day 85 and I am 15 days away, I figured this was in order.

I know it is not recommended to do this, but compared to other folks that started around the same time I did, including some of those with zero HTML+CSS experience, I feel like I am about a month or two behind them in terms of progress. If we're using FCC as a yardstick, they're all in and around the Data Visualization section and I am still stuck in the Algorithm and Data Structures.

However! I am aware that the working like a Japanese salaryman hours that my day job demanded ate up 2.5 weeks in May and then getting into the funk due to the stolen phone/invasion of privacy last month severely demotivated me for another 2 weeks or so. I also took a long detour into Udemy courses (which I still plan on finishing) as well so FCC is not the best yardstick really. I guess that works out to be why I am "a month behind."

We all know the reasons why you should not compare your current self with someone else. Everyone learns differently and may have other circumstances in their lives that may help or hinder progress. Someone spending time between semesters at their parents home, covering their room and board will probably have more time to learn than I would since I have that day job eating up 9+ hours of my weekday (if you add in commute time). And I am probably better off in terms of being able to dedicate time to learning than a working parent with kids (and kudos to them!).

But the reason I follow these folks is not only for the camaraderie, but because I find myself feeling pretty hopeless and demotivated and I actually feel like the comparisons actually help motivate me! What it boils down to is that they are able to dedicate a whole lot more hours then I can (whatever their circumstances) whereas I sometimes only squeak by with the minimum 1 hour a day (or less on a handful of days). It makes me want to find ways to get in more hours! In fact, this was the reason I got out of my funk from last month.

Also seeing someone else's progress is extremely gratifying to me as well. The thought of "I can get there too as long as I put in the time!" is the first thing that crosses my mind.

So as long as you are aware that this is not a race, I don't think comparisons are inherently a bad thing. There are always ways to turn it on its head and use it to your advantage.


Tuesday, June 25, 2019

Day 079: Accessing Objects with Variables

Still working through the FCC Javascript Algorithms And Data Structures section and I am going through them pretty quickly thanks to all the practice I got on Codewars and Edabit as well as Angela Yu's Bootcamp (which I still haven't finished by the way. Currently at 90% done... need to finish soon!). I am hoping to get the certification for this section sooner rather than later. No specific date, other than "soon". Whenever I list a date, I seem to jinx it where something shitty occurs and derails me for a bit.

But I digress. So I also managed to finish two of the projects for the certification, the Palindrome Checker and the Telephone Number Validator (Regex). I think they are the two easier projects (and I actually enjoyed regex?) so I expect to spend a bit more time working through the other ones. I already looked ahead and they seem pretty difficult!

Anyways, I just want to plop the bit below as a reminder to myself on how to access through the keys of an object, in the below example is by using the For In loop (which I need more practice with).


let users = {
  Alan: {
    age: 27,
    online: false
  },
  Jeff: {
    age: 32,
    online: true
  },
  Sarah: {
    age: 48,
    online: false
  },
  Ryan: {
    age: 19,
    online: true
  }
};

function countOnline(obj) {
  // change code below this line
  let count = 0;
  for (let user in obj) {
    console.log(obj[user]["online"])
    if (obj[user].online === true){
    count++;
    }
  }
  return count; 
  // change code above this line
}

console.log(countOnline(users));

I got really tripped up with this one. Just a note to myself that I need to use brackets when accessing the key values with a variable!

obj[user]["online"]   or   obj[user].online

It was something I was banging my head over for about 30 mins. /bleh

Oh yeah, I changed the blog subdomain from anncc.blogspot.com to anncodes.blogspot.com. Not sure why I didn't think of that to begin with..


Sunday, June 23, 2019

Day 077: Finally Out of the Slump? Coding/Algorithm Challenges

As I eluded to in my tweet, I was still feeling some sort of way after the theft and invasion of privacy so much so that it affected me a lot more than I care to admit. It still really bothers me even now.


Like I really couldn't bring myself to do anything productive and only squeaked by with "coding" by watching (and sometimes coding along) with videos CSS, NodeJS and such. But thankfully a member from my Daily Accountability group suggested doing Codewars problems together which really helped get me out of the slump.

I really enjoyed it when I did the Lighthouse Labs 30 day challenge. But now that I am kind of having a go at it myself, I am finding the challenges on these types of sites really addicting. And I get to learn more about JS and practice to boot!

So far, I've signed up for:

I think I will stick with those 3 for now. 3 is even probably a bit much right now.

I like the Codewars set up the most, though it can get really slow at times. Edabit is a close second and is much faster. Hackerrank can be confusing at times with their instructions and set up (or maybe it's the issues with the particular set of challenges I've encountered), but so far so good. What is great about all of them is that they display other user solutions after you complete your own which also has been a great learning experience to see how more experienced folks do it. This sometimes leads me down a rabbit hole of learning about different methods and getting more exposure to them.

FreeCodeCamp Challenges

Even better was finding out that FCC had challenges in their JS Algorithms & Data Structures section. I mean, I probably peeked ahead at them when I started FCC way back when and thought to myself that it all looks like gibberish and that it will make sense to me in time... well, now's the time! I guess I want to save some of my answers that I was particularly pleased with.

Basic Algorithm Scripting: Return Largest Numbers in Arrays
Probably not the most efficient code in the world, but I was pretty happy with solving this one. It is close to the basic solution they presented.
function largestOfFour(arr) {
let answer = [];
  for (let i = 0 ; i < 4 ; i++) {
    let maxNum = arr[i][0];
    for (let j = 0 ; j < 4; j++){
      if (arr[i][j] > maxNum) {
        maxNum = arr[i][j];
      }
    }
    answer.push(maxNum);
  }
  console.log(answer);
return answer;
}


Basic Algorithm Scripting: Title Case a Sentence 
I solved a similar one to this particular challenge in Codewars (or was it Edabit?), but it was done with the basics length and iterating through the array with a for loop. I needed some practice with using map() and came up with the below. It's a bit of "code golf" (for me at least). I also got some use out of substring() as well!
function titleCase(str) {
  let arr = [];
  str.toLowerCase().split(" ").map(x => arr.push(x[0].toUpperCase() + x.substring(1)));
  return arr.join(" ");
}

titleCase("I'm a little tea pot");


Basic Algorithm Scripting: Chunky Monkey
Only because I wanted to get more practice out of a while loop, I came up with the following answer which is similar-ish to one of their advanced solutions. I also ended up using slice() and originally attempted to push it into an array assuming that it removes the items from the array, but slice doesn't work that way. After peeking at the rest of the solutions, what I wanted to use was splice() which does actually remove the elements from the array.
function chunkArrayInGroups(arr, size) {
  let answer = [];
  let add = 0;
 while (answer.length < arr.length/size) { 
     answer.push(arr.slice(0+add,size+add))
     add = add + size;
    }
  console.log(answer)
  return answer;
}


Basic Algorithm Scripting: Mutations
A tiny bit more code golfing.
function mutation(arr) {
  for (let i = 0 ; i < arr[1].length ; i++){
    if (arr[0].toLowerCase().indexOf(arr[1].toLowerCase()[i]) < 0) {
      return false;
    }
  }
  return true;
}


JavaScript Algorithms and Data Structures Projects: Telephone Number Validator
This one was a doozy. I was initially very scared of regular expressions, but after going through the RegEx section in the FCC, it's not so bad! Especially when you have a handy tool like Regex101 with you.

FCC's regex /^(1\s?)?(\(\d{3}\)|\d{3})[\s\-]?\d{3}[\s\-]?\d{4}$/ 
MY regex /^1?\-?\s?(\(\d{3}\)|\d{3})\-?\s?\d{3}\s?\-?\d{4}$/ 

I was surprised at how close I came to their basic solutions. My answers aren't a perfect match but it still works. That's what I love about programming.. there's more than one right answer!


Sunday, June 16, 2019

Day 070: In a Slump - Phone Stolen

So the day after the last post, my phone was stolen when I was at the grocery store. It was a first generation Pixel that was due to be replaced anyways so in terms of actual cost, at most I lost the $50 or so trade in value for the phone.

Originally the phone was connected to a case in which my car keys (with the keyless fob) was attached to, along with my IDs, and credit cards. I do not carry cash. Initially, with the car keys alone being gone, it could have been about $700 to reprogram and replace (which is freaking ridiculous, btw). As well as paying to replace the word ID and drivers license which would have cost $25 per ID. Cancelling the credit cards were easy enough. And $400 to replace the cell phone, which I was delaying another year since I was saving up for a vacation and the Pixel still worked just fine. There was also the worry that since my IDs had my address on it, the thieves would know where I live and had my house keys so the locks would need to be replaced.

Unfortunately, the store cameras were not facing the aisle my cart was in, so they were not able to confirm who took it. I also reported it to the police, but that didn't do much either. But I suppose the silver lining was that 2 hours later, everything else was returned with the exception of phone being ripped out of the case. I am still going to change my locks as a precaution.

Oh yeah, the feeling after realizing it was gone was one of panic and vulnerability. And the fact that I did not even know anyone's phone number to even call for help was even worse! The only number I knew was literally my own phone number! The grocery store was a 30 minute walk from home and that's what I had to do. It was not a good walk home.

The likeliest culprit was probably a pair of teens hovering around me before it was stolen since it was about 1 min between checking my phone and finding it missing. At least that is my hope because that phone connected to a whole lot of accounts: emails, work, medical, retirement and I am hoping that teenagers are less nefarious in terms of trying to break in and get my personal information. No, I am not the type of person to take compromising photos of myself or anyone (that's just stupid) so at least I don't have to worry about that. Everything was password protected and changing the login credentials would just about block everything out. I am not sure if I set it up so that the memory is wiped after multiple failed attempts of logging into the phone. I did try the Find My Device tool from Google and the phone never reconnected with the network after it was stolen. My hope is that if I did not set it so that the memory is wiped after X failed attempts, that they just did a reset and wiped everything.

There were lots of accounts I had 2 factor authentication to which essentially blocks out many of my accounts until the new phone arrived and the suspended number reactivated.

So I basically spent about 8 hours following the theft on the computer changing passwords and on the phone with various companies in regards to proving my identity to reset the 2 factor authentication. Then I spent the next few days worrying and dealing with follow up issues of not being able to access accounts (including my work accounts, since they require 2FA to access the network).

Not to mention finally getting my new phone, the Pixel 3a and then spending 3 hours in Verizon last Friday trying to get it reconnected to the network so I can get my phone number back and finally re-access some of the 2FA that required my phone number. /Sigh

The theft happened on a Saturday afternoon. That was the weekend I was feeling pretty damn good about the highs previously and was planning on doing another Personal Mini Bootcamp on Saturday and Sunday. The best possible outcome in terms of least $$ associated of having my car keys returned happened. But even a week later, I still feel like shit about it all and just thinking very poorly of humanity in general. Seriously, who the fuck does that? And there's basically nothing I can do about it either.. nothing!

I've basically been derailed since then and had been trying to make myself feel better and not worry about the what ifs. It has been a lot less productive in learning to code and I have been feeling pretty demotivated. Compare the previous week of 22 hours of very focused coding and learning to barely getting to 10 hours in. And that is only because I had to make myself watch some videos on foundational JS or CSS to at least keep it in my mind, not that I was actively coding or anything. It's been a week and I am not sure how to get myself motivated again. Ugh.

I was attempting to do another mini bootcamp at least one 8hr day of coding this weekend and not just watching videos. But I find myself procrastinating by cleaning the house or other menial chores, playing video games, or even using my family as an excuse to stay away from the computer and generally keeping my mind off things.

I know I need to give myself the permission to do what I need to do to feel better, but the fact that I am cognizant of how much the theft and invasion of privacy is affecting me makes me upset even more. /Sigh

I'll do what I have to do and hopefully my next post is back to normal.


Friday, June 7, 2019

Day 061: Networking and Support Wins

Hey! It's been one day over two months since I started learning to code! Woo!

I'm still going through Angela Yu's Web Dev bootcamp (getting close to the finish line!). I've only finished a few small independent projects along the way and hope to get much more under my belt in the coming days. I didn't finish the FCC JS certification yet since I was interrupted with the busy season at work and I took a detour into the wonderful world of Udemy. I do intend to get that FCC JS certification eventually!

In the meantime, I want to report a few significant wins this week. Before I start, let me preface it with the fact that I am an introvert and I HATE having to go to networking events. I would rather get my teeth pulled than to have to small talk myself though these types of things. It is just so uncomfortable for me, I am figuratively dying inside. However, I've worked in front-desk type positions before and overall have been working long enough generally that I can fake it through the whole thing so that people around me don't get so uncomfortable with me being so awkward and in pain (or maybe they do notice? That would explain the cautious backing away, lol).

Monday: The Approach 

So I am part of a leadership program at work. It's a small internal program that consists of workshop and presentations. My cohort was having our graduation ceremony of sorts this past Monday. Let's just say I would not have joined this program if my boss didn't strongly urge me to do it. It is a pretty good program and a convenient excuse to get to know other folks at my workplace (and I actually made a friend out of it). But if I had a choice not to participate (without looking bad to the higher ups), I would have chosen to stay away from it.

So "graduation" rolls around and I was delighted to find that the guest speaker was a CEO of a machine learning company in the city! Yes, one of the few female CEOs of a tech company! Wowowowowwo! Her speech was short but inspiring and I was sitting on the edge of my seat drinking in everything she said!

Before she even finished, I already decided that I will approach her and began formulating how I was to do that, since I NEVER do anything like this. I wondered how my extroverted, salesy friends would do it? Even so, I didn't think too hard about it, because I approached her after right away and told her how inspiring her story was (and it was!). I also told her that I was currently learning to code and am hoping for a career transition. I was sweating bullets the whole time and my heart was racing and was trying really hard to not be awkward and weird.

Imagine my surprise to see that she was so excited for me and was even saying how she has some positions opened in her company (where I had to meekly inform her that I was not quite at that level yet). She offered to connect on Linkedin and later have coffee...!! Ahhhhhhhhhhhhhh!!

If you told me 3 months ago that I would have done something like this, I would have laughed in your face. I still can't believe that I did this. It was way out of my comfort zone, but so worth it.

Wednesday: The Science Fair

The second event was another internal event for career development/connections. I didn't actually plan on going to this but was walking by a sign they had with a greeter standing by. I mentioned to myself "oh yeah, this is going on." The greeter heard me and said, "You should go!" So I thought why the heck not? And off I went.

It was sort of set up like a science fair how each department had their own table. My org is big enough that each major department (or channel?) has their own HR, admin, marketing, IT, development teams as well as organization-wide teams that oversee the overall mission of the organization.

At the event, I found some friends and chatted with them a bit. After everyone took their leave, I kind of poked around to look for the organizational wide IT/tech dept. There was only one person manning their table and someone else was talking to them. I loitered around a bit looking at their job postings, none of which I was qualified for and waited for my turn to chat. There were a few times I was tempted to just walk away because I felt awkward and uncomfortable, but I am glad I did not. Eventually, I had my turn and awkwardly fumbled out my words (so awkward!) and told the woman I was learning to program and am looking for a career transition. But once I began talking, I could not believe how excited I was to talk to her and I could not shut up.

She was an HR person who works for the tech dept, but still was so happy for me to be a woman actually interested in tech. As I was yapping on, there was another woman who approached and was awkwardly waiting for her turn to talk to the tech dept and I just randomly asked what programming languages she knows. My husband tells me later that this was kind of a silly question and should have asked her what stack she was working with instead. Hey, I am new at this! It was kind of evidenced in her face with the confused look she gave me (haha!). But she explained that she was in devOps for one of the smaller departments. However! Since she was already in the know, she referred me to a bunch of internal organization wide resources that I had no idea even existed! An especially important group is a women in tech group! Yassss!

Friday: Lunch Time

awesome support from a friend + delicious udon for lunch = WIN!
And just today at lunch, I had lunch with my friend in HR at a delicious Udon spot she introduced me to.

I finally told her about my plans on learning to code and pivoting to a different career in a year.

Since she works in HR, I was a bit shy in letting her know. I knew each other before I started working at the same place and have become better friends since I started working here. However, I was unsure of how she'd feel/react because she is in HR after all. This news can potentially can affect her work. I also had a fear of her telling my boss before I was ready (which she would never do, honestly, but the fears there).

But you should know the theme of the post by now. She was absolutely SUPPORTIVE of me and my decision. She was going so far as offering to help connect me to folks she knew in our IT/tech department. I was planning on approaching them anyways, but getting an intro would be even better!

Too Long Didn't Read

I am getting way out of my comfort zone reaching out to people and realizing how it does NOT feel uncomfortable when it is about something I am passionate and care deeply about.

Just is put yourself out there! You will be shocked at how people just want to help and see you succeed! You might even surprise yourself as well.

I am just bursting with so much optimism and motivation right now!

Wednesday, May 29, 2019

Day 053: BTDT Tip Calculator & Bill Splitter - using parseFloat, toFixed & building it in order to make it work!

Yesterday, I took take a short break from the bootcamp for a day to let the information sink in a bit (see active and diffuse learning). So what better time than to do my next BUILD THE DAMN THING project. It is a handy tip calculator & bill splitter that I probably spent way more time on that I should have.

See the Pen Tip Calculator/Bill Splitter by 4nn (@4nn) on CodePen.

Some Things I Learned

I guess I already knew these things, but it was more so putting it into practice and getting to experience the joys of parsing strings to numbers to strings to numbers so the formula would work.

I initially thought this would be quick and easy since I banged out the formula in the console in less than 5 mins.

parseInt(), parseFloat(), .toFixed()

Of course the console just deals with the parameters as numbers. It is a different story when you are pulling values from the DOM, which would output those numbers into a string. You can't really do math with strings!

So I became intimately familiar with the parse functions to get those strings into numbers. (Good to know when I tackle the building a calculator project)

parseInt() parses the value into an integer. I used this in the beginning since I was testing with whole numbers.
parseFloat() parses the value into the floating point number (with all the decimals and such).

Once that was all set, I later used the .toFixed() method to get the numbers into 2 decimal places.

Voila! The math actually worked with the DOM in codepen!

So I go about to add in the conditionals and error messages and such, but the conditionals did not work because it was essentially asking if the preTipBill === NaN. Why did it keep coming up as NaN even though the math worked out previously? Enter frustrationland!

My husband probably noticed my annoyance after some time which was his cue to help (of which I didn't ask for his help, but recognize that I need to get better at knowing when to ask). So he identified that I was doing too many things at a time before calling the if statement. I was assigning the DOM values to the variable and then reassigning the variables to parseFloat().toFixed() and then setting the condition statement. It looked something like this:

 let preTipBill = document.getElementById("preTipBill").value;
 preTipBill = parseFloat(preTipBill).toFixed(2);
 let tipPercent = document.getElementById("tipPercent").value;
 let splitBetween = document.getElementById("splitBetween").value;
 splitBetween = parseFloat(splitBetween).toFixed(0);

 if (preTipBill === "" || tipPercent === "" || preTipBill.length === 0 || tipPercent.length === 0) {
  ...
 }

Of course that mess was then checking the if conditionals to preTipBill === NaN which is not what I want especially when trying to reassign blank splitBetween values to 1 if the user opts not to split the bill. Anyways, once he pointed that out, I got it right away. Like, RIGHT AWAY. Rookie mistake!

  let preTipBill = document.getElementById("preTipBill").value;
  let tipPercent = document.getElementById("tipPercent").value;
  let splitBetween = document.getElementById("splitBetween").value;

  if (preTipBill === "" || tipPercent === "" || preTipBill.length === 0 || tipPercent.length === 0) {
    document.getElementById("output").innerHTML = "Please input all required amounts!";
  } else {

    preTipBill = parseFloat(preTipBill).toFixed(2);
    splitBetween = parseFloat(splitBetween).toFixed(0);

I needed to reassign the values LATER, preferably once the condition is met. Just moving the reassignments fixed the whole thing. Sheesh!

In working through all the projects in the Angela Yu Web Dev Bootcamp, the location of the reassignments were sort of laid out for you when working through the projects and it made a ton of sense at the time, of course. But it really isn't until you've been frustrated and 😬 over it for an hour that it really sinks in. The ORDER of your code matters! I found this to be a very valuable lesson.

On a side note: it's my mom's birthday this Saturday and I'll definitely be pulling out this little calculator at the end of the meal!

Here's the User Story
  • user inputs total initial bill
  • user inputs desired tip amount
  • user gets error message if initial bill and tip amounts are missing
  • display the tip subtotal
  • display the total amount
  • user can opt to split the bill, input number of people to split it with
  • display the per person initial bill
  • display the per person tip and total
  • if user does not split bill, only display the tip & final total
  • have button calculate and clear all