#!/usr/bin/env python3 """Variables with values exclosed in 3 double quotes (") allow multi-line strings. It can also be used for comments. Any words in curly braces like {this} are placeholders & can be replaced later if desired with the method 'format' on string variables. Single line strings can have replaceable placeholders too. Below is a variable named "foo" containing a single line string with a placeholder... foo = "Here is a single line placeholder of {replaceme}." We can just print foo as-is using... print(foo) or replace _all_ "{replaceme}" within it using format... print(foo.format(replaceme='new value here')) or replace it with another variable... new_replaceme='this is a new replacement' print(foo.format(replaceme=new_replaceme) Make sure that any variables, (new_replaceme in the above in this case) is defined or you'll get a KeyError if you try to print a format()'d string! """ msg = """Voltage Divider Calculator (v1.1) Formula: "Voltage out is Voltage in * Resistor 2 / Resistor 1 + Resistor 2" You entered: Voltage in {voltage} Resistor 1 {resistor1} Resistor 2 {resistor2} Which equals: {output} Output voltage is: "{output}", rounded (nearest 10) is "{rounded}"! """ error = """Usage: python3 {script} . Example: python3 {script} 5000 2000 4000 Seeing an Error? ValueError: You enter an invalid value (or left it empty). """ def main(args): """ The parameter args is a list populated by your shell/terminal. All values are added in the order they were passed to the script. The first item in the list args[0] will always be the script that was passed to python. If you named this file foo.py and called python3 foo.py args[0] would be the string "foo.py". """ # Remove this script's file-name and store it in the variable # "script" for later use. script = args.pop(0) """ "try and except" allows us to capture an exception (in this case we only want to capture a ValueError so we can first print a nice error message and then have python raise it, printing it underneath, and finally exiting. """ try: """ What "list(map(int, args))" is doing... As we've already removed the script file-name from the args list we should just be left with numberic values. However, they're strings and we need integers! We use the built-in method "map" which calls the method given ("int" here), that'll convert each value (from strings) within the list to the integers we need. Now we have a new problem we've given ourselves :(. "map" will return a map object which we don't want so we need to convert (the map object) back into a list, using, you guessed it, the method named "list"! Each value from the converted list is then unpacked into the variables "voltage", "resistor1" and "resistor2" (from right to left). So say we have a list of [1, 2, 3], We can unpack those values as... one, two, three = [1, 2, 3] """ voltage, resistor1, resistor2 = list(map(int, args)) # Here we're just calulating the voltage value using the values # from each variable. output = voltage * (resistor2 / (resistor1 + resistor2)) except ValueError: """ Oh no, we're missing a value or a non-numeric value was entered! Let the user know by printing our nice error message, contained with in the "error" multi-line variable above. Remember the "replaceme" variable we talked about earlier? Well, we're doing the same thing here but we're replacing the text "{script}" (in the "error" variable above) with the variable "script" (also above!). It sounds confusing? Yes, I agree. It can be made easier by using another word different to your variable as a placeholder and replace it with any variable you like! script = "carrots are lovely" msg = "my {placeholder}." print(msg.format(placeholder=script)) """ print(error.format(script=script)) """ STOP! Ham, Ahem... Exception time! "raise" here (unless captured by another try/except block) just tells python to print the exception then stop executing the script. """ raise """ If we get here it means our voltage has been calculated, and so (just like the above error message) we format then print the _good_ message "msg" variable and we're done. """ print(msg.format(voltage=voltage, resistor1=resistor1, resistor2=resistor2, output=output, rounded=round(output))) """ This "if block" tells python not to run the method "main" (above) If our script was imported by another python script. The method "main" will only get called if our script was called directly by python and is the "main" (hence __main__ below) script. This also means we import our script from within another script and call our module's (what python calls scripts) method "main". """ if __name__ == '__main__': import sys # main(sys.argv) calls our main function & passes the arguments # given to it by the terminal. # sys.exit returns the value from the method main. sys.exit(main(sys.argv))