#set document(title: "3.1 Strings revisited", 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")) == 3.1#h(0.6em)Strings revisited === Learning objectives By the end of this section you should be able to - Extract a specific character from a string using an index. - Use escape sequences to represent special characters. === Indexes A string is a sequence of zero or more characters. Each character has an index that refers to the character's position. Indexes are numbered from left to right, starting at 0. Indexes are also numbered from right to left, starting at -1. #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[String indexes] #link("https://www.openstax.org/r/string-indexes")[String indexes; ch 3, video 1] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[String indexes] ] === Unicode Python uses #strong[Unicode], the international standard for representing text on computers. Unicode defines a unique number, called a #strong[code point], for each possible character. Ex: "P" has the code point 80, and "!" has the code point 33. The built-in ord() function converts a character to a code point. Ex: ord("P") returns the integer 80. Similarly, the built-in chr() function converts a code point to a character. Ex: chr(33) returns the string "!". Unicode is an extension of #strong[ASCII], the American Standard Code for Information Interchange. Originally, ASCII defined only 128 code points, enough to support the English language. Unicode defines over one million code points and supports most of the world's written languages. #figure(table( columns: 3, align: left, inset: 6pt, [32  (space)   33  ! 34  " 35  \# 36  \$ 37  % 38  & 39  ' 40  ( 41  ) 42  \* 43  + 44  , 45  - 46  . 47  / 48  0 49  1 50  2 51  3 52  4 53  5 54  6 55  7 56  8 57  9 58  : 59  ; 60  \< 61  = 62  \> 63  ?], [64  \@         65  A 66  B 67  C 68  D 69  E 70  F 71  G 72  H 73  I 74  J 75  K 76  L 77  M 78  N 79  O 80  P 81  Q 82  R 83  S 84  T 85  U 86  V 87  W 88  X 89  Y 90  Z 91  \[ 92  \\ 93  \] 94  ^ 95  \_], [96  \` 97  a 98  b 99  c 100  d 101  e 102  f 103  g 104  h 105  i 106  j 107  k 108  l 109  m 110  n 111  o 112  p 113  q 114  r 115  s 116  t 117  u 118  v 119  w 120  x 121  y 122  z 123  { 124  | 125  } 126  ~ 127  (delete)], )) #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[ord() and chr()] ] === Special characters An #strong[escape sequence] uses a backslash (\\) to represent a special character within a string. #figure(table( columns: 4, align: left, inset: 6pt, table.header([Escape sequence], [Meaning], [Example], [Screen output]), [\\n], [A newline character that indicates the end of a line of text.], [print("Escape\\nsequence!")], [Escape #linebreak() sequence!], [\\t], [A tab character; useful for indenting paragraphs or aligning text on multiple lines.], [print("Escape\\tsequence!")], [Escape    sequence!], [\\'], [A single quote; an alternative to enclosing the string in double quotes.], [print('I\\'ll try my best!')], [I'll try my best], [\\"], [A double quote; an alternative to enclosing the string in single quotes.], [print("I heard you said \\"Yes\\"")], [I heard you said "Yes"], [\\\\], [A backslash character.], [print("This prints a \\\\")], [This prints a \\], )) #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Tabs and newlines] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Hopper quote] #link("https://openstax.org/r/100gracehopper")[Grace Hopper] (1906–1992) was a famous computer scientist (and rear admiral in the US Navy!) who came up with the idea of machine-independent programming languages. She envisioned a programming language based on English and made many contributions that paved the way for modern programming languages, including Python. Write a program that prints the following text, including the quotation marks. Your program may not use single quotes (') anywhere in the code. The last line must be indented with a tab character. "To me programming is more than an important practical art. It is also a gigantic undertaking in the foundations of knowledge." -- Grace Hopper ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Shift cipher] During the Roman Empire, Julius Caesar (100–44 BCE) used a simple technique to encrypt private messages. Each letter of the message was replaced with the third next letter of the alphabet. Ex: If the message was CAT, the C became F, the A became D, and the T became W, resulting in the message FDW. This technique is known as a shift cipher because each letter is shifted by some amount. In Caesar's case, the amount was three, but other amounts (besides 0) would work too. Write a program that prompts the user to input the following two values (example input in bold): Enter a 3-letter word: #strong[CAT] Shift by how many letters? #strong[3] The program should then shift each letter of the word by the desired amount. Based on the example above, the output would be: The secret message is: FDW Hint: Use the ord() function to convert each letter to an integer, add the shift amount to each integer, use the chr() function to convert each integer to a character, and concatenate the resulting characters. ]