py3minepi / py3minepi-legacy

Original attempt to port Minecraft Pi to Python 3
https://github.com/py3minepi/py3minepi
Other
25 stars 7 forks source link

API example: Setting the table for dinner #9

Open jonathanfine opened 9 years ago

jonathanfine commented 9 years ago

We're expecting six people for dinner. There's a rectangular table in the dining room, two on each side and one at each end. That seats six. So how do we set the table?

It's obvious really. We go to each place in turn, and at put at each place a plate, knife and fork. For a more elaborate meal there's more - glasses for drink, cutlery for additional courses. But the basis idea is the same.

Building a castle or a palace is similar. Once the walls are up we go round adding the battlements and windows. The same method works for a classical Greek temple.

I'd like the API to support this way of thinking.

for place in places:
    place.put(setting)

This approach owes a lot to the turtle in Logo. To quote from wikipedia, using the turtle means

students could understand (and predict and reason about) the turtle's motion by imagining what they would do if they were the turtle.

dbrgn commented 9 years ago

While I like this approach, that requires to initialize a "Places" list first. How do you think that should look?

Syntax like this

places = [Place(x, 0, 0) for x in range(10)]
for place in places:
    place.put(setting)

is probably harder to grasp for a beginner than

for x in range(10):
    mc.set_block(x, 0, 0, blocks.WOOD)

While the set_block syntax, the tuples and the coordinates are debateable, I think a procedural approach is a bit easier to grasp than a declarative one.

jonathanfine commented 9 years ago

I agree with you, @dbrgn, that the range(10) statement is in many ways easier for the beginner to understand. And it's certainly something that should be available,and which they should be taught. Although I think range(-10) will be a gotcha for many users.

But range() won't work for setting the table for dinner, which is much harder than putting down a row of blocks. It won't work even if we the places as a tuple of (x, y, z) values given to us.

With logo the turtle has three attributes

  1. a location
  2. an orientation
  3. a pen

A major difficulty in teaching the computer how to lay the table for dinner, as described above, is to ensure that the knives are point in the correct direction, namely away from the person who will be using them. Hence my quote from wikipedia. We need the orientation as well, to lay the table correctly.

bennuttall commented 9 years ago
places = [Place(x, 0, 0) for x in range(10)]
for place in places:
    place.put(setting)

While I agree this is better, it requires pointing out that places is user specified according to the domain, place is conventional as the singular of places and as much as I'm a fan of list comprehension, that requires some explanation. Without explanation, they see those domain specific language words as Python keywords; it becomes magic foo that students will use every time. When they come to write code to plant a line of plants (or, to be more Pythonic, a shrubbery), they'll write:

places = [Place(x, 0, 0) for x in range(10)]
for place in places:
    place.put(setting)

bennuttall commented 9 years ago

Also how would you write the list comprehension over two or three dimensions? Comprehensions with multiple loops? Ditch for nested append?

places = [Place(x, y, z) for z in range(5) for y in range(7) for x in range(10)]

(I'm not even sure what order I'd put them in)

Personally I'd use itertools.product. Perhaps we could offer that functionality in the background?

dbrgn commented 9 years ago

I'd do a loop. It's more explicit and easier to understand.

places = []
for x in range(10):
    for y in range(7):
        for z in range(5):
            places.append(Place(x, y, z))
bennuttall commented 9 years ago

Yeah, I'd probably suggest the same (it's append though).

dbrgn commented 9 years ago

Oops :) Of course.