Browsing Tag

command line

Python

The game of Tic Tac Toe in Python

January 29, 2014

The last time I wrote an article we talked about the properties of a list. Many of you have pointed out some improvements that we incorporated in a later post addressing the issues some have you had with the code. This time, I would like to take on a larger program that utilizes some techniques we talked about as well as some new ones. In this article we are going to program the game of Tic Tac Toe in Python. I trust most people, if not everyone, have heard of the game and played it as children. Like always, I will be using Python 2.7.3 to test run my code. Some modification might be required for newer versions of Python.

The game of Tic Tac Toe is a perfect assignment for any programmers. You will be surprised how many times we go back to this game from a different angle. From this game you can learn turn based gaming programming, artificial intelligence , user interaction and many others topics. For now we are going to limit the game to non computer players. Here is a brief description of our assignment:

You are to implement the two player game of Tic Tac Toe. The program should display the board and prompt each user a move. The program should validate each move and handle any incorrect input. The entire user interaction should be command line based. Upon winning or a draw of the game, an appropriate message should be displayed acknowledging such condition.

The specs for this game are intentionally vague for the purpose of this article. We are going to tackle this problem one thing at a time. Let’s start by breaking down the program into some smaller blocks. Here is some rough pseudocode for us to work with:

  1. Setup Game
  2. Ask for user input on each turn
  3. Check if win condition met or no more moves
  4. Display the appropriate message and quit the game.

Let’s get started. First, let us think about how we can represent the board. A Tic Tac Toe board is a 3 X 3 grid. We could use a 2 dimensional list, or we can use one list with 9 elements that correspond to our 3 X 3 grid. So we are going to end up representing the board in Python in 1 list. Further more, we will set a value, -1, for an unclaimed cell, 0, for ‘O’ and 1 for ‘X’. This means that at any point in the game the list, board, will contain all the information we need for the game. Let’s take a look at the initial setup for the game:


board = []
	for i in range(9):
		board.append(-1)

That is it. This alone gives us a board with 9 cells all empty. Now let us tackle the display part. Although it is nice that we can represent the whole game in 1 variable, it is not very practical for the user. We want to display the game just like we would if we were to be playing on a pice of paper. To do so we will need to to print out a 3 X 3 grid from a 1 dimensional list. Let us first look at a quick example.

Let us consider that we have the list of numbers 1 to 9, and we want to print them out like this:

tic_tac_toe_map

To do so we can use this code:


a_list = [1,2,3,4,5,6,7,8,9]

for i in range(3):
	for j in range(3):
		print a_list[i*3+j],
	print 

The output would be:

wpid-3x3matrixpython-2013-11-12-15-13.png

How did this happen? Well, let us think about the values i and j take within the inner loop:

i_and_j_map_python

Now we want the values to be 0 to 8 to correspond to the list indexes of a_list. After playing with the numbers a little bit I found out that the formula i*3 + j gives me the values 0 to 8. Like this:

formulated_i_and_j_map_python

Cool. Let us now use this information to print out our Tic Tac Toe board. We already had the code to generate our board. Now lets see if we can print it. Consider the following function:


def print_board(board):

	print "The board look like this: \n"

	for i in range(3):
		print " ",
		for j in range(3):
			if board[i*3+j] == 1:
				print 'X',
			elif board[i*3+j] == 0:
				print 'O',
			else:
				print ' ',

			if j != 2:
				print " | ",
		print

		if i != 2:
			print "-----------------"
		else:
			print 

What will the function output? This:

wpid-tic_tact_tow_empty_board_python-2013-11-12-15-13.png
It is empty because all I did is generated an empty board using the code above. What would have happened if we sent it another list? Let’s investigate the code. It has a double loop like before, only instead of just printing out a_list[i*3+j] we take a look at it and print the appropriate value. If the list at that index contains the value 1 we print ‘X’ if it is 0, we print ‘O’. Otherwise it is just an empty space. The rest of the print statements are used to generate the lines. Note that we also use the comma (‘,’) to suppress the carriage return. You can read this article to find out more about Strings in Python.

So we completed our first part. We have a method to display the board and we have a setup for the game. Now let us see what is asking a user for input. Remember that we need to validate that the move is legal, i.e. the spot is not taken, and that the move is numeric between 1-9. Recall we are using a list to store the board. That means that will little effort we can ask the user which cell he would like to place a move in. Before we take user input, we will need to let the user know about this mapping of his/her moves. To do so let’s print out some instructions regarding the cell enumeration. Since we already have a function to print the board, with a little modification to it we can add an elif and write a small function to print the instructions, like this:


def print_instruction():
	print "Please use the following cell numbers to make your move"
	print_board([2,3,4,5,6,7,8,9,10])

If called, this function will print out:

wpid-tic_tac_toe_board_map_python_w_instructions-2013-11-12-15-13.png

Now, consider the following function that takes a player’s move and validates that it is a number between 1 to 9 and of numeric type:


def get_input(turn):

	valid = False
	while not valid:
		try:
			user = raw_input("Where would you like to place " + turn + " (1-9)? ")
			user = int(user)
			if user >= 1 and user <= 9:
				return user-1
			else:
				print "That is not a valid move! Please try again.\n"
				print_instruction()
		except Exception as e:
			print user + " is not a valid move! Please try again.\n"
			print_instruction()

This function will keep asking the user for a spot to place their move. If it is not numeric, we use a try-except block to catch the exception. If not between 1-9, we use a simple if-statement. Either way we notify the user of their error with an appropriate message. This is pretty straight forward. You always want to make sure the any user input is indeed valid. You should except the user to err. In this case, we accept user input as a sting and we try to convert it to an integer. Any input that is not between the numbers 1 to 9 will be considered invalid input and an appropriate message will be displayed.

wpid-python_err_input_ttt-2013-11-12-15-13.png

Great. We are actually almost done. The next part is how to check if a someone the Tic Tac Toe game. The function is not pretty, in fact it is hard coded for all possible board situations. It simply works. If there is a winner, the winners symbol will be returned, namely ‘X’ or ‘O’. If there is no winner, the function will return -1. Let us take a look:


def check_win(board):
	win_cond = ((1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9),(3,5,7))
	for each in win_cond:
		try:
			if board[each[0]-1] == board[each[1]-1] and board[each[1]-1] == board[each[2]-1]:
				return board[each[0]-1]
		except:
			pass
	return -1

So far we have talked about all the parts we need to make the game. Now it is time to put it all together. We will use all the functions we talked about and add some more logic. For example, we will have the game login in a while-loop. The loop will keep going while we do not have a winner. We will also keep track of the number of moves made. If less than 4 move were made, there is no sense to check for a win condition. If there were 9 moves made and no winner, the game is a tie. Other than that, the code should be fairly simple by now.


def main():

	# setup game
	# alternate turns
	# check if win or end
	# quit and show the board

	print_instruction()

	board = []
	for i in range(9):
		board.append(-1)

	win = False
	move = 0
	while not win:

		# print board
		print_board(board)
		print “Turn number “ + str(move+1)
		if move % 2 == 0:
			turn = ‘X’
		else:
			turn = ‘O’

		# get user input
		user = get_input(turn)
		while board[user] != -1:
			print “Invalid move! Cell already taken. Please try again.\n”
			user = get_input(turn)
		board[user] = 1 if turn == ‘X’ else 0

		# advance move and check for end game
		move += 1
		if move > 4:
			winner = check_win(board)
			if winner != -1:
				out = “The winner is “
				out += “X” if winner == 1 else “O”
				out += “ ☺”
				quit_game(board,out)
			elif move == 9:
				quit_game(board,”No winner :(”)

Since the output of this will be a little long, I will let you have fun and download it yourself, download Command Line Tic Tac Toe for Python If I have time in the future, I will try to record my screen and add the output.

Have fun playing!

Cool Stuff

Generating and Checking Passwords in Python

January 2, 2013

During my typical day I find myself logging in to about a dozen or more services. Good password habits tell us to keep the passwords different for each service or username. Not only that, most websites require you to use special characters, upper and lower case, keep changing the password and my top 'favorite', replace your password every X amount of time. As computers are getting faster, cracking passwords is becoming easier. To compensate, we are told to use longer passwords, great. So in theory, we all have 32-64 character passwords that are supper strong and our privacy is kept safe. In reality, we have maybe a handful of passwords and the forgot password link (in hope that we used an email we actually have). So in a time where we have all our information online and kept by passwords we hope not to be cracked, so what can we do with this 'too many passwords' problem?

The answer to this question is short and simple, we do what we can. In this post we will look at how to randomly generate passwords and how to check their security level to some degree. So let us get to it. Generating passwords is something that is rather straight forward. To sum it all up, randomly choose X characters from a given set. We will look at a few ways to generate passwords starting from a simple one. All of them follow that same basic rule.


import random
import sys

def main(argv):

	if (len(sys.argv) != 2):
		sys.exit('Usage: simple_pass.py <password_length>')
    
	password = ''
	for i in range(int(argv[0])):
		password += chr(random.randint(33,126))
	
	print 'You new password is: ' + password

if __name__ == "__main__":
	main(sys.argv[1:])

Using the python random module and passing in via command line the length of the password, we are able to randomly generate a unique password. The passwords are built from all printable ASCII characters randomly chosen. Later we will come back to this example to test a checking password strength program. Here are some example runs of this program.

wpid-pythongenrandompassword1-2013-01-2-02-24.png

This is a nice and simple script anyone can write and by all means use and distribute. It might be a quick hack, but still is not enough to get to be a true generator. Before we move on to another, more sophisticated password generator, lets actually look at a really unique generator using python's lambda.


import random
import string

pass_gen = lambda length, ascii =  string.ascii_letters + string.digits + string.punctuation: "".join([list(set(ascii))[random.randint(0,len(list(set(ascii)))-1)] for i in range(length)])

To use this lambda simply call it with the length required, like so:

wpid-pythongeneratepasswordex2.2.1-2013-01-2-02-24.png

Most password requirements today specify the number of special characters, uppercase, lowercase and numbers require in a password. Using the python string library, we can use string attributes to choose a number of specific characters from each set. Now we can modify our password generator to accept the number of uppercase, lowercase, digits and special charcters. The new code and example output will look like this:


import random
import sys
import string

def main(argv):

	if (len(sys.argv) != 5):
		sys.exit('Usage: simple_pass.py <upper_case> <lower_case> <digit> <special_characters>')
    
	password = ''
	
	for i in range(len(argv)):
		for j in range(int(argv[i])):
			if i == 0:
				password += string.uppercase[random.randint(0,len(string.uppercase)-1)]
			elif i == 1:
				password += string.lowercase[random.randint(0,len(string.lowercase)-1)]
			elif i == 2:
				password += string.digits[random.randint(0,len(string.digits)-1)]
			elif i == 3:
				password += string.punctuation[random.randint(0,len(string.punctuation)-1)]
	
	print 'You new password is: ' + ''.join(random.sample(password,len(password)))

if __name__ == "__main__":
	main(sys.argv[1:])


wpid-pythongeneratepasswordex3-2013-01-2-02-24.png

So at this point we can generate randomize and customize passwords. Let us now move to checking a password strength algorithm and check what kind of passwords we are generating. We will start by using a modified version of a password checker found on Password Advisor. I had to modify the code to get it to run and to create some output. Take a look.


import re

def CheckPassword(password):
    strength = ['Blank','Very Weak','Weak','Medium','Strong','Very Strong']
    score = 1

    if len(password) < 1:
        return strength[0]
    if len(password) < 4:
        return strength[1]

    if len(password) >=8:
        score = score + 1
    if len(password) >=10:
        score = score + 1
    
    if re.search('\d+',password):
        score = score + 1
    if re.search('[a-z]',password) and re.search('[A-Z]',password):
        score = score + 1
    if re.search('.,[,!,@,#,$,%,^,&,*,(,),_,~,-,]',password):
        score = score + 1

    return strength[score]
    
def main():
	
		
	user_input = raw_input("Check: ")

	while(user_input != 'quit'):
		print CheckPassword(user_input)
		user_input = raw_input("Check: ")

if __name__ == "__main__":
	main()


wpid-pythonpasswordstrengthchecker2-2013-01-2-02-24.png

The program uses length and python's regular expressions to determine a score for the password. This is a fairly straight forward calculation. A password longer than 8 characters is awarded 1 point, longer than 10 is awarded an additional point. Then, for each character from a character set the password is awarded another point. The points corresponding to an index on the strength list and an appropriate rating is determined. Let us see how our three password generators from before hold up to this checker standards. (The code has been slightly modified for testing).


import passwordadvisor
import random
import string
import re
import sys 

def ex1(num):

	password = ''
	for i in range(int(num)):
		password += chr(random.randint(33,126))
	
	return password
	
ex2 = lambda length, ascii =  string.ascii_letters + string.digits + string.punctuation: "".join([list(set(ascii))[random.randint(0,len(list(set(ascii)))-1)] for i in range(length)])

def ex3(argv):
    
	password = ''
	
	for i in range(len(argv)):
		for j in range(int(argv[i])):
			if i == 0:
				password += string.uppercase[random.randint(0,len(string.uppercase)-1)]
			elif i == 1:
				password += string.lowercase[random.randint(0,len(string.lowercase)-1)]
			elif i == 2:
				password += string.digits[random.randint(0,len(string.digits)-1)]
			elif i == 3:
				password += string.punctuation[random.randint(0,len(string.punctuation)-1)]
	
	return ''.join(random.sample(password,len(password)))
	
def checker(argv):

	example_1 = ex1(argv[1])
	print example_1 + ' ' + passwordadvisor.CheckPassword(example_1)
	
	example_2 = ex2(int(argv[2]))
	print example_2 + ' ' + passwordadvisor.CheckPassword(example_2)
	
	example_3 = ex3([argv[3],argv[4],argv[5],argv[6]])
	print example_3 + ' ' + passwordadvisor.CheckPassword(example_3)
		
def main(argv):
	if (len(sys.argv) != 7):
		sys.exit('Usage: ex4.py <length1> <length2> <upper_case> <lower_case> <digit> <special_characters>')
		
	checker(sys.argv)

if __name__ == "__main__":
	main(sys.argv[1:])

python exp 3

Test runs have shown that any password of length 8 is considered medium to strong by this measures. Notably the third generator has generated the strongest password at all test runs when 2 characters were chosen from each set. I have tested out the passwords generated using the website appropriately named HowSecureIsMyPassword. I do not advise nor condemn you trying to type your real password, but I have checked our generated passwords using this site. It seems that by their standards any 8 characters long password will take anywhere for a day to 20 days for a desktop PC to crack. For a 16 characters long password it seems that it will take 412 trillion years. So we are still safe on that side. It was shocking to know that some other sites that rank passwords, like ThePasswordMeter ranked any 8 character password we generated as high while HowSecureIsMyPassword claims it will take a day to crack the same password. However, 16 character long passwords were considered strong at both sites.

wpid-howsecure1.1-2013-01-2-02-24.png

wpid-thepassmeter-2013-01-2-02-24.png

wpid-howsecure1.2-2013-01-2-02-24.png

wpid-thepassmeter2-2013-01-2-02-24.png

Let us look at least at one more measure of password strength called bit strength, used to measure the strength of random generated passwords. it follows a formula where each character contributes an amount of bits calculated by the following formula:

 log_{2}(N)

The results is multiplied by the number of characters and a final bit strength is calculated. The threshold recommend, according to Wikipedia, for most secure systems is 80-bits. Let us look at how this will look in code and how our generated passwords measure up to this threshold. The code is very similar to the previous example, only replacing the checker function. (Download code for password generator and checker)


def bit_strength(password):
	return str(math.floor(len(password)*math.log(94,2)))


python exp 4

Since the character set we have include 94 possible characters in all generators, we have a constant log value (~6.55). This means that no matter what password we generate, even 88888888 will have the same ‘bit strength’ as ‘1.U*1!lh’. We can all recognize that the latter one will be much harder to crack than the first one. This is because the formula applies for randomly generated passwords. I will let the statistician among us calculate the odds of generating 88888888 out of 8 characters with 94 possible values for each character. I will "guesstimate" that it is very close to 0. We can draw a graph following this information to determine the length threshold required for a randomly generated password to pass the bit strength threshold.

wpid-lengthofpasswordvstrength2-2013-01-2-02-24.png

You will notice that any password above 15 characters is over 100 on the bit strength index. This means that it will comply with the secure password guideline as indicated on Wikipedia. It also means that if you can remember a randomly generated password, you will need less than 32 characters to secure your password. Keep in mind that this is limited to random generated password and not human created passwords.

So what can you do? In the mean time keep remembering that regardless of the source of password, the length is a directly proportional to the password strength according to any calculation. At this point I have no real solution to the ‘too many passwords’ problem, but I do have hope. I will continue with my work on the matter and post any changes I might have. Keep your passwords secure and safe.

Cool Stuff

Creating Progress Bars with Python

December 31, 2012

Ever since I can remember, progress bars had my interest. I think it is a neat way to convey to the user that his or her request is being processed. Furthermore, progress bars can give an indication on the percentage of the task that has been completed and/or timing when applicable. In this post I want to explore different types of progress bars and how you can incorporate them in your program. If you are really interested in the history of progress bars, they pre-date the modern computer back to 1896 and are connected with Gantt Chart. For more information of the topic I advise a Google search for progress bars or the Wikipedia entry for progress bar.

The first thing you should know about progress bars is when to use them. Just like any code, they have a certain overhead (negligible) and just because you can does not mean you should. So when should a programmer use a progress bar? When the task requires more than a reasonable time. You will know what a reasonable time is based on the program and your test runs. Along their other usage, progress bars can indicate to the user that work is being done and that the computer did not "freeze" on them. As a rule of thumb, try to used the progress bar when a large task is on hand, not something small. Loading a file is reasonably fast (most of the time). Loading 20GB of files into the memory of the program might take some time. In the latter scenario you probably should use a progress bar. It is very frustrating to the user when they hit ‘enter’ or ‘return’ and nothing happens instantly. Give the user some comfort knowing their request is being processed.

wpid-progress_bar-2012-12-29-19-192.gif

To simplify things I will focus on command line interfaces using Python2.6 (Documentations for python2.6 for offline reference). The same ideas presented here can be applied to GUI interfaces, but that is not trivial. Nothing with GUI development is trivial at all. The first thing to do when considering using a progress bar is to examine the problem. Different programs need different types of progress bars. There are three large sub-categories to all problems that require progress bars:

  • Problems that are solved by doing smaller identical tasks of known quantity
  • Problems that are solved by doing multiple tasks but known quantity.
  • Problems that are solved by doing unknown number of tasks and/or unknown quantity.

Lets start with the first category. Lets assume that we have a function called do_task() that does something. For the purpose of this post all the function will use python sleep function for a small amount of time. That will emulate as if the program was accomplishing a real task. We are going to invoke the function multiple times and each time it completes we will print a dot ('.'). The code will look something like this:


import time
import sys

def do_task():
	time.sleep(1)

def example_1(n):
	for i in range(n):
		do_task()
		print '\b.',
		sys.stdout.flush()
	print ' Done!'
	
print 'Starting ',
example_1(10)

The output will look like this:

wpid-pythonprogressbarexample1-2012-12-29-19-192.png

For a small amount of tasks, something like this will suffice. However, what if the program had to run 100, 1,000 or 1 million times. Clearly a million dots ('.') printed out to the screen will not be a good idea. We can modify the program to print a single dot ('.') for every 10% compilation of the task. Note that at any point in any of the examples discussed in this post the dot (‘.’) can be replaced by whatever you want. It can be an ‘x’ or a ‘#’ or any other printable ascii character will do.


import time
import sys

def do_task():
	time.sleep(1)

def example_1(n):
	steps = n/10
	for i in range(n):
		do_task()
		if i%steps == 0:
			print '\b.',
			sys.stdout.flush()
	print ' Done!'
	
print 'Starting ',
sys.stdout.flush()
example_1(100)

python loading bar mid way

Now let us add some more information about the process. First lets add some brackets so the user has some indication of how many more dots they are about to see. Notice that in previous examples and in the next examples we utilize sys.stdout.flush(), suppressing the carriage return using a comma (‘,’) at the end of the print statement and print a special character, ‘\b’. The special character ‘\b’ returns the printing cursor one step backwards. This is what allows us to print ahead and move backwards. Also note that every time we use the python print statement with a comma, the next print statement has a space in front of it. This is way using the special character ‘\b’ becomes necessary. Take a look at the next example:


import time
import sys

def do_task():
	time.sleep(0.1)

def example_1(n):
	steps = n/10
	for i in range(n):
		do_task()
		if i%steps == 0:
			print '\b.',
			sys.stdout.flush()
	print '\b]  Done!',
	
print 'Starting [          ]',
print '\b'*12,
sys.stdout.flush()
example_1(100)


And the output mid way and at the end:

wpid-pythonprogressbarmidway-2012-12-29-19-19.png

wpid-pythonprogressbarwithbracketsend-2012-12-29-19-19.png

After we have gone through the basics of the first type of loading bars lets move on to the second. Let us assume that we need to complete x tasks and each one is similar in time. For our code we can emulate this by using the sleep function again. Since the tasks are not the same tasks, we will not have the loop. Instead, we will call the functions one at a time. After each task is complete we will update our progress bar.


import time
import sys

def update_progress_bar():
	print '\b.',
	sys.stdout.flush()
	
print 'Starting ',
sys.stdout.flush()

#task 1
time.sleep(1)
update_progress_bar()

#task 2 
time.sleep(1)
update_progress_bar()

#task 3 
time.sleep(1)
update_progress_bar()

#Add as many tasks as you need. 

print ' Done!'

wpid-pythonmultitaskprogressbar-2012-12-29-19-19.png

We have moved forward in this example to create a function that updates the progress bar and to the second category of progress bars. Although by now we can write our own progress bar, let us take a look at some libraries that are already written nice progress bars you can use.  The first one is by Anler Hernández Peral and available through ActiveState Recipes and progress bar v.1 code. Running the code gives a quick example like this:

wpid-progress_bar_1exampeoutput-2012-12-29-19-19.png

In order to utilize the code for your own program you will have to import it. Following the example for ActiveState, Here is 2 ways you can use the code and their output: (Note: I have named the module progress_bar_1.py)


from progress_bar_1 import ProgressBar

p = ProgressBar()
print p

for i in range(10):
	print p+1

wpid-pythonprogress_bar_1output_1-2012-12-29-19-19.png


from progress_bar_1 import ProgressBar

custom_options = {
	'end': 10,
	'width': 10,
	'fill': 'x',
	'format': '%(progress)s%% [%(fill)s%(blank)s]'
}

p = ProgressBar(**custom_options)
print p

for i in range(10):
	print p+1


python progress_bar_1 output_2.1

Note that now we have moved into creating an object for our progress bar. That allows us to update and print it as we see fit. It also allows for some more custom setting as we can see in the second example. I will let you explore those on your own, but if you need help please contact the Captain. The second library will introduce some more fancy output. It is called progressbar 2.2 and the code for progressbar2.2. The code for it is a little lengthy (about 360 lines), so I will not include it in this post. Running the module as is, yields 4 example outputs that should look like this:

progressbar examples output

A closer look at the examples will provide you all the information you need to use this module. The ideas are very similar to the last example where you have a progress bar object you instantiate and then progress as needed. In the examples it was included in a for loop, but may be applied for multiple tasks as well.

After we have examine all these example, lets move to to the final category, the unknown one. Let us assume our program will need to complete an operation that either we do not know how many steps are involved or how long it will take. The solution is rather simple, a spinning loading. We still acknowledge to the user that the process is being executed, but cannot provide any insight as to the progression. Please note that you should note use this progress bar unless it is an absolutely must.


import sys
import time

print 'Loading....  ',
sys.stdout.flush()

i = 0

while i &lt;= 10:
	if (i%4) == 0: 
		sys.stdout.write('\b/')
	elif (i%4) == 1: 
		sys.stdout.write('\b-')
	elif (i%4) == 2:
		sys.stdout.write('\b\\')
	elif (i%4) == 3: 
		sys.stdout.write('\b|')

	sys.stdout.flush()
	time.sleep(0.2)
	i+=1
        
print '\b\b done!'


loading bar mid way

Similar to the examples above, if we want to use this in an application we can build a class around. Unlike the other examples in this case you will have to use threads in order to run the spinning loading bar while the program is running. A small note, you will not be able to print from the code that is running as it will mess up the loading bar. Also notice that now we are using while loops as oppose to the for loop we used before. This is because now we do not have a measure to estimate compilation of the program. The output will be the same as the example above.


import sys
import time
import threading

class progress_bar_loading(threading.Thread):
    
    def run(self):
            global stop
            global kill
            print 'Loading....  ',
            sys.stdout.flush()
            i = 0
            while stop != True:
                    if (i%4) == 0: 
                    	sys.stdout.write('\b/')
                    elif (i%4) == 1: 
                    	sys.stdout.write('\b-')
                    elif (i%4) == 2: 
                    	sys.stdout.write('\b\\')
                    elif (i%4) == 3: 
                    	sys.stdout.write('\b|')

                    sys.stdout.flush()
                    time.sleep(0.2)
                    i+=1
                    
            if kill == True: 
            	print '\b\b\b\b ABORT!',
            else: 
            	print '\b\b done!',

      
kill = False      
stop = False
p = progress_bar_loading()
p.start()

try:
	#anything you want to run. 
	time.sleep(1)
	stop = True
except KeyboardInterrupt or EOFError:
         kill = True
         stop = True


So now what? Now you know how to create your own custom progress bars in python. You may choose to implement the principles and I might do so myself. If I do I will make sure to post it up. As a last point I would like to mention the usage of progress bars once more. As a programmer you are responsible for the human computer interaction. Progress bars are a tool to convey to the user to stand by. Please use progress bars to actually mean something. Do not just display dots like the first examples. Try to estimate how long it will take, how much of the task has been accomplished, anything at all you can tell the user might help. As a user, there is no progress bar more annoying then ones that tell you nothing. In 2006, Peter Beddow wrote an article On the Abolition of the Computer Progress Bar. I suggest you read that article before using progress bars in large scale applications. Let us as programers bring back the loading bars the actually help the user, not that ones that annoy everyone.

Cool Stuff

Playing around with Strings and Python

December 28, 2012

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