A while back we talked about some ASCII charcters. I thought some of you might find these shortcuts useful. I always find myself looking up how to do copyright and trademark symbols with the keyboard. I knew there had to be someway to type some of these in. I am defiantly going to have to print this off and keep somewhere handy. Here are the Keyboard Special Character Shortcuts:
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:
- Setup Game
- Ask for user input on each turn
- Check if win condition met or no more moves
- 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:
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:
How did this happen? Well, let us think about the values i and j take within the inner loop:
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:
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:
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:
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.
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-1] == board[each-1] and board[each-1] == board[each-1]: return board[each-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!
With school back in session again, I would like to remind everyone how home work really gets done. It doesn't get done nice and neat, not prepared ahead of time and it is not really complete. It gets done a night before and if we are lucky it compiles and runs, or makes sense.
You're in the midst of a heated battle. You have the enemy in your sights, when suddenly everything freezes and one of the players whizzes past as though he was on roller skates. A second later, a message appears, saying that you're disconnected from the server because your Internet connection timed out. According to Online Gaming 2013, the latest report from global information company, The NPD Group, 72 percent of U.S. gamers report gaming online. Chances are you're among this group, and you understand the need for high speed Internet options to avoid lag and frustration.
The Need for Speed
In many metropolitan areas in the U.S., the choices you're looking at are FIOS versus cable. According to Netindex, the top average speeds are from Verizon FIOS and Optimum Online at approximately 37 mbps. Comcast cable comes in next at 28 mbps, so if you're looking for the fastest speeds possible, look into FIOS providers. Otherwise, consider the packages and pricing available for the Internet service. The 10 mbps difference won't make or break you if you aren't playing twitchy games, so if the price is significantly lower on the cable option, go that route. Each Internet service provider may also offer different speed tiers of service, so don't assume that the base tier is the fastest option. For example, Time Warner Cable has a 15 mbps basic service, but provides a 20 mbps higher speed Internet service for an additional cost.
If you're lucky enough to live in Austin, Texas; Kansas City, Missouri; or Provo, Utah, you have access to the highest speed residential fiber optic Internet provider: Google Fiber. Their paid service goes up to 1000 mbps, allowing multi-gig games and updates to download within a few minutes, and giving you the bandwidth you need for even the most information heavy games. Imagine downloading Battlefield 4 on Origin in the time it takes you to get a drink refill. Some Internet service providers are planning on increasing their speeds to play catch up with Google, but it takes some time to build up the network infrastructure necessary to provide higher speed Internet.
Internet Options to Avoid
Dial-up is an obvious no-go when it comes to online gaming, nor is DSL a competitive option. If you live in a remote area that only has access to dial-up and 3G networks, you may be tempted to use satellite Internet options. A 3G mobile data connection will work well enough for basic online games, but you don't want to attempt playing a MMO, FPS, or another type of game that sends and receives a lot of data between the server and yourself. However, while Ars Technica reports that 15 mbps satellite Internet is available throughout the US, the latency with the signal makes it difficult to successfully play online games. It would be good for downloading your games, however, since the latency won't have a profound impact on your experience.
As a consultent and a software developer I do get paid often to think, to come up with solutions. Often my solutions are accepted and implemented with some success. Every now and then I get shot down. When I do, this is the only explanation I can come up with:
Since many of my commenters ask for something a little more advance in Python, I wrote up this script I wrote. Notice that this script will allow you to use almost anything you would come to except from an email client. Sending Email From Python is simpler than you think. That includes cc and bcc fields, html mode and attachment files. You will have to use your own email configuration, I left the settings from gmail, but any email account could be used. Just fill in your user name and password. You can include this module and use the compose_email() function to send emails directly from you Python program. As a word of advice, try to not send too many emails all at once (like 400 emails). Gmail will not send the emails and your email address will be marked as spam. Use with caution.
NOTE: The only output of the program is a single print statement (assuming it all went well), that will indicate an email has been sent.
#account setup username = '***'; password = '***'; server = 'smtp.gmail.com:587'; #imports from time import sleep; import smtplib; from email.mime.application import MIMEApplication from email.mime.text import MIMEText; from email.mime.multipart import MIMEMultipart; # create msg - MIME* object # takes addresses to, from cc and a subject # returns the MIME* object def create_msg(to_address, from_address='', cc_address='', bcc_address='', subject=''): msg = MIMEMultipart(); msg['Subject'] = subject; msg['To'] = to_address; msg['Cc'] = cc_address; msg['From'] = from_address; return msg; # send an email # takes an smtp address, user name, password and MIME* object # if mode = 0 sends to and cc # if mode = 1 sends to bcc def send_email(smtp_address, usr, password, msg, mode): server = smtplib.SMTP(smtp_address); server.ehlo(); server.starttls(); server.ehlo(); server.login(username,password); if (mode == 0 and msg['To'] != ''): server.sendmail(msg['From'],(msg['To']+msg['Cc']).split(","), msg.as_string()); elif (mode == 1 and msg['Bcc'] != ''): server.sendmail(msg['From'],msg['Bcc'].split(","),msg.as_string()); elif (mode != 0 and mode != 1): print 'error in send mail bcc'; print 'email cancled'; exit(); server.quit(); # compose email # takes all the details for an email and sends it # address format: list,  - to #  - cc #  - bcc # subject format: string # body format: list of pairs  - text #  - type: # 0 - plain # 1 - html # files is list of strings def compose_email(addresses, subject, body, files): # addresses to_address = addresses; cc_address = addresses; bcc_address = addresses; # create a message msg = create_msg(to_address, cc_address=cc_address , subject=subject); # add text for text in body: attach_text(msg, text, text); # add files if (files != ''): file_list = files.split(','); for afile in file_list: attach_file(msg, afile); # send message send_email(server, username, password, msg, 0); # check for bcc if (bcc_address != ''): msg['Bcc'] = bcc_address; send_email(server, username, password, msg, 1); print 'email sent' # attach text # attaches a plain text or html text to a message def attach_text(msg, atext, mode): part = MIMEText(atext, get_mode(mode)); msg.attach(part); # util function to get mode type def get_mode(mode): if (mode == 0): mode = 'plain'; elif (mode == 1): mode = 'html'; else: print 'error in text kind'; print 'email cancled'; exit(); return mode; # attach file # takes the message and a file name and attaches the file to the message def attach_file(msg, afile): part = MIMEApplication(open(afile, "rb").read()); part.add_header('Content-Disposition', 'attachment', filename=afile); msg.attach(part); #to be tested... compose_email(['firstname.lastname@example.org','',''], 'test v.5.0', [['some text goes here...\n',0]], ''); #compose_email can take the following arguments: # 1. to recipients (separated by a comma) # 2. cc recipients (separated by a comma) # 3. bcc recipients (separated by a comma) # 4. subject # 5. a list with message and mode (plain txt or html) # 6. files to be attached
We spend a lot of time talking about end users and how they interact with application you write. I think you will find that this applies:
Last time we talked about using functions in Python, this time let us take it a step farther and create a module. Functions are great and you are going to use them everywhere, but what happens when you need to use a function in more than one place? What happens when a function needs to be utilized in different files within one application? In Python, we create modules, which are just your regular .py files. We can use functions (and objects) from other files by using an import statement. Every language has some form of an import statement. In C we use an include statement. The idea is that when you need, you can include code from another code file. For this post, lets assume a scenario. Imagine that you are an entry level programmer at a software company. You are assign to a team that is working on some large scale scientific application in Python. As the newbie on the team, you are giving the task to write functions that will be used for temperature conversation in multiple parts of the program. You are given the following function pseudocode and are requested to write the code for them:
- c2f(t) will take a float temperature in Celsius and return a float temperature in Fahrenheit
- c2k(t) will take a float temperature in Celsius and return a float temperature Kelvin
- f2c(t) will take a float temperature in Fahrenheit and return a float temperature Celsius
- f2k(t) will take a float temperature in Fahrenheit and return a float temperature Kelvin
- k2c(t) will take a float temperature in Kelvin and return a float temperature in Celsius
- k2f(t) will take a float temperature in Kelvin and return a float temperature in Fahrenheit
So these functions are pretty easy to write, they are all 1 line of code. Using some basic formulas from Wikipedia Conversion of units of temperature the code in Python for temperature conversion might look like this:
def c2f(t): return (t*9/5.0)+32 def c2k(t): return t+273.15 def f2c(t): return (t-32)*5.0/9 def f2k(t): return (t+459.67)*5.0/9 def k2c(t): return t-273.15 def k2f(t): return (t*9/5.0)-459.67
That was simple. Notice that we have included in every calculation an implicate conversion to float, so even if t is not a float, the result will return as a float. That might be useful if at some other part of the application some numeric calculation is required. Especially if the calculation requires higher level of accuracy. Within a couple of minutes you hand your boss (email him/her) a file named temperature.py and you think you are done. In most cases you might be done, but have you tested your code? Rushing code is never a good idea. Take the time to fully test you code and make sure it works the way you think it does. This example might be straight forward, but other examples might be more complicated. It is a good habit to always self test you code. Here is one way you can test the code:
def main(): menu = “\nTemperature Convertor\n\n"+\ "1. Celsius to Fahrenheit\n"+\ "2. Celsius to Kelvin\n"+\ "3. Fahrenheit to Celsius\n"+\ "4. Fahrenheit to Kelvin\n"+\ "5. Kelvin to Celsius\n"+\ "6. Kelvin to Fahrenheit\n"+\ "7. Quit" user_input = 0 while user_input != 7: print menu user_input = raw_input("Please enter a valid selection: ") try: user_input = int(user_input) except: print user_input + " is not a valid selection, please try again\n" if user_input == 1: t = get_user_input() print str(t) + " degree Celsius is " + str((c2f(t))) + " degree Fahrenheit" elif user_input == 2: t = get_user_input() print str(t) + " degree Celsius is " + str((c2k(t))) + " degree Kelvin" elif user_input == 3: t = get_user_input() print str(t) + " degree Fahrenheit is " + str((f2c(t))) + " degree Celsius" elif user_input == 4: t = get_user_input() print str(t) + " degree Fahrenheit is " + str((f2K(t))) + " degree Kelvin" elif user_input == 5: t = get_user_input() print str(t) + " degree Kelvin is " + str((k2c(t))) + " degree Celsius" elif user_input == 6: t = get_user_input() print str(t) + " degree Kelvin is " + str((k2f(t))) + " degree Fahrenheit" elif user_input == 7: quit() else: print str(user_input) + " is not a valid selection, please try again\n" if __name__ == "__main__": main()
The output of the code might look like this: Now this main() function is in a different file called converter.py. The file content has now functions that can convert anything. However, in the very top of the file there is one magical statement:
from temperature import *
There are different ways to include code from another .py file, but for now, we can use this one. All it is is a small indication for Python to know that if they need to open a temperature.py file as well as the converter.py file. The only requirement is that both files are in the same working directory, that is that they are in the same folder. When you examine the code you may notice that some code was added to account for invalid entries, such as if a user enters a character instead of a number. There is also a hidden function called get_user_input() that looks like this:
def get_user_input(): user_input = 0 while type(user_input) != type(1.0): user_input = raw_input("Enter degrees to convert: ") try: user_input = float(user_input) except: print user_input + " is not a valid entry" return user_input
This function makes sure the user enters a numeric value to convert. At this point you have all the tools necessary to tell you boss that you have tested you code and it works properly. You might also want to keep this as part of the code in case you want to use it in the future. I have uploaded the code in case you want to test it out for yourself, Temperature Conversation Application in Python.