Live data from Hacker News

Pycraft: Minecraft engine in Python

github.com

11–20 of 49 posts

Re: Pycraft: Minecraft engine in Python

#11
post #2

I've always wanted to have an MC clone in Python with GUI event hooks to run scripts. Like pull a lever and an email is sent sort of thing. Will this fork allow for something like that? I'm not against adding it myself if allowed, btw.

Couldn't something like that be done in Minetest?

Re: Pycraft: Minecraft engine in Python

#12
I cringe when I see code like this: if len(vals) in range(1, 5):

It seems like a harmless enough thing to do but that code is effectively creating a new array with values [1, 2, 3, 4, 5] and testing if the result of len() is in that array by iterating over it. This check is happening multiple times for each draw call every frame.

Sadly I see this kind of stuff in Python all the time and it just adds weight to the argument that Python is not a performant language. 1 <= len(vals) <= 5 would have been more pythonic and certainly more efficient (and obvious) but I have to wonder if under the hood it's just doing the same inefficient operation.

Re: Pycraft: Minecraft engine in Python

#13
post #10
post #8

Earlier quoted context omitted.

Yes, you are correct. But normal MC is not open source. :)

Even though Notch was supposed to make it open source at some point. Another broken promise.

That point was when Minecraft was worthless. It's currently somewhere around the $2.5b mark in value. But that's just splitting hairs, it won't likely ever be open-sourced after MS acquired it.

That said, they also promised a modding API too...

Re: Pycraft: Minecraft engine in Python

#14

I cringe when I see code like this: if len(vals) in range(1, 5): It seems like a harmless enough thing to do but that code is effectively creating a new array with values [1, 2, 3, 4, 5] and testing if the result of len() is in that array by iterating over it. This check is happening multiple times for each draw call every frame. Sadly I see this kind of stuff in Python all the time and it just adds weight to the arg…

Why do you suspect 1 You can actually get a very good idea for what Python is doing under the hood using the dis module:

    dis.dis(lambda: 1 >   27 ROT_TWO             
                 28 POP_TOP             
                 29 RETURN_VALUE        
Compare to:

    dis.dis(lambda: len(vals) in range(1, 5))
      1           0 LOAD_GLOBAL              0 (len)
                  3 LOAD_GLOBAL              1 (vals)
                  6 CALL_FUNCTION            1
                  9 LOAD_GLOBAL              2 (range)
                 12 LOAD_CONST               1 (1)
                 15 LOAD_CONST               2 (5)
                 18 CALL_FUNCTION            2
                 21 COMPARE_OP               6 (in)
                 24 RETURN_VALUE

Re: Pycraft: Minecraft engine in Python

#15

I cringe when I see code like this: if len(vals) in range(1, 5): It seems like a harmless enough thing to do but that code is effectively creating a new array with values [1, 2, 3, 4, 5] and testing if the result of len() is in that array by iterating over it. This check is happening multiple times for each draw call every frame. Sadly I see this kind of stuff in Python all the time and it just adds weight to the arg…

This is in Python 3. xrange is now range, so only a generator is constructed.

Agreed that 1 <= len(vals) < 5 would be more Pythonic.

Re: Pycraft: Minecraft engine in Python

#16
post #14

I cringe when I see code like this: if len(vals) in range(1, 5): It seems like a harmless enough thing to do but that code is effectively creating a new array with values [1, 2, 3, 4, 5] and testing if the result of len() is in that array by iterating over it. This check is happening multiple times for each draw call every frame. Sadly I see this kind of stuff in Python all the time and it just adds weight to the arg…

Why do you suspect 1 You can actually get a very good idea for what Python is doing under the hood using the dis module: dis.dis(lambda: 1 > 27 ROT_TWO 28 POP_TOP 29 RETURN_VALUE Compare to: dis.dis(lambda: len(vals) in range(1, 5)) 1 0 LOAD_GLOBAL 0 (len) 3 LOAD_GLOBAL 1 (vals) 6 CALL_FUNCTION 1 9 LOAD_GLOBAL 2 (range) 12 LOAD_CONST 1 (1) 15 LOAD_CONST 2 (5) 18 CALL_FUNCTION 2 21 COMPARE_OP 6 (in) 24 RETURN_VALUE

Eh? That dis output doesn't really tell us which is more efficient. To know that, you'd need to know how `COMPARE_OP` works for each of it's arguments, which is what @Negative1 believes will be not-as-efficient (along with range creation).

This output doesn't really provide any clarification.

Re: Pycraft: Minecraft engine in Python

#18
post #15

I cringe when I see code like this: if len(vals) in range(1, 5): It seems like a harmless enough thing to do but that code is effectively creating a new array with values [1, 2, 3, 4, 5] and testing if the result of len() is in that array by iterating over it. This check is happening multiple times for each draw call every frame. Sadly I see this kind of stuff in Python all the time and it just adds weight to the arg…

This is in Python 3. xrange is now range, so only a generator is constructed. Agreed that 1 <= len(vals) < 5 would be more Pythonic.

To be pedantic (which I think is warranted here), range does not return a generator, it returns a sequence called a range object. This object can be indexed, sliced, and (relevant to this discussion) supports the 'in' operator.

"x in range(10)" will operate in constant time and memory in Python 3. Whether it is actually more efficient than "0

  $ python3 -m timeit -s 'x = 8' 'x in range(10)'
  1000000 loops, best of 3: 0.351 usec per loop
  $ python3 -m timeit -s 'x = 8' '0 
Even aside from this, I find the "0 <= x < 10" syntax to be clearer.

Re: Pycraft: Minecraft engine in Python

#20

I cringe when I see code like this: if len(vals) in range(1, 5): It seems like a harmless enough thing to do but that code is effectively creating a new array with values [1, 2, 3, 4, 5] and testing if the result of len() is in that array by iterating over it. This check is happening multiple times for each draw call every frame. Sadly I see this kind of stuff in Python all the time and it just adds weight to the arg…

In python 3 range() does not build a list but produce a range object. Testing x in range(a,b) will actually call the __contains__ method of the object which is O(1). The only overhead here may be the object creation. See this http://stackoverflow.com/q/30081275
Post reply on HN