#set document(title: "8.1 String operations", 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")) == 8.1#h(0.6em)String operations === Learning objectives By the end of this section you should be able to - Compare strings using logical and membership operators. - Use lower() and upper() string methods to convert string values to lowercase and uppercase characters. === String comparison String values can be compared using logical operators (\<, \<=, \>, \>=, ==, !=) and membership operators (in and not in). When comparing two string values, the matching characters in two string values are compared sequentially until a decision is reached. For comparing two characters, ASCII values are used to apply logical operators. #figure(table( columns: 5, align: left, inset: 6pt, table.header([Operator], [Description], [Example], [Output], [Explanation]), [\> or \>=], [Checks whether the first string value is greater than (or greater than or equal to) the second string value.], ["c" \> "d"], [False], [When comparing "c" operand to "d" operand, the ASCII value for "c" is smaller than the ASCII value for "d". Therefore, "c" \< "d". The expression "c" \> "d" evaluates to False.], [\< or \<=], [Checks whether the first string value is less than (or less than or equal to) the second string value.], ["ab" \< "ac"], [True], [When comparing "ab" operand to "ac" operand, the first characters are the same, but the second character of "ab" is less than the second character in "ac" and as such "ab" \< "ac".], [==], [Checks whether two string values are equal.], ["aa" == "aa"], [True], [Since all characters in the first operand and the second operand are the same, the two string values are equal.], [!=], [Checks whether two string values are not equal.], ["a" != "b"], [True], [The two operands contain different string values ("a" vs. "b"), and the result of checking whether the two are not the same evaluates to True.], [in], [Checks whether the second operand contains the first operand.], ["a" in "bc"], [False], [Since string "bc" does not contain string "a", the output of "a" in "bc" evaluates to False.], [not in], [Checks whether the second operand does not contain the first operand.], ["a" not in "bc"], [True], [Since string "bc" does not contain string "a", the output of "a" not in "bc" evaluates to True.], )) #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Using logical and membership operators to compare string values] ] === lower() and upper() Python has many useful methods for modifying strings, two of which are lower() and upper() methods. The #strong[lower()] method returns the converted alphabetical characters to lowercase, and the #strong[upper()] method returns the converted alphabetical characters to uppercase. Both the lower() and upper() methods do #emph[not] modify the string. #examplebox("Example 1")[Converting characters in a string][ In the example below, the lower() and upper() string methods are called on the string variable x to convert all characters to lowercase and uppercase, respectively. x = "Apples" \# The lower() method converts a string to all lowercase characters print(x.lower()) \# The upper() method converts a string to all uppercase characters print(x.upper()) The above code's output is: apples APPLES ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Using lower() and upper()] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Number of characters in the string] A string variable, s\_input, is defined. Use lower() and upper() to convert the string to lowercase and uppercase, and print the results in the output. Also, print the number of characters in the string, including space characters. s\_input = "Today is a great DAY!" ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[What is my character?] Given the string, s\_input, which is a one-character string object, if the character is between "a" and "t" or "A" and "T", print True. Otherwise, print False. #linebreak() Hint: You can convert s\_input to lowercase and check if s\_input is between "a" and "t". s\_input = "B" ]