characterThis class allows us to create characters and prefix them with a special character when the str() function is applied to them.

Nothing too exciting there.

We only have to make a few minor modifications to the Document and Cursor classes to work with this class.

In the Document class, we add these two lines at the beginning of the insert method, as follows:def insert(self, character): if not hasattr(character, 'character'): character = Character(character)This is a rather strange bit of code.

Its basic purpose is to check whether the character being passed in is a Character or a str.

If it is a string, it is wrapped in a Character class so all objects in the list are Character objects.

However, it is entirely possible that someone using our code would want to use a class that is neither a Character nor a string, using duck typing.

If the object has a character attribute, we assume it is a Character-like object.

But if it does not, we assume it is a str-like object and wrap it in Character.

This helps the program take advantage of duck typing as well as polymorphism; as long as an object has a character attribute, it can be used in the Document class.

This generic check could be very useful.

For example, if we wanted to make a programmer’s editor with syntax highlighting, we’d need extra data on the character, such as what type of syntax token the character belongs to.

Note that, if we are doing a lot of this kind of comparison, it’s probably better to implement Character as an abstract base class with an appropriate __subclasshook__.

In addition, we need to modify the string property on Document to accept the new Charactervalues.

All we need to do is call str() on each character before we join it, as demonstrated in the following:@property def string(self): return "".

join((str(c) for c in self.

characters))This code uses a generator expression.

It’s a shortcut to perform a specific action on all the objects in a sequence.

Finally, we also need to check Character.

character, instead of just the string character we were storing before, in the home and end functions when we’re looking to see whether it matches a newline character, as demonstrated in the following:def home(self): while self.

document.

characters[ self.

position-1].

character != '.': self.

position -= 1 if self.

position == 0: # Got to beginning of file before newline break def end(self): while self.

position < len( self.

document.

characters) and self.

document.

characters[ self.

position ].

character != '.': self.

position += 1This completes the formatting of characters.

We can test it to see that it works as follows:>>> d = Document()>>> d.

insert('h')>>> d.

insert('e')>>> d.

insert(Character('l', bold=True))>>> d.

insert(Character('l', bold=True))>>> d.

insert('o')>>> d.

insert('.')>>> d.

insert(Character('w', italic=True))>>> d.

insert(Character('o', italic=True))>>> d.

insert(Character('r', underline=True))>>> d.

insert('l')>>> d.

insert('d')>>> print(d.

string)he*l*lo/w/o_rld>>> d.

cursor.

home()>>> d.

delete()>>> d.

insert('W')>>> print(d.

string)he*l*loW/o_rld>>> d.

characters[0].

underline = True>>> print(d.

string)_he*l*loW/o_rldAs expected, whenever we print the string, each bold character is preceded by a * character, each italicized character by a / character, and each underlined character by a _ character.

All our functions seem to work, and we can modify characters in the list after the fact.

We have a working rich text document object that could be plugged into a proper graphical user interface and hooked up with a keyboard for input and a screen for output.

Naturally, we’d want to display real bold, italic, and underlined fonts in a UI, instead of using our __str__ method, but it was sufficient for the basic testing we demanded of it.