Re: [Tutor] Game of python, help please.
On 4/17/2012 2:23 PM, leo degon wrote: Ok so I've done a bit of work on the program and rewrote it. I tried to take everyones advice. I've used more functions, I've made it so that it is a list of lists each containing an integer instead of another list with a single entry. I'm glad to see you using some of my ideas! Im am having problems thinking of how to simply and elegantly calculate the surrounding cells. I could brute force it as i did originally, but I'd like some pointers of how to avoid that. As of now, the script is finished for that 'small' detail. I have it so that instead of actually calculating the surrounding cells, that functions says that all the cells on the board are surrounding by three cells. Therefore setting the entire board alive after the turn zero. I am still trying to include three different versions of the bounadry conditions. Boundary conditions, what happens when a cell on the edge of the board tries to calculate the number of surrounding live cells. Dead- Those nonexistent cells add nothing. Live-Those nonexistent cells add one per cell. So add 5 to the corners, and one to edges. Bound- The dimensions are bound. So you get to the end and loop around. [snip] I again recommend you add extra rows and columns around the space so you always use one formula for surround. For dead initialize the extra cells to 0 For live initialize the extra cells to 1 For bound - every time you change a boundary cell make the same change to the corresponding extra cell. I hope that makes sense. Does it? Also recall my condensed way of summing surrounding cells. I realize I made a mistake in my original proposal - in that it counted the cell itself as well as the neighbors. Easy to fix. Originally I suggested: for r in range(1,x+1): for c in range1,(y+1): surrounding = sum([sum(space[r+z][c-1:c+2]) for z in(-1,0,1)]) New suggestion: def determinelife(surronding,space,i,j): return sum(space[i-1][j-1:j+2]) + sum(space[i][j-1:j+2:2]) + sum(space[i+1][j-1:j+2]) HTH -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Game of python, help please.
I actually just finished it, without the extra cells. I used a combiniation of two functions and a some exception handling to do so. Here is the script. #leoslife.py # John Conways Game of Life. plan='''displays: the text of the game of life for a set number of X x Y for a set of R turns. [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] Get X,Y,T, Initial Values, Boundry conditions Create a data space X x Y Assign initial value print initial value and the text' initial value' do while turnsT: check data space according to boundry conditions create new data space according to rules and old data space. replace dataspace print data space. print end. ''' #import modules needed to run import random # define functions to be used #function to get an integer between lower and upper bound def getnum(prompt,lower=3,upper=10): while True: n=input(prompt+ Enter an integer between %s and %s. : %(lower,upper)) if n.isdigit(): n=int(n) if lower=n=upper: return n def printset(x): for i in x: print(i) def basesurrounding(space,i,j): if i==0: if j==0: s=[space[i][j+1],space[i+1][j],space[i+1][j+1]] elif j==(y-1): s=[space[i][j-1],space[i+1][j-1],space[i+1][j]] else: s=[space[i][j-1],space[i][j+1],space[i+1][j-1],space[i+1][j],space[i+1][j+1]] elif i==(x-1): if j==0: s=[space[i-1][j],space[i-1][j+1],space[i][j+1]] elif j==(y-1): s=[space[i-1][j-1],space[i-1][j],space[i][j-1]] else: s=[space[i-1][j-1],space[i-1][j],space[i-1][j+1],space[i][j-1],space[i][j+1]] else: if j==0: s=[space[i-1][j],space[i-1][j+1],space[i][j+1],space[i+1][j],space[i+1][j+1]] elif j==(y-1): s=[space[i-1][j-1],space[i-1][j],space[i][j-1],space[i+1][j-1],space[i+1][j]] else: s=[space[i-1][j-1],space[i-1][j],space[i-1][j+1],space[i][j-1],space[i][j+1],space[i+1][j-1],space[i+1][j],space[i+1][j+1]] return(s) def findsurrounding(space,i,j,boundry,x): if boundry=='d': surrounding=0 for i in x: surrounding+=i return(surrounding) if boundry=='l': surrounding=8-len(x) for i in x: surrounding+=i return(surrounding) else: try: return(space[i-1][j-1]+space[i-1][j]+space[i-1][j+1]+space[i][j-1]+space[i][j+1]+space[i+1][j-1]+space[i+1][j]+space[i+1][j+1]) except IndexError: try:#if x goes over. return(space[i-1][j-1]+space[i-1][j]+space[i-1][j+1]+space[i][j-1]+space[i][j+1]+space[0][j-1]+space[0][j]+space[0][j+1]) except IndexError: try:#if y goes over return(space[i-1][j-1]+space[i-1][j]+space[i-1][0]+space[i][j-1]+space[i][0]+space[i+1][j-1]+space[i+1][j]+space[i+1][0]) except IndexError:#both go over return(space[i-1][j-1]+space[i-1][j]+space[i-1][0]+space[i][j-1]+space[i][0]+space[0][j-1]+space[0][j]+space[0][0]) def determinelife(surronding,space,i,j): if surronding==3: return(1) elif (surronding2 or surronding3): return(0) else: if space[i][j]==1: return(1) else: return(0) #get x,y,t initial value, boundry condition x=getnum('How many rows?') y=getnum('How many columns?') t=getnum('How many turns?') #get boundry conditions boundry=0 while boundry not in (b,d,l): boundry=input(Press 'b' for bound dimenions, 'd' for dead boundry, or 'l' for live boundry. : ) #get initial set up of space initial=0 while initial not in ('r','c','g','e'): initial=input(Press 'r' for random intitial set up, 'c' for a checker board pattern, 'g' for a single glider, or 'e' for a pattern that repeats infinitely. : ) if initial=='g': if x5: x=5 if y5: y=5 if initial=='e': if x6: x=6 if y6: y=6 #create space space = [] for i in range(x): space.append([]) for j in range(y): space[i].append(0) #set intital distribution if initial=='r': for i in range(x): for j in range(y): space[i][j]=random.randint(0,1) elif initial=='c': for i in range(x): for j in range(y): if (i+j)%2==0: space[i][j]=1 else: space[i][j]=0 elif initial=='g': space[1][2]=1 space[2][3]=1 space[3][1]=1 space[3][2]=1 space[3][3]=1 elif initial=='e': space[2][2]=1 space[2][3]=1 space[2][4]=1 space[3][1]=1 space[3][2]=1 space[3][3]=1 #show initial conditions of board on turn 0 print(-Turn 0-\n) printset(space) for turn in range(t): #Create new empty space new=[] for i in range(x): new.append([]) for j in range(y): new[i].append(0) #rewrite each space for i in range(x): for j in range(y):
Re: [Tutor] Game of python, help please.
Ok so I've done a bit of work on the program and rewrote it. I tried to take everyones advice. I've used more functions, I've made it so that it is a list of lists each containing an integer instead of another list with a single entry. Im am having problems thinking of how to simply and elegantly calculate the surrounding cells.I could brute force it as i did originally, but I'd like some pointers of how to avoid that. As of now, the script is finished for that 'small' detail. I have it so that instead of actually calculating the surrounding cells, that functions says that all the cells on the board are surrounding by three cells. Therefore setting the entire board alive after the turn zero. I am still trying to include three different versions of the boundry conditions. Boundary conditions, what happens when a cell on the edge of the board tries to calculate the number of surrounding live cells. Dead- Those nonexistent cells add nothing. Live-Those nonexistent cells add one per cell. So add 5 to the corners, and one to edges. Bound- The dimensions are bound. So you get to the end and loop around. the script follows #leoslife.py # John Conways Game of Life. plan='''displays: the text of the game of life for a set number of X x Y for a set of R turns. [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] Get X,Y,T, Initial Values, Boundry conditions Create a data space X x Y Assign initial value print initial value and the text' initial value' do while turnsT: check data space according to boundry conditions create new data space according to rules and old data space. replace dataspace print data space. print end. ''' #import modules needed to run import random # define functions to be used #function to get an integer between lower and upper bound def getnum(prompt,lower=3,upper=10): while True: n=input(prompt+ Enter an integer between %s and %s. : %(lower,upper)) if n.isdigit(): n=int(n) if lower=n=upper: return n def printset(x): for i in x: print(i) def findsurronding(space,i,j,boundry): #s=space[i-1][j-1]+space[i-1][j]+space[i-1][j+1]+space[i][j-1]+space[i][j+1]+space[i+1][j-1]+space[i+1][j]+space[i+1][j+1] return(3) def determinelife(surronding,space,i,j): if surronding==3: return(1) elif (surronding2 or surronding3): return(0) else: if space[i][j]==1: return(1) else: return(0) #get x,y,t initial value, boundry condition x=getnum('How many rows?') y=getnum('How many columns?') t=getnum('How many turns?') #get boundry conditions boundry=0 while boundry not in (b,d,l): boundry=input(Press 'b' for bound dimenions, 'd' for dead boundry, or 'l' for live boundry. : ) #get initial set up of space initial=0 while initial not in ('r','c','g','e'): initial=input(Press 'r' for random intitial set up, 'c' for a checker board pattern, 'g' for a single glider, or 'e' for a pattern that repeats infinitely. : ) if initial=='g': if x5: x=5 if y5: y=5 if initial=='e': if x6: x=6 if y6: y=6 #create space space = [] for i in range(x): space.append([]) for j in range(y): space[i].append(0) #set intital distribution if initial=='r': for i in range(x): for j in range(y): space[i].__setitem__(j,random.randint(0,1)) elif initial=='c': for i in range(x): for j in range(y): if (i+j)%2==0: space[i].__setitem__(j,1) else: space[i].__setitem__(j,0) elif initial=='g': space[1].__setitem__(2,1) space[2].__setitem__(3,1) space[3].__setitem__(1,1) space[3].__setitem__(2,1) space[3].__setitem__(3,1) elif initial=='e': space[2].__setitem__(2,1) space[2].__setitem__(3,1) space[2].__setitem__(4,1) space[3].__setitem__(1,1) space[3].__setitem__(2,1) space[3].__setitem__(3,1) #show initial conditions of board on turn 0 print(---Initial Board---\n) printset(space) for turn in range(t): #Create new empty space new=[] for i in range(x): new.append([]) for j in range(y): new[i].append(0) #rewrite each space for i in range(x): for j in range(y): surronding=findsurronding(space,i,j,boundry) mortality=determinelife(surronding,space,i,j) new[i][j]=mortality space=new[:] print('---Turn %s' %(str(turn+1))) printset(space) print(This is the end ) On Tue, Apr 10, 2012 at 10:44 AM, bob gailer bgai...@gmail.com wrote: On 4/9/2012 10:56 PM, Dave Angel wrote: On 04/09/2012 10:33 PM, bob gailer wrote: On 4/9/2012 2:26 AM, leo degon wrote: Hello all, Im trying to learn python and programming in my free time, and I'm trying to do a little
Re: [Tutor] Game of python, help please.
On 17/04/12 19:23, leo degon wrote: Ok so I've done a bit of work on the program and rewrote it. I tried to take everyones advice. I've used more functions, I've made it so that it is a list of lists each containing an integer instead of another list with a single entry. It still looks too complicated to me. #set intital distribution if initial=='r': for i in range(x): for j in range(y): space[i].__setitem__(j,random.randint(0,1)) What's with the __setitem__ stuff? You should never normally need to call that directly. I would expect something like for i in range(x): for j in range(y): space[i][j] = randint(0,1) Or, using list comprehensions: for i in range(x): space[i] = [randint(0,1) for j in range(y)] Or even: space = [[randint(0,1) for j in range(y)] for i in range(x)] Which, for x,y = 3,4 gives a structure like: space [[1, 0, 0, 0], [1, 0, 1, 1], [0, 1, 1, 0]] elif initial=='c': for i in range(x): for j in range(y): if (i+j)%2==0: space[i].__setitem__(j,1) Again I'd just use space[i][j] = 1 HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Game of python, help please.
Ok that was simple change. Dont know why but there was a small error preventing that from working before. But the problem is with the creating findsurrounding function On Tue, Apr 17, 2012 at 3:14 PM, Alan Gauld alan.ga...@btinternet.comwrote: On 17/04/12 19:23, leo degon wrote: Ok so I've done a bit of work on the program and rewrote it. I tried to take everyones advice. I've used more functions, I've made it so that it is a list of lists each containing an integer instead of another list with a single entry. It still looks too complicated to me. #set intital distribution if initial=='r': for i in range(x): for j in range(y): space[i].__setitem__(j,random.**randint(0,1)) What's with the __setitem__ stuff? You should never normally need to call that directly. I would expect something like for i in range(x): for j in range(y): space[i][j] = randint(0,1) Or, using list comprehensions: for i in range(x): space[i] = [randint(0,1) for j in range(y)] Or even: space = [[randint(0,1) for j in range(y)] for i in range(x)] Which, for x,y = 3,4 gives a structure like: space [[1, 0, 0, 0], [1, 0, 1, 1], [0, 1, 1, 0]] elif initial=='c': for i in range(x): for j in range(y): if (i+j)%2==0: space[i].__setitem__(j,1) Again I'd just use space[i][j] = 1 HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ __**_ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/**mailman/listinfo/tutorhttp://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Game of python, help please.
On 4/9/2012 10:56 PM, Dave Angel wrote: On 04/09/2012 10:33 PM, bob gailer wrote: On 4/9/2012 2:26 AM, leo degon wrote: Hello all, Im trying to learn python and programming in my free time, and I'm trying to do a little personal project to trying and gain some skills. Im trying to do version of John conways game of life. I have a working version of the game. Written for 3.2.2 on a mac to be accessed through terminal. SNIP These nested loops for i in range(X): SPACE.append([]) for j in range(Y): SPACE[i].append([0]) can be replaced with: space = [0]*y]*x not counting the typo, that's the trap I was warning about. If he does NOT replace the individual cells with zeroes and ones, this is wrong. You pointed that out. But it's also wrong for the rows, as you only have one row here, duplicated x times. OOPS - what comes of trying to be creative while tired. Sorry and thanks for pointing out my error. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Game of python, help please.
On 04/09/2012 02:26 AM, leo degon wrote: Hello all, Im trying to learn python and programming in my free time Welcome to the list; I think you'll enjoy Python programming, and think it makes an excellent first language. , and I'm trying to do a little personal project to trying and gain some skills. Im trying to do version of John conways game of life. I have a working version of the game. Written for 3.2.2 on a mac to be accessed through terminal. Thanks for giving that information. Many people skip the step of describing the environment. Some general comments first. You've managed in the code below to avoid many of the beginner mistakes in Python, like building a two dimensional array by replicating one row. But you do have a few quirks, by inspection. I've not tried to run any of the code. The biggest one is that you have only one function. Much of this code is very repetitive, and thus likely to have errors in some portion that doesn't run too often. And when you fix one place, you have to check many others to see whether it has the same problem. So factor it out into functions according to feature. A good start is to write a function for each line in your docstring, except for the the do-while statement. Then when you realize the biggest function is the nextmove one, factor that as well. Most of it is spent calculating 'surronding'. I also found it strange that each element of the grid is itself a list, with exactly one element (an integer 0 or 1) in it. Why not just make it an integer ? There are a lot of places which would then change, so probably you shouldn't do that till you've refactored things to simplify. I'm trying to give it a number of options. it dimensions, the max number of turns, initial set up, and boundary conditions. The dimensions and turns were pretty easy to include. The boundary conditions more difficult, and now I'm getting stuck on the initial set up options. I can set it up randomly but Im having problems implementing a checker board pattern. SNIP #while not(initial=='r' or initial=='c' or initial=='g' or initial=='e'): #initial=input(' SPACE=[] for i in range(X): SPACE.append([]) for j in range(Y): SPACE[i].append([0]) print(SPACE) #initial set up-random, checker board, glider, eternal. initial=0 while not(initial =='r' or initial =='c' or initial=='g' or initial=='e'): initial=input('Chose inital setup: press r for random,c for checker, g for glider,e=eternal') if initial=='c': idex=0 for i in range(X): jdex=0 for j in range(Y): if (idex+jdex)%2==0: SPACE[idex][jdex]=[0,] jdex+=1 else: SPACE[idex][jdex]=[1,] jdex+=1 idex+=1 Here you have set each element of the grid to be a list containing a tuple containing an int. To be consistent with the rest of the code as it currently is, you should use SPACE[idex][jdex] = [0] or if/when you take my earlier suggestion to make it just an int, SPACE[idex][jdex] = 0 Note, though, that you don't want to make too many changes to the logic at the same time. SNIP turn=0 while turnT: Any reason not to replace those two lines and the one at the end with: for turn in range(T): HTH -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Game of python, help please.
On 4/9/2012 2:26 AM, leo degon wrote: Hello all, Im trying to learn python and programming in my free time, and I'm trying to do a little personal project to trying and gain some skills. Im trying to do version of John conways game of life. I have a working version of the game. Written for 3.2.2 on a mac to be accessed through terminal. In addition to Dave's comments I add: I'm trying to give it a number of options. it dimensions, the max number of turns, initial set up, and boundary conditions. Please explain boundary conditions The dimensions and turns were pretty easy to include. The boundary conditions more difficult, and now I'm getting stuck on the initial set up options. I can set it up randomly but Im having problems implementing a checker board pattern. It really helps when you explain the problem. What does not work as expected? '''displays: the text of the game of life for a set number of X x Y for a set of R turns. [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] [-][-][-][-][-] I suggest you simplify the display by using - or x e.g.: ---xx--- ---xxx-- xx-- Get X,Y,T, Initial value Create a data space X x Y Assign initial value print initial value and the text' initial value' do while turnsT: check data space create new data space according to rules and old data space. replace dataspace print data space. print end. ''' import random X,Y,T=0,0,0 while not 4X102: X=int(input('How many rows? enter a integer between 5 and 101: ')) while not 4Y102: Y=int(input('How many columns? enter a integer between 5 and 101: ')) while not 4T102: T=int(input('How many turns? enter a integer between 5 and 101: ')) Good place for a function: (untested). Also note it's common practice to use names starting with lower case for variables. Note how we validate input to ensure it is integer. def getNum(prompt, lower, upper): while True: n = input(prompt + enter a integer between %s and %s % (lower, upper)) if n.isdigit(): n = int(n) if lower = n = upper: return n x = getNum(How many rows?, 5, 101) y = getNum(How many rows?, 5, 101) t = getNum(How many rows?, 5, 101) entry=0 while not (entry=='b' or entry=='l' or entry=='d'): can be simplified to while entry not in ('b', 'l', 'd') entry=input('Press b for bound dimensions, press l for live boundry, or press d for dead boundry: ') #while not(initial=='r' or initial=='c' or initial=='g' or initial=='e'): #initial=input(' SPACE=[] Note (again) it's common practice to use names starting with lower case for variables. These nested loops for i in range(X): SPACE.append([]) for j in range(Y): SPACE[i].append([0]) can be replaced with: space = [0]*y]*x Assuming you decide to have each cell contain either 1 or 0. You might also consider giving space an extra row at the top and one at the bottom, ditto for extra columns. That will make calculating the neighbor count a lot easier, at the cost of maintaining the extra rows/columns. for r in range(1,x+1): for c in range1,(y+1): surrounding = sum([sum(space[r+z][c-1:c+2]) for z in(-1,0,1)]) OK enough for now - there's more but I'm out of time/energy right now. -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Game of python, help please.
On 04/09/2012 10:33 PM, bob gailer wrote: On 4/9/2012 2:26 AM, leo degon wrote: Hello all, Im trying to learn python and programming in my free time, and I'm trying to do a little personal project to trying and gain some skills. Im trying to do version of John conways game of life. I have a working version of the game. Written for 3.2.2 on a mac to be accessed through terminal. SNIP These nested loops for i in range(X): SPACE.append([]) for j in range(Y): SPACE[i].append([0]) can be replaced with: space = [0]*y]*x not counting the typo, that's the trap I was warning about. If he does NOT replace the individual cells with zeroes and ones, this is wrong. You pointed that out. But it's also wrong for the rows, as you only have one row here, duplicated x times. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor