Content
- String continued
- String literals
- String constants
- More about string looping
- Some String Methods
- String Formatting
- Basic File IO
- Examples
- Programming Style
- Top down design
Strings continued
1. String literals
Four kinds of quotes
# single-quoted or double-quoted strings are the most common
print('single-quotes')
print("double-quotes")
# triple-qouted strings are less common (though see next section for a typical use)
print('''triple single-quotes''')
print("""triple double-quotes""")
Newlines in strings
print("abc\ndef") # \n is a single newline character
print("""abc
def""")
print("""\
You can use a backslash at the end of a line in a string to exclude
the newline after it. This should almost never be used, but one good
use of it is in this example, at the start of a multi-line string, so
the whole string can be entered with the same indentation (none, that is).
""")
More Escape Sequences
print("Double-quote: \"")
print("Backslash: \\")
print("Newline (in brackets): [\n]")
print("Tab (in brackets): [\t]")
print("These items are tab-delimited, 3-per-line:")
print("abc\tdef\tg\nhi\tj\\\tk\n---")
An escape sequence produces a single character
s = "a\\b\"c\td"
print("s =", s)
print("len(s) =", len(s))
Concatenated Literals
s = "abc" "def" # ok (but "abc" + "def" is preferred)
print(s)
s = s "def" # error (only works with string literals, not variables)
String Literals as Multi-line Comments
"""
Python does not have multiline comments, but you can do something similar
by using a top-level multiline string, such as this. Technically, this is
not a comment, and Python will evaluate this string, but then ignore it
and garbage collect it!
"""
print("wow!")
2. String constants
import string
print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz
print("-----------")
print(string.ascii_uppercase) # ABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.digits) # 0123456789
print("-----------")
print(string.punctuation) # '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
print(string.printable) # digits + letters + punctuation + whitespace
print("-----------")
print(string.whitespace) # space + tab + linefeed + return + ...
3. More about string looping
"for" loop with split
names = "fred,wilma,betty,barney"
for name in names.split(","):
print(name)
"for" loop with splitlines
# quotes from brainyquote.com
quotes = """\
Dijkstra: Simplicity is prerequisite for reliability.
Knuth: If you optimize everything, you will always be unhappy.
Dijkstra: Perfecting oneself is as much unlearning as it is learning.
Knuth: Beware of bugs in the above code; I have only proved it correct, not tried it.
Dijkstra: Computer science is no more about computers than astronomy is about telescopes.
"""
for line in quotes.splitlines():
if (line.startswith("Knuth")):
print(line)
4. Some String Methods
Character types: isalnum(), isalpha(), isdigit(), islower(), isspace(), isupper()
# Run this code to see a table of isX() behaviors
def p(test):
print("True " if test else "False ", end="")
def printRow(s):
print(" " + s + " ", end="")
p(s.isalnum())
p(s.isalpha())
p(s.isdigit())
p(s.islower())
p(s.isspace())
p(s.isupper())
print()
def printTable():
print(" s isalnum isalpha isdigit islower isspace isupper")
for s in "ABCD,ABcd,abcd,ab12,1234, ,AB?!".split(","):
printRow(s)
printTable()
String edits: lower(), upper(), replace(), strip()
print("This is nice. Yes!".lower())
print("So is this? Sure!!".upper())
print(" Strip removes leading and trailing whitespace only ".strip())
print("This is nice. Really nice.".replace("nice", "sweet"))
print("This is nice. Really nice.".replace("nice", "sweet", 1)) # count = 1
print("----------------")
s = "This is so so fun!"
t = s.replace("so ", "")
print(t)
print(s) # note that s is unmodified (strings are immutable!)
Substring search: count(), startswith(), endswith(), find(), index()
print("This is a history test".count("is")) # 3
print("This IS a history test".count("is")) # 2
print("-------")
print("Dogs and cats!".startswith("Do")) # True
print("Dogs and cats!".startswith("Don't")) # False
print("-------")
print("Dogs and cats!".endswith("!")) # True
print("Dogs and cats!".endswith("rats!")) # False
print("-------")
print("Dogs and cats!".find("and")) # 5
print("Dogs and cats!".find("or")) # -1
print("-------")
print("Dogs and cats!".index("and")) # 5
print("Dogs and cats!".index("or")) # crash!
format a string with %s
breed = "beagle"
print("Did you see a %s?" % breed)
format an integer with %d
dogs = 42
print("There are %d dogs." % dogs)
format a float with %f
grade = 87.385
print("Your current grade is %f!" % grade)
format a float with %.[precision]f
grade = 87.385
print("Your current grade is %0.1f!" % grade)
format multiple values
dogs = 42
cats = 18
exclamation = "Wow"
print("There are %d dogs and %d cats. %s!!!" % (dogs, cats, exclamation))
format right-aligned with %[minWidth]
dogs = 42
cats = 3
print("%10s %10s" % ("dogs", "cats"))
print("%10d %10d" % (dogs, cats))
format left-aligned with %-[minWidth]
dogs = 42
cats = 3
print("%-10s %-10s" % ("dogs", "cats"))
print("%-10d %-10d" % (dogs, cats))
5. Basic File IO
def readFile(path):
with open(path, "rt") as f:
return f.read()
def writeFile(path, contents):
with open(path, "wt") as f:
f.write(contents)
contentsToWrite = "This is a test!\nIt is only a test!"
writeFile("foo.txt", contentsToWrite)
contentsRead = readFile("foo.txt")
assert(contentsRead == contentsToWrite)
print("Open the file foo.txt and verify its contents.")
Example 1: Caesar shift
def encrypt(message, shiftNum):
result = ""
for char in message:
result += shift(char, shiftNum)
return result
def shift(char, shiftNum):
shiftNum = shiftNum % 26
if(not char.isalpha()): return char
shiftedOrd = ord(char) + shiftNum
if char.islower():
distanceFromOrigin = (shiftedOrd - ord('a')) % 26
return chr(ord('a') + distanceFromOrigin)
else:
distanceFromOrigin = (shiftedOrd - ord('A')) % 26
return chr(ord('A') + distanceFromOrigin)
# An alternative solution
def shift(char, shiftNum):
shiftNum = shiftNum % 26
if(not char.isalpha()): return char
shifted = ord(char) + shiftNum
if ( ((char <= 'Z') and (shifted > ord('Z'))) or
((char <= 'z') and (shifted > ord('z')))):
return chr(shifted - 26)
else:
return chr(shifted)
Example 2: longestSubpalindrome(s)
Write the function longestSubpalindrome(s), that takes a string s and returns the longest palindrome that occurs as consecutive characters (not just letters, but any characters) in s. So:
longestSubpalindrome("ab-4-be!!!") returns "b-4-b". If there is a tie, return the lexicographically larger value -- in Python, a string s1 is lexicographically greater than a string s2 if (s1 > s2). So:
longestSubpalindrome("abcbce") returns "cbc", since ("cbc" > "bcb"). Note that unlike the previous functions, this function is case-sensitive (so "A" is not treated the same as "a" here). Also, from the explanation above, we see that longestSubpalindrome("aba") is "aba", and longestSubpalindrome("a") is "a".
Example 3: leastFrequentLetters(s)
Write the function leastFrequentLetters(s), that takes a string s, and ignoring case (so "A" and "a" are treated the same), returns a lowercase string containing the least-frequent alphabetic letters that occur in s, each included only once in the result and then in alphabetic order. So:
leastFrequentLetters("aDq efQ? FB'daf!!!") returns "be". Note that digits, punctuation, and whitespace are not letters! Also note that seeing as we have not yet covered lists, sets, maps, or efficiency, you are not expected to write the most efficient solution. Finally, if s does not contain any alphabetic characters, the result should be the empty string ("").
5
Programming Style
See here.
Top-down Design
See here.
How to approach a programming problem:
- Understand the problem
- Devise a plan
- Use explicit, clear, small steps
- Don't require human memory or intuition
- Translate the algorithm into code
- Write test cases
- Write code (starting here is a big mistake!)
- Test code
- Examine and review
For step 2 (devising a plan), here are a few useful strategies:
- Top-down design (also known as "divide and conquer")
- Break up the problem into smaller parts.
- Assume solutions to smaller parts exist.
- Combine them to get the overall solution.
- Solve each smaller part separately.
- Incremental layers of complexity
- Start with basic functionality.
- Add more functionality.
- Build your program layer by layer.
For example, suppose you are writing the Pong Game.
- Start with a ball bouncing around.
- Add paddles.
- Make paddles move up and down with keystrokes.
- Make the ball interact with the paddles.
- Implement scoring a goal.
- Keep track of scores.
- ...
- Solving a simplified version
- Identify a meaningful simplified version of the problem.
- Solve the simplified version.
- This can give you good intuition on how to solve the general problem. The solution to the simplified version can sometimes serve as a helper function.