Nava2
2010-09-21 17:49:19
Well, as the title suggests:
SPyRL Python Resource Library
Firstly: Please note, this is a work in progress and I am working on it in my spare time, which is limited. I want your help and input!
Currently, the ideals I am aiming for are as follows:
I am posting this because I have made some progress from Wizzup's implementation of pyMML. The point of SPyRL is to be a higher level implementation than pyMML. It will be fully OOP, but with the intent for script writers to have a choice on whether to write their scripts in OOP or in linear style. I don't personally thing RuneScape scripts need OOP nature ;) but the library looks nice as OOP.
If you would like to contribute but do not know Python; I sincerely suggest checking out the Official Python Tutorial.
Here are some example files I have written thus far:
colour.py
CTS.py:
All of these files are attached as a .zip.
This is more or less a `lets get the gears going' kind of approach. I want input, help and anything else you can offer. I do not have the free time to do this, but I am willing to put what I can.
Due to the immature nature of pyMML, this is far from complete and needs some help with getting more methods exported.
Changes:
Cheers,
n2
SPyRL Python Resource Library
Firstly: Please note, this is a work in progress and I am working on it in my spare time, which is limited. I want your help and input!
Currently, the ideals I am aiming for are as follows:
- Flexible
- Open
- Fast
- Mutable (read: customizable)
- Heavily Documented
- This will be done using ReStructured Text and Sphinx. The same as the Simba Docs and the official python documentation.
- OOP-enabled, but not forced.
- Threading factories (no guarentees for this one..)
- Platform Independant
I am posting this because I have made some progress from Wizzup's implementation of pyMML. The point of SPyRL is to be a higher level implementation than pyMML. It will be fully OOP, but with the intent for script writers to have a choice on whether to write their scripts in OOP or in linear style. I don't personally thing RuneScape scripts need OOP nature ;) but the library looks nice as OOP.
If you would like to contribute but do not know Python; I sincerely suggest checking out the Official Python Tutorial.
Here are some example files I have written thus far:
colour.py
"""
Colour Class
------------
Set of classes and methods for finding colour objects. These are essentially
OOP wrappers for the linear style of pyMML.
"""
class Colour(object):
"""
Colour object is created to hold information and methods pertaining to
colour finding. Information stored is completely mutable.
"""
#The colour stored in the current instance.
value = None
#The :class:`CTS.CTS' to attempt to use before using the defaulted global
_cts = None
#The colour tolerance to search with.
_tol = 0
def __init__(self, col, **kwargs):
"""
Creates the colour object. Col is to be an integer or another
Colour object which can then be copied.
:param col: the colour to search for
:type col: int, None, or :class:`colour.Colour`
Valid Keyword Arguements:
:keyword cts: Specify a specific CTS object to be used, will use
global if left un specified.
:keyword tol: Specify a tolerance to search with. Can be set later.
"""
if col.__class__ == int:
self._value = col
elif col.__class__ == Colour:
self.__copy_Colour(col)
elif col != None:
raise TypeError('Invalid Type passed as \'col\' in Colour.__init__')
#check for keyword args passed.
if "cts" in kwargs:
if kwargs["cts"].__class__ == CTS.CTS:
self._cts = kwargs["cts"]
if "tol" in kwargs:
if kwargs["tol"].__class__ == int:
self._tol = kwargs["tol"]
def __copy_colour(self, colour):
"""
Copies *colour* into the current :class:`Colour.colour` into the
current object. The copy includes **all** methods and attributes.
:param :class:`Colour.colour` colour: The colour object to copy.
"""
if not colour.__class__ == Colour:
raise TypeError("Will not copy attributes from other class than \
colour.Colour.")
#clear all values initially
self.__dict__.clear()
#copy values from *colour* to *self*
for key,value in colour.__dict__.items():
self.__dict__[key] = value
def find(self, box, **kwargs):
#TODO add custom CTS support.
"""
Searches *box* for the first occurance of a colour supplied by the
stored information or parameters.
:param tuple box: Area to search in.
:keyword int tol: The immediate tolerance of the colour, if
unspecified will be the stored value.
:keyword bool spiral: Defaults to *false*, if true, will search in
a spiral pattern from another keyword arg *start_point*
:keyword tuple start_point: If keyword *spiral* is *true* then will
default to center of *box* if un-specified. Otherwise, will search
starting from location specified.
:returns tuple: First found occurance of the colour.
"""
tol = kwargs.get("tol", self._tol)
self._tol = tol
#TODO Add spiral support.
#use_spiral = kwargs.get('spiral', None)
#if use_spiral
#use the MMLColour Library to find the colours.
mmlcolor.Color.find(box, self.value, tol)
#TODO add CTS/spiral support
def find_all(self, box, **kwargs):
"""
Overridden method from :class:`interfaces.Finable`.
:param tuple box: Coordinate area to search in.
:keyword int tol: The immediate tolerance of the colour to search
for. If unspecified, will be a stored value.
"""
tol = kwargs.get("tol", self._tol)
self._tol = tol
#use MMLColour to find colours
mmlcolor.Color.findall(box, self.value, self._tol)
def to_RGB(self):
"""
Converts the stored colour into RGB values.
:return tuple: Returns a tuple containing (R,G,B)
"""
r = self.value & 0xff
g = self.value >> 8 & 0xff
b = self.value >> 16 & 0xff
return r,g,b
def to_hsl(self, fixed=false):
"""
Converts the stored colour into its HSL values.
:return tuple: Returns a tuple in the form of H,S,L.
"""
r,g,b = self.to_RGB()
r /= 255.0
g /= 255.0
b /= 255.0
cmin = min(r,g,b)
cmax = max(r,g,b)
L = 0.5 * (cmax+cmin)
if cmax == cmin:
H,S = 0.0,0.0
else:
D = cmax-cmin
if L < 0.5:
S = D/(cmax+cmin)
else:
S = D / (2 - cmax - cmin)
if r == cmax:
H = (g-b)/D
elif g == cmax:
H = 2 + (b-r)/D
else:
H = 4 + (r-g)/D
H /= 6
if H < 0:
H += 1
if fixed:
return H*100, S*100, L*100
else:
return H,S,L
def to_XYZ(self):
"""
Converts the stored colour to XYZ.
:returns tuple: Tuple in the form of X,Y,Z
"""
r,g,b = self.to_RGB()
r /= 255.0
g /= 255.0
b /= 255.0
if r > 0.04045:
r = ((r + 0.055) / 1.05 ) ** 2.4 * 100
else:
r /= 7.73994
if g > 0.04045:
g = ((g + 0.055) / 1.05 ) ** 2.4 * 100
else:
g /= 7.73994
if b > 0.04045:
b = ((b + 0.055) / 1.05 ) ** 2.4 * 100
else:
b /= 7.73994
X = r*0.4124 + g*0.3576 + b*0.1805
Y = r*0.2126 + g*0.7152 + b*0.0722
Z = r*0.0193 + g*0.1192 + b*0.9505
return X,Y,Z
def __add__(self, other):
"""
Adds two colours together, will return an :class:`int` if *int* is
passed, otherwise will return :class:`colour.Colour`. Will raise an
error if the type is not supported.
:type other: int or :class:`colour.Colour`
:returns: int or :class:`colour.Colour` dependant on
*other.__class__*
"""
if other.hasattr('__int__'):
return self.value + other
elif other.hasattr('value'):
return Colour(self.value + other.value)
else:
raise NotImplemented('Type {0} is not implemented.'.format( \
other.__class__))
def __sub__(self, other):
"""
Subtracts two colours together, will return an :class:`int` if
*int* is passed, otherwise will return :class:`colour.Colour`. Will
raise an error if the type is not supported.
:type other: int or :class:`colour.Colour`
:returns: int or :class:`colour.Colour` dependant on
*other.__class__*
"""
if other.hasattr('__int__'):
return self.value - other
elif other.hasattr('value'):
return Colour(self.value - other.value)
else:
raise NotImplemented('Type {0} is not implemented.'.format( \
other.__class__))
CTS.py:
class UnsupportedSpeed(Exception):
pass
#Default modifiers for each Colour Tolerance Speed.
_def_modifiers = [(),(),(0.2,0.2)]
class CTS(object):
"""CTS objects are used to store information for colour searches when using
the different colour tolerance speeds. One global CTS is maintained and
localized CTS objects can be created.
"""
## Current Speed Used
__speed = 0
## Current modifiers for the CTS object.
__mods = ()
def __init__(self, speed, modifiers=None, **kwargs):
"""Creates CTS objects. These maintain their information and are not to
be modified outside the objects internal methods.
:param int speed: The Colour Tolerance Speed to be stored and set.
:param tuple modifiers: The modifiers used in the varios CTS formulas.
"""
if not isinstance(speed, int):
raise TypeError('`speed\' must be of type int.')
if speed in (0,1,2):
__speed = speed
else:
raise UnsupportedSpeedError('Unsupported CTS passed as CTS.')
#check to make sure the modifiers correspond to the CTS.
if isinstance(modifiers, tuple) and __speed_mod_check(speed, modifiers):
__mods = modifiers
else:
__mods = _def_modifiers[__speed]
#TODO insert warning for kwargs not supported, yet passed.
def _speed_mod_check(self, speed, modlen):
if speed in (0,1):
return modlen == 0
elif speed == 2:
return modlen == 2
#TODO is this right..? :/
def set_modifiers(self, *mods):
"""Set the modifier list to contain the mods passed. Speeds is assumed
to be the current speed if no speed is specified."""
if _speed_mod_check(__speed, len(mods)):
__mods = mods
def get_modifiers(self):
"""Returns the modifiers used by this CTS.
:param int speed: The CTS speed to return modifiers to.
:returns tuple: A tuple containing the modifiers stored.
"""
return __mods
#TODO is this right..? :/
def set_speed(self, speed):
"""Sets a new CTS to the object.
:param int speed: The new CTS.
"""
if speed in range(0,2):
__speed = speed
__mods = _def_modifiers[speed]
#global CTS used in all colour functions if another is not specified.
#TODO Rename
current_CTS = CTS(0)
All of these files are attached as a .zip.
This is more or less a `lets get the gears going' kind of approach. I want input, help and anything else you can offer. I do not have the free time to do this, but I am willing to put what I can.
Due to the immature nature of pyMML, this is far from complete and needs some help with getting more methods exported.
Changes:
- Interfaces.py is no more, much better approach being used.
- Attachment is useless, don't download it. :<
Cheers,
n2