1 Replies - 1505 Views - Last Post: 12 February 2013 - 09:07 AM Rate Topic: -----

#1 blahblahbal  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 30
  • Joined: 04-February 13

Python Hollow Cylinder command I made

Posted 05 February 2013 - 11:08 PM

This is probably the ugliest code I have ever made, though I might have seen worse since my days of Terraria modding.

    @build_list
    @op_only
    def commandHCylinder(self, parts, fromloc, overriderank):
        "/hcyl blocktype radius height axis [x y z] - Op\nPlace/delete a block and /hcyl block radius height axis"
        if len(parts) < 8 and len(parts) != 5:
            self.client.sendServerMessage("Please enter a type, radius, height, axis(and possibly a coord triple)")
        else:
            # Try getting the normal axis
            normalAxis = parts[4]
            if normalAxis == 'x' or normalAxis == 'y' or normalAxis == 'z':
                pass
            else:
                self.client.sendErrorMessage("Normal axis must be x, y, or z.")
                return
            # Try getting the radius
            try:
                radius = int(parts[2])
            except ValueError:
                self.client.sendErrorMessage("Radius must be a Number.")
                return
            # Try getting the height
            try:
                height = parts[3]
            except ValueError:
                self.client.sendErrorMessage("Height must be a Number.")
                return
            # Try getting the block as a direct integer type.
            try:
                block = chr(int(parts[1]))
            except ValueError:
                # OK, try a symbolic type.
                try:
                    block = chr(globals()['BLOCK_%s' % parts[1].upper()])
                except KeyError:
                    self.client.sendErrorMessage("'%s' is not a valid block type." % parts[1])
                    return
            # Check the block is valid
            if ord(block) > 49:
                self.client.sendErrorMessage("'%s' is not a valid block type." % parts[1])
                return
            # If they only provided the type argument, use the last two block places
            if len(parts) == 5:
                try:
                    x, y, z = self.client.last_block_changes[0]
                except IndexError:
                    self.client.sendErrorMessage("You have not clicked for a center yet.")
                    return
            else:
                try:
                    x = int(parts[5])
                    y = int(parts[6])
                    z = int(parts[7])
                except ValueError:
                    self.client.sendServerMessage("All parameters must be integers")
                    return
            limit = self.getBuildLimit(overriderank)
            if 2*3.14*(radius)**2>limit:
                self.client.sendErrorMessage("Sorry, that area is too big for you to hcyl.")
                return
            # Draw all the blocks on, I guess
            # We use a generator so we can slowly release the blocks
            # We also keep world as a local so they can't change worlds and affect the new one
            world = self.client.world
            a, b, c = self.client.last_block_changes[0]
            normalAxis = parts[4]
            if normalAxis == "x":
                def generate_changes():
                    a, b, c = self.client.last_block_changes[0]
                    x, y, z = self.client.last_block_changes[0]
                    height = int(parts[3])
                    while x < (height + a):
                        for i in range(-radius-1, radius):
                            for j in range(-radius-1, radius):
                                for k in range(-radius-1, radius):
                                    if (i**2 + j**2 + k**2)**0.5 + .604 < radius and (i**2 + j**2 + k**2)**0.5 + .604 > radius-1.208:
                                        # Test for axis
                                        var_placeblock = 1
                                        if i != 0 and normalAxis == 'x':
                                            var_placeblock = 0
                                        if j != 0 and normalAxis == 'y':
                                            var_placeblock = 0
                                        if k != 0 and normalAxis == 'z':
                                            var_placeblock = 0
                                        if var_placeblock == 1:
                                            if not self.client.AllowedToBuild(x+i, y+j, z+k) and not overriderank:
                                                self.client.sendErrorMessage("You do not have permission to build here.")
                                                return
                                            try:
                                                world[x+i, y+j, z+k] = block
                                            except Assertionerror:
                                                self.client.sendErrorMessage("Out of bounds hcyl error.")
                                                return
                                            self.client.queueTask(TASK_BLOCKSET, (x+i, y+j, z+k, block), world=world)
                                            self.client.sendBlock(x+i, y+j, z+k, block)
                                            yield
                        x += 1
                block_iter = iter(generate_changes())
                def do_step():
                    # Do 10 blocks
                    try:
                        for x in range(10):
                            block_iter.next()
                        reactor.callLater(0.01, do_step)
                    except StopIteration:
                        if fromloc == "user":
                            self.client.sendServerMessage("Your hcyl just completed.")
                        pass
                do_step()
            elif normalAxis == "y":
                def generate_changes():
                    a, b, c = self.client.last_block_changes[0]
                    x, y, z = self.client.last_block_changes[0]
                    height = int(parts[3])
                    while (y < (height + B)/>):
                        for i in range(-radius-1, radius):
                            for j in range(-radius-1, radius):
                                for k in range(-radius-1, radius):
                                    if (i**2 + j**2 + k**2)**0.5 + .604 < radius and (i**2 + j**2 + k**2)**0.5 + .604 > radius-1.208:
                                        # Test for axis
                                        var_placeblock = 1
                                        if i != 0 and normalAxis == 'x':
                                            var_placeblock = 0
                                        if j != 0 and normalAxis == 'y':
                                            var_placeblock = 0
                                        if k != 0 and normalAxis == 'z':
                                            var_placeblock = 0
                                        if var_placeblock == 1:
                                            if not self.client.AllowedToBuild(x+i, y+j, z+k) and not overriderank:
                                                self.client.sendErrorMessage("You do not have permission to build here.")
                                                return
                                            try:
                                                world[x+i, y+j, z+k] = block
                                            except Assertionerror:
                                                self.client.sendErrorMessage("Out of bounds hcyl error.")
                                                return
                                            self.client.queueTask(TASK_BLOCKSET, (x+i, y+j, z+k, block), world=world)
                                            self.client.sendBlock(x+i, y+j, z+k, block)
                                            yield
                        y += 1
                block_iter = iter(generate_changes())
                def do_step():
                    # Do 10 blocks
                    try:
                        for x in range(10):
                            block_iter.next()
                        reactor.callLater(0.01, do_step)
                    except StopIteration:
                        if fromloc == "user":
                            self.client.sendServerMessage("Your hcyl just completed.")
                        pass
                do_step()
            elif normalAxis == "z":
                def generate_changes():
                    a, b, c = self.client.last_block_changes[0]
                    x, y, z = self.client.last_block_changes[0]
                    height = int(parts[3])
                    while z < (height + c):
                        for i in range(-radius-1, radius):
                            for j in range(-radius-1, radius):
                                for k in range(-radius-1, radius):
                                    if (i**2 + j**2 + k**2)**0.5 + .604 < radius and (i**2 + j**2 + k**2)**0.5 + .604 > radius-1.208:
                                        # Test for axis
                                        var_placeblock = 1
                                        if i != 0 and normalAxis == 'x':
                                            var_placeblock = 0
                                        if j != 0 and normalAxis == 'y':
                                            var_placeblock = 0
                                        if k != 0 and normalAxis == 'z':
                                            var_placeblock = 0
                                        if var_placeblock == 1:
                                            if not self.client.AllowedToBuild(x+i, y+j, z+k) and not overriderank:
                                                self.client.sendErrorMessage("You do not have permission to build here.")
                                                return
                                            try:
                                                world[x+i, y+j, z+k] = block
                                            except Assertionerror:
                                                self.client.sendErrorMessage("Out of bounds hcyl error.")
                                                return
                                            self.client.queueTask(TASK_BLOCKSET, (x+i, y+j, z+k, block), world=world)
                                            self.client.sendBlock(x+i, y+j, z+k, block)
                                            yield
                        z += 1
                block_iter = iter(generate_changes())
                def do_step():
                    # Do 10 blocks
                    try:
                        for x in range(10):
                            block_iter.next()
                        reactor.callLater(0.01, do_step)
                    except StopIteration:
                        if fromloc == "user":
                            self.client.sendServerMessage("Your hcyl just completed.")
                        pass
                do_step()
            else:
                self.client.sendErrorMessage("The axis must be x, y, or z!")



I've also made another ugly bit of code, but I can't seem to find it at the moment.

Oh, I'd like to try and fix this code up a bit, if someone doesn't mind helping :P.

Is This A Good Question/Topic? 0
  • +

Replies To: Python Hollow Cylinder command I made

#2 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7621
  • View blog
  • Posts: 12,849
  • Joined: 19-March 11

Re: Python Hollow Cylinder command I made

Posted 12 February 2013 - 09:07 AM

View Postblahblahbal, on 06 February 2013 - 01:08 AM, said:

Oh, I'd like to try and fix this code up a bit, if someone doesn't mind helping :P/>.


If you really want help on this, try posting in the python forum. This is mostly a novelty forum. Or, if you want to talk about refactoring more generally, software development would be the right forum.

That being said, you want to think about extracting repeated code to functions which you define once and use many times. Those functions should be small and single-purposed. (When I say "small", I mean under 20 lines - I'm usually looking at 10 or less). They should have names that make it obvious in use what they're doing. When you're working with these functions, you should prefer to pass state from function to function, rather than maintaining a global state. This makes your functions self-contained and it minimizes error.

One way to think of it is this: If I were to ask you what this program does, you should be able to tell me in broad strokes, in a few steps. Those broad steps should outline the functions you want. Each of those steps might have sub-steps, which you should break down in just the same way, until you get to things which are so small that they consist only of a few primitive operations: those are your functions.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1