Avoid Loops, Use Map()

roller coaster loops
roller coaster loops

Loops make me dizzy. I would rather write my code using the map() function. It’s similar to a foreach loop, but with a twist. Instead of traversing a collection, map() transforms a collection. I only realized this similarity, however, after writing many loops where I should have used map().

Today, this is how I decide which to use:

  • Map() function – use when transforming a collection
  • Foreach loop – use when traversing a collection
  • For loop – only use when I don’t have a collection

Transforming Collections

Collection is a general term — it’s any variable that contains elements. For example, my collection of selfies that I took at an art museum. I want to transform my selfies into black-and-white photos before uploading them to my social feed.

3 selfies I took at an art musuem
Grayscale versions of my selfies.

Foreach Loop

Assume I have a pure function called grayscale() that takes an image and returns a grayscale version of that image.

const selfies = [selfieA, selfieB, selfieC];
const coolSelfies = [];

// ES6 JavaScript foreach loop syntax
for (const selfie of selfies) {  
   coolSelfies.push(grayscale(selfie));
}

This code works fine but has a readability issue. A future maintainer of the code must spot the push() statement to understand the relation between selfies and coolSelfies. This may seem like a small gripe. But imagine if that statement was buried under more lines of code. The relationships between collections can become confusing.

Map() Function

I should have written the loop using the JavaScript array map() function.

const selfies = [selfieA, selfieB, selfieC];

const coolSelfies = selfies.map(selfie => {
   return grayscale(selfie); 
});

This code highlights the relationship between the two collections — coolSelfies is declared as a transformed version of selfies. Transforming a collection means looping through a collection for the purpose of building a new collection. Using map() clarifies this intent to readers.

Code Clarity

In JavaScript, the arrow function syntax allows an implied return statement if I leave out the curly brackets.

const coolSelfies = selfies.map(selfie => grayscale(selfie));

Depending on how grayscale() is defined, I can make this code even shorter by removing the anonymous arrow function.

const coolSelfies = selfies.map(grayscale);

I can read this code easier than a loop. But not all loops should be avoided. Loops that don’t transform a collection should stay as foreach loops.

Traversing Collections

Traversing means iterating or looping through a collection. For example, I want to post each of my cool selfies to my social media feed. Assume I have a function upload() that takes an image and uploads it to the internet.

for (const selfie of coolSelfies) {
  upload(selfie);
}

An alternative choice would be using the JavaScript array forEach() function.

coolSelfies.forEach(selfie => upload(selfie));

This is a case where a foreach loop is better than a map() function, because of several reasons:

  • upload() has no return value, so there is no way to create a new collection from the loop.
  • upload() isn’t a pure function. It’s best practice to not use map() with functions that have side-effects, such as starting an upload.

Code Clarity

At this point, I must contradict myself. Loops are often more readable than map(). Programmers understand loops. Loops are common. Loops exist in almost every programming language.

The map() function is not as widespread. It involves functional programming. Functional programming is not how most people learn to code, regardless of being trained or self-taught.

I’ve refactored many foreach loops into map() functions thinking I was making the code more readable. I try not to do that anymore. It’s not worthwhile to tear up vetted code just to avoid loops.

Avoid For Loops

A less drastic approach is to avoid writing for loops. Here’s my original loop as a for loop:

const selfies = [selfieA, selfieB, selfieC];
const coolSelfies = [];

for (const index = 0; index < selfies.length - 1; index++) {
   coolSelfies.push(grayscale(selfies[index]));
});

The for loop signature (the length conditional and the index variable) takes up a lot of space in my code. But the size of the loop and the direction of the loop aren’t actually that important. A foreach loop would be better here because it abstracts away those variables.

I still use for loops, but only for tasks that a foreach loop couldn’t accomplish. Such as precise array manipulation or looping a constant number of times.

Using the right loop for the job

Any type of loop will get the job done. But I like to use the most specific type of loop that I possibly can. This clarifies the code and prevents bugs.

  • For loop – general looping
  • Foreach loop – looping through a collection
  • Map() function – transforming a collection into another collection

If you want to learn more about using map() in your code, read up on functional programming. Functional programming is all about combining map() with other transformative functions, such as filter() and reduce().

Willpower is Overrated

path through a burned out woods, but with plenty of flowers growing

It’s been four years since I quit drinking.

When people learn I don’t drink, they often speculate that I must have a lot of willpower.

I don’t rely on willpower to stay sober. In the past four years, I’ve learned that constant vigilance is not a long-term solution to my goals.

Willpower is a Limited Resource

My self-control diminishes as my brain gets tired. There are studies that back up this theory. I can admit I think about drinking after a long day of work.

Instead of testing my willpower by going to a bar with coworkers, or a party with friends, I stay home and save my energy. It uses less willpower to make the decision before there’s even alcohol around.

Humans Are Fallible

People don’t always make rational decisions. In the past, I associated failure with a lack of willpower. Now I realize I was setting my expectations too high. I’m only human.

Knowing that I can be impulsive is why I’m so vocal about not drinking. When I do go to a party, I bring a case of La Croix, slap it down and announce “I don’t drink”. For that extra bit of accountability.

Willingness, Not Willpower

Willingness, not willpower, is the key to maintaining my behavior. I’m willing to decline party invitations, and I’m willing to tell people I don’t drink. I’ve declined so many beers that “no thank you” has become an automatic response. The willingness to learn this habit is very different than having an iron will.

This mindset has served me well. In the past four years, I’ve returned to school, graduated and started my career. Being willing to quit drinking, as well as not relying on my own willpower, has helped me accomplish these goals.

path through a burned out woods, but with plenty of flowers growing

2018 Yearly Roundup

Before launching into the new year, I try to reflect on the past one. For me, 2018 was a year of transition. I graduated, I got a job, and I started living on my own.California is my respawn point

Before launching into the new year, I try to reflect on the past one. For me, 2018 was a year of transition. I graduated, I got a job, and I started living on my own.

January

I started in Illinois, but I flew to California immediately to finish the last pieces of my Computer Science degree.

The Quad at the U of ICalifornia is green in the winter

Back at school, I starting learning a technology called Angular. This paid off because:

February

Having employment lined up, I focused on my schoolwork. Of course, I also went on lots of hikes.

Hiking!A Good OmenMy favorite spot in SLODunes at Grover Beach

March

I finished my senior project, I earned my degree, and I hiked up a hill to take this picture of the campus.

Cal Poly

The graduation ceremony wasn’t until summer, so I ran in a local 10K as a symbolic victory lap.

Finishing a 10k

Then I drove back to Urbana, Illinois.

The timing worked out to spend Easter in Boulder, visiting my family and friends.

Colorado

Boulder

April

Back in Illinois

I barely had time to catch my breath before…

Illinois 10K

May

I flew back to California for a big family reunion!

Family Reunion by Laurie Kantor Finn
photo by Laurie Kantor Finn <- one of my distant cousins

There were relatives from this side of family who hadn’t seen me since I was eight years old. It was a fun weekend.

June

Graduation Ceremony

I made one more trip to California this year, to attend my graduation ceremony.

A bittersweet moment indeed, because it felt like closing a chapter of my life.

grandparents

Walking across the stagedegree

July

Two of my best friends, Ray and Maria, married each other! I was asked to provide music along my brothers – what a treat to be part of that day.

Wedding <3Dressed up

August

My Autumn months were about getting into the Midwest mindset. I participated in lots of local events.

IndianapolisSweet Corn Festival

September

I moved out of my parents’ house to a place in Champaign, closer to where I work.

Then, I had my 10 year high school reunion.

oh 8!
“I can’t believe it’s been 10 years!”

I finished up the month with a visit to Chicago, and attended a local arts festival. The festival had a hackathon portion and my team got third place. We made a website about the local election.

Shedd Aquarium in Chicago.
the Shed Aquarium
Tesla Coil Performance in Urbana
Tesla Coil Performance

October

This was a super busy month for me, in the best of ways.

  • Visited Chicago again and went to the Museum of Modern Art
  • Got my SCUBA certification
  • Went to lot of Halloween parties
One with the computer
Rock Quary in KankakeeKickapoo State ParkPumpkin Party 2018Halloween Jam at the Pineapple Collective

November

Playing music for the fam

My brothers and I play 1930’s style jazz music, in a band we call the Hot Club of Urbana.

We played a mini-concert for our relatives who visited during Thanksgiving.

We also had two paid gigs this month. Playing music so often might be the best perk of living in the same town as my family.

The Iron Post
Iron Post with Hot Club of Urbana
Urbana Free Library
Hot Club of Urbana at the Urbana Free Library

Hot Club of Urbana

December

To top off a great year, my family vacationed in Costa Rica for Christmas.

Tamarindo
Resort land
Selfie time
Brothers on a bridge
Bayou
My family

Looking Back on 2018

Looking at my previous roundup post from last year, I hit these goals:

  • Graduating
  • Running a 10k – I ran two!
  • Contributing to an open souce project – I fixed a bug.
  • Playing more violin – accomplished with the help of my brothers

The goals I failed were:

  • Blogging often – I ended the year with only 5 new posts
  • Buying a new desk to help with my back pain
  • Replacing my bedtime phone habit with books
  • Reading 20 books – I read 14

Looking Forward to 2019

My resolution is to create a website for my band. It sounds fun to combine my music and programming into something new and personal.

I’m also setting these goals for myself:

  • Run a 10K in under an hour
  • Read 15 books
  • Redesign this blog. It’s still using a default theme.
  • Record music and post it online. I perform plenty, but recording is a different skill.
  • Get an adjustable standing desk for work
  • Sleep more than 7 hours a day on average. My alarm app tells me I’m only getting 6.5 hours
  • Contribute more open source code

Final Thoughts

2018 had me completing big life milestones left and right. I don’t expect this next year to feel as groundbreaking, nor do I need it to be either.

I plan to be in the Champaign-Urbana area for all of 2019. I’d like at least a year without feeling like I have each foot in a different state.

I want 2019 to be about consistency. I’m in a good spot, so a nice consistent year would let me finish my 20’s with a lot to be grateful for.

Happy New Years dear readers! Good luck in all your 2019 endeavors.

Costa Rica Pacifc Sunset

Book Review: Real-World SRE

Real World SRE

I picked up Real-World SRE: The Survival Guide for Responding to a System Outage and Maximizing Uptime, as a crash course in the field (and also because I know the author from college). I assumed it would be about expensive technology, dire consequences, and the drive for 99.9999% uptime.

Turns out, reliability in the real world is:

  1. Identifying problems
  2. Learning to fix them
  3. Growing from the process

Any developer can benefit from this book. The technical sections are paired with functional advice about how to manage time, energy, and expectations. Because of this, I found it surprisingly relevant to my work as a frontend developer.

The topics I enjoyed the most were:

  • A deep dive into the inner workings of HTTP
  • UX design for admin dashboards
  • How to share knowledge between departments

This book convinced me that everyone (even the frontend team) should know where the backups are located. Who would’ve guessed that communication is the trick to reliability.

I’m Gay

Rainbow Flag

Anyone who interacts with me on a regular basis already knows I’m gay. But this is my first time sharing so openly online. My hope is doing so will encourage others in their own journey of coming out.

Myself

Growing up, the idea of me being gay was too anxiety producing to seriously consider. I didn’t start coming out to myself until I was 20 years old.

My Family

Telling my family took some guts, even when I knew deep down I would be accepted. I finally realized that keeping this secret was affecting my mental health. What a relief it was when I told my brothers, my parents, and my extended family.

My Friends

Today, I make it a point of pride to come out to my friends, my coworkers, and my neighbors. I figure being open about who I am helps fight the stigma. As an added bonus, coming out repeatedly lets me tally up confidence points.

The Internet

My coming out journey has included a parallel journey of coming into the LGBTQIA+ community. Nothing has helped my confidence more than seeing others like me succeed. This is why I’m coming out to the Internet today. I know who I am, and I want to thank my family and my community by sharing this feeling with the world.

Rainbow Flag

“rainbow flag on white background : harvey milk plaza, san francisco (2012)” by torbakhopper is licensed under CC BY 2.0

I Graduated

cal poly from the p

My first time taking classes at Cal Poly was in 2008, but I stopped attending regularly in 2012. I spent a couple years embracing the identity of being a Computer Science dropout, living at home, and working odd jobs. Time rekindled my desire to have a degree, and in 2016 I began completing the requirements I had left. So I was accompanied by a feeling of slight disbelief when I found myself flying back to California — to graduate as part of the class of 2018.

Walking across the stage

The ceremony had the desired effect of making my graduation feel like a reality:

  • The caps
  • The gowns
  • The fold-out chairs
  • The astroturf
  • The streamer cannons
  • The speeches
  • And the Cal Poly band
The commencement speaker was Andrew Jassy, the CEO of AWS (Amazon’s cloud computing service). It seemed to fit the occasion that the key message I took away from his speech was patience, especially in regards to my upcoming career.

degree

The Computer Science department also held a smaller, more intimate ceremony. The professors faces lit up with big smiles when they saw me. Over the years, they had observed me in and out of their halls. Every student had a chance to talk into the mic. When my turn came, I thanked the advising center for sending me that initial email in 2016 asking me to return. I thanked Cal Poly for keeping my credits around for 10 years. I thanked my parents and grandparents for supporting me throughout the entire journey.

My Mom <3dadgrandparentsSteak Dinner
After the ceremony, my family treated me to a California steakhouse. I ordered the biggest, best-tasting steak I’ve ever had. I couldn’t finish it, so I ate more for dinner the following night. But I couldn’t even finish it then either, and I ended up leaving the last piece of steak behind.
I felt like I was leaving a part of my heart behind in California too. Maybe one day I’ll be back. For now, I’m looking forward to spending some time in Illinois. Playing lots of music, and spending time with my friends and family. I want to become more involved in the local tech scene. And finally, I want to continue blogging, because this is an adventure worth sharing.

I Got Hired

I recently accepted a job offer at Pavlov Media, in Urbana-Champaign. After I finish my degree, I’ll start working there as a front-end web developer. I’m excited to return to my hometown, but I’m even more excited to call myself a college graduate and a professional software developer. These new identities are quite the boost to my ego.

My ego is telling me I’m at nearing the end of a great journey. I’m finally graduating, and I’ve landed a real developer job. Instead of this mindset, I’d like to think this is only the beginning of my journey. I want to be humble as I enter the industry. To remind myself, allow me to share two moments where my self-pride as a programmer has gotten the better of me.

I used to help run a website for Cal Poly’s campus radio station. I’d get emails telling me to post announcements and events, and I’d be unhappy when the descriptions for these events were not written yet. “I’m a programmer, but I’m being asked to do marketing”. I’d grumble and hastily write what was needed. I didn’t realize it at the time, but I’m sure the quality of my writing was affected by my resentment. Since then, I’ve become more open to practicing non-technical skills.

I’ve also learned not to equate my programming skills with my own self worth. When this happens, I don’t respond well to constructive criticism. During a code review at an internship, I remember being upset at one of my features being cut. Because my feature was deemed unnecessary, I felt unnecessary. But there was really no reason to take it personally. My pride prevented me from gracefully moving on.

I’m will try to take these lessons to heart as I start working at Pavlov Media. Thanks for reading and I’ll keep you all updated on how it goes.

View of Downtown Urbana” by Daniel Schwen is licensed under CC BY-SA 4.0

2017 Yearly Roundup

Today is January 1st and this blog turns 1 year old today. My resolution from last year was to blog weekly. I didn’t quite make my goal, but that’s all the more reason to write a yearly roundup! I was inspired by my friend Nat who does a similar style article every year. Kind of like sending out Christmas cards.

January

My family and I flew out to California to visit my grandparents, but also to finish my Cal Poly paperwork for my return. Then I celebrated my birthday with friends Emma and Sven who were traveling down the coast.

Trek

Winter Bird Festival

This month a close friend passed away unexpectedly. I tried to pour my focus into my class at the University of Illinois.

February

Meadow Brook Park

Mainly I was busy with group projects for my class, Operating Systems. My team members were entrenched in the student mindset, which I happily fed off of. We’d meet at Merry Ann’s diner and code into the night.

March

The Bean
China TownPokemon in Chicago

I visited Chicago twice, at the beginning and end of the month. First was visiting my cousin Sophia who goes to the University of Chicago. The second time was to visit my friend Tyler, who teaches high school in the area. We had a pretty mild winter, no snow to be seen at this point. Also, my Operating Systems midterm went well.

April

Meadowbrook Parksmoker cookout at Charlie's

At first, I couldn’t remember much from April other than doing my taxes (and playing the new Zelda). But looking through my pictures I can tell the weather was getting warmer. I went on some walks and my friends were having cookouts. In Illinois, people jump at the first signs of Spring to spend time outdoors.

May

Team Rocket cosplayMay Third

I finished my classes. To celebrate, I went up to Chicago again, this time for Anime Central. I’d never been to an anime convention before, I met lots of cool folks, saw some cool costumes.

June

The local farmers market started so my brothers and I busked on the weekends. It gets hot playing up a storm, so I was grateful for the powerful AC at my mall job afterwards. I’d get a cold brewed coffee from the market, and then lead game demos outside the store. What a great combo and a great memory.

Farmer's MarketDr G's Brainworks

July

I went to Chicago again, this time for Pokemon Go Fest. The actual event had technical issues, but I still got to wander around downtown with my family and friends.

pokemon go fest
Articuno get

Near the end of the month I visited a friend in Atlanta for the first time. I hiked up a hill with my violin and played music with a hula dancer by chance.

Kennesaw Hill

August

Prairie Fruit FarmBig gig

Playing at the farmer’s market got us a gig at a goat farm!

They Might Be GiantsSolar Eclipse

My family also continued our tradition of going to Gen Con, a board game convention in Indianapolis. There we saw a They Might Be Giants concert,. and the timing was right for driving south to the solar eclipse afterwards. Unfortunately, a cloud covered up the sun at the exact wrong time.

September

Plains GuardDetour near BoulderSomewhere in the southwestNot actual state line

I drove from Illinois to California because it was time for classes at Cal Poly, the final step in getting my degree. I was anxious, as technically I was crashing one of the classes. But things went smoothly, I made it to San Luis Obispo on a rainy day, and started school a week later.

Morro Bay RockSan Luis ObispoHearst CastleBubblegum Alley

SLO life is good and I feel pretty much right at home here.

October

Hi DadGrover Beach Boardwalk

Right before the month began, my Dad flew out to visit, and near the end of the month my Mom flew out for a short visit as well. If there’s any reason I’m doing well it’s all the support I get. My main class was about ethics in software, and I ended up with several papers that will easily become future blog posts.

November

Thanksgiving Dinner!

Even with my classes in the bag, I found it difficult not to stress over the final projects. I flew home briefly for Thanksgiving, which gave a nice reprise from school. The quarter ended with A’s and I only have my senior project left to earn my degree. I’m feeling pretty proud!

December

December was a whirlwind. First, a flight back to Illinois through Chicago where I saw some friends at a convention. Afterwards, down to Urbana to visit more. Finally, I traveled to Hawaii with my grandparents and family to celebrate Christmas.

Scary ledgeThe Allerton Gardenmore allerton gardenfeels like mystso green!this hike was very muddy

Looking Back on 2017

Wow. I mean, I moved further along my degree this year than the previous four. Working at a board game store was overall great and I think I’m a better salesman than before. Driving cross country made me realize I’m older. Last time I drove that far I could go longer without the same soreness and fatigue. In general I sit too often, but otherwise I did a pretty good job keeping active physically and mentally in 2017.

Books

I listened to most of my books through an Audible subscription. Mainly self-help style books and podcasts that make for easy listening in the car. War of Art, which is about procrastination, was my favorite and I listened to it twice. The book that engrossed me the most was a dystopian sci-fi series, Red Rising, and I am betting it will end up being made into a movie.

For next year, I think I can finish at least 20 books. Especially if I start using my Kindle more.

Music


Last.fm says I only listened to 1,740 songs, which seems incredibly low. I must have been only tracking MP3s played on my phone. But either way, the top 3 albums reported were ones I enjoyed a lot. Spirit Phone is silly but still hits me hard, Sufjan Stevens is required listening for anyone who enjoys the Midwest, and Ghosting’s album samples all the Miyazaki films’ soundtracks.

Cashmere CatThey

I also saw some live music, most notably Andrew Bird (who makes me really want to learn to sing), Cashmere Cat, and They Might Be Giants.

Looking Forward to 2018

I’m definitely getting my degree in March, and I’m curious to see where that degree will take me. I’d love to stay in SLO. Regardless, I’m getting my software development career moving again.

My official New Year’s Resolution is to write more articles here. I have gotten a lot better at writing in the past year, but I’m still not satisfied with how I approach this strange art form. I’m going to publish 2 more articles this month, and will reevaluate my frequency on Jan 31st.

Some other mini goals I have:

  • Music. People enjoy my violin so much, I ought to honor that and practice more. I could also practice voice seriously, for the sake of those who live around me.
  • Running. I’m actually pretty good at endurance running, and I learned about a 10k run this Spring in SLO. Might be a great way to celebrate graduating.
  • Stretching. This quarter I spent so much time coding in my chair that my neck and back suffered. Gotta do more stretches and also buy a new chair/desk this year.
  • Using my phone less. I want to replace my bedtime phone habit with book reading.
  • Open Source contributing. I keep seeing articles about doing this, just choose a project and run with it.

Final Thoughts

Lots of things to accomplish, and it’s tricky to think about the large scope of it all. I’ll try to take things one day at a time. Tonight is a supermoon, and that’s gotta be a good omen. My Dad took a picture of it rising over a snowy field, which strikes me as the correct way to sign off this post and start 2018. Thanks for reading.

Super Moon rises in Urbana, Jan 1st 2017

Drawing Power from Your Own Inexperience

Power through serenity

A month into my summer internship, I booted up my work PC for the first time.

No computer for a month at a software engineering internship? At the time, the company was hiring new employees faster than the support team could set up computers. Days passed, weeks passed, as I waited for a PC to magically appear in my office. I twiddled my thumbs, edited the development wiki, and sat in on meetings. The first month of my internship was wasting away as I waited.

Only once did I go downstairs and meekly ask. “When is my PC going to be ready?” The overworked tech support team told me to be patient.

Now, I take full responsibility for this wasted month.

I ought to have explained I was there for a three month internship, and I needed a PC immediately in order to even get started. But in my head, I had a voice telling me the actual employees had priority. They could produce real work, and I couldn’t. So why should I care if my computer arrived on time? They had more important things to worry about.

I thought being an intern meant I had to accept the wait. In reality, being an intern was one of my greatest assets. People will go out of their way to help the intern. All you have to do is ask.

My poor communication continued into the rest of the internship.

I sent out vague mass emails when trying to get hold of needed files. I journeyed the high-rise, searching through cubicles instead of setting up meetings. I had agreed to a project that was way above my skill level; using statistical analysis to categorize information. But I never made that fact clear to my managers. I was lost.

With my mindset, I couldn’t ask for help without feeling like I was interrupting the real engineers. They were in crunch mode, trying to get their product completed by the holiday season. My little problems couldn’t possibly be worth their time. Going back to my desk and working alone became preferable.

It’s not a surprise the summer ended without a finished project. But I did leave with a lesson. If you feel inexperienced at your job, you can use that to your advantage. Put your inexperience out there like you’re proud of it. You deserve extra help because of it.

Plains Guard

Being Too Agreeable is a Recipe for Chaos

A couple years ago I worked at a smoothie shop on a college campus. More than my juice blending skills, I got to practice my customer interaction skills.

One interaction involved a frantic search for a missing piece of an orange juicer. My efforts were fruitless. Soon the impatient customer demanded a refund, but I had no clue how to issue refunds. Regardless, I spent the next moments panicking and poking at the buttons on the register. When my manager finally showed up to save the day,  she calmly denied the refund, pulled the missing part from the drying rack, and made the juice.

Another time, I arrived at work on a Sunday to find customers waiting outside. We didn’t open for another half-hour, but they were late for some event and I was overly eager to help. I let them in and made their smoothies. At the time, it seemed like I was going above and beyond my obligations as an employee. The customer comes first, right? It took my manager’s scolding afterwards to realize that I had gone beyond what I was allowed to do as an employee.

Being too agreeable is a recipe for chaos. In both cases, my customers would have been better served by bluntness rather than empathy. I should have told the first customer that the orange juicer wasn’t working today. I should have told the early birds that the store was closed. I’m pretty sure by helping them, I further delayed the event they were late to.

Fast food is an endless stream of busywork. With queues out the door and wait times up to ten minutes, it’s difficult to not feel rushed. But being rushed never helped. I would spill smoothies and mix up orders. The more hurried I acted, the more often my customers grew impatient. I had to learn a new mindset. Everyone would get their juice eventually. I could deliver drinks with a smile, and it almost seemed like my customers became more accepting of the wait as well.

It’s worth preserving my serenity over fixing every problem thrown in my path. I learned I can’t please everyone. Setting business boundaries allows me to provide a more consistent service. I’m grateful for this lesson, and hope to remember it often.

Of course, the greatest lesson was how to make a mean smoothie.