#set document(title: "7.2 Importing names", 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.2#h(0.6em)Importing names === Learning objectives By the end of this section you should be able to - Import functions from a module using the from keyword. - Explain how to avoid a name collision when importing a module. === The from keyword Specific functions in a module can be imported using the from keyword: from area import triangle, cylinder These functions can be called directly, without referring to the module: print(triangle(1, 2)) print(cylinder(3, 4)) #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Exploring further] As shown below, the from keyword can lead to confusing names. ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Importing functions] #link("https://www.openstax.org/r/importing-functions")[Importing functions; ch 7, video 2] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[The from keyword] ] === Name collisions Modules written by different programmers might use the same name for a function. A #strong[name collision] occurs when a function is defined multiple times. If a function is defined more than once, the most recent definition is used: from area import cube def cube(x):    \# Name collision (replaces the imported function)   return x \*\* 3 print(cube(2)) \# Calls the local cube() function, not area.cube() A programmer might not realize the cube function is defined twice because no error occurs when running the program. Name collisions are not considered errors and often lead to unexpected behavior. Care should be taken to avoid name collisions. Selecting specific functions from a module to import reduces the memory footprint; however, importing a complete module can help to avoid collisions because a #emph[module.name] format would be used. This is a tradeoff the programmer must consider. #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Module and function names] #link("https://www.openstax.org/r/module-function-names")[Module and function names; ch 7, video 3] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Name collisions] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Exploring further] If a name is defined, imported, or assigned multiple times, Python uses the most recent definition. Other languages allow multiple functions to have the same name if the parameters are different. This feature, known as #strong[function overloading], is not part of the Python language. ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Missing imports] Add the missing import statements to the top of the file. Do not make any changes to the rest of the code. In the end, the program should run without errors. def is\_prime(n): """Returns True if n is prime.""" if n \< 2: return False for i in range(2, int(sqrt(n)) + 1): if n % i == 0: return False return True \# Test the is\_prime function for n in range(10): if is\_prime(n): print(n, "is prime") else: print(n, "is NOT prime") def pizza\_rate(size, price): """Calculates the value of a pizza coupon. Args: size (int): Diameter of the pizza in inches. price (float): Advertised price of the pizza. Returns: float: The pizza's price per square inch. """ return price / circle(size / 2) \# Test the pizza\_rate function print() print(" Small for \$4.99:", pizza\_rate(10, 4.99)) print(" Medium for \$5.99:", pizza\_rate(12, 5.99)) print(" Large for \$7.99:", pizza\_rate(14, 7.99)) print("X-Large for \$9.99:", pizza\_rate(16, 9.99)) ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Party favors] The following program does not run correctly because of name collisions. Fix the program by modifying import statements, function calls, and variable assignments. The output should be: Bouncy ball area: 13 Bouncy ball volume: 4 Cone hat area: 227 Cone hat volume: 209 from area import cone, sphere import math def cone(radius, height): """Gets the volume of a cone.""" return math.pi \* radius\*\*2 \* height/3 def sphere(radius): """Gets the volume of a sphere.""" return 4/3 \* math.pi \* radius\*\*3 \# A bouncy ball is 2 inches in diameter. area = sphere(1) volume = sphere(1) print("Bouncy ball area:", round(area)) print("Bouncy ball volume:", round(volume)) \# A cone hat is 10 inches in diameter and 8 inches tall. area = cone(5, 8) volume = cone(5, 8) print("Cone hat area:", round(area)) print("Cone hat volume:", round(volume)) ]