Wednesday, February 13, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Mad Lib (4) - Vue.js style

I thought a madlib lended itself more appropriately to Python, but perhaps that's because I grew up in the age of Zork and Leather Goddess of Phobos.  It works just fine with Vue, although the branching it's asking for next might be a challenge.  I haven't really tried control statements with Vue.  Wait, that's not true - I used the for/next in the random quote example.

I might actually have to put a little thought into the structure for that one.  I'm not sure what "branching" means in that context.  Select one of two verbs at random, and then use the other one later?  Allow them to only select from a few options and branch depending on the one they select?  That second one makes more sense if I'm not going to implement some NLP weirdness.  I haven't used a dropdown in Vue, so that will be a good challenge.


The code....I wonder how long until these start exceeding my textarea and I'll have to actually change the tag attributes.

Tuesday, February 12, 2019

Alita and Trevor Noah

Those two things are completely unrelated.  Tonight, after spending the last two days digging out of the fourth snowiest February in Minnesota history (the snow banks at the end of the driveway are as tall as I am, even with two toppings by Eryn), we went to a Alita: Battle Angel premier.  The Rosemount theater had a good deal for advance screening tickets and, combined with my gift card and rewards card, there weren't even any additional fees.  Bargain.  The movie itself was perfectly serviceable, but that speaks for itself.  The focus was on the spectacle and it felt like the character interactions were a bit lacking because of it.  I enjoyed it; very reminiscent of Ready Player One in design, but not nearly as good as that movie.

Last Saturday Eryn and I went to see Trevor Noah at the Xcel Center for his Loud and Clear Tour.  I won tickets and parking from work.  We tried to go to the Red Cow before hand, but it was too crowded, so we ended up at the Bohemian sausage place, which makes Eryn a bit nostalgic for the one in Eagan that quit paying their bills and skipped town.

Ming and his family were at the show on the other side of the Xcel from us.  We could barely see them when we squinted.  Eryn loved the show and laughed a lot.  She was somewhat annoyed with the first comedian whose bit was about things millennials didn't know about (but do), but she liked the second guy and his bit about his uncle and micro-airlines, and she loved Trevor Noah.  He did some politics, but focused more on differences in men and women, branding (although that was political, and had a pretty varied set.  Eryn was amused when he was talking about branding and asked all the men to put their hands up then said "put your hand down if you've stopped masturbating", and followed it up with the guys not wanting their wives/spouses to think they were quitters.  We couldn't tell if Ming put his hand down.




Zombie Chia

Our Christmas zombie chia lady started to get sort of gross for real.  She was always kind of gross, particularly as we didn't get the hair on the top of her head to sprout, only the hair on the sides.  And then it started to grow forward because that's where the heat from the fireplace rose up.  But eventually the sprouts started drooping into the gel-like water and rotting.  Zombie sprouts on a zombie head.  Nasty.

She was surprisingly difficult to clean.  Even now I think there are some seeds that won't come off.  Life is tenacious.  Undead life even more so.

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Mad Lib (4)

Simple one - do a madlib in this style and try it with string interpolation/substitution. Part II will be harder - it branches...I wonder if I'll have to use a picker to limit choices....I'll have to ponder that one. This one needs some sort of NLP to clean up the verb.

noun = input("Please provide a noun: ")
verb = input("Please provide a verb: ")
adverb = input("Please provide an adverb: ")
adjective = input("Please provide an adjective: ")

print("Do you " + verb + " your " + adjective + " " + noun + " " +  adverb + " That's funny!")

print(f'With literal string interpolation: Do you {verb} your {adjective} {noun} {adverb}.  That\'s funny!')
print('With interpolation: Do you %s your %s %s %s}.  That\'s funny!'%(verb,adjective,noun,adverb))


================ RESTART: C:/Users/u0024159/Desktop/MadLib.py ================
Please provide a noun: banana
Please provide a verb: ate
Please provide an adverb: quickly
Please provide an adjective: yellow
Do you ate your yellow banana quickly That's funny!
With literal string interpolation: Do you ate your yellow banana quickly.  That's funny!
With interpolation: Do you ate your yellow banana quickly}.  That's funny!
>>> 

Monday, February 11, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Quotes

https://jsfiddle.net/NodToNothing/kac3o5hj/

Again, I made up my own A/C a bit.  The example called for separating the quote from the attribution, and I see how to do that, but I'm not going to.  I had more fun inserting a randomizer for Princess Bride quotes.  The top quote is random, but the bottom unordered list shows all the quotes in the Vue list so I could try a control loop.


Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Word Count

https://jsfiddle.net/NodToNothing/Lk5wsxab/8/

Well, I was going to limit myself to one exercise per day, but this seemed pretty straight forward given the last JSFiddle - use a built in length function (that was momentarily tricky because I wanted to use str. and length(), but it was intuitive), avoid nothing, count every key press. That last one was pretty much a gimme from Vue using computed properties (although I could have done it inline).



Code, in case I lose my fiddles...

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 2, Saying Hello

https://jsfiddle.net/NodToNothing/arbhqcs6/3/

Interesting exercise - keep the input, concat, and output separate.  Write it without variables and do different greetings for different people.  In the end, I'm the arbitrator of what constitutes the acceptance criteria, so I used Vue again and bound the mustache output to a function tied to an input box.  Admittedly, I could have skipped the function altogether and just printed Hello in HTML and then the value of the input box.  No concatenation at all, at least not actively.

I did learn that Vue ignores the value on the input and you need to set it in the initial data values.  There's a lot of magic under the covers tying the message variable and val model together in a function mapped to the HTML.  That's slick.  I shouldn't be too impressed given I played with React back in 2013 for a team demo and have been through Angular training, but I find it refreshing anew, particularly given how fast you can set up a UI.  VB COM speed to demo days indeed.


Cheater textarea again for anyone who wants to grab some "code", although it's easier to go to the JSFiddle.  I got to thinking I'd usually do this in Python (and IDLE) and it looks like I can go Py fiddle as well: https://pyfiddle.io/  Although that's not really any faster than running IDLE on my desktop.

Sunday, February 10, 2019

Mountain Biking (not me)

I saw this video on YouTube and watched it with my family. It's insane. We were all twitchy watching it. I can barely go a few miles an hour on my local course without gripping the bars so tight my hands hurt, and it's fairly level. And...even then, I've fallen over before and biffed my arm on a tree.  This is outside my imagination in some ways.

 

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part g/h

Ok....now it gets tricky.  I'm supposed to turn the tip calculator into a GUI, and then a GUI with a slide.  I could just use C#, but that's pretty week.  I might as well go VB COM (and in case that's offensive, I still have a secret santa program running on VB COM including Outlook integration for almost 15+ years.  I compiled it and just use it...I'm too lazy to update.  If I went digging, I probably have tgXML around as well, my treasure generator using XML in VB COM for AD&D third edition).  So I was thinking I might try pure javascript, but then thought, well, I'll have to pull in bootstrap and this npm live-server thing is cool, but ultimately sort of a waste of my time and disk space.  And as soon as I thought that, I thought, why don't I just use Angular?  And that made me think, that seems so heavy...oh yeah, people use Vue and React. I pondered React, but realized I have a developer on my team who keeps telling me how wonderful it is so, being the obstinate person I am, I used Vue, on JSFiddle so I could use someone's pre-fiddled fun circle slider, and save my work without having to find it locally.

My biggest issue wasn't the basic structure of Vue, it was trying to parseFloat and Math.roundup and get it to work within the framework of Vue without concatenating.

Here it was doing the stupid concatenation instead of math, which really annoyed me, because it wasn't a Vue-specific issue.

Here I fixed it.  You can see where I started to put it into a function instead of inline, which is better, but I was lazy and just proving my point (that I could do it).


You can play with it here...
https://jsfiddle.net/NodToNothing/e6c7amk9/1/

And here's the code using a cheater textarea....

Saturday, February 09, 2019

Snow

Ice, snow, ice, snow....bit of a mess out there.  I've got one friend who slid and sideswiped his car, and my wife spun out and took a chunk out of her hubcap last night.  For me, it's been fairly uneventful, although Thursday, getting Eryn to and from school was a bit of a challenge.

In the morning, it was clear but icy when we left, but just a few minutes into our ride and it started to snow and whiteout.  When we got closer to school I had to have her confirm that what I was turning onto was the off ramp.  After dropping her off, I stopped to answer my phone and hack a portal (ingree) on the way back to work, so I pulled into a church lot.  But someone had cleverly plowed the first few feet of the lot and nothing else, which I couldn't see in the white out, so the Mustang just stopped, pinned by snow under it and wedged along the side.  I was momentarily panicked (obviously AAA would be a while), but then scooped out all the snow I could, carefully lined the wheels up exactly with how I'd come in and backed it out in the main road when there was a gap.

Later, after a LOT more snow had fallen I went to pick Eryn up and made a stop at the library.  Unfortunately, the library is at the bottom of a big hill.  So I got down fine, but the rear wheel drive wasn't having it trying to do the almost 45 degree turn uphill.  I couldn't even drive across the parking spots without getting stuck and having to back up.  I had almost given up when I decided the angle on the other side gave me a better run at the hill and had been tamped down a bit more by other library patrons.  So I went in reverse all around the lot until I got traction to turn and roll up the hill.  Definitely helpful that there weren't many cars around.

Likewise, when I stopped at the school to pick Eryn up, I did a drive through the lot to make sure I wasn't going to block every other car going through the lot and at the little hill that exits onto the main road, it was obvious I wasn't going to be able to turn left.  So I turned right, hopped the berm of snow, and then immediately turned left.  The guy behind me looked surprised, but understanding.  Later, I saw a guy outside his car pushing while his daughter drove to get over that same berm in a car with a higher base.

So we got home, and then couldn't manage to get into the garage.  I could have parked on the street and shoveled, but I wasn't so sure I wouldn't have to push it loose if I did that.  So Eryn and I swapped places so she could drive while I pushed.

I pushed.  And pushed.  And pushed.  And pushed some more.  Finally I asked her if she was giving it enough gas, because it seemed it wasn't getting any acceleration at all.  She said yes, so I said to give it a bit more.  I pushed, and then asked, was she sure she was in drive?  No.  She was in park.  She was embarrassed.  But at least it was easy to get in the garage after that.  Unfortunately, it's what likely made my back hurt so bad in conjunction with the shoveling.

Here's a nice sunrise picture of the ice at rest.  Cahokia has their earthen mounds.  We have a snow mound/s.  Mean Mr. Mustard says he's on vacation, but for all I know his car is under that pile somewhere and he's running out of gas to keep himself warm barely a hop, skip, and a jump from his cube.  Very To Build a Fire.


Friday, February 08, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part f

Version f...I think that's also 6. Break it out into functions. Some of that was already done, but I finished the job. I guess, if I was being a good programmer, I might have it ask whether the tip should be rounded up or not. And yeah, there's some weird code in a few spots, but fast and functional was my goal, not elegant.
 
import math

#Version 1: basic
#Version 2: round up
#Version 3: next, ONLY enter numbers
#Version 4: ask again for a number - already done!
#Version 5: no negative numbers
#Version 6: use some functions

def inputNumber(message):
  while True:
    try:
       returnValue = float(raw_input(message))
       if returnValue < 0:
           raise ValueError
       else:
           return returnValue
    except ValueError:
       return inputNumber("Not a non-negative value! Try again.")

def grandTotal(tip, bill):
    return str(y + (y * x/100))

def grandTotalRounded(tip, bill):
    return str(y + math.ceil((y * x/100)*100)/100)
    
def tipPrint(tip):
    return str((y * x/100)*100)

def tipRoundedPrint(tip):
    return str(math.ceil((y * x/100)*100))


#print("Enter a tip:")
x = inputNumber("Enter a tip:")
print("Tip is: " + str(x))
#print("Enter a bill/total: ")
y = inputNumber("Enter a bill/total: ")
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + tipPrint(x) + " cents") #cents
print("Tip rounded up is: " + tipRoundedPrint(x) + " cents")  #what do I expect?
print("Total is: " + grandTotal(x,y))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + grandTotalRounded(y,x))

Sigh...mismatched function name.  If I had a dime for every time...

Enter a tip:3
Tip is: 3.0
Enter a bill/total: 82.55
Bill is: 82.55
Tip is: 247.65 cents
Tip rounded up is: 248.0 cents

Traceback (most recent call last):
  File "C:/Python27/TipCalculator.py", line 45, in 
    print("Total is: " + grandTotal(x,y))
NameError: name 'grandTotal' is not defined
>>> ================================ RESTART ================================
>>> 
Enter a tip:3
Tip is: 3.0
Enter a bill/total: 82.55
Bill is: 82.55
Tip is: 247.65 cents
Tip rounded up is: 248.0 cents
Total is: 85.0265
Total rounded up is: 85.03
>>> ================================ RESTART ================================
>>> 
Enter a tip:-2
Not a non-negative value! Try again.1.8
Tip is: 1.8
Enter a bill/total: 77.25
Bill is: 77.25
Tip is: 139.05 cents
Tip rounded up is: 140.0 cents
Total is: 78.6405
Total rounded up is: 78.65

Thursday, February 07, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part d/e

It was exciting to find out I'd already done part d/4, so I jumped right into no negative numbers. That would be a really mean tipping system. I found some other bugs as I went - I spelled negative wrong, the tip info didn't say "cents" so you couldn't be sure what was going on there, and my error handling message wasn't generic enough to cover all cases (versus specific messages, which is annoying for me, although good for the user).
import math

#Version 1: basic
#Version 2: round up
#Version 3: next, ONLY enter numbers
#Version 4: ask again for a number - already done!
#Version 5: no negative numbers

def inputNumber(message):
  while True:
    try:
       returnValue = float(raw_input(message))
       if returnValue < 0:
           raise ValueError
       else:
           return returnValue
    except ValueError:
       return inputNumber("Not a non-negative value! Try again.")


#print("Enter a tip:")
x = inputNumber("Enter a tip:")
print("Tip is: " + str(x))
#print("Enter a bill/total: ")
y = inputNumber("Enter a bill/total: ")
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + str((y * x/100)*100) + " cents") #cents
print("Tip rounded up is: " + str(math.ceil((y * x/100)*100)) + " cents")  #what do I expect?
print("Total is: " + str(y + (y * x/100)))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + str(y + math.ceil((y * x/100)*100)/100))

I notice that I don't always have the right precision...my money isn't necessarily two decimal spots. I think I know how to fix that with a decimal or I could bite the bullet and use one of the money packages/imports that exists. That might be part 8. I notice I have to flip it to a GUI coming up here soon...I'll have to port this code over to javascript (although I'd be much, much faster with C#).

Enter a tip:-1
Tip is: -1.0
Enter a bill/total: 1.50
Bill is: 1.5
Tip is: -1.5
Tip rounded up is: -1.0
Total is: 1.485
Total rounded up is: 1.49
>>> ================================ RESTART ================================
>>> 
Enter a tip:-1
Not an integer! Try again.-2
Not an integer! Try again.3
Not an integer! Try again.4
Not an integer! Try again.
>>> ================================ RESTART ================================
>>> 
Enter a tip:-2
Not an integer! Try again.3
Tip is: 3.0
Enter a bill/total: 150
Bill is: 150.0
Tip is: 450.0
Tip rounded up is: 450.0
Total is: 154.5
Total rounded up is: 154.5
>>> ================================ RESTART ================================
>>> 
Enter a tip:-3
Not a non-negiative value! Try again.0
Tip is: 0.0
Enter a bill/total: 150
Bill is: 150.0
Tip is: 0.0 cents
Tip rounded up is: 0.0
Total is: 150.0
Total rounded up is: 150.0
>>> ================================ RESTART ================================
>>> 
Enter a tip:-2
Not a non-negative value! Try again.-3
Not a non-negative value! Try again.-4
Not a non-negative value! Try again.3
Tip is: 3.0
Enter a bill/total: 17.25
Bill is: 17.25
Tip is: 51.75 cents
Tip rounded up is: 52.0
Total is: 17.7675
Total rounded up is: 17.77
>>> 

Wednesday, February 06, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part c

Version 3, or c, depending on your preference. Goal is to only enter numbers. This wasn't working for me very well until I swapped input for raw_input. Apparently I could have eval-ed the input, or been a normal boy and just used Python 3. It's on here somewhere.

import math

#Version 1: basic
#Version 2: round up
#Version 3: next, ONLY enter numbers

def inputNumber(message):
  while True:
    try:
       return float(raw_input(message))
    except ValueError:
       return inputNumber("Not an integer! Try again.")


#print("Enter a tip:")
x = inputNumber("Enter a tip:")
print("Tip is: " + str(x))
#print("Enter a bill/total: ")
y = inputNumber("Enter a bill/total: ")
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + str((y * x/100)*100)) #cents
print("Tip rounded up is: " + str(math.ceil((y * x/100)*100)))  #what do I expect?
print("Total is: " + str(y + (y * x/100)))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + str(y + math.ceil((y * x/100)*100)/100))

This was actually way more interesting on output then I'd have expected. First, I was using a function from 101 computing, and they converted input to int...that was no good. It rounded my whole bill. So I used a float. Which works. Even with a more complicated set of inputs. And then my non-numeric inputs crashed, which is where I had to switch to raw_input for 2.7 and a tighter loop.
Enter a tip:7
Tip is: 7
Enter a bill/total: 2.50
Bill is: 2
Tip is: 0
Tip rounded up is: 0.0
Total is: 2
Total rounded up is: 2.0
>>> ================================ RESTART ================================
>>> 
Enter a tip:7
Tip is: 7.0
Enter a bill/total: 2.50
Bill is: 2.5
Tip is: 17.5
Tip rounded up is: 18.0
Total is: 2.675
Total rounded up is: 2.68
>>> ================================ RESTART ================================
>>> 
Enter a tip:8.5
Tip is: 8.5
Enter a bill/total: 2.57
Bill is: 2.57
Tip is: 21.845
Tip rounded up is: 22.0
Total is: 2.78845
Total rounded up is: 2.79
>>> 

Tuesday, February 05, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1 Part b

I don't know why this was so difficult.  I'm pretty sure that /100, *100, /100 is probably wrong anyway, it just works because the math works.  Anyway, rounding UP the pennies in the % because I'm a greedy corporate f*cker.


import math

print("Enter a tip:")
x =input()
print("Tip is: " + str(x))
print("Enter a bill/total: ")
y = input()
print("Bill is: " + str(y))

#this won't work because I need a precision factor (cents) in my ceil()
#so use full ints?
print("Tip is: " + str((y * x/100)*100)) #cents
print("Tip rounded up is: " + str(math.ceil((y * x/100)*100)))  #what do I expect?
print("Total is: " + str(y + (y * x/100)))

#with 3% and 1.85 should be 1.91
print("Total rounded up is: " + str(y + math.ceil((y * x/100)*100)/100))


Output for a good use case:
Enter a tip:
3
Tip is: 3
Enter a bill/total: 
1.85
Bill is: 1.85
Tip is: 5.55
Tip rounded up is: 6.0
Total is: 1.9055
Total rounded up is: 1.91

Monday, February 04, 2019

Exercises for Programmers: 57 Challenges to Develop Your Coding Skills - Chapter 1

Chapter 1, the most basic option for a tip calculator using Python.  No type checking and no error handling.

print("Enter a tip:")
x =input()
print("Tip is: " + str(x))
print("Enter a bill/total: ")
y = input()
print("Bill is: " + str(y))

print("Tip is: " + str(y * x/100))
print("Total is: " + str(y + (y * x/100)))


  • Step 2: round up the tip to the cent and the total to the cent.
  • Step 3: restrict the user to numbers for the bill and tip %.
  • Step 4: if the input isn't a number/%, ask them to try again or bail.
  • Step 5: no negatives
  • Step 6: use functions
  • Step 7: make it a gui (well, that's not going to happen in Python....maybe use Javascript) - use a slider, not a prompt.  Could use Visual Studio/C# as well, although that's got overhead.

These Shining Lives

Last night we went to see These Shining Lives at Theatre in the Round.  It was about four women who worked in a watch factory licking radium brushes until they fell ill and died.

It was a good play, but there was more exposition than showing, although I'm not sure how that's avoidable.  You can't exactly show the women with bones extracted from their jaws and pitted with radiation poisoning.  You have to imagine that part. And I'm pretty sure whatever you imagine, it's not as bad as the reality.  Go here (http://boredomtherapy.com/radium-girls/) and you can see a knee and chin affected by radium-based cancer.  Specifically, the chin/jaw of the main character.  They should have shown the photos at the play.  Pretty damn horrific.  I've always said I appreciate my job because although it might screw with the temporary livelihood of individuals, it never puts me in a position where I have to worry about their long term health and/or life.

Here's a link to a Radium Girls reading, which is parallel and took place in Connecticut instead of Ottawa (Illinois). 

 

Betrayal at House on the Hill: Legacy

We've been playing a four person series of Betrayal at House on the Hill: Legacy.  Eryn, Pooteewheet, Me, and P (friend of Eryn's).  On Saturday we played episode one.  Which is a little disingenuous as there is an episode zero.  An introduction.  Episode one was more fun than episode zero, although the narrative elements make it really enjoyable.  It's basically an RPG with some boardgame functions wrapped around it.

I like the naming your character convention.  I went with little Weezie Lynn Gables and her teddy bear Sanford.  I got the Scholar role, which was largely pointless, and weird for a 12 year old.  It was more amusing when I drew a card that said I was chained up in a room and had to unchain myself.  I told my wife Sanford and I were play acting a bit of bondage, but I had escaped because we had a safe word.  Justifiably creepy for a precocious little scholar.


I was pretty sure I handled the game correctly and basically barricaded myself in a room on the top floor behind rows of traps that basically prevented the other characters from backing up.  So not only did I have traps between me and the baddy, I had all the other characters between me and the baddy.  This is undoubtedly how a 12 year old should approach being knowingly stalked by supernatural entities.  Make the adults deal with it and set up some Home-Alone traps just in case they're useless.

Sunday, February 03, 2019

I'm tired of typing month/day/year once a month...

Quick code for listing month/day/year in Python.  I believe [0] is the first weekday of the month.  Weird little function/library.  There are a lot of variations to play with: https://docs.python.org/2/library/calendar.html

import datetime, calendar
year = 2019
month = 1
num_days = calendar.monthrange(year, month)[1]
for i in range(1,num_days+1):
    print(str(month) + "/" + str(i) + "/" + str(year) + ": ")

Acceptance criteria failure! My numbers are first to last, I want last to first.  So the range gets modified.

import datetime, calendar
year = 2019
month = 2
num_days = calendar.monthrange(year, month)[1]
for i in range(num_days, 0, -1):
    print(str(month) + "/" + str(i) + "/" + str(year) + ": ")

February 2019 Reading




Saturday, January 26, 2019

Yellow Bike

I like bicycling videos.  There's a whole post about them around here somewhere that's been slowly falling apart as the videos disappear off Youtube.  I have bicycles I pound into the ground that last longer than some things on Youtube.  It's not a very permanent platform which surprises me, given the things I put up on it in the early days are still there.  That said, I know of at least one video I have that disappeared because there was copyrighted music playing in the background.  I never post for hits - only for a personal archive, so it's amusing how tightly fair use of whatever is just playing over a speaker somewhere, like a coffee shop, can negate your right to a video.  Given the whole microtransaction culture, you have to worry at some point you might not be able to post something in any way because it has someone's copyrighted/patented color, advertising playing somewhere, clothing patterns, or one of a million things you'll need permission to show.  Hyperbole and vaguely the stuff of science fiction, but it has parallels.

Then again, sometimes it just moves.  I think the Pushbike song is one such example - I should just relink.

Anyway, courtesy of one of the RAGBRAI groups I follow, here's Pedro the Lion singing about his Yellow Bike.