'Python/Turtle - How to execute a function on each sublist within a list
I am a complete Python newbie, my task is to create a function that will draw icons into a grid in turtle (900x600 grid, 5 columns and 4 rows, each square is 150x150 pixels). The type, position and orientation of the icons must be based on 4 given variables from a data set. The function has to be able to interpret a data set of the form:
data_set = [icon_style, bottom_left_column, bottom_left_row, orientation]
an example of a full data set, which draws 4 icons, is as follows:
data_set_03 = [['A', 1, 0, 'N'], ['C', 2, 1, 'E'], ['A', 3, 2, 'S'], ['A', 4, 3, 'W']]
Meaning the first icon is of type A, drawn at column 1, row 0, facing north. The second icon is of type C, drawn at column 2, row 1, facing East. etc etc, for all 4 icons in that list.
To tackle this challenge, first I defined a function to interpret the list and create 4 variables that will be used later by the function which draws the icons
def read_icons(w,x,y,z):
if w == 'A':
icon = icon_01
elif w == 'B':
icon = icon_02
elif w == 'C':
icon = icon_03
elif w == 'D':
icon = icon_04
if x == 0:
x_coord = -450
elif x == 1:
x_coord = -300
elif x == 2:
x_coord = -150
elif x == 3:
x_coord = 0
elif x == 4:
x_coord = 150
elif x == 5:
x_coord = 300
if y == 0:
y_coord = -300
elif y == 1:
y_coord = -150
elif y == 2:
y_coord = 0
elif y == 3:
y_coord = 150
if z == 'N':
heading = 90
elif z == 'E':
heading = 0
elif z == 'S':
heading = 270
elif z == 'W':
heading = 180
Finally, I added this at the end of the function to test the drawing - I was planning to move this into my draw_icons function later
icon()
read_icons(*data_set_01)
icon() is what tells the function to draw the icon, so I can see if it is being drawn correctly, and read_icons(*data_set_01) executes the whole function based on data_set_01
This works well when drawing any SINGLE icon, The correct icon is drawn in the correct location, with the correct orientation. This works for any dataset such as
data_set_01 = ['B', 1, 2, 'N']
Where only 1 icon is drawn.
However, my issue is that when I attempt to use a data set that contains information for more than one icon, such as
data_set_03 = [['A', 1, 0, 'N'], ['C', 2, 1, 'E'], ['A', 3, 2, 'S'], ['A', 4, 3, 'W']]
I run into a whole heap of errors.
The following is my best attempt at creating the draw_icons function, using a for each loop to run the read_icons() function once for each sub-list:
def draw_icons(data_set):
for sublist in data_set:
read_icons(*data_set)
penup()
goto(x_coord, y_coord)
setheading(heading)
pendown()
icon()
draw_icons(data_set_03)
However this code results in the error:
goto(x_coord, y_coord)
NameError: global name 'x_coord' is not defined
Whereas my x_coord had no problem being defined when variables for only 1 icon were used.
My second attempt was to try to remove the for loop and explicitly run read_icons on each sub-list 1 by 1:
def draw_icons(data_set):
read_icons(*data_set[0])
penup()
goto(x_coord, y_coord)
setheading(heading)
pendown()
icon()
read_icons(*data_set[1])
penup()
goto(x_coord, y_coord)
setheading(heading)
pendown()
icon()
read_icons(*data_set[2])
penup()
goto(x_coord, y_coord)
setheading(heading)
pendown()
icon()
read_icons(*data_set[3])
penup()
goto(x_coord, y_coord)
setheading(heading)
pendown()
icon()
However the same error was encountered.
I was hoping that the draw_icons(data_set_03) would work as follows:
For the first sublist of data_set_03, that is: ['A', 1, 0, 'N'], define w,x,y and z based on the rules of read_icons(), then draw the icon as per these variables.
Next, move to the second sublist of data_set_03, that is: ['C', 2, 1, 'E'], re-define w,x,y and z based on the rules of read_icons() and draw the next icon as per these variables.
Rinse and repeat for sublists 3 and 4, until all 4 icons are drawn correctly.
Am I correct in thinking that data_set_03 is divided into the following sub-lists?
sublist 0 = ['A', 1, 0, 'N']
sublist 1 = ['C', 2, 1, 'E']
sublist 2 = ['A', 3, 2, 'S']
sublist 3 = ['A', 4, 3, 'W']
If so, why does my for loop not generate 4 variables from the first sub-list, drawn the icon, then overwrite the 4 variables with their new values from the second sub-list then drawn the second icon, etc etc.
Am I approaching this completely wrong? This is a beginner task, and so producing functioning code is the only requirement, however ugly it may be. I do not need to be elegant or concise as of yet. This has been my own honest attempt at completing the challenge, but have ran into a hurdle at this point.
Any assistance or insight into this would be greatly appreciated!
Solution 1:[1]
The code
def draw_icons(data_set):
for sublist in data_set:
read_icons(*data_set)
penup()
goto(x_coord, y_coord)
setheading(heading)
pendown()
icon()
draw_icons(data_set_03)
is almost correct. There are two problems with this code though.
1: You pass the whole dataset into read_icons.
This causes lists to pass into the read_icons function. The function either has the wrong number of arguments or the wrong kind of arguments.
Try giving your read_icons the arguments *sublist.
2: Python variables have scope. You define x_coord, y_coord, heading,
and icon within draw_icons meaning that they are invalid outside of the function draw_icons.
I suggest you make the variables global (put them at the top of your code).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | DucksEL |
