Where makeup meets code!
I love eyeshadow. I have over 40 eyeshadow palettes (a palette is a container with any number of individual eyeshadow colors), and I don't think my obsession diminishes my status as a progressive woman in technology. I am known for my sparkly blue colors which represent my never-ending devotion to Ravenclaw house in Harry Potter. The sad truth, however, is that I suck at choosing and applying eyeshadow, which might have something to do with the fact that
- I have too many colors to choose from, and
- I need to take my glasses off to do it.
Yet this doesn't stop my insatiable need for acquiring more shadow options. After I left my trusted makeup store last week having spent over $100 in products, including a new eyeshadow palette (none of which I needed), I thought
"if only choosing and applying eyeshadow was as easy as writing a function."
That is the origin story of this blog post. Using code to solve practical problems is a hallmark of the field of technology, but it takes practice. Here is my attempt at a "think-aloud"* to solve my eyeshadow problem.
*For those of us with a background in education, a think-aloud is a method of making an invisible thought process, visible. We use this technique frequently in reading instruction.
Function Basics and My Eyeshadow Routine
Understanding functions is a rite of passage in programming. When you first begin your journey, you write out each and every line of code, numerous times. Enter functions. A function is nothing more than a procedure, a set of steps for completing a task. Generally, a function will take some input data, perform the required procedure with that data, and return any resulting data. What makes functions so versatile in code is that you can call that function, or set of steps, over and over again with different inputs, hence different outputs.
Putting on eyeshadow is like following a set of steps. I stick to the same set of steps (function) for choosing and applying eyeshadow practically everyday illustrated in the below diagram.This image was part of a blog post on BellaBox HERE
Let's think about this in terms of programming where we have an input, a set of steps, and an output.
- Input: I need to input an eyeshadow palette. Let's say the "Sweet Peach"palette by Too Faced Cosmetics.
- Function: My function needs to filter through all of the colors (18 total) and find the four key colors to use: highlighter, medium, smokey, and blender.
- Output: Tell me specifically which colors match which eye application area.
Input Eyeshadow Data
Have you guessed the first problem here? The input data isn't as simple as a variable with a string or number value:
The Sweet Peach palette has 18 colors. You might be thinking, we can write each color out in an array (or list):Yes, that's only 6 out of the 18, and yes, eyeshadow color names are quirky.
There is still a problem with the shape of this data. An array is just a list of the colors. Each color needs a label to identify which type of color it is: highlighter, medium, smokey, and blender. A better option might be an array of objects. An object is a collection of data organized by a key and a value. In each object here, we have two key value pairs, one for the type and the other for the color:
Perfect. Every time I use "SweetPeachCombination" as my input, I will know exactly which color to use for which part of my eye.
FindColor Function: The Parameter and the Argument
Now that we have some data, we can look at what the function might do. I want to be able to call this FindColor function with any input data and know exactly what color goes where. First, I need to loop through the array. Then, I need to log the type and color. The code could look like this:I am using ES6 template literals in the console.log.
Since this is not actual code, I'm just going to log the information to the console. On my actual website, I update the information through the DOM. See website HERE.
Let's dissect the above code.
The function is called findColor, and it has one parameter.
Parameter, here, is a technical way of saying input placeholder — meaning, we need the combination information in order to run the function. Remember, though, we can use any combination we want, so the parameter is not specific.
How do I tell the function which combination to use? When we call the function:
we pass in the specific combination. This changes the technical word. It is not a parameter anymore, it is now an argument. The difference being that this is the real data, not a placeholder. You can see that clearly because the parameter is called "combination" while the argument is called "SweetPeachCombination."
Refactoring the Eyeshadow Inputs
Seems like a pretty lame function right now, right? I'm literally giving it the data of which color goes where and then having the function spit that information right back out (the output). But remember I have 40 palettes of eyeshadow. I honestly can't remember each individual color or possible combination. Right now, I have just one combination for just one palette…
I bet you see where I'm going with this.
My eyeshadow input data doesn't reflect reality — multiple palettes with multiple colors means endless possibilities. The shape of the data does not have to change, but I need to add more information:This is one of my blue combinations, so I've named it accordingly.Can't leave out Slytherin House and the green combination!
Naturally, we will need to revise the function based on this new information, but that's the easiest part:
Theoretically, I could have 400 combinations! I don't have that kind of time in the morning to look for the right combination. That's why my FindColor function works perfectly. Everytime I call that function, I use a combination argument.
The Most Important Part
I say this all the time about programming. If you can dream it, you can build it.
I dreamed of an eyeshadow color picker, and I built it (screen cap below).Check it out HERE. Get the code HERE.
So what are you going to build next?
Learning To Code Is Hard, But You Can Do It!
Learning new skills can be frustrating. The natural ups and downs on the path to progress can cause learners to become stuck, encounter mental blocks, or even give up altogether. As a former college professor in the field of education, I can say with certainty, a little knowledge about educational psychology goes a long way when you want to be a successful student of code. With a few tips, you can take charge of your learning and persevere.
You'll be creating Patronuses (I mean code) in no time!
Learning to code is not quick and easy. Many coders, including myself, have discussed reasons why learning to code is so challenging (here, here, here, and here). To become a programmer, you need to have experiences that force you to move through a hierarchy of learning objectives (known in education as Bloom's Taxonomy of Learning). Doing so ensures that you can progress from simply recalling coding concepts to being able to develop your own original code. Bloom's Taxonomy has six levels: Remember, Understand, Apply, Analyze, Evaluate, and Create.
In this post, I address the six levels in the hierarchy, describe the types of learning outcomes in each level using action verbs, provide a clear example from the Harry Potter series (with a link to the corresponding video clip), and then relate it back to learning to code.
In this level, you are able to recall, recite, define and list.
In this level, you are able to explain, discuss, describe, and report.
In The Sorcerer's Stone, Hagrid takes Harry to get his school supplies, and Harry takes the opportunity to ask Hagrid about his dead parents. Hagrid explains the events surrounding their tragic end, but also describes the condition of the wizarding world at the time, and they discuss the scar on Harry's head. When do you need to discuss your code like this? One example is when you ask for help. If you use Slack or Stack Overflow, it is critically important that you describe the code you have written, what you expected to happen, what happened instead, and what you tried as a result. You may not have the solution to fix your code, but you demonstrate that you understand where you are in the process. Force yourself to go through those steps when you want to ask for help. It will reinforce your understanding. Often, when I go through this process, I am able to answer my own question at the end. It is the process that engages our brain. (View Scene Here)
In this level, you are able to use, implement, and demonstrate.
During Defense Against the Dark Arts class in The Prisoner of Azkaban, Professor Lupin explains how to deal with a boggart, a creature that feeds off of your fears. First, you must concentrate on something absurdly funny and then clearly enunciate the incantation: Riddikulus. In the scene, the Professor has the students use the spell against a real boggart. Doesn't this example of applying feel like practicing? That's because practicing what you have learned is extremely important regardless of the subject. With coding, though, this means you can follow the coding requirements of a user story to demonstrate what you have learned. For example, the FreeCodeCamp curriculum asks you to complete a variety of assignments such as a tribute page, a random quote generator, and a weather application. To do this, you must recall and understand the coding required. You may still need to "Google" some of your code, but that is all part of demonstrating your ability to apply what you have learned. (View Scene Here)
(Can you guess the subject of my FreeCodeCamp tribute page? Take a look here.)
In this level, you are able to draw conclusions, make connections, and compare and contrast.
At the end of The Chamber of Secrets, Harry draws conclusions and explains to Ron that the monster from the Chamber is a basilisk, a serpent. He connects the information about the basilisk provided to him by Hermione with clues from each time the monster encountered a student (they were turned to stone rather than killed). Harry also deduces that the voice he (and he alone) has been hearing is the basilisk since only Harry can understand Parseltongue (snake language). As Harry draws conclusions, he has an almost "Aha" moment. It's not unlike the moment you examine error messages from your code in Chrome Developer Tools and know what to do to fix the broken code (analyze and apply). As a developer, you will need to analyze your code on a constant basis, but analyzing only comes after you not only recall but also understand and apply code. (View Scene Here)
In this level, you are able to critique, assess, select, and justify.
In The Order of the Phoenix, Harry teaches a group of fellow students defensive spells and charms to protect them if they should encounter a Death Eater. As Harry walks around the group, he assess the use of spells and offers suggestions on how to improve — he shows Neville how to properly move his wand and suggests he focuses on a fixed point. In one scene, he even raises some students' wands higher for better execution. Of course, you won't have Harry critiquing your code. Instead, a programmer must critique their own code and look for places to make the code more efficient. Doing this without changing the outcome of the code is called refactoring. Sometimes you need to evaluate code before you write it. For example, you may have a situation where you could use more than one type of function: is using an if statement better than using a switch statement? Weigh your options and select the most appropriate option. Evaluating is a natural extension to analyzing. (View Scene Here)
In this level, you are able to develop, design, work, and assemble.
We never truly understand just how brilliant Professor Snape is when it comes to magic until The Half-Blood Prince. Harry stumbles upon Snape's old Potions schoolbook, and in the margins finds that Professor Snape (known only as the Half-Blood Prince) has created brand new spells, many of them curses, and modifies existing potion recipes for better implementation. Unfortunately, Harry tries the "Sectumsempra" curse on Draco and nearly kills him. You don't have to create evil curses to know you have achieved some mastery in coding; instead, you can take an original idea, wireframe it, build it, and troubleshoot it. Notice, though, that you must have gone through all levels of the hierarchy in order to successfully create. Snape would not have been able to develop new curses if he didn't first remember principles of magic, understand spellwork and evaluate his progress. (View Scene Here)
Learning coding, like magic, isn't easy. It requires hard work and patience. You must remember that Harry doesn't really perform much magic on his own in the first book. He hadn't learned enough yet. Regardless, he still became a great wizard and eventually defeated the evil Voldemort. Keep that in mind on your journey to becoming a programmer. It won't happen over night. Focus on experiences that will move you through the hierarchy of learning.
One thing Harry has that we all need is friends to share the burden. With Ron and Hermione by his side, the three friends persevere through many challenges. Find your "Ron" and "Hermione" in the coding community by joining a study group, attending meet up events, and participating in discussion boards either on Facebook, Slack, or Stack Overflow. But be patient with people. You don't know where they are in the levels of hierarchy.