Monday, February 18, 2019

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

I realized I claimed credit for reading all of chapter two, but had an exercise left, so I thought I'd better get it done today after a bit of Far Cry New Dawn so I'm not strictly lying to myself (my days are sometimes off in my reading list, but in general I try to keep them aligned within a day or two)..

JSFiddle: https://jsfiddle.net/NodToNothing/ehk24y50/
Fiddles: https://jsfiddle.net/user/NodToNothing/fiddles/

Exercise 6 was a retirement calculator.  Amusingly, I can see in that last Fiddle where I'm reusing Vue code and leaving in bits, like the default being Scooter, where it doesn't matter because I'm working with numerics, not strings.  So....ignore those parts.  At the very least, I don't want to hear about it because it doesn't matter except for elegance/purists.  It's not like I have someone sitting nearby to code review my hobby activities.

I did learn a bit more about the difference between computed properties and functions in Vue, so that was useful in the context of this snippet.  No methods in there, but....that's because I really didn't need them once I started playing around a little more.

The code...less than in some of the others.  Vue takes a lot of the work out of things:

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

I was right.  The simple math exercise was really, really simple.  Use Vue and it'll lock the format to numeric, has a UI, autoupdates the answers and, with a min and a bit of javascript (validity.valid) enforces 0+, aka no negative numbers, per the exercise challenges.

Fiddle: https://jsfiddle.net/NodToNothing/f18vahdp
Fiddles: https://jsfiddle.net/user/NodToNothing/fiddles/

Output working as advertised:



The Fiddle code...

Sunday, February 17, 2019

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

Wow...the length of these titles is getting a bit off the hook.  Maybe I need to go with EfP57 as a short form.  I lose my keywords; but I don't care about my keywords.

The challenge for the madlib exercise was to put some control logic in the system.  I didn't like the acceptance criteria, because there's some knowledge of what's being entered that's necessary.  To avoid that, I thought I could force the user down a path of limited choices....aka a select/dropdown.  In that case, the branching logic is pretty straightforward because you know the possible values.  I see where to implement it in the display of the sentence using the computed property.  Getting the drop downs set up in the first place was the hard part.  Vue isn't intuitive to me.  Although, and I am ashamed, flipping "key" to "name" in the bound property was so simple I'm embarrassed it took as long to intuit as it did.  This will also be the first exercise with code so long it doesn't fit in an easy image, so all I'm posting is the textarea with scroll.

So here's the fiddle: https://jsfiddle.net/NodToNothing/L8rpd6ak/
Here's all my fiddles: https://jsfiddle.net/user/dashboard/fiddles/

Here's my oops where I use the key instead of the name.  I tried to get to the object via some collection notation [index] and failed repeatedly even though I got back a viable object inserting those indexes.

You can see it inserting the indexes into the concatenated sentence above.  That IS hilarious.

And there it works.  The trick was changing :value="verb.key" to :value="verb.name".  Simple.  Easy Peasy.  But I couldn't find an example on the web.  All sorts of other examples, just not that one.  And as you can see from the "person" code, I borrowed the initial code for modification and the example of how to flip it wasn't there.  Well, for as stupid as that was, I feel undeservedly smart. And I can finally move on to exercise #5 "Simple Math" which must be easier.

Saturday, February 16, 2019

IGH Career Day 2019

I did the middle school career day over at IGH again this year.    It's four twenty minute presentations on what it's like to be an IT/Application Development Manager.  I'm always worried everyone is more prepared than me because I try to give it with no power points, a few white board drawings, and it varies from presentation to presentation.  There are cops there with K9s some years, and firefighters dressed in their gear.  Best I could do is bring an app.

My outline generally goes like:

  • Hello, I'm me. IT Managers go by a few names.  I build apps.  I like my job.  Most people with my job have a CompSci degree and were developers.  I was in history/writing/English.  I know devs who were lawyers, bioscience majors, and travel agents.
  • I work for a big company that most works with lawyers and judges and the government, but we have reporters who are amazing as well.
  • Anyone's parents work with me?  It's a big place.
  • You're all familiar with apps.  If you get to the credits at the end of a game (Far Cry) or a movie (Avengers of some sort) you'll see those huge lists of people after the voice actors and actors...a manager helps pull all those things together to get a product out in time, although usually within a limited scope.  My scope is IT.  But that's more than just developers...
    • There are folks in quality/testing, PMs, big data, databases, ops (dev ops), business partners,  R&D, security, other kinds of development...I don't coordinate all of them, but I talk to all of them to make sure what's being built is what everyone imagines.  We have to agree.
    • On the dev side, for my big company, the levels are software engineer, senior software engineer, lead software engineer, and then architect or manager.  That can change from time to time and place to place.  Then I talk about how much all those roles make because that's the most exciting piece of info I have for some of them.
  • I've seen a lot of apps over the last 20 years
    • Mainframes and build it on your desktop
    • Distributed, but I could kick the server if I wanted to
    • Distributed , but the servers lived on the other side of the campus in a plane-proof bunker
    • Cloud, and the bunkers are in different regions
    • APIs where everyone is back to building it on their desktop, but all the expensive pieces are now cheap and in the cloud.
    • Patterns often remain the same from app to app and how to coordinate work, even if the underlying architecture changes.
  • What's exciting about what I'm working on.
    • There is a supreme court, district courts, state courts, county courts, even city courts.  Add up all those docs and you get hundreds of millions.
    • Extract the entities and pertinent data, and you get hundreds of billions.
    • Extract the relationships and you're in the trillions.
    • You couldn't do that with books.
    • Now you get a super cool chart/visualization that shows all that data distilled into a time to rule or other way to make a decision.  That saves them money.  Saves the customer money.  Means the law should be more affordable and accurate.
    • APIs mean you can give that power to a lot of developers who may create something you never imagined by mashing up products.
  • Questions
    • Best one was "is it easy to make something" which prompted a bit more talking about APIs and crowdsourced apps and how cheap the cloud and new tools make it if you want to run it at scale.
    • Do you know my mom?
It's a lot to fit into 20 minutes, and I usually take them to minute 19 before we get to questions.  But they almost never have questions, so I guess that's ok.  I was impressed this year that they weren't playing with their free fidget spinners (one presenter was in sales) - very well behaved.  The teacher told them it was nice to be back in 2015.


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).