CMU 15-110: Principles of Computing
Strings
- String Literals
- Some String Constants
- Some String Operators
- Looping over Strings
- Example: isPalindrome
- Strings are Immutable
- Some String-related Functions
- Some String Methods
- Basic File IO
- String Literals
- Four kinds of quotes
print('single-quotes') print("double-quotes") print('''triple single-quotes''') print("""triple double-quotes""") - Newlines in strings
print('ab\ncd') # \n is a single newline character print(len('ab\ncd')) # 5 print('''ab cd''') - String Literals as Multi-line Comments
''' One way to 'comment out' a large block of code is to place it in triple-quotes. Python will basically ignore that code. '''
- Four kinds of quotes
- Some String Constants
import string print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz print(string.ascii_uppercase) # ABCDEFGHIJKLMNOPQRSTUVWXYZ print(string.digits) # 0123456789 print(string.punctuation) # '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' print(string.whitespace) # space + tab + linefeed + return + ...
- Some String Operators
- String + and *
print('abc' + 'def') print('abc' * 3) print('abc' + 3) # error - The in operator
print('ring' in 'strings') print('wow' in 'amazing!') print('Yes' in 'yes!') print('' in 'No way!') - String indexing and slicing
- Indexing a single character
s = 'abcdefgh' print(s) print(s[0]) print(s[1]) print(s[len(s)-1]) print(s[len(s)]) # crashes (string index out of range) - Negative indexes
s = 'abcdefgh' print(s) print(s[-1]) print(s[-2]) print(s[-len(s)]) print(s[-len(s)-1]) # crashes (string index out of range) - Slicing a range of characters
s = 'abcdefgh' print(s) print(s[0:4]) print(s[2:4]) - Slicing with default parameters
s = 'abcdefgh' print(s) print(s[3:]) print(s[:3]) print(s[:])
- Indexing a single character
- String + and *
- Looping over Strings
- "for" loop with indexes
s = 'abcd' for i in range(len(s)): print(i, s[i]) - "for" loop without indexes
s = 'abcd' for c in s: print(c) - "for" loop with split
names = 'fred,wilma,betty,barney' for name in names.split(','): print(name) - "for" loop with splitlines
lines = ''' Q: What do you get when you cross a stream and a brook? A: Wet feet. Q: What do you get when you cross poison ivy with a 4-leaf clover? A: A rash of good luck. ''' for line in lines.splitlines(): if (line.startswith('Q:')): print(line)
- "for" loop with indexes
- Example: isPalindrome
# There are many ways to write isPalindrome. Here are a few: def isPalindrome1(s): for i in range(len(s)): if (s[i] != s[-1-i]): return False return True def reverseString(s): # Note: there are shorter and more efficient ways, but this is very clear result = '' for c in s: result = c + result return result def isPalindrome2(s): return (s == reverseString(s)) def isPalindrome3(s): while (s != ''): if (s[0] != s[-1]): return False s = s[1:-1] return True print(isPalindrome1('abcba'), isPalindrome1('abca')) print(isPalindrome2('abcba'), isPalindrome2('abca')) print(isPalindrome3('abcba'), isPalindrome3('abca'))
- Strings are Immutable
- You cannot change strings! They are immutable.
s = 'abcde' s[2] = 'z' # Error! Cannot assign into s[i] - Instead, you must create a new string
s = 'abcde' s = s[:2] + 'z' + s[3:] print(s)
- You cannot change strings! They are immutable.
- input(), str(), and len()
name = input('Enter your name: ') print('Hi, ' + name + '. Your name has ' + str(len(name)) + ' letters!') - chr() and ord()
print(ord('A')) # 65 print(chr(65)) # 'A' print(chr(ord('A')+1)) # ?
- Character types
s.isalpha() True if s only contains letters A-Z,a-z s.isdigit() True if s only contains digits 0-9 s.isspace() True if s only contains whitespace (spaces, tabs, newlines) s.islower() True if the letters in s are all lowercase (a-z) s.isupper() True if the letters in s are all uppercase (A-Z) - String edits
s.lower() Returns a copy of s in lowercase s.upper() Returns a copy of s in uppercase s.strip() Returns a copy of s without leading or trailing whitespace s.replace(old, new) Returns a copy of s replacing occurrences of old with new
For example: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')) - Substring search
s.count(t) Returns number of times t occurs in s s.startswith(t) Returns True if s starts with t s.endswith(t) Returns True if s ends with t s.find(t) Returns the index of where t starts in s, or -1 if not there s.index(t) Returns the index of where t starts in s, or crashes if not there
For example: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!
# Note: As this requires read-write access to your hard drive,
# this will not run in the browser in Brython.
def readFile(path):
# This makes a very modest attempt to deal with unicode if present
with open(path, 'rt', encoding='ascii', errors='surrogateescape') 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.')