Program design: weights on Mars
About this video
The instructor builds a program that calculates an object's weight on different planets using weight = mass x gravity. They use an if-elif chain with a compound or condition to set gravity for Mars, Mercury, Venus and Jupiter, debug a Jupiter branch that used == instead of =, add an else branch for unrecognized planets, and use a separate conditional (if gravity) to skip the calculation when the planet isn't recognized.
You'll be able to
- use an if-elif-else chain to choose a value based on user input.
- combine cases with or when they share the same result.
- use temporary print statements to debug which branch runs.
- explain the difference between == and = and spot the bug when they are mixed up.
Key words
- chained conditional
- An if with elif and else branches where only one branch runs.
- round
- A built-in function that takes a number and how many decimal places to round it to.
- default value
- A starting value given to a variable before a conditional, like gravity = 0.
- debugging print statement
- A temporary print added to see which code runs or what a variable holds.
- catch-all
- A case, handled by else, for every input not matched by the earlier conditions.
Transcript
- -instructor] Let's design a program with chain conditionals. We wanna build a program that calculates an object's weight on different planets. We have the formula for this already. Weight equals mass times gravity. So if we know an object's weight on earth, we can divide by earth's gravity to get the mass.
And then once we have the mass, we can just multiply by the gravitational force of whatever planet we're interested in. Our starter code here calculates an object's weight on Mars. We take the gravitational force on Mars, which is 3.7 meters per second squared.
Then we ask for the weight of the object on earth and then we plug those two numbers into our formula to get the weight on Mars. I am thinking I wanna round this number though, so it's a bit easier for the user to look at. There's definitely a built-in function for this.
Okay, looks like it's just called round and it takes two arguments. The number to be rounded and the number of decimal places to round to. That's looking a lot cleaner. Now I wanna make this work for other planets too, not just Mars. So we're gonna want an input function call that asks the user to enter a planet name.
We'll assign that to the variable planet and then we'll use a conditional to assign the value of gravity. Let's start with the Mars case that we already had. Before I start my conditional, I wanna make sure to initialize my variable gravity to a default value.
Let's say zero here probably makes sense. We'll want our condition to be planet equals equals the string Mars. If this evaluates to true, then we wanna set gravity to 3.7, which is the gravitational force on Mars. So we end it, that assignment statement inside that if branch.
There are a lot of planets. So let's just start with a few of them. We'll do Mars Mercury, Venus, and Jupiter. Mercury's gravitational force is also 3.7. So we can just use the or operator to turn this into a compound condition that checks that the planet is Mars or Mercury.
Next, we wanna check that the planet equals Venus. This is related to the previous condition and it's mutually exclusive with it. The planet can't both be Mars and Venus, so it makes sense to use an elif branch here. If the planet equals equals Venus, then we wanna set gravity to Venus's gravitational force.
Then we have the Jupiter case, which is another branch. Now let's test that conditional. If I enter Mars, it's giving the same weight that I had before, so that must be correct and Mercury should give the same answer. And then Venus' gravitational force is bigger, so its weight should be bigger.
And then Jupiter should be even bigger still. Ooh, wait, that's a zero. Maybe that means gravity still has this default value zero. When we do the calculation and maybe this branch isn't actually executing. Let me test that hypothesis by adding some temporary debugging print statements.
I'll add one inside this Jupiter elif branch so I can see if this branch is actually getting executed. And then maybe I'll print down here what the value of gravity is right before I calculate the weight. Interesting. So it is hitting that branch 'cause it's executing this print statement and it says that the value of gravity is zero.
That's bizarre because if it's executing this branch, it should be executing this assignment statement, which means gravity should be 23.1. Oh wait, I see the bug. I use the equality operator, not the assignment operator. So this is checking if gravity equals equals 23.1 instead of assigning 23.1 to gravity.
Okay. But I need to go in and clean up those debugging print statements 'cause I don't want my users to see them. What do we wanna happen if the user enter something that's not a planet at all or is a typo, or is a planet we just don't support yet? This case is a catchall.
It's any string that's not Mars, Mercury, Venus or Jupiter, which could be any of infinite possibilities. So we can't really express that with a separate condition. We need an else branch. Let's just give the user an informative error message and tell them that we don't recognize that planet name.
So we make sure to indent this print statement inside the else branch. Let's test that else case. It prints unrecognized planet, but then it prints, it would weigh zero kilograms on potato. If the user enters in unrecognized planet, I don't wanna print out what it would weigh 'cause it doesn't make sense.
Actually, thinking about it, I don't need to do any of these calculations at all. I don't even need to ask them what the weight on earth is because I'm not gonna do anything with it. So if I wanna skip all these lines of code, I'm gonna need another conditional.
I don't wanna chain it with the existing conditional because it's not mutually exclusive with all those cases. It should run if the planet is Mars, Mercury, Venus, or Jupiter. So we use an if to start a new conditional and then I wanna indent all of these lines of code inside it.
What should my condition be though? How do I know if I was in the else case before? Well, if none of these three branches executed, then the value of gravity would still be zero. So I can have this condition be if gravity is not equal to zero, but I can actually use a shortcut here because zero cast to a Boolean is false and any other float cast to a Boolean is true.
So I can just shorten this condition to if gravity, which checks that gravity has some value that's not zero. Now, if I enter some unrecognized planet name, it just gives me that error message and then skips all of the calculations. Ooh, break time. I'm gonna add a quick comment here so I remember where to pick up later.
I'll note down the gravitational forces of the remaining planets in case you wanna give it a try.
Video © Khan Academy, used under CC BY-NC-SA. Watch on Khan Academy. Puzzicle is not affiliated with Khan Academy.