26 August, 2009

Ruby & Project Realisations

This isn't going to be a long post as it is rather late in the evening (morning) and not only am I trying to rest my leg (hyperextended my knee playing football (soccer for the Americans out there) on Monday evening), but I'm also in need of greater amounts of sleep having a four month old daughter for whom I am the primary care giver starting tomorrow given that my wife works in the academic world.

Short and to the point (for me at least) is that I'm delving back into Ruby (for the third time chronologically), but for the second time on a 'serious' level (i.e. with the intent to actually produce usable code and not simply proof-of-concept understanding code). I'm realising that while I love python which has been part of my daily work for the past five plus years, moreso Django/python in the past two, that it is becoming my 'Java/C#' if you will. By that I mean that it is my work language. It is a clean and elegant language which allows me to focus on getting what I wish completed, completed with minimal fuss and easy maintainability due to its explicit albeit brief and neatly aligned syntax. I feel though that something is missing.

If I can go back a little (and long time readers from previous versions of this blog circa 2002-2006 would remember me discussing this before) and bring up what eventually became my professional lingua of frustration: perl. Larry Wall's masterpiece which I utilised professionally from as far back as 1995 albeit I was working with rexx and pascal(!) more so then. I used perl and was attracted to it because of its expressive hacker roots, but was eventually disgusted by the lack of a decent enforceable object model for doing any kind of OOP work, not to mention maintainability was not its strong suit regardless of how meticulous one might be as a software engineer/coder, etc. This is what ultimately lead me to look at ruby but only briefly as it had residual taste of perl all over it. I found python shortly thereafter and have been happy ever since, until recently.
Sure I've looked and learned other languages in the meantime (as well as used them for personal and professional purposes), but just for the past three weeks or so I've realised that some of python's strong suit do indeed take some of the more guttural joy out of hacking out code. In my line of work I find formality and structure do wonders at getting solid code and meeting my clients' needs, which is the whole point. I'm at the point professionally where I don't get calls or emails saying that "something broke". It is much akin to Apple computers. Things just work without fail, as should be expected.

This ties into my other piece of the recent puzzle. I'm doing web framework design and implementation (amongst other custom software components) for primarily lifestyle, art and fashion magazines. It does pay the bills and it is at least involved with a creative branch of what can be a boring industry (publishing), though I find myself pining for more intellectually/scientific/theoretical research based projects/content. This isn't going to be happening anytime soon where I'm currently spending my efforts (professionally as it were). I have no design to stop doing what I'm doing and for whom I'm doing said work. I enjoy the relationship I have with my clients and there isn't anything wrong there. I'm being kept busy with new work so that's nothing about which to complain.

What I am looking to do is start working on some more experimental/theoretical designs and codebases/classes/packages in Ruby so that I can further explore the language and enjoy the more 'hack' mindedness which I find comes with such an expressive language. I will most definitely share my results with all the CodeDEVL readership (as well as podcast subscribers). I may even post a screen-cast soon as my copy of Snow Leopard for my Octo-Mac Pro (8-Core) should be here on Friday and includes new screen-cast capturing built-in to Quicktime X.

If anyone is in the Doylestown region of Pennsylvania and would like to meet up to talk code, please drop me a line. My email is simply 'eric' at this domain (assuming you're not reading this from the source blogger domain but the domain for which the header image at the top of the page states clearly.

I'll keep everyone informed. Until next time..

-Eric

Labels: , , , , , , ,

27 April, 2008

SimulaE - Model Update

I've made mention of my virtual world simulation project on multiple blog entries, most recently related to Ruby and making a rewrite of the existing engine in said language to test out its applicability (the language not the simulation), which by the way I found to be the lesser language for this kind of application, but I'm not saying anything about the language as a whole.  Either way, onto SimulaE, which after all is what this post is about today.

I have been rattling my brains (and occasionally those of my friends) regarding the basic SimulaE Object model, which up to this point has served its purpose.  Though the time has come for it to evolve.  It can implemented in a simpler manner and I have known this in my mind all along though it hasn't been an issue in the process of designing the parser which has for the most part been satisfactorily completed. Now that my focus has returned to the object model, I feel it a fine time to share that update thus far.  Comments are always welcome and most are appreciated.  

The fault before was that I broke the objects into the wrong sub classes.  Originally I had the parent Object class,  and subclasses for Room objects, Exist Objects and Person Objects.  This is a horrible idea and leads to unnecessary complexity.  

The newest model:

Object (super class)
MovableObject (isa Object)
PortalObject (isa Object, isnota MovableObject)

PortalObjects, hereafter POB are a much more dynamic version of the previous "room" objects.   A POB behaves in the following manner(s):

1. Object(s) enter into the object containing said portal.
2. Exits an object when contained therein.
3. Can exit (when specified) to a specific object, though by default exists to the parent container object.

If a MovableObject, hereafter MOB, is not contained within the same container as the POB, POB leads into the container.  
If the MOB is contained within the same container as the POB, POB leads out of the container.

By working in this manner, we ensure that the simulation object model more closely mimics the real world, whilst still allowing for exceptions to transpire for non-real world based applications of this group of models as well as anything they may be working on at CERN in Switzerland which breaks our current understanding of physics. 

I haven't had time to implement this new set of models yet, but as I write that code, I will be posting the revised Python source.

Labels: , , , , , ,

19 February, 2008

Ruby: Somehow I overlooked this Gem of a Language

About 5 years ago I started looking into a language that prior to it's "Rails" fame, was lesser known and even lesser utilised.  I tried it a bit and found it leaving me wanting more.  I've kept tabs on it over the years, reading the tutorials and writing several quasi-AI experimental applications for my SimulaE research, but I ended up being enticed by Python, a language which I stand by, including the wonderful (but until recently unused by me) framework Django (Python's Rail's equivalent, focused on Publishing).   

I've programmed professionally using Python for several contracts/years now and find it quite enjoyable.  In fact, I'm currently coding specifically in Python for Inkedmagonline.com, but that doesn't mean that I don't continue my personal exploration and education for both personal and professional reasons.  I decided to re-experience Ruby by picking up the hallowed PickAxe book and giving it another honest chance.  I'm glad I did.  

I believe that Python, and the values espoused in Tim Peter's "De Zen van Python" (The Zen of Python) (my copy just happens to be in Dutch, otherwise I'd post it for others) have helped me to look at Ruby in a different light.  There are some key differences in the two languages, but I can see now the inherent power in Ruby that I was overlooking before.  In fact, some of those key pieces, syntactically as they were which make Ruby so enticing this time around are the very same 'features' I feel are missing in Python.  It only took me working in an environment with situations where said language features would prove the best solution to the problem(s) on hand for me to realise it.

I am not going to spend time detailing all of the specifics, though I may mention one or two nonetheless.  I'm more so bringing this point up so that others might be reminded that giving something new a single chance might be to your own disadvantage.  After all, I didn't like Python the first time I tried it either.  I think it is partially a matter of how we grow as developers that allow us to know what we're missing, that same spark of realisation that gives us the "a ha" of relief when we find it hiding in a new language, programming methodology, etc.  
What brought me back to looking into Ruby a second time is of all things, Smalltalk.  The whole "everything is an object" concept is nothing new to me, or to programming languages.  However in dynamic strongly typed languages, it is.  More importantly is manner of how even rudimentary objects such as integers, floats and strings are treated in Ruby.  They have methods which can be both called using the standard instance.methodname call format, and have their standard methods overridden.  The second being something far more wonky and kludgy in Python (and a non-option in perl).  

The fact that key methods are instance based such as "len" or "length" for example makes a world of difference for consistency.  It speaks to the overall design that "Matz" (Yukihiro Matsumoto creator of Ruby) had in mind during the planning phase.  In Python, a language in which everything is truly an object as well, this starts to get rather confusing.  While Python does treat every integer and string as an object, it mixes the traditional functional paradigm for calling items such as 'len' so that to find the value of 'a', one would type len(a), as opposed to the more object based a.len ..  This seems counter-intuitive and quite frankly a real surprise when you look at the overall design of Python.

I'm not ripping on Python as I do wholeheartedly enjoy the language, I'm just starting to feel aches and pains over decisions which are ingrained into the language, as well as not being seen as an issue or being addressed in py3k (or Python 3000/Python v3.0) as it were.  I just think that my eyes have been opened to Ruby again and I like what I'm seeing.  I am actively looking to find a future professionally as it were utilising it as nothing beats having fun while accomplishing what one would hope accounts to 'great' things.  We'll see what the future holds.

Next Step:  Migrate my SimulaE virtual world/real model object simulation from Python into Ruby as a test run.  Lather, rinse, repeat and then see what the side-by-side comparison's look like.

Until next time...


Labels: , , , , , , , , , ,

05 February, 2008

The Importance of Being Challenged

In this most recent engineering, architecting and development endeavour which I simply refer to as my "job" or "contract", I have come to some conclusions which I feel require sharing.  I'll be very straightforward so as to not waste certain readers' time.  Many of the more seasoned lifetime coders will know (and have experienced many times over) that which I am writing about, which can be summed up as such:  If you are not being constantly challenged, you are atrophying as a developer.

I often write about my own experiences as I know them better than any single other developers experience(s).  This is not because I feel that I'm the end all be all of coders.  Far from it, I do feel that I'm good at what I do, however I prefer to look at my writings as a form of navel gazing, a self-reflective ascertaining how I can better grow in my art and profession.  It is exactly the same manner in which I'm going to proceed regarding today's message.

As I have mentioned, I have most recently jumped into a contract situation at the personal request of a rather successful life-long entrepreneur and given that the opportunity sounded rather interesting, I turned down a salaried position worth almost double because the challenge that was proposed.  Please don't get me wrong, I took a position fixing a half-assed php open-source hot or not style rating system because the employee responsible by no fault of his own necessarily, and due to a lack of a sense of urgency was unable to get a system such as that prescribed, in place by a contractual client deadline.  This was not the reason I took the contract, whilst simultaneously being precisely why I took the contract. 

I'm not a fan of php, and most definitely not a fan of a vast majority of already written php applications open source or otherwise.  What I am referring to more so is that I was brough into an environment where it wasn't the same old same old.  Now I wouldn't have stayed were the job going to continually require php specifically just out of my distaste of said language.   I did know that while I don't consider myself a web developer, I would be required on more than one occasion to work on web applications.  

These weren't to all be simple ones either, any moderately proficient web developer and non-web developer alike could figure a good many of these solutions out.   What really did it for me was that I would be required to not only work under a fairly frequent set of short deadlines due to the nature of the publishing industry as well as the time frame required to keep the site and features current.

The importance of all off these ramblings is this simple point.  Being experienced and disciplined as a Software Engineer/Developer/Architect, etc. ad nauseam helps me to know 'what' I need to do, and gives me insight as to how I might go about solving an issue.  It is however, the actual specifics which put those tidbits of understanding and knowledge into play which go outside a given comfort zone.  It is only then, when we find ourselves in unfamiliar territory, under threat of tight deadlines coupled with our own personal desires to do our best and produce code to which we are proud to associate our name.  

I know that earlier in my career there were times (albeit very few, which I can honestly say) that I too fell into this 'comfort zone'.  I found out though, that this comfort zone is boring and causes one to stagnate.  We code because we love it.  Coding and problem solving is in our blood, and in our hearts.  It is how we look at the world and as such isn't something from which we can remove ourselves.  

If you only know low-level languages, learn a high level language.  If you only work in functional programming paradigms, learn object or aspect oriented ones.  If you only work with interpreted languages, learn compiled langauges, etc.  I'm not saying give up your current lingua franca, I'm simply saying expand your horizons.  The more ways you have of looking at, describing and ultimately understanding a given problem, the more ways you have to solve said problem.  This doesn't solely benefit you, it benefits everyone for whom your code will be written and utilised. 

You knowledge needs to be a living, dynamic pool of information, not a static, never changing one and the way to ensure that is to aggressively fight off the status quo.  Be aggressive, absorb all that you can.  The best way to do this isn't by dipping your toes into the shallow end of the kiddie pool, it is accomplished by putting on your goggles and climbing that high dive, plunging in head first.  

Take a chance for once, you might just learn something.  

Till next time..

Labels: , , , , , , , , , , ,

10 July, 2007

Python's 'Pickle' Module

Recent changes to the SimulaeObject class have proven to be a big leap forwards in regards to flexible object manipulation for both testing and live environments.  The issue at hand was in regards to how to load and/or save object 'types' as it were.  Initial thoughts were to go with a simple configuration file which contained each and every object a la something akin to the httpd.conf file from Apache 1.3 (& 2.x?) for handling virtual hosts.  Then it dawned on me that this was a mistake which I personally made once before, and was almost about to fall victim to once more.  


The solution was sitting right in front of me all along, the standard library's 'pickle' module (or alternatively the 'cpickle' variation for speed's sake).  Due to the issues presented in a virtual world simulation the topic of object blueprints and simulation population ease come to mind rather quickly.  The best environment for manipulating these new objects will ultimately be via the methods provided by both the the SimulaE package (SimulaE.loadObject(filename_to_load, [optional_load_path]) as well as at the code level in the parent class in SimulaE.SimulaeObject.saveObject(filename_to_save_as, [optional_save_path]).


By going this route it has been realised that a simple loop and/or script-like routine could be used to create all the generic object templates needed for design platforms, and for customisation all one need do is use the loadObject routine, make the necessary alterations and re-save said item as a more concrete, concise and specialised object, named appropriately of course.  


Let us take an example of a room type object (more simply put, a larger container object).  We'll use simple constructor information here for the sake of staying on focus.  We're going to make a 4 metre x 5.5 metre dining room, with a 2.75 metre ceiling, simple called "Dining Room".  It will be empty sans an already pickled to storage butler object we've created for the sake of this example (whose filename is simply "butler_jeeves"), though future discussions on SimulaE's container and stack loading methods are forthcoming.


import SimulaE

generic_dr = SimulaE.SimulaeObject(name='Dining Room', width=4.0, length=5.5, height=2.75)

generic_butler = SimulaE.loadObject('butler_jeeves')

generic_dr.addToContents(generic_butler)

generic_dr.saveObject('diningroom4x5.5x2.75wButler')


We now have a pickled version of this generic dining room of the aforementioned dimensions, sporting its own copy of Jeeves the butler, saved to a physical file on whatever storage device we're set to utilise.  We can overwrite said object by simply saving the item with the filename as it exists on whatever storage device is in use.  There is also the flexibility of specifying alternative file save and load paths with allow for multiple parallel simulations and/or individuals to work in safe separate but equal spaces, very much along the lines of a Unix mentality.  Another advantage by working in this manner is being able to create a path full of simulation objects and copy said path en masse for alternative and/or backup purposes.


Either way you slice the pickle (module), it proves to be quite (ful)filling, making one feel quite (programmatically) satisfied.

Labels: , , , , ,

20 April, 2007

Simple Rapid Application Development in Python

I've always found it interesting reading about coding paradigms and what not, including ways in which a coder can increase his/her throughput. Meaning, how can I quickly pump out software that is easily portable, eloquently written, and easily maintainable by either myself and/or someone else one, two, six, eighteen months down the road? 


I've found out the answer to that question, in the form of a language, and it isn't Perl, Java, or Ruby. Simply put, it is Python by Guido van Rossum. The language that I loved to hate for so long due to what was perceived as a nasty control freak mentality regarding white space sensitivity, and the "lack" of freedom of being able to use {'s, ('s, ['s and ;'s anywhere I wanted. 


I've been using Python as mentioned previously in this blog for both large professional projects as well as certain other miscellaneous personal object-focused projects of mine and about two years ago when accepting a one-off project outside of my normal employment environment, I decided to try utilising my new favourite language for professional work. I must say that it was indeed a very simple program that I could've easily written in Perl, but no where as cleanly as in Python. The standard python libraries/classes included with every distribution (including as a stock install on my OS X 10.3 Panther equipped Apple Macintosh G3 iBook which I was using at the time) made it a clear choice (at least to attempt).


The premise of the program was amongst the most simplest of tasks. The client has a Microsoft Frontpage created website with a form. It currently points to no where because the individual doesn't know anything about capturing form data, so that's where I come in. All that is wanted is for all of the fields to be commingled into an e-mail to be fired off every time someone submits that form. He doesn't initially even want data format and/or content checking, but I inquired anyway (I'm not some code monkey who doesn't try to analyse what the non-coder *really* needs/wants/means). 


The code itself took a matter of about 15 minutes to write down, organise and test. The code is more than fifty-percent blank lines and/or comments. Using the standard smtplib and cgi libraries/classes, this turned out to be an absolute breeze. The advantage of easily stepping through the dictionary (hash) produced by the cgi.FieldStorage() method was a cinch thanks to the built-in cgi.has_key() and cgi.value() methods. 


While this is hardly an example of actual RAD, or any detailed work for a language such as Python, it does give a simple real world example of why I will continue to push for the use of this language. What I wrote worked the first time I wrote it, without any errors. I reads like pseudo-code and it was enjoyable to write because it flowed so easily from my mind into Python's very natural syntax. I used to espouse Perl for such things, but in comparison, I find it difficult to think that I held Perl in such regards for natural syntax. 


This doesn't mean that I'm a one language only person. Much of the application infrastructure I've produced at my current (and previous) employers' establishments I design and implemented in Perl on a multitude of Linux and/or FreeBSD boxes. This has changed as I've moved to a FreeBSD centric platform layout, with the intent of someday using Python as the shining star for any medium to large implementations, and let it share the small jobs with a mix of Perl and Bash scripts. 


I only wish I could get others to give Python a fair shot as it truly is one of those languages that deserve a second look, it may just changed your entire perspective on how you code. 

Labels: , , , , , , , , ,

04 April, 2007

Updating Existing Perl to 'use strict' Standards

     Now that a little over a week and a half has passed at my new place of employment, I find that I understand my new environment enough to make some observations in a not-too-specific manner out of respect for my new employer.


    First let me state that all of the existing software is a product of its environment and that it all functions as it was intended.  That being said I’m able to say with a clean conscience (after that little preamble) state that the code was ... lacking.  


    I am thankful for this to some degree.  For one thing it provided an opportunity for employment at a place I enjoy with some very intelligent individuals who all seem to have their own special abilities and areas of expertise.  


    More importantly though, I’m thankful because it places me in a situation I find most mentally stimulating.  It makes me re-think an entire existing architecture and being that I have held the role of Software Architect (amongst others) for much of my professional life, it is all the more appropriate. 


    It is one thing to walk into an new environment with a clean slate in which one may design to their heart’s content, yet another wholly different situation when the software exists in a production environment of one form or another.  There are so many more facets with which to deal when the database structure and all of the depending software is tightly build upon that aforementioned code base.  


    The whole point of this rambling is that my first week and a half has passed and while I have done much more with the database redesign, class design, object handlers, etc., I have finally been able to enjoy that great feeling which comes when turning previously un ‘strict’able perl code into a fully compliant piece of code.  I might also add that I ensured the code conformed within the guidelines of Damnian Conway’s “Perl Best Practices” book, which while a little different than my own manner of laying out perl code, is wonderful none the less.


    Now that this honeymoon is over, I can move onward and upward to greater code causes to champion, and based upon the intents of the owner of the company I don’t doubt that there will be a wonderful logic requiring plethora of future projects for which I am to contend.  I only hope that others out there are as lucky in their endeavours.

Labels: , , , , , , ,

28 June, 2006

Rethinking Real-World Object Models in Simulations

    Over the past quarter century I have routinely pondered back to the time of my childhood and early experiences with interactive fiction text-based adventure games.  Chances are that if you were involved with computers  at any point prior to the mid-eighties, you have experienced what I speak of.  If not, maybe you experienced multi-user dungeons (MUDs) in your college or bulletin board (BBS) years.


    In many cases these ‘games’ were written in the low level language du jour, such as ‘C’, or in a custom language like ‘Inform’ (in the case of Infocom games) which was also written in ‘C’.   There were languages which would’ve been better suited for these games/simulations, object oriented programming (OOP) languages such as Smalltalk, or Objective-C, but they were generally not utilised as such.  


    Recently in my workplace I have been developing full time (for the past couple of years) in Python, a wonderful high level language written by Guido van Rossum which is a proper OOP language.  As such, the idea of writing a simulation (not a ‘game’ per se) which would allow me to focus on not only how one would model the real world (to a certain depth), but as an exercise in python objects.  


    While the code is still an ongoing side work of mine, I am posting the parent class (SimObject) and it’s associated child classes (Place, Person and ExitObject) for review by those who are interested.  Please note that due to certain conflicts with word press, proper pythonic indentation (required for execution) is not established as such.  



#####################################################

#                            S  I  M  O  B  J  E  C  T       C   L   A   S   S                          #

#####################################################


class SimObject:

    object_master_list=[]

    def __init__(self,

                object_id = 0,

                object_sku = 0,

                short_description = 'Short Description',

                long_description = 'Long Description',

                name = 'Name',

                weight = 1.0,

                height = 1.0,

                width  = 1.0,

                depth  = 1.0,

                visible  = True,

                closed   = False,

                contents = [],

                stack    = []):

        self._object_id         = object_id

        self._object_sku        = object_sku

        self._short_description = short_description

        self._long_description  = long_description

        self._name              = name

        self._weight            = weight

        self._height            = height

        self._width             = width

        self._depth             = depth

        self._visible           = visible

        self._closed            = closed

        self._contents          = []

        self._stack             = []

        self.object_master_list.append(self)

        


    def getObjectById(self,object_id):

        for sim_objects in self.object_master_list:

            if sim_objects.getObjectId() == object_id:

                return sim_objects

                

    def addContents(self,item):

        try:

            self._contents.append(item)

            return True

        except:

            return False


    def addToStack(self,item):

        try:

            self._stack.append(item)

            return True

        except:

            return False

            

    def isVisible(self):

        return self._visible

        

    def getContents(self):

        return self._contents       


    def getShortDescription(self):

        return self._short_description


    def getLongDescription(self):

        return self._long_description


    def getSize(self):

        return "Object Details ... Weight: %.2f, Height: %.2f, Width: %.2f, Depth: %.2f" % (self._weight, self._height, self._width, self._depth)


    def getHeight(self):

        return self._height


    def getWeight(self):

        return self._weight


    def getName(self):

        return self._name


    def getObjectId(self):

        return self._object_id


    def getDescription(self):

        output = ''

        vowels = ['a','e','i','o','u']

        if isinstance(self,Place):

            short_desc = self.getShortDescription()

            output += short_desc + "\n"

            underline = ''

            for i in str(short_desc):

                underline += '-'

            output += underline + "\n"

            output += self.getLongDescription() + '\n'

            for thing in self.getContents():

                if isinstance(thing,ExitObject):

                    if thing.isVisible():

                        output += "There is "

                        if thing.getName()[0].lower() in vowels:

                            output += 'an '

                        else:

                            output += 'a '

                        output += thing.getName() + ' '

                        output += 'here.\n'

                    else:

                        ### Don't short exits if they are just cardinal directions (_visible=False)

                        pass


            itemlist = []

            peoplelist = []

            for thing in self.getContents():

                if isinstance(thing,SimObject) and not isinstance(thing,ExitObject) and not isinstance(thing,Person):

                    itemlist.append(thing.getName()) 

                elif isinstance(thing,Person):

                    peoplelist.append(thing.getName())

            if len(itemlist) == 1:

                output += "There is "

                if itemlist[0][0].lower() in vowels:

                    output += 'an '

                else:

                    output += 'a '

                output += itemlist[0] + ' '

                output += 'here.\n'

            if len(itemlist) >= 2:                                    

                total_items = len(itemlist)

                item_counter = 1

                output += "There are "

                for items in itemlist:

                    if items[0].lower() in vowels:

                        output += 'an '

                    else:

                        output += 'a '  

                    if item_counter <= total_items-2:

                        output += str(items)+', '

                    elif item_counter == total_items-1:

                        output += str(items)+' and '

                    else:

                        output += items + " "

                    item_counter += 1

                output += "here.\n"

                output += "\n"

            if len(peoplelist) == 1:

                output += str(peoplelist[0]) + " is here.\n" 

            elif len(peoplelist) > 1:

                item_counter = 1

                total_items = len(peoplelist)

                for items in peoplelist:

                    if item_counter <= total_items-2:

                        output += str(items) + ', '

                    elif item_counter == total_items-1:

                        output += str(items) + ' and '

                    else:

                        output += str(items)

                    item_counter += 1

                output += "are here.\n"  

        elif isinstance(self,Person):

            output += self.getName()

            output += "is standing before you!\n"

        elif isinstance(self,ExitObject):

            if self.isVisible():

                output += str(self.getShortDescription()) + '\n'

            else:

                output += "You see nothing out of the ordinary here.\n"

        else:

            output += "unsure of type!\n"

        output += "\n"

        return output

        

#####################################################

#                              P   L   A   C   E        C   L   A   S   S                                  #

#####################################################


class Place(SimObject):

    def __init__(self,

                object_id = 0,

                object_sku = 0,

                short_description = 'Short Description',

                long_description = 'Long Description',

                name = 'Name',

                weight = 1.0,

                height = 1.0,

                width  = 1.0,

                depth  = 1.0,

                visible = True,

                contents = []):

        SimObject.__init__(self,

                            object_id=object_id,

                            short_description = short_description,

                            long_description  = long_description,

                            name              = name,

                            weight            = weight,

                            height            = height,

                            width             = width,

                            depth             = depth,

                            visible           = visible,

                            object_sku        = object_sku,

                            contents          = [])



#####################################################

#                          P   E   R   S   O   N          C   L   A   S   S                              #

#####################################################


class Person(SimObject):

    def __init__(self,name="",object_id=0,object_sku=0):

        SimObject.__init__(self,name=name,object_id=object_id,object_sku=object_sku)

        self._hp   = 100

    def isAlive(self):

        if self._hp > 0:

            return True

        else:

            return False

    def getStats(self):

        print "%s has %i hit points remaining!" % (self._name,self._hp)

    def receiveHit(self,damage="0"):

        self._hp = self._hp - damage

        if self._hp <>

            self._hp = 0

    def attack(self,enemy):

        if type(enemy) == type(self):

            attempt_roll = randint(1,10)

            if attempt_roll > 5:

                enemy.receiveHit(attempt_roll)         

            else:

                print "Missed %s!" % str(enemy._name)

        else:

            print "Cannot attack %s" % str(enemy)

    def getSize(self):

        return "Person Details ... Weight: %.1f, Height: %.1f, Width: %.1f, Depth: %.1f" % (self._weight, self._height, self._width, self._depth)

    def move(self,destination):

        #### add test against dimensions.  person WxD must be greater than Exit HxW, and the smallest Person dimension much be

        #### smaller than the smallest Exit dimension

        destination_room = self.getObjectById(destination)

        destination_room.addContents(self)


#####################################################

#                                  E   X   I   T        C   L   A   S   S                                    #

#####################################################


class ExitObject(SimObject):

    def __init__(self,visible=False,name="ExitName",short_description='Exit',

long_description='an Exit',aliases=(), destination=0,object_id=0,object_sku=0, weight=1.0,width=1.0,height=1.0,depth=1.0,closed=False):

        """Aliases are lists of names by which this exit can be referenced"""

        SimObject.__init__(self,visible=visible,name=name,short_description= 

short_description, long_description=long_description,object_id=object_id,

object_sku=object_sku, weight=weight,width=width,height=height,depth=depth,

closed=closed)

        self._aliases = aliases

        self._destination = destination

    def getDestination(self):

        return self._destination

    def getAliases(self):

        return self._aliases

Labels: , , , , , , , , ,