Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Pollyanna
Mar 5, 2005

Milk's on them.


I'm trying to program Conway's Game of Life using OOP and NumPy arrays. I've created a class for the gameboard and a class for a cell object. The cell object has grid attributes (x, y) and calling spawn(x, y) on it changes the value on the gameboard at (x, y) to True from False. I intended this to be spawning a cell object at (x, y), but now that I think about it, that's not what's happening at all.

I have a feeling I'm on the wrong track, here. Does this make any sense? Is OOP a good way to program this, or should I think of a different way?

Adbot
ADBOT LOVES YOU

Dominoes
Sep 20, 2007

outlier posted:

You spend too much time futzing around with the tool, trying to solve tool issues or work within tool idioms, rather than solving the problem domain you're actually interested in. Especially since I work as a computational biologist and programming is really, truly just a means to an end.
This describes why I've just given up, again, on compiling python modules from source.

QuarkJets posted:

Most people using Python don't have a need for compiling executables, so there's relatively little community interest.
ie: Python's a language for programmers?

What are some high-level languages better suited to making applications, that are similar to Python? C#?

Dominoes fucked around with this message at 20:22 on Sep 27, 2013

Pollyanna
Mar 5, 2005

Milk's on them.


outlier posted:

Thanks. It's a frequent irritant of mine, and an idea that came to me after working with Plone for several years. You spend too much time futzing around with the tool, trying to solve tool issues or work within tool idioms, rather than solving the problem domain you're actually interested in. Especially since I work as a computational biologist and programming is really, truly just a means to an end.

Bioinformatics/computational biology is part of the reason why I chose to start learning Python. Unfortunately, the same thing that makes Python common in that field means that there's not much support for anything that doesn't do what a bioinformatician or computational biologist wants (i.e. anything beyond scripting and automation).

Kinda sad. Hopefully Python will become more popular for other problem fields in the future.

Dominoes posted:

What are some high-level languages better suited to making applications that are similar to Python? C#?

As far as I've seen, Python is pretty unique. The language I can think of that's most similar to Python is, uh...Ruby? v:shobon:v

Pollyanna
Mar 5, 2005

Milk's on them.


e: quote != edit

No Safe Word
Feb 26, 2005

Pollyanna posted:

As far as I've seen, Python is pretty unique. The language I can think of that's most similar to Python is, uh...Ruby? v:shobon:v
They're pretty far apart other than they are both:
- popular scripting languages
- similar in their level of maturity of development

From basically every other perspective they're incredibly different.

I'd frankly say C# is more like Python than Ruby is in spirit, even if C# is a statically typed (unless you use the DLR!) compiled language.

Pollyanna
Mar 5, 2005

Milk's on them.


Well, I'm thinking from a syntax perspective. Python is a very minimally verbose and "obvious" language, while the C family is way too "ornamental" for my tastes. Ruby is closer to Python than C-style with regards to syntax, which is why I brought it up.

I don't really know much about the differences between programming languages other than syntax. :v: Syntax is the biggest one to me, a pain-in-the-rear end syntax is a good reason for me not to like it.

Dren
Jan 5, 2001

Pillbug

Pollyanna posted:

I'm trying to program Conway's Game of Life using OOP and NumPy arrays. I've created a class for the gameboard and a class for a cell object. The cell object has grid attributes (x, y) and calling spawn(x, y) on it changes the value on the gameboard at (x, y) to True from False. I intended this to be spawning a cell object at (x, y), but now that I think about it, that's not what's happening at all.

I have a feeling I'm on the wrong track, here. Does this make any sense? Is OOP a good way to program this, or should I think of a different way?

Why does the cell have grid attributes? The cell class should only have 1 thing, whether or not the cell is alive or dead.

Your grid class, then, provides the abstraction of coordinates. Set it up so you are able to query it for the cell at a certain location. Then you could write some helper functions to scan the grid, evaluate the states of cells, and tell you what the next iteration of the grid should look like.

Dominoes posted:

This describes why I've just given up, again, on compiling python modules from source.

ie: Python's a language for programmers?

What are some high-level languages better suited to making applications that are similar to Python? C#?

Python is a lot easier on Linux. If you want something it's 'pip install X' rather than 'hunt internet for compiled binaries or suffer through compiling them yourself'. I recommend that you switch if you can.

Pollyanna
Mar 5, 2005

Milk's on them.


Dren posted:

Why does the cell have grid attributes? The cell class should only have 1 thing, whether or not the cell is alive or dead.

Your grid class, then, provides the abstraction of coordinates. Set it up so you are able to query it for the cell at a certain location. Then you could write some helper functions to scan the grid, evaluate the states of cells, and tell you what the next iteration of the grid should look like.

Well... cause I thought each cell object would have their own position...I think? :psyduck: And it could be about cell objects interacting rather than going through the grid "this position turns to False and this one turns to True" which now I'm confused augh.

Okay, wait. So I want to make an array of cell objects rather than booleans. Duh, that makes sense. Sorry...

About that, though. I want it to set every value in it to an instance of class Cell upon starting up. It bitches that it doesn't know what a class Cell is, though. I've imported both Grid and Cell classes into the main script. What gives?

quote:

Python is a lot easier on Linux. If you want something it's 'pip install X' rather than 'hunt internet for compiled binaries or suffer through compiling them yourself'. I recommend that you switch if you can.

I'm on OSX which is Unix-based, but installing Python isn't the problem. It's doing anything in Python that isn't scripting or automation that becomes a pain in the rear end, mostly because it isn't well-supported by the community and there's not a lot of information or modules for stuff like creating applications. I can think of PyGame and (of all things) RenPy that are executable based, but not much else.

Pollyanna fucked around with this message at 20:41 on Sep 27, 2013

Dominoes
Sep 20, 2007

I remember trying to make a Ubuntu binary - I gave up, because it actually seemed more difficult to find info on than Windows.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Ubuntu binaries make no sense, since Python ships with Ubuntu, and you can simply ship your script with a shebang line to make it run.

Dren
Jan 5, 2001

Pillbug
You could use booleans instead of Cell objects. Cell objects only have one bit of state, alive or dead (true or false). Also, I'm not sure why you're using numpy arrays, regular lists will work just fine.

Try making a super simple game of life. Use an 8x8 grid and don't use any classes at all. Implement your grid as a list of booleans of length 64, call it gameboard_list. Write a function that accepts the list and (x, y) coordinates as arguments and returns the cell value at that position.

Using the function that accesses the cell at certain coordinates write a function to turn the gameboard into plain old text. Do like, a '*' for alive cells and a ' ' for dead cells. Then print that to the screen.

Next, write a function that takes the current gameboard_list, checks each coordinate in it, and returns a new list representing the next stage of the gameboard (as opposed to modifying the current list). It might help to create a function that can return to you all of the values of the neighbors of a cell.

Once you've got that going think about making a grid class to encapsulate gameboard_list and provide the methods that your game logic needs in order to interact with the grid. It could allow you to initialize it with any size and include the functions for getting cells by coordinates and getting neighbors as methods. Display logic doesn't really belong in this class but it wouldn't be the worst thing to include the method for representing the grid as a string as the grid object's __str__ method. A good str() representation could be useful for debugging if you try to hook the grid class up to some other display method such as a GUI environment or pygame or a web app.

Dominoes
Sep 20, 2007

Suspicious Dish posted:

Ubuntu binaries make no sense, since Python ships with Ubuntu, and you can simply ship your script with a shebang line to make it run.
I doubt anyone reading this post would be able to run any python program I made on their Ubuntu computer without a bit of legwork. Imagine asking a non-programer to do that.

NOTinuyasha
Oct 17, 2006

 
The Great Twist

Suspicious Dish posted:

Ubuntu binaries make no sense, since Python ships with Ubuntu, and you can simply ship your script with a shebang line to make it run.

The point is to roll all dependencies and a copy of the Python interpreter itself into one executable so the whole thing is totally portable and doesn't depend on any local resources or tools in order to run. Even though Linux applications are generally distributed through package managers I can see why some people would want to go the portable executable route.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

NOTinuyasha posted:

The point is to roll all dependencies and a copy of the Python interpreter itself into one executable so the whole thing is totally portable and doesn't depend on any local resources or tools in order to run. Even though Linux applications are generally distributed through package managers I can see why some people would want to go the portable executable route.

I think I like how calibre does the not-from-a-package-manager thing.

http://calibre-ebook.com/download_linux

Calibre is an example of a pretty complex desktop UI wrote in python.

Dren
Jan 5, 2001

Pillbug
Anyone try http://www.pip-installer.org/en/latest/usage.html#pip-freeze?

BigRedDot
Mar 6, 2008

Dren posted:

That looks pretty good. They seem to have a handle on the scientific/data stuff. Does the community have repos for it to support packages that continuum doesn't provide? E.g. How would I go about getting beautifulsoup with it?

Community repos are located at https://binstar.org. If a package is not there it is usually a simple matter to build on using conda recipes (which can then be uploaded to binstar for others to use). Alternatively, you can still pip install or setup.py install into conda environments if necessary.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

NOTinuyasha posted:

The point is to roll all dependencies and a copy of the Python interpreter itself into one executable so the whole thing is totally portable and doesn't depend on any local resources or tools in order to run. Even though Linux applications are generally distributed through package managers I can see why some people would want to go the portable executable route.

Of course, yeah, and sandboxed and bundled applications are something we're actively pursuing because using package management for app deployment is terrible. I was thinking of something like a simple script rather than a complex app.

Pollyanna
Mar 5, 2005

Milk's on them.


Dren posted:

You could use booleans instead of Cell objects. Cell objects only have one bit of state, alive or dead (true or false). Also, I'm not sure why you're using numpy arrays, regular lists will work just fine.

Try making a super simple game of life. Use an 8x8 grid and don't use any classes at all. Implement your grid as a list of booleans of length 64, call it gameboard_list. Write a function that accepts the list and (x, y) coordinates as arguments and returns the cell value at that position.

Using the function that accesses the cell at certain coordinates write a function to turn the gameboard into plain old text. Do like, a '*' for alive cells and a ' ' for dead cells. Then print that to the screen.

Next, write a function that takes the current gameboard_list, checks each coordinate in it, and returns a new list representing the next stage of the gameboard (as opposed to modifying the current list). It might help to create a function that can return to you all of the values of the neighbors of a cell.

Once you've got that going think about making a grid class to encapsulate gameboard_list and provide the methods that your game logic needs in order to interact with the grid. It could allow you to initialize it with any size and include the functions for getting cells by coordinates and getting neighbors as methods. Display logic doesn't really belong in this class but it wouldn't be the worst thing to include the method for representing the grid as a string as the grid object's __str__ method. A good str() representation could be useful for debugging if you try to hook the grid class up to some other display method such as a GUI environment or pygame or a web app.

I've never been able to just generate a list of x by y dimensions and im too brain fried right now to figure that out. thanks for the help :) but i'll have to tackle this later :(

Dren
Jan 5, 2001

Pillbug
represent a list of x by y (8 by 8) dimensions with a flat list
Python code:
gameboard_list = [False] * 64
Then write a function to translate (x,y) coordinates into a flat list index.

Write the function get_coord such that this code works:
Python code:
gameboard_list = [False] * 64

gameboard_list[0] = True
gameboard_list[17] = True
gameboard_list[62] = True

def get_coord(gameboard_list, x, y):
    # implement this
    pass

assert(get_coord(gameboard_list, 0, 0) == True)
assert(get_coord(gameboard_list, 2, 1) == True)
assert(get_coord(gameboard_list, 7, 6) == True)
Next, write yourself a set_coord function.

Nippashish
Nov 2, 2005

Let me see you dance!

Dren posted:

represent a list of x by y (8 by 8) dimensions with a flat list

Then write a function to translate (x,y) coordinates into a flat list index.

This both more complicated and more verbose than just using a 2d numpy array.

Dren
Jan 5, 2001

Pillbug
It's not that much worse. I was leaning that way so I could have the eventual grid class be a wrapper around the list that he could attach the functions to as methods by changing gameboard_list to self. Using array syntax in a class requires overloads and I was trying to stay away from that.

Pollyanna
Mar 5, 2005

Milk's on them.


The Game of Life benefits massively from some sort of GUI, since it's visual almost by principle. I was gonna go with the classes idea so I could make starting a game way less of a pain in the rear end, but that doesn't work so well...

edit: Yeah, I see a lot of griping about trying to program GoL in Python online. :sigh:

Pollyanna fucked around with this message at 00:38 on Sep 28, 2013

Crosscontaminant
Jan 18, 2007

Conway's Game of Life is precisely the example Jack Diederich uses to illustrate a case where people jump to use objects where they just add overhead for no benefit. Model the world as a dictionary (nested lists give you trees, not matrices) and write two functions - a generator to produce the neighbours for a given cell one at a time, and a function to generate the next iteration of the world given the previous one.

Pollyanna
Mar 5, 2005

Milk's on them.


Hmm. So I create a dictionary with keys 1 through x, where x is the x dimension of the board, and each key has their own keys 1 through y, where y is the y dimension of the board. Those keys have False as their value initially.

So I need to create a dictionary of dictionaries? Can you do that?

Dominoes
Sep 20, 2007

Pollyanna posted:

...create a dictionary of dictionaries? Can you do that?
Yes.

Pollyanna
Mar 5, 2005

Milk's on them.


:psyduck: This seems very simple. Why didn't I know that?

Guess I'm more of a novice than I thought.

Dominoes
Sep 20, 2007

You can also make dictionaries of lists, lists of dictionaries, lists of lists of dictionaries of numpy arrays etc.

FoiledAgain
May 6, 2007

Dominoes posted:

You can also make dictionaries of lists, lists of dictionaries, lists of lists of dictionaries of numpy arrays etc.

You can make dictionaries where the values are all lists. The keys cannot be lists, because lists are mutable. I'm sure you know this, I'm just adding on for people less familiar with Python.

Hot Dog Day #42
Jun 17, 2001

Egbert B. Gebstadter
For this particular application, a dict of dicts seems like a strange choice, since all the dicts involved would only have consecutive integer indices. I would either use a list of lists, or a single dict whose keys are coordinate pairs, e.g.:

Python code:
 the_world = { (i,j) : False for i in range(x) for j in range(y) }

Pollyanna
Mar 5, 2005

Milk's on them.


Right, so:

Python code:
xdim = 10
ydim = 10

a = {}
b = {}

for x in range(1, xdim+1):
    b[x] = False

for y in range(1, ydim+1):
    a[y] = b
Returns a nested dictionary that resembles a 10x10 grid of False. Now I can just call a[x][y] and change it. :)

Hot Dog Day #42 posted:

For this particular application, a dict of dicts seems like a strange choice, since all the dicts involved would only have consecutive integer indices. I would either use a list of lists, or a single dict whose keys are coordinate pairs, e.g.:

Python code:
 the_world = { (i,j) : False for i in range(x) for j in range(y) }

That's kind of what I tried to do with the numpy array idea, but it didn't work.

I need to be able to say "for every key x in a: for every key x in range(1, xdimension): if a[x-1 through x + 1][x-1 through x+1] has less than two Trues, die, else if (...)"

This seems really ugly and verbose and kind of a pain in the rear end. Is there an easier way to iterate over a dictionary of dictionaries?

Pollyanna fucked around with this message at 03:12 on Sep 28, 2013

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Thermopyle posted:

I think I like how calibre does the not-from-a-package-manager thing.

http://calibre-ebook.com/download_linux

Calibre is an example of a pretty complex desktop UI wrote in python.

Sublime Text is also python (I am fairly sure entirely python) and it's a very decent UI, the custom theming on it is also very good.

breaks
May 12, 2001

Pollyanna posted:

Returns a nested dictionary that resembles a 10x10 grid of False. Now I can just call a[x][y] and change it. :)

This doesn't do what you want. You are repeatedly assigning the same dictionary b to various keys in dictionary a, so when you modify any a[key], it will change all of them (because they are all the same dict).

quote:

This seems really ugly and verbose and kind of a pain in the rear end. Is there an easier way to iterate over a dictionary of dictionaries?

The most straightforward implementation is the single dictionary with keys that are tuples (x,y). Use the the_world dictionary made by the dict comprehension you quoted and see if you can write a function that determines whether a given cell should live.

Nippashish
Nov 2, 2005

Let me see you dance!
Use a 2d numpy array to model the states of cells in the world. Use convolution operations to count neighbors.

Pollyanna
Mar 5, 2005

Milk's on them.


breaks posted:

This doesn't do what you want. You are repeatedly assigning the same dictionary b to various keys in dictionary a, so when you modify any a[key], it will change all of them (because they are all the same dict).


The most straightforward implementation is the single dictionary with keys that are tuples (x,y). Use the the_world dictionary made by the dict comprehension you quoted and see if you can write a function that determines whether a given cell should live.

Well, the function would have to be, if the target is (x, y), then

Python code:
print the_world[(i, j] for i in range (x-1, x+2) for j in range (y-1, y+2))]
When I do this, it bitches about invalid syntax at the first for. :(

Hot Dog Day #42
Jun 17, 2001

Egbert B. Gebstadter
You wrote (i,j] with a square bracket, when you meant (i,j). E2: Oops, now I see what you were trying to do.

E: You also likely want that whole generator expression wrapped in square brackets, so that you'll be printing a list. I don't think you can just print a naked generator expression (or you can, but it won't give you what you expect). So, something like
code:
print [ the_world[(i, j)] for i in range (x-1, x+2) for j in range (y-1, y+2)) ]

Hot Dog Day #42 fucked around with this message at 04:13 on Sep 28, 2013

Pollyanna
Mar 5, 2005

Milk's on them.


Python code:
>>> print [the_world[(lx, ly) for i in range (x-1, x+2) for j in range (y-1, y+2))]]
  File "<stdin>", line 1
    print [the_world[(lx, ly) for i in range (x-1, x+2) for j in range (y-1, y+2))]]
                                ^
SyntaxError: invalid syntax
Uggh why do I suck so much at this :negative:

edit oh gently caress me that's so obvious. brbrb

edit yay

Python code:

x = 10
y = 10

the_world = { (i,j) : False for i in range(x) for j in range(y) }

x = 4
y = 4

try:
	neighbors = [ the_world[(i, j)] for i in range (x-1, x+2) for j in range (y-1, y+2) ]
except KeyError:
	print "Out of range."

Pollyanna fucked around with this message at 04:19 on Sep 28, 2013

Hot Dog Day #42
Jun 17, 2001

Egbert B. Gebstadter
Yeah sorry about that, I hadn't realized quite what you were trying to do and the code I posted was pretty bad as a result. I think the code I've got in there now is what you want.

Pollyanna
Mar 5, 2005

Milk's on them.


:cool:

Python code:
def togglecell(xcoord, ycoord):
	x = xcoord
	y = ycoord
	if the_world[x,y] == False:
		the_world[x,y] = True
	else:
		the_world[x,y] = False

def neighbors(xcoord, ycoord):
	x = xcoord
	y = ycoord
	try:
		neighbors = [ the_world[(i, j)] for i in range (x-1, x+2) for j in range (y-1, y+2) ]
		return neighbors
	except KeyError:
		print "Out of range."
		quit()

def checkneighbors(xcoord, ycoord):
	x = xcoord
	y = ycoord
	if neighbors(x, y).count(True) < 2:
		print "It died."
	elif neighbors(x, y).count(True) > 3:
		print "It died."
	elif neighbors(x, y).count(True) == 2:
		print "It lived!"
	elif neighbors(x, y).count(True) == 3:
		print "It lived!"
	else:
		print "Something went wrong!"

wide = 10
high = 10

the_world = { (i,j) : False for i in range(wide) for j in range(high) }

x = 4
y = 4

togglecell(4, 3)
togglecell(4, 5)
togglecell(3, 5)

checkneighbors(x, y)

Third
Sep 9, 2004
The most noble title any child can have.
Maybe I'm reading it wrong, but isn't neighbors returning the cell itself as a neighbor?

Adbot
ADBOT LOVES YOU

Pollyanna
Mar 5, 2005

Milk's on them.


returnh posted:

Maybe I'm reading it wrong, but isn't neighbors returning the cell itself as a neighbor?

Whoops, good catch. I need it to remove the input cell from the neighbors list.

Python code:
def neighbors(xcoord, ycoord):
	x = xcoord
	y = ycoord
	try:
		neighbors = [ the_world[(i, j)] for i in range (x-1, x+2) for j in range (y-1, y+2)]
		neighbors = neighbors - neighbors[(x, y)]
		return neighbors
	except KeyError:
		print "Out of range."
This should fix it, right? It removes the element x, y (aka the target cell) from the list.

edit oh wait poo poo, dictionaries aren't mutable are they :/

Pollyanna fucked around with this message at 04:54 on Sep 28, 2013

  • Locked thread