Playing around with Strings and Python

Python is my favorite language. It allows anything from high level to low level programming. It is very easy to understand. Python can be written as an algorithm that you can execute. Today, I want to show you some cool tricks on how to manipulate strings in python.

NOTE: I am running Python2.6. I highly recommend you read the Python 2.6 String documentation prior to proceeding. I suggest you also download python2.6 documentation for offline reference.

Python stores strings in it’s virtual memory as arrays. This is very useable since you can address each character individually. Strings are 0 based arrays and support reverse indexing. However, unlike arrays, strings are not mutable. Strings also support concatenation and other cool stuff. Let’s take a look at the following output:
wpid-wpid-pythonstringmanipulation-2012-12-28-01-53-2012-12-28-01-53.png
Now, lets have fun with the output and give it some more meaning. First lets ask the user for a string and print out the characters of the string each on a line. To do so we will run this code:


a_string = raw_input("Enter some text: ")
for char in a_string:
	print char

Running the program should give you the following output for the input “Hello World!”:

wpid-wpid-pythonprintcharactersofstring-2012-12-28-01-53-2012-12-28-01-53.png

Now lets use the python built in sleep function from the time library. This will delay the printout of each char by a given time. This will cause a neat effect for the user.


import time

a_string = raw_input("Enter some text: ")

for char in a_string:
	print char
	time.sleep(1)

So far it is still dull. Let’s take it a step further and have colors. There is a great library to add colors to python standard output called termcolor. I suggest you take a look at the code for termcolor. To use it we can either create a text object and color it, or use the provided cprint function. Here is the example of printing in res through standard output:


import time
import termcolor

a_string = raw_input("Enter some text: ")

for char in a_string:
	termcolor.cprint(char, "red")
	time.sleep(1)

wpid-wpid-pythonstringredcolor-2012-12-28-01-53-2012-12-28-01-53.png

Termcolor also support printing on color, blinking, bold, italic and others. There is a brief example on the termcolor web page on how to use. That should cover anything you need to know. If I get the time I will come back and write a tutorial for it. If you have questions before such time, feel free to contact the Captain. For the next one, we will print each letter in a different color, like this:


import time
import termcolor

a_string = raw_input("Enter some text: ")
i = 0

for char in a_string:
	if (i%7 == 0):
		termcolor.cprint(char, "grey")
	elif (i%7 == 1):
		termcolor.cprint(char, "red")
	elif (i%7 == 2):
		termcolor.cprint(char, "green")
	elif (i%7 == 3):
		termcolor.cprint(char, "yellow")
	elif (i%7 == 4):
		termcolor.cprint(char, "blue")
	elif (i%7 == 5):
		termcolor.cprint(char, "magenta")
	elif (i%7 == 6):
		termcolor.cprint(char, "cyan")

	time.sleep(1)
	i += 1

wpid-wpid-pythonprintingindiffrentcolors-2012-12-28-01-53-2012-12-28-01-53.png

Now what if you want to print in the same line? Well, we will need to use another standard library called sys.stdout. What we will do is suppress the carige return from the print statement by placing a comma (‘,’) at the end of the print statement. Without flushing the print statement, the output will just appear after the entire line was printed out. Since we want the suspense, we add the flush. Thus printing the input string back to standard output, one character at a time. Check it out:


import time
import termcolor
import sys

a_string = raw_input("Enter some text: ")

for char in a_string:
	print char,
	sys.stdout.flush()
	time.sleep(1)

wpid-wpid-pythonprintacharacteratatime-2012-12-28-01-53-2012-12-28-01-53.png

If we want a different color on each character and have them all on the same line we will need to use the object colored and the regular print statements like before. The code will look like this:


import time
import termcolor
import sys

a_string = raw_input("Enter some text: ")
i = 0

for char in a_string:
	if (i%7 == 0):
		print termcolor.colored(char, "grey"),
	elif (i%7 == 1):
		print termcolor.colored(char, "red"),
	elif (i%7 == 2):
		print termcolor.colored(char, "green"),
	elif (i%7 == 3):
		print termcolor.colored(char, "yellow"),
	elif (i%7 == 4):
		print termcolor.colored(char, "blue"),
	elif (i%7 == 5):
		print termcolor.colored(char, "magenta"),
	elif (i%7 == 6):
		print termcolor.colored(char, "cyan"),

	sys.stdout.flush()
	time.sleep(1)
	i += 1

The screen capture:

wpid-wpid-pythonsamelinediffretcolorcharacters-2012-12-28-01-53-2012-12-28-01-53.png

That is all for. Now you have some extra tools in you arsenal to making some neat command line programs using python. If you are really into it I suggest you take a look at the following program, it is really sci-fi.

download python string sci-fi


# written and executed on mac OSX 10.6.8 running python 2.6.8

import time
import termcolor
import sys
import random

colors = ("grey", "red", "green", "yellow", "blue", "magenta", "cyan")
attributes = ("bold", "underline", "blink", "reverse")

def get_color():
	global colors
	return colors[random.randint(0,len(colors)-1)]
	
def get_on_color():
	global colors
	return "on_" + colors[random.randint(0,len(colors)-1)]
	
def get_attributes():
	global attributes
	return attributes[random.randint(0,len(attributes)-1)]
	
for i in range(100**2):
	x = random.randint(0,6)
	the_char = chr(random.randint(33,126))
	if (x%6 == 0):
		print termcolor.colored(the_char, get_color(), get_on_color(), attrs=[get_attributes()]),
	elif (x%6 == 1):
		print termcolor.colored(the_char, get_color(), get_on_color()),
	elif (x%6 == 2):
		print termcolor.colored(the_char, get_color()),
	elif (x%6 == 4):
		print termcolor.colored(the_char, get_color(), attrs=[get_attributes()]),
	elif (x%6 == 5):
		print termcolor.colored(the_char, get_on_color(), attrs=[get_attributes()]),
	else:
		print the_char,
	
	sys.stdout.flush()
	time.sleep(0.3)


Screen capture of the string secret program - 1

Screen capture of the string secret program - 2

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.
  • sukkerfri

    &quotlol&quot

    • CptDeadBones

      Thanks?

  • Pingback: Playing with Strings and Colors in Python | My Daily Feeds()

  • agf

    Nice post. Since you're writing about strings, you might want to give print 'n'.join("Hello World") as an alternative to the loop. It would generally be considered better style to put functions or values in a list or dict and then use the index of the character to get the correct thing out, rather than use if/elif/else. A relatively idiomatic Python example might be print ' '.join(termcolor.colored(char, ('grey', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan')[i]) for i, char in enumerate(a_string))

    • CptDeadBones

      You are correct. Using the join functionality will be nicer and a better style. I wanted to point out the usage of the array and increase redability. For a non programmer, or a beginner, the loop is something you could follow. In a general sense I tend to code more for readability the effcintcy. Unless I am programming in LISP. Then everything is out the window. Thank you for your remark. I will try to add an edit to the post.

    • Ian Witham

      Better, but I wouldn't use enumerate. You will get an error if your string is longer than the color tuple for a start. Better to dig in to the standard library and use the itertools modules. The "cycle" function is useful for creating and endless loop of color names which can be "zipped" to the corresponding characters of your string. For example,you could create an iterator like this:

      my_colors = 'grey', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan'
      a_string = "Hello World"
      my_iterator = itertools.izip(itertools.cycle(my_colors), a_string).

      Now you can print the joined string like this:

      print ''.join((termcolor.colored(char, color) for char, color in my_iterator))

      • CptDeadBones

        Very interesting approach. From a readability prospective I prefer my version, but yours works too.

  • cobbal

    Small typo: "x%5 == 5" isn't going to be True very often.

    • CptDeadBones

      Corrected. Thank you!

  • bahadirio

    Blink looks cool. Thnx for introducing termcolor lib

    • CptDeadBones

      You are welcome!

  • Gary Josack

    I feel like your use of "array" will be confusing to a Python beginner unless you explicitly state you're talking about a C array. Python has an array type but most people will be using lists. Especially the people most likely to find this post useful.

    • CptDeadBones

      I can see your point. I think it is a matter of prospective. Not every beginner will know what a C array is either. It is part of python's power to use list to solve things (LISP?), but not only. In python you could think of a string as a list, if that helps. Thanks for the insight.

      • Gary Josack

        My point is just that "array" is a less useful term than "list" to a python programmer. I've been programming in Python for years and very rarely see anyone make use of arrays in Python. A python programmer will most certainly know about lists though.

        • CptDeadBones

          I understand and agree. Perhaps I should have used quotation makrs around "array". It is only an analogy I made because of direct indexing that reassembles to most people an array strcture. You are correct that in python it is actually a list and an array in python a C like wrapper to actual arrays. Thank you for pointing this out, I will try to be more accurate in the future.

  • Ian Witham

    I had a go at creating a more concise version of your final script. Hope you don't mind! Couldn't test it with colors on the PC I'm using, so maybe you can let me know if it works :-)

    https://gist.github.com/4472264

    • CptDeadBones

      It works just fine. The only issue you have is that you have to print out term.colored() result. Otherwise no output will be printed out to the screen.