Re: [Tutor] print() invalid syntax (Jim Gallaher)
> Message: 2 > Date: Tue, 23 Dec 2014 18:27:10 + > From: stuart kurutac > To: "tutor@python.org" > Subject: [Tutor] print() invalid syntax error > Message-ID: > Content-Type: text/plain; charset="iso-8859-1" > > Hello all, > > I'm working my way through the Michael Dawson book "Python Programming for > the Absolute Beginner..." > I tried running with version 3.2.3 and the native version (2.7.3) For his book he mentions he uses Python 3. Python 2 might work, but it's not guaranteed. Sincerely Jim Gallaher ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Making Doubly Linked List with Less Lines of Code.
I wrote some code recently to make a linked list of Nodes for a 2d graph, so it consists of rows and columns. Now I wanted to make the code support being doubly linked, forwards and backwards. The difficult part of this is that the links are per row and per column. But the code I think is overly bloated. I am currently working on reducing the complexity of it. If any one has the time to look at it, if you have ideas for how I can re-write it to be much smaller I would appreciate the information. If you need more code let me know, but I tried to condense it since this singular function is around 325 lines of code. Thank you. The function to make the linked list: def make_linked_lists(self): previous_row_node = None previous_col0_node = None previous_col1_node = None previous_col2_node = None previous_col3_node = None previous_col4_node = None previous_col5_node = None previous_col6_node = None previous_col7_node = None current_node = None self.tile_list = list() for row in range(0, self.rows): for col in range(0, self.cols): current_node = self.get_instance_of_id(str(col) + ',' + str(row)) self.tile_list.append(current_node) if row == 0: if col == 0: self.row0 = current_node self.col0 = current_node previous_col0_node = current_node elif col == 1: self.col1 = current_node previous_col1_node = current_node elif col == 2: self.col2 = current_node previous_col2_node = current_node elif col == 3: self.col3 = current_node previous_col3_node = current_node elif col == 4: self.col4 = current_node previous_col4_node = current_node elif col == 5: self.col5 = current_node previous_col5_node = current_node elif col == 6: self.col6 = current_node previous_col6_node = current_node elif col == 7: self.col7 = current_node previous_col7_node = current_node if previous_row_node is not None: previous_row_node.next_row_node = current_node current_node.prev_row_node = previous_row_node previous_row_node = current_node elif row == 1: if col == 0: self.row1 = current_node previous_row_node = None previous_col0_node.next_col_node = current_node current_node.prev_col_node = previous_col0_node previous_col0_node = current_node elif col == 1: previous_col1_node.next_col_node = current_node current_node.prev_col_node = previous_col1_node previous_col1_node = current_node elif col == 2: previous_col2_node.next_col_node = current_node current_node.prev_col_node = previous_col2_node previous_col2_node = current_node elif col == 3: previous_col3_node.next_col_node = current_node current_node.prev_col_node = previous_col3_node previous_col3_node = current_node elif col == 4: previous_col4_node.next_col_node = current_node current_node.prev_col_node = previous_col4_node previous_col4_node = current_node elif col == 5: previous_col5_node.next_col_node = current_node current_node.prev_col_node = previous_col5_node previous_col5_node = current_node elif col == 6: previous_col6_node.next_col_node = current_node current_node.prev_col_node = previous_col6_node previous_col6_node = current_node elif col == 7: previous_col7_node.next_col_node = current_node current_node.prev_col_node = previous_col7_node previous_col7_node = current_node if previous_row_node is not None: previous_row_node.next_row_node = current_node previous_row_node = current_node el
Re: [Tutor] Making Doubly Linked List with Less Lines of Code.
On Wed, Dec 24, 2014 at 04:35:06PM -0500, WolfRage wrote: > I wrote some code recently to make a linked list of Nodes for a 2d > graph, so it consists of rows and columns. Now I wanted to make the code > support being doubly linked, forwards and backwards. The difficult part > of this is that the links are per row and per column. But the code I > think is overly bloated. I am currently working on reducing the > complexity of it. If any one has the time to look at it, if you have > ideas for how I can re-write it to be much smaller I would appreciate > the information. If you need more code let me know, but I tried to > condense it since this singular function is around 325 lines of code. Wow. It certainly is bloated. I don't have time to look at it in any detail right now, as it is Christmas Day here, but I'll give you a suggestion. Any time you find yourself writing more than two numbered variables, like this: > previous_col0_node = None > previous_col1_node = None > previous_col2_node = None > previous_col3_node = None > previous_col4_node = None > previous_col5_node = None > previous_col6_node = None > previous_col7_node = None you should instead think about writing a list: previous_col_nodes = [None]*8 Then, instead of code like this: > if col == 0: > self.col0 = current_node > previous_col0_node = current_node > elif col == 1: > self.col1 = current_node > previous_col1_node = current_node > elif col == 2: > self.col2 = current_node > previous_col2_node = current_node etc. you can just write: for col in range(number_of_columns): self.columns[col] = current_node previous_col_nodes[col] = current_node Look for the opportunity to write code like this instead of using range: for col, the_column in enumerate(self.columns): self.columns[col] = process(the_column) Any time you write more than a trivial amount of code twice, you should move it into a function. Then, instead of: if row == 0: if col == 0: a elif col == 1: b elif col == 2: c elif col == 3: d elif col == 4: e elif row == 1: if col == 0: a elif col == 1: b elif col == 2: c elif col == 3: d elif col == 4: e elif row == 3: # same again you can write a function: def process_cell(row, col): if col == 0: a elif col == 1: b elif col == 2: c elif col == 3: d elif col == 4: e # later on for row in rows: for col in cols: process_cell(row, col) Try those suggestions, and come back to us if you still need help. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Making Doubly Linked List with Less Lines of Code.
OK thanks for the rapid response, I will start rewriting the functions in this way now, and will come back with what I wind up with. Also Merry Christmas! On 12/24/2014 04:56 PM, Steven D'Aprano wrote: On Wed, Dec 24, 2014 at 04:35:06PM -0500, WolfRage wrote: I wrote some code recently to make a linked list of Nodes for a 2d graph, so it consists of rows and columns. Now I wanted to make the code support being doubly linked, forwards and backwards. The difficult part of this is that the links are per row and per column. But the code I think is overly bloated. I am currently working on reducing the complexity of it. If any one has the time to look at it, if you have ideas for how I can re-write it to be much smaller I would appreciate the information. If you need more code let me know, but I tried to condense it since this singular function is around 325 lines of code. Wow. It certainly is bloated. I don't have time to look at it in any detail right now, as it is Christmas Day here, but I'll give you a suggestion. Any time you find yourself writing more than two numbered variables, like this: previous_col0_node = None previous_col1_node = None previous_col2_node = None previous_col3_node = None previous_col4_node = None previous_col5_node = None previous_col6_node = None previous_col7_node = None you should instead think about writing a list: previous_col_nodes = [None]*8 Then, instead of code like this: if col == 0: self.col0 = current_node previous_col0_node = current_node elif col == 1: self.col1 = current_node previous_col1_node = current_node elif col == 2: self.col2 = current_node previous_col2_node = current_node etc. you can just write: for col in range(number_of_columns): self.columns[col] = current_node previous_col_nodes[col] = current_node Look for the opportunity to write code like this instead of using range: for col, the_column in enumerate(self.columns): self.columns[col] = process(the_column) Any time you write more than a trivial amount of code twice, you should move it into a function. Then, instead of: if row == 0: if col == 0: a elif col == 1: b elif col == 2: c elif col == 3: d elif col == 4: e elif row == 1: if col == 0: a elif col == 1: b elif col == 2: c elif col == 3: d elif col == 4: e elif row == 3: # same again you can write a function: def process_cell(row, col): if col == 0: a elif col == 1: b elif col == 2: c elif col == 3: d elif col == 4: e # later on for row in rows: for col in cols: process_cell(row, col) Try those suggestions, and come back to us if you still need help. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Making Doubly Linked List with Less Lines of Code.
Here is a condensed version of all of the applicable code but with out Linked List filled in, as I am preparing to re-write it. class GameTile(): def __init__(self, id, **kwargs): self.id = id class GameGrid(): def __init__(self, **kwargs): self.cols = 8 self.rows = 10 # Each variable below is a link to the head Node in the respective # row or column. self.row0 = None self.row1 = None self.row2 = None self.row3 = None self.row4 = None self.row5 = None self.row6 = None self.row7 = None self.row8 = None self.row9 = None self.col0 = None self.col1 = None self.col2 = None self.col3 = None self.col4 = None self.col5 = None self.col6 = None self.col7 = None self.skip_to_row = None self.skip_to_col = None self.tile_list = list() def make_linked_lists(self): prev_row_node = None prev_col0_node = None current_node = None for row in range(0, self.rows): for col in range(0, self.cols): for node in self.tile_list: if node.id == str(col) + ',' + str(row): current_node = node def update(self): for row in range(0, self.rows): element = None if row < 7: pass for column in range(0, self.cols): self.tile_list.append(GameTile(id=str(column) + ',' + str(row))) def print_lists(self): for node in self.tile_list: print(node.id) temp = GameGrid() temp.update() temp.make_linked_lists() temp.print_lists() ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Making Doubly Linked List with Less Lines of Code.
Quick comment: the structure of the code here catches my eye: > # Each variable below is a link to the head Node in the respective > # row or column. > self.row0 = None > self.row1 = None > self.row2 = None > self.row3 = None > self.row4 = None > self.row5 = None > self.row6 = None > self.row7 = None > self.row8 = None > self.row9 = None It seems highly regular; the code here is maintaining a collection of row variables. Because it's so regular, you might consider using a list to represent this collection. Concretely: self.rows = [None, None, None, None, None, None, None, None, None, None] We can express this more concisely in Python as: self.row = [None] * 10 Once we have this, then we can get at any particular row through its offset. So instead of: self.row0 we say: self.row[0] The big win with a list representation is that the offset can be computed. So if we need to do an operation on each row, we might say: for i in range(10): ## ... Do something with self.row[i] And if you see the full power of this, you'll realize that this allows us to express loops to do something to _all_ the rows, expressing that action just once. Or if we need to do something for every other row, that too is not too difficult to express: for i in range(0, 10, 2): ## ... Do something with self.row[i] In contrast, doing the same thing without using an explicit container representation means that doing container-wide actions is harder to do. This is the code smell that we saw at the beginning of this post, where we see repetitive code. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Making Doubly Linked List with Less Lines of Code.
On Wed, Dec 24, 2014 at 1:35 PM, WolfRage wrote: > I wrote some code recently to make a linked list of Nodes for a 2d graph, so > it consists of rows and columns. Now I wanted to make the code support being > doubly linked, forwards and backwards. What are the _operations_ you want to support? Can you say more about this? Representations make certain operations easier or more difficult, and you're focusing on representations, which is fine. But I'm not quite sure what operations you need to support. You mention the concept of a 2d graph arranged in rows and columns. I am assuming you want at least two operations. * Given a row and column, add a Node at that position. * Given a row and column, get the Node (or nodes?) at that position. Conceptually, these are "insertion" and "lookup". But note that I am not sure what you want out of "lookup". I can't tell because it's not obvious, so you need to let us know. Does that sound reasonable? Let's put a stake on the ground and nail purpose first. And then figure out representation after that. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Making Doubly Linked List with Less Lines of Code.
> It seems highly regular; the code here is maintaining a collection of > row variables. Because it's so regular, you might consider using a > list to represent this collection. Concretely: > > self.rows = [None, None, None, None, None, None, None, None, None, None] Whoops. Apologies: I should have named the variable "row" to be consistent with the rest of the message: self.row = [None, None, None, None, None, None, None, None, None, None] That being said, still easier just to say: self.row = [None] * 10 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor