#set document(title: "7.1 Module basics", author: "OpenStax / XYZ Homework") #set page(width: 8.5in, height: auto, margin: 1in) #import "@preview/cetz:0.5.2" #set text(font: ("STIX Two Text", "Libertinus Serif", "New Computer Modern"), size: 10.5pt, lang: "en") #show math.equation: set text(font: ("STIX Two Math", "New Computer Modern Math")) #set par(justify: true, leading: 0.62em, spacing: 0.9em) #set enum(spacing: 1.1em) // room between list items so tall inline fractions don't collide #set list(spacing: 1.1em) #set table(stroke: 0.5pt + rgb("#c7ccd3")) #let BLUE = rgb("#183B6F") // brand navy — section bars + example/solution labels (white on navy 11.09:1) #let ORANGE = rgb("#A94509") // brand primary-700 — AA-safe deep orange for TEXT (5.93:1 on white; raw brand #F37021 is 2.94:1 and must never carry text) #let RED = rgb("#DC2626") // brand error-600 #let GREEN = rgb("#059669") // brand success-600 (decoration only; small green text uses green-text #007942) #show heading.where(level: 1): it => block(width: 100%, above: 0pt, below: 16pt, fill: gradient.linear(BLUE, rgb("#2C5AA0")), inset: (x: 14pt, y: 12pt), radius: 3pt, text(fill: white, weight: "bold", size: 19pt, it.body)) #show heading.where(level: 2): it => block(width: 100%, above: 18pt, below: 10pt, fill: BLUE, inset: (x: 10pt, y: 6pt), radius: 2pt, text(fill: white, weight: "bold", size: 12pt, it.body)) #show heading.where(level: 3): it => text(fill: ORANGE, weight: "bold", size: 12.5pt, it.body) #show heading.where(level: 4): it => text(fill: BLUE, weight: "bold", size: 10.5pt, it.body) #let examplebox(label, title, body) = block(width: 100%, breakable: true, fill: rgb("#EFF1F5"), stroke: 0.5pt + rgb("#CFDDF0"), radius: 4pt, inset: 10pt, above: 12pt, below: 12pt)[ #block(below: 6pt)[#box(fill: BLUE, inset: (x: 6pt, y: 2pt), radius: 2pt, text(fill: white, weight: "bold", size: 8.5pt, label)) #h(0.4em) #strong[#title]] #body] // rail = decorative left rule (raw brand token); labelcolor = AA-safe label text shade #let notebox(label, rail, labelcolor, tint, body) = block(width: 100%, breakable: true, fill: tint, stroke: (left: 3pt + rail), inset: (left: 10pt, rest: 8pt), radius: (right: 4pt), above: 11pt, below: 11pt)[ #text(fill: labelcolor, weight: "bold", size: 7.5pt, tracking: 0.5pt)[#upper(label)] #linebreak() #body] #let solutionbox(body) = block(above: 4pt, below: 8pt)[ #text(fill: BLUE, weight: "bold", size: 8.5pt)[Solution] #linebreak() #body] #let figph(msg) = block(width: 100%, height: 60pt, fill: rgb("#f6f7f9"), stroke: (paint: rgb("#c7ccd3"), dash: "dashed"), radius: 4pt, inset: 10pt)[ #align(center + horizon, text(fill: rgb("#889"), style: "italic", size: 9pt, msg))] // Standardize inlined figure sizes: measure the natural CeTZ canvas, then scale to a // consistent envelope (aspect-aware; see build_typst.py FIG_* constants). Unlike the // print preamble, dimensions are FLOORED: in an editor a user can trim a figure to a // degenerate 1-D shape (a bare line), and w/h or tw/w would then divide by zero. #let _STD_W = 3.5 #let _WIDE_W = 5.6 #let _MAX_H = 3.4 #let _ASPECT_WIDE = 2.2 #let _UPSCALE_MAX = 1.15 #let stdfig(body) = context { let m = measure(body) let w = calc.max(m.width / 1in, 0.01) let h = calc.max(m.height / 1in, 0.01) let tw = if w / h > _ASPECT_WIDE { _WIDE_W } else { _STD_W } let s = calc.min(tw / w, _MAX_H / h, _UPSCALE_MAX) align(center, box(scale(x: s * 100%, y: s * 100%, reflow: true, body))) } #show figure: set block(breakable: false) #set figure(gap: 8pt) #show figure.caption: set text(size: 8.5pt, fill: rgb("#555")) == 7.1#h(0.6em)Module basics === Learning objectives By the end of this section you should be able to - Write a module that consists only of function definitions. - Import the module and use the functions in a program. === Defining a module Modules are defined by putting code in a #emph[.py] file. The area module below is in a file named area.py. This module provides functions for calculating area. #examplebox("Example 1")[The area module][ """Functions to calculate the area of geometric shapes.""" import math \# 2D shapes def square(side):     """Gets the area of a square."""     return side\*\*2 def rectangle(length, width):     """Gets the area of a rectangle."""     return length \* width def triangle(base, height):     """Gets the area of a triangle."""     return 0.5 \* base \* height def trapezoid(base1, base2, height):     """Gets the area of a trapezoid."""     return 0.5 \* (base1 + base2) \* height def circle(radius):     """Gets the area of a circle."""     return math.pi \* radius\*\*2 def ellipse(major, minor):     """Gets the area of an ellipse."""     return math.pi \* major \* minor \# 3D shapes def cube(side):     """Gets the surface area of a cube."""     return 6 \* side\*\*2 def cylinder(radius, height):     """Gets the surface area of a cylinder."""     return 2 \* math.pi \* radius \* (radius + height) def cone(radius, height):     """Gets the surface area of a cone."""     return math.pi \* radius \* (radius + math.hypot(height, radius)) def sphere(radius):     """Gets the surface area of a sphere."""     return 4 \* math.pi \* radius\*\*2 ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Defining a module] ] === Importing a module The module defined in #emph[area.py] can be used in other programs. When importing the area module, the suffix .py is removed: import area print("Area of a basketball court:", area.rectangle(94, 50)) print("Area of a circus ring:", area.circle(21)) The output is: Area of a basketball court: 4700 Area of a circus ring: 1385.4423602330987 #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Importing area in a Python shell] #link("https://www.openstax.org/r/importing-area")[Importing area; ch 7, video 1] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Importing a module] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Conversion module] Write a module that defines the following functions: + cel2fah(c) – #linebreak() Converts a temperature in Celsius to Fahrenheit. #linebreak() The formula is 9/5 \* c + 32. + fah2cel(f) – #linebreak() Converts a temperature in Fahrenheit to Celsius. #linebreak() The formula is 5/9 \* (f - 32). + km2mi(km) – #linebreak() Converts a distance in kilometers to miles. #linebreak() The formula is km / 1.60934. + mi2km(mi) – #linebreak() Converts a distance in miles to kilometers. #linebreak() The formula is mi \* 1.60934. Each function should include a docstring as the first line. A docstring for the module has been provided for you. The module should not do anything except define functions. When you click the "Run" button, the module should run without error. No output should be displayed. """Functions that convert metric and imperial units.""" ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[European vacation] Write a program that uses the conversion module from the previous exercise to complete a short story. The program's output should match the following example (input in bold): How fast were you driving? #strong[180] Woah, that's like 112 mph! What was the temperature? #strong[35] That's 95 degrees Fahrenheit! Notice this exercise requires two files: + #emph[european.py], the main program. Input and output statements are provided as a starting point. Edit the lines with TODO comments to use the conversion module. + #emph[conversion.py], the other module. Copy and paste your code from the previous exercise. Import this module in #emph[european.py] after the docstring. """Example program that uses the conversion module.""" speed\_in\_km = float(input("How fast were you driving? ")) speed\_in\_mi = 0 \# TODO print("Woah, that's like", round(speed\_in\_mi), "mph!") temp\_in\_c = float(input("What was the temperature? ")) temp\_in\_h = 0 \# TODO print("That's", round(temp\_in\_h), "degrees Fahrenheit!") ]