v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

Difference between revisions of "User:Button/BAMM"

From Dwarf Fortress Wiki
Jump to navigation Jump to search
(→‎Button's Workspace: Came up with a solution for the GROWTH_PRINT $,$ vs $,& problem)
Line 19: Line 19:
 
Sometimes I'm on a computer I can't put a git client on.
 
Sometimes I'm on a computer I can't put a git client on.
  
<pre>class TreeNode():
+
<pre>
"""Parent class for the other Node classes.
+
_is_logging_initialized = False
 +
 
 +
# TODO Allow file to be passed in, or possibly even a dict?
 +
def load_run_config():
 +
"""Load config information from the default file.
 
 
Contains default implementations of common Tree functionality.
+
Also initializes loggers if they haven't been already.
 +
"""
 +
    print("Loading run configuration...")
 +
    global runconfig
 +
    runconfig_file = open(runconfig, 'r')
 +
    global properties
 +
    for line in runconfig_file:
 +
        uncommented = line.strip().split('#')[0]
 +
        props = uncommented.strip().split('=')
 +
        if len(props) == 0 or (len(props) == 1 and len(props[0]) == 0):
 +
            continue
 +
        elif len(props) != 2:
 +
            print('Line "', line, '" in ', runconfig,
 +
                  ' is improperly configured. Please format properties thus: \
 +
                  "propertyname=value" (without quotes).')
 +
        elif not _property_has_format_error(props[0], props[1]):
 +
            set_property(props[0], props[1])
 +
        else:
 +
            print ('Line "', line, '" in', runconfig,
 +
                  'is improperly configured. Please format properties thus: \
 +
                  "propertyname=value" (without quotes).')
 +
 
 +
    runconfig_file.close()
 +
 
 +
initialize_logging()
 +
userlog.info("**********")
 +
    modderslog.info("**********")
 +
    userlog.info("Run configuration loaded.")
 +
userlog.debug("Properties:")
 +
    for propname in properties.keys():
 +
        userlog.debug("Property %s:", propname)
 +
        for item in properties[propname]:
 +
            userlog.debug("\t%s", item)
 +
 
 +
 
 +
# TODO implement parameters with defaults (and update docstring)
 +
def initialize_logging()
 +
"""Initialize loggers config.userlog and config.modderslog
 
 
Members:
+
Will not double-initialize.
self._parent = the parent TreeNode of this TreeNode. Any given subclass of TreeNode should only have TreeNodes of its own type as _parent.
 
self._tag = The string that this node represents. This should be overridden and re-defined by subclasses.
 
self._children = A dict of type string:TreeNode, where the key is the child's ._tag property.
 
 
Functions:
 
self.__init__(self,parent=None)
 
 
"""
 
"""
 +
global _is_logging_initialized
 
 
    def __init__(self,parent=None):
+
if _is_logging_initialized:
"""Create a TreeNode.
+
return
+
else:
Sets self._parent to argument parent, initializes an empty dict for self._children, and sets self._tag = None.
+
_is_logging_initialized = True
"""
+
 
        self._parent = parent
+
    # Logging
        self._children = {}
+
    fmt = logging.Formatter('%(message)s')
        self._tag = None
+
 
        #if parent != None:
+
    userhandler = logging.FileHandler(properties[USERSLOG][1])
        #    parent.add_child(self)
+
    userhandler.setFormatter(fmt)
       
+
     userlog.addHandler(userhandler)
    def add_child(self, child_node):
 
"""Add a child to this TreeNode."""
 
        self._children[child_node._tag] = child_node
 
   
 
    def find_match(self, tag):
 
"""Find a TreeNode related to this TreeNode which has the given tag.
 
 
tag is a value corresponding to the ._tag field of TreeNode you're calling this on. REMEMBER: Different TreeNode subclasses have different formats of ._tags!
 
 
The return value is a TreeNode with the specified ._tag value, or None.
 
 
The TreeNodes searched are this node's immediate children, and its direct ancestors' immediate children.
 
"""
 
        curr_node = self
 
        matching_node = None
 
        out_of_parents = False
 
        while matching_node is None and not out_of_parents:
 
            #matching_node = curr_node.get_template_match(tag)[0]
 
            #if matching_node == None:
 
            matching_node = curr_node.get_child(tag)
 
            if curr_node._parent is None:
 
                out_of_parents = True
 
            else:
 
                curr_node = curr_node._parent
 
        return matching_node
 
      
 
    def get_child(self, tag):
 
"""Return an immediate child with the given tag, or None if no such child exists."""
 
        if tag in self._children.keys():
 
            return self._children[tag]
 
        else:
 
            return None
 
  
class TemplateNode(TreeNode):
+
    if properties[DEBUG][1]:
"""An implementation of TreeNode specialized for holding tag templates.
+
        userlog.setLevel(logging.DEBUG)
+
    else:
Members:
+
        userlog.setLevel(logging.INFO)
self._parent = the parent TemplateNode of this TemplateNode.
 
self._tag = the string representing a valid format of raw tag. Literals are themselves; colons separate tokens; $s indicate identifiers; ?s indicate graphics information; and &s indicate non-identifier, non-graphics information. For more fluidly-formatted tags, the following format indicates more than one tag:
 
x(#,#) , where the x is a $, ? or &, the #s are a min/max pair, and the max is optional. See templates.config
 
self._is_graphics_tag = The template config file is formatted in such a way that which tags are graphics tags is straightforward. This is a bool retaining that information. It is set to False by default, then later set to True where appropriate by the template loading function.
 
self._
 
"""</pre>
 
  
<pre>
+
    modderhandler = logging.FileHandler(properties[MODDERSLOG][1])
OBJECT:PLANT|PLANT:$|GROWTH:$|GROWTH_PRINT:?(5,5):$(2,2):&(0,1)
+
    modderhandler.setFormatter(fmt)
OBJECT:PLANT|PLANT:$|GROWTH:$|GROWTH_PRINT:?(5,5):ALL:&(0,1)
+
    modderslog.addHandler(modderhandler)
OBJECT:PLANT|PLANT:$|GROWTH:$|GROWTH_PRINT:?(5,5):NONE:&(0,1)
+
    modderslog.setLevel(logging.INFO)
  
def get_best_match(template_tokens_bag):
 
if not template_tokens_bag: # empty bag returns false
 
return None
 
elif len(template_tokens_bag) == 1:
 
return template_tokens_bag[0]
 
else:
 
best_currently = template_tokens_bag[0]
 
best_tokens = 0
 
for tag in template_tokens_bag:
 
challenger_tokens = 0
 
for token in tag:
 
if token != '?' and token != '&' and token != '$':
 
challenger_tokens = challenger-tokens + 1
 
if challenger_tokens > best_tokens:
 
best_currently = tag
 
best_tokens = challenger_tokens
 
return best_currently
 
  
 +
def _property_has_format_error(propkey, value):
 +
"""Returns True if the property is formatted incorrectly.
 +
 +
* propkey is the "name" of the property, and is expected to be one of the CONFIG.X module variables declared up above.
 +
* value is the value you wish to check for compatibility with the property in question.
 +
 +
Returns True if:
 +
 +
* The property key is not recognized
 +
* The property's type is IS_BOOL and the value is not 'True' or 'False
 +
* The property's type is IS_DIR and the value is an existing (non-directory) file
 +
* The property's type is IS_FILE and the value is an existing directory.
 +
 +
Otherwise, returns False.
 +
"""
 
</pre>
 
</pre>

Revision as of 22:19, 1 June 2015

About

Features

Planned Features

Usage Instructions

Download

You can download the script from GitHub.

Python 3

Configuration

Button's Workspace

Sometimes I'm on a computer I can't put a git client on.

_is_logging_initialized = False

# TODO Allow file to be passed in, or possibly even a dict?
def load_run_config():
	"""Load config information from the default file.
	
	Also initializes loggers if they haven't been already.
	"""
    print("Loading run configuration...")
    global runconfig
    runconfig_file = open(runconfig, 'r')
    global properties
    for line in runconfig_file:
        uncommented = line.strip().split('#')[0]
        props = uncommented.strip().split('=')
        if len(props) == 0 or (len(props) == 1 and len(props[0]) == 0):
            continue
        elif len(props) != 2:
            print('Line "', line, '" in ', runconfig,
                  ' is improperly configured. Please format properties thus: \
                  "propertyname=value" (without quotes).')
        elif not _property_has_format_error(props[0], props[1]):
            set_property(props[0], props[1])
        else:
            print ('Line "', line, '" in', runconfig,
                   'is improperly configured. Please format properties thus: \
                   "propertyname=value" (without quotes).')

    runconfig_file.close()

	initialize_logging()
	userlog.info("**********")
    modderslog.info("**********")
    userlog.info("Run configuration loaded.")
	userlog.debug("Properties:")
    for propname in properties.keys():
        userlog.debug("Property %s:", propname)
        for item in properties[propname]:
            userlog.debug("\t%s", item)


# TODO implement parameters with defaults (and update docstring)
def initialize_logging()
	"""Initialize loggers config.userlog and config.modderslog
	
	Will not double-initialize.
	"""
	global _is_logging_initialized
	
	if _is_logging_initialized:
		return
	else:
		_is_logging_initialized = True

    # Logging
    fmt = logging.Formatter('%(message)s')

    userhandler = logging.FileHandler(properties[USERSLOG][1])
    userhandler.setFormatter(fmt)
    userlog.addHandler(userhandler)

    if properties[DEBUG][1]:
        userlog.setLevel(logging.DEBUG)
    else:
        userlog.setLevel(logging.INFO)

    modderhandler = logging.FileHandler(properties[MODDERSLOG][1])
    modderhandler.setFormatter(fmt)
    modderslog.addHandler(modderhandler)
    modderslog.setLevel(logging.INFO)


def _property_has_format_error(propkey, value):
	"""Returns True if the property is formatted incorrectly.
	
	* propkey is the "name" of the property, and is expected to be one of the CONFIG.X module variables declared up above.
	* value is the value you wish to check for compatibility with the property in question.
	
	Returns True if:
	
	* The property key is not recognized
	* The property's type is IS_BOOL and the value is not 'True' or 'False
	* The property's type is IS_DIR and the value is an existing (non-directory) file
	* The property's type is IS_FILE and the value is an existing directory.
	
	Otherwise, returns False.
	"""