String Operations, Methods, and Functions#

As Cryptography primarily deals with enciphering and deciphering messages written as text, the string data type will be used very frequently. There are special operations that can be performed on strings to combine, slice, and display them in ways that will be beneficial for the study of Cryptography.

Concatenating Strings#

Two strings can be combined end-to-end in a process called concatenation. This operation uses the + symbol between string literals or variables referencing string objects to create a new string.

print('hello' + 'student')
hellostudent
word1 = 'hello'
word2 = 'students'
print(word1 + word2)
print(word2 + word1)
hellostudents
studentshello

Notice that unlike addition, the order of concatentation is important, as strings will be combined left to right.

Formatting Strings#

Many object types have built-in features that give them special abilities. These abilities are called methods and many of the methods related to strings allow you to format them a specific way. You call a method onto an object by appending .methodName() to the end of the object, where methodName is replaced with the name of the method you intend to you.

For example, to use the upper() method on the object hello:

print( 'hello'.upper() )
HELLO

Methods also work on variables that point to str type objects:

password = "I'll never tell!"
print( password.upper() )
I'LL NEVER TELL!

Note that the method upper() does not change the value of the object password, which is still has the original value of “I’ll never tell!”. The method creates a temporary value that can be used instead of the actual value of the object.

A table of frequently used methods for string objects and their actions is provided below.

method name

usage

result

upper()

string.upper()

Makes all characters upper-case

lower()

string.lower()

Makes all characters lower-case

capitalize()

string.captialize()

Capitalizes the first character in the string

title()

string.title()

Capitalizes the first character in each word

swapcase()

string.swapcase()

Swaps the case of each character

replace()

string.replace(old, new, count)

Replaces old with new. Case sensitive.

find()

string.find(‘A’)

Returns the index of the first location string A is found, or if not found returns -1. Case sensitive.

index()

string.index(‘A’)

Returns the index of the first location string A is found, or if not found returns an error. Case sensitive.

count()

string.count(‘A’)

Returns an integer that represents how many ‘A’s are in the string

Methods can be combined by continuing them to the end of your expressions.

Examples:

We can replace the substring 'bananas' with the string 'apples'.

print( 'I like bananas'.replace('bananas','apples') )
I like apples

You don’t need to replace all occurrences of 'bananas' though if you don’t want. You can specify how many occurrences to replace by using a a 3rd parameter for your method. The example below will replace only occurrence #1 with 'apples'.

print( 'I like bananas! bananas are my favorite'.replace('bananas','apples', 1) )
I like apples! bananas are my favorite

Methods can be combined and will be applied in order from left to right, so make sure you think through the order to apply them! In the second example using upper() after find() will result in an error because find() will result in an integer, and integers don’t have a upper() method that can be used.

print( 'mississippi'.upper().count('S') )
4
print( 'mississippi'.count('S').upper() )
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-f9b5968baf56> in <module>
----> 1 print( 'mississippi'.count('S').upper() )

AttributeError: 'int' object has no attribute 'upper'

Using the find() method will return the location of the first occurrence of the substring 'n'. Notice that a character location, or index, starts counting with the first character at 0. More on this below.

print( "I'll never tell!".find('n') )
5

Including 2 additional integers in the find() method will allow you narrow down the search. In the example below the find() method will return the location of the first occurrence of the substring ‘l’ between indices 10 and 15.

print( "I'll never tell!".find('l', 10, 15))
13

If a find() method can’t find a substring, it will return the value of -1. The index() method, which works similarly, returns an error message when it can’t find a substring.

print( password.upper().find('n') )
-1
print( 'hello'.index('Q') )
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-128724154227> in <module>
----> 1 print( 'hello'.index('Q') )

ValueError: substring not found

Notice this last cell produced a new type of error, ValueError. This error is raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception (error message). In this case, it means that the index() method was correctly given a str type object Q, but it was not found in the the string the method was acting upon, hello.

Removing Spaces#

A good trick to keep in mind is how to remove spaces. You can remove spaces, or any other character, using the .replace() method where the second argument is an empty string, ''

print( 'When this command is run there will be no more spaces'.replace(' ', '') )
Whenthiscommandisruntherewillbenomorespaces

The len() Function#

The built-in len() function will return an integer that indicates how many characters are stored a string.

len( 'hello there' )
11

We’ll see later that the len() function can be used on other types of objects, such as lists.

String Indices#

When creating a string object in Python, each character in the string is indexed, meaning it has an integer, starting at 0, assigned to each character in the string that denotes the position of that character in the string. For example:

code = 'secret'

The variable code now points to a string object containing the characters secret. The string has been indexed, meaning assigned a position value, starting with 0:

0

1

2

3

4

5

code

s

e

c

r

e

t

You refer to a character stored at a single index, or range of indices using a special syntax.

The syntax stringName[a] will return the character found at index a in the string stringName

The following Python code will print only the character in string code found at index 4.

print( code[4] )
e

which will also work directly on any literal string object as well:

print( 'secret'[2] )
c

Negative Indices#

You can use negative numbers for indices, which will count indices from the end of the string.

-6

-5

-4

-3

-2

-1

code

s

e

c

r

e

t

print( code[-3] )
r

String Slicing#

You can return a sequence of characters from a string, called slicing, by using the notation stringName[start:stop:step], which will return the characters starting at index start and ending at the index just before index stop, moving by step number of spaces each time. Not all of these positions are required, and can be omitted.

If start is omitted, it’s assumed to start at index 0, if stop is omitted it’s assumed to stop at the last index, and if step is omitted it’s assumed to use a step size of 1.

print( code[1:4] )
ecr
print( code[1:6:2] )
ert
print( code[::3] )
sr
print( code[:5:] )
secre
print( code[3::] )
ret

As you can see that by using all 3 values for start, stop, and step you can extract almost any portion of a string.

Indices Out of Range#

If you reference an index value that is not assigned to a character, you’ll receive an error indicating that the string index is out of range meaning, the index you provided is outside the range of values Python was expecting for this string.

code[7]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-18-80ed44c22a90> in <module>
----> 1 code[7]

IndexError: string index out of range
code[-10]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-19-d21b880b4f52> in <module>
----> 1 code[-10]

IndexError: string index out of range