Browse Source

chore: Python3 support + Abandonned Python2 support

master
Michaël Costa 9 months ago
parent
commit
3dafe11f43
30 changed files with 769 additions and 2869 deletions
  1. +8
    -0
      .editorconfig
  2. +6
    -0
      .flake8
  3. +13
    -0
      .gitignore
  4. +571
    -0
      .pylintrc
  5. +9
    -61
      README.md
  6. +21
    -28
      ant.py
  7. +10
    -13
      ants.py
  8. +29
    -37
      config.py
  9. +34
    -35
      display.py
  10. +0
    -250
      doc/ant.html
  11. +0
    -243
      doc/ant.txt
  12. +0
    -59
      doc/ants.html
  13. +0
    -30
      doc/ants.txt
  14. +0
    -79
      doc/config.html
  15. +0
    -58
      doc/config.txt
  16. +0
    -360
      doc/display.html
  17. +0
    -339
      doc/display.txt
  18. +0
    -205
      doc/farm.html
  19. +0
    -180
      doc/farm.txt
  20. +0
    -105
      doc/mine.html
  21. +0
    -74
      doc/mine.txt
  22. +0
    -241
      doc/playground.html
  23. +0
    -220
      doc/playground.txt
  24. +0
    -68
      doc/utils.html
  25. +0
    -48
      doc/utils.txt
  26. +14
    -18
      farm.py
  27. +0
    -53
      gendoc.sh
  28. +14
    -18
      mine.py
  29. +15
    -21
      playground.py
  30. +25
    -26
      utils.py

+ 8
- 0
.editorconfig View File

@ -0,0 +1,8 @@
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

+ 6
- 0
.flake8 View File

@ -0,0 +1,6 @@
[flake8]
ignore = E111,I001,I004,I003,E265,E114,E501,I005
exclude = .git,__pycache__
max-line-length = 160
use-flake8-tabs = true
tab-width = 2

+ 13
- 0
.gitignore View File

@ -0,0 +1,13 @@
*un~
*.swp
*.pyc
*/__pycache__
build/
dist/
infra.egg-info/
python_infra.egg-info/
test.py
populate_dir.py
.vscode/
venv/
.idea

+ 571
- 0
.pylintrc View File

@ -0,0 +1,571 @@
[MASTER]
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code.
extension-pkg-whitelist=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
# number of processors available to use.
jobs=1
# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
# complex, nested conditions.
limit-inference-results=100
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Pickle collected data for later comparisons.
persistent=yes
# Specify a configuration file.
#rcfile=
# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
confidence=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once). You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use "--disable=all --enable=classes
# --disable=W".
disable=print-statement,
parameter-unpacking,
unpacking-in-except,
old-raise-syntax,
backtick,
long-suffix,
old-ne-operator,
old-octal-literal,
import-star-module-level,
non-ascii-bytes-literal,
raw-checker-failed,
bad-inline-option,
locally-disabled,
file-ignored,
suppressed-message,
useless-suppression,
deprecated-pragma,
use-symbolic-message-instead,
apply-builtin,
basestring-builtin,
buffer-builtin,
cmp-builtin,
coerce-builtin,
execfile-builtin,
file-builtin,
long-builtin,
raw_input-builtin,
reduce-builtin,
standarderror-builtin,
unicode-builtin,
xrange-builtin,
coerce-method,
delslice-method,
getslice-method,
setslice-method,
no-absolute-import,
old-division,
dict-iter-method,
dict-view-method,
next-method-called,
metaclass-assignment,
indexing-exception,
raising-string,
reload-builtin,
oct-method,
hex-method,
nonzero-method,
cmp-method,
input-builtin,
round-builtin,
intern-builtin,
unichr-builtin,
map-builtin-not-iterating,
zip-builtin-not-iterating,
range-builtin-not-iterating,
filter-builtin-not-iterating,
using-cmp-argument,
eq-without-hash,
div-method,
idiv-method,
rdiv-method,
exception-message-attribute,
invalid-str-codec,
sys-max-int,
bad-python3-import,
deprecated-string-function,
deprecated-str-translate-call,
deprecated-itertools-function,
deprecated-types-field,
next-method-defined,
dict-items-not-iterating,
dict-keys-not-iterating,
dict-values-not-iterating,
deprecated-operator-function,
deprecated-urllib-function,
xreadlines-attribute,
deprecated-sys-function,
exception-escape,
comprehension-escape
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
enable=c-extension-no-member
[REPORTS]
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details.
#msg-template=
# Set the output format. Available formats are text, parseable, colorized, json
# and msvs (visual studio). You can also give a reporter class, e.g.
# mypackage.mymodule.MyReporterClass.
output-format=text
# Tells whether to display a full report or only the messages.
reports=no
# Activate the evaluation score.
score=yes
[REFACTORING]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
# Complete name of functions that never returns. When checking for
# inconsistent-return-statements if a never returning function is called then
# it will be considered as an explicit return statement and no message will be
# printed.
never-returning-functions=sys.exit
[SIMILARITIES]
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
# Minimum lines number of a similarity.
min-similarity-lines=4
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,
XXX,
TODO
[SPELLING]
# Limits count of emitted suggestions for spelling mistakes.
max-spelling-suggestions=4
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package..
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[STRING]
# This flag controls whether the implicit-str-concat-in-sequence should
# generate a warning on implicit string concatenation in sequences defined over
# several lines.
check-str-concat-over-line-jumps=no
[LOGGING]
# Format style used to check logging format string. `old` means using %
# formatting, while `new` is for `{}` formatting.
logging-format-style=old
# Logging modules to check that the string format arguments are in logging
# function parameter format.
logging-modules=
[BASIC]
# Naming style matching correct argument names.
argument-naming-style=snake_case
# Regular expression matching correct argument names. Overrides argument-
# naming-style.
#argument-rgx=
# Naming style matching correct attribute names.
attr-naming-style=snake_case
# Regular expression matching correct attribute names. Overrides attr-naming-
# style.
#attr-rgx=
# Bad variable names which should always be refused, separated by a comma.
bad-names=foo,
bar,
baz,
toto,
tutu,
tata
# Naming style matching correct class attribute names.
class-attribute-naming-style=any
# Regular expression matching correct class attribute names. Overrides class-
# attribute-naming-style.
#class-attribute-rgx=
# Naming style matching correct class names.
class-naming-style=PascalCase
# Regular expression matching correct class names. Overrides class-naming-
# style.
#class-rgx=
# Naming style matching correct constant names.
const-naming-style=UPPER_CASE
# Regular expression matching correct constant names. Overrides const-naming-
# style.
#const-rgx=
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming style matching correct function names.
function-naming-style=snake_case
# Regular expression matching correct function names. Overrides function-
# naming-style.
#function-rgx=
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
e,
Run,
_
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
# Naming style matching correct inline iteration names.
inlinevar-naming-style=any
# Regular expression matching correct inline iteration names. Overrides
# inlinevar-naming-style.
#inlinevar-rgx=
# Naming style matching correct method names.
method-naming-style=snake_case
# Regular expression matching correct method names. Overrides method-naming-
# style.
#method-rgx=
# Naming style matching correct module names.
module-naming-style=snake_case
# Regular expression matching correct module names. Overrides module-naming-
# style.
#module-rgx=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
# These decorators are taken in consideration only for invalid-name.
property-classes=abc.abstractproperty
# Naming style matching correct variable names.
variable-naming-style=snake_case
# Regular expression matching correct variable names. Overrides variable-
# naming-style.
#variable-rgx=
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# Tells whether to warn about missing members when the owner of the attribute
# is inferred to be None.
ignore-none=yes
# This flag controls whether pylint should warn about no-member and similar
# checks whenever an opaque object is returned when inferring. The inference
# can return multiple potential results while evaluating a Python object, but
# some branches might not be evaluated, which results in partial inference. In
# that case, it might be useful to still emit no-member and other checks for
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
missing-member-hint=yes
# The minimum edit distance a name should have in order to be considered a
# similar match for a missing member name.
missing-member-hint-distance=1
# The total number of similar names that should be taken in consideration when
# showing a hint for a missing member.
missing-member-max-choices=1
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid defining new builtins when possible.
additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,
_cb
# A regular expression matching the name of dummy variables (i.e. expected to
# not be used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored. Default to name
# with leading underscore.
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=2
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=200
# Maximum number of lines in a module.
max-module-lines=1000
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,
dict-separator
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[DESIGN]
# Maximum number of arguments for function / method.
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in an if statement.
max-bool-expr=5
# Maximum number of branch for function / method body.
max-branches=12
# Maximum number of locals for function / method body.
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of return / yield for function / method body.
max-returns=6
# Maximum number of statements in function / method body.
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[IMPORTS]
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Deprecated modules which should not be used, separated by a comma.
deprecated-modules=optparse,tkinter.tix
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled).
ext-import-graph=
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled).
import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled).
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,
_fields,
_replace,
_source,
_make
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=cls
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "BaseException, Exception".
overgeneral-exceptions=BaseException,
Exception

+ 9
- 61
README.md View File

@ -7,43 +7,13 @@
## Disclaimer
This module is intended to run as a python 2.7 module and is provided AS IS under the WTFPL (See LICENSE.TXT).
This module is intended to run as a python3 module and is provided AS IS under the WTFPL (See LICENSE.TXT).
This module has been tested on Linux and OpenBSD systems **ONLY**.
However it uses python 2.7 standard modules only and it may run on Windows or MacOS.
Your mileage may vary.
## Content
* ./README.md
* ./LICENSE.TXT
* ./gendoc.sh
* ./screenshot.png
* ./ants.py
* ./ant.py
* ./config.py
* ./display.py
* ./farm.py
* ./mine.py
* ./playground.py
* ./utils.py
* ./doc/ant.html
* ./doc/ant.txt
* ./doc/config.html
* ./doc/config.txt
* ./doc/display.html
* ./doc/display.txt
* ./doc/farm.html
* ./doc/farm.txt
* ./doc/mine.html
* ./doc/mine.txt
* ./doc/playground.html
* ./doc/playground.txt
* ./doc/utils.html
* ./doc/utils.txt
However it uses python3 standard modules only and it may run on Windows or MacOS.
Your Mileage May Vary.
## Goal
@ -55,28 +25,6 @@ It also provides a way to understand python multi-thread programming and inter-p
This project is **NOT** science, it's **CAB**.
## API and documentation
The documentation can be generated by running the **gendoc.sh** shell script from within the module directory:
```
$ gendoc.sh
Generating documentation:
[+] ./playground.py
[+] ./config.py
[+] ./farm.py
[+] ./mine.py
[+] ./ant.py
[+] ./ants.py
[+] ./display.py
[+] ./utils.py
```
The **gendoc.sh** script SHOULD be used as a Git pre-commit hook.
For all details on objects and there method and attributes, see all files in the **/doc** directory.
## TODO
* ~~A convenient way to close the application and all its threads (See 'Run the application') !~~
@ -102,15 +50,16 @@ $ git clone https://github.com/doug-letough/ants.git ants
## Configuration
You'll find a bunch of parameters to play with in the application configuration file **config.py**.
You'll find a bunch of parameters to play with in the application configuration file `config.py`.
Default values will do fine.
## Run the Ants application
Run the following commands
```
```bash
$ cd ants
$ python -m ants
```
@ -121,11 +70,10 @@ Closing the main window SHOULD exit the application.
In case the application does not quit properly, run the following command to ensure that all remaining processes are killed:
```
```bash
$ kill -15 $(ps aux | grep "python -m ants" | grep -v grep | awk -F ' ' '{print $2}')
```
## Logging
This application logs many things to stderr.
@ -141,4 +89,4 @@ This will still display the log to stderr and log this output to the ants.log fi
## Uninstall
Simply remove the module directory.
Simply remove the module directory.

+ 21
- 28
ant.py View File

@ -1,30 +1,27 @@
#!/usr/bin/env python
# -*- coding:Utf-8 -*-
"""Provides the Ant class for the ants module.
"""
import config
import uuid
import threading
import multiprocessing
import random
import time
import logging
import utils
__author__ = "Doug Le Tough"
__copyright__ = "Copyright 2017, Doug Le Tough"
__credits__ = ["Doug Le Tough",]
__author__ = "Michaël Costa"
__copyright__ = "Copyright 2017, Michaël Costa"
__credits__ = ["Michaël Costa"]
__license__ = "WTFPL"
__version__ = "1.0.0"
__maintainer__ = "Doug Le Tough"
__email__ = "doug.letough@free.fr"
__version__ = "2.0.0"
__maintainer__ = "Michaël Costa"
__email__ = "michael.costa@mcos.nc"
__status__ = "Testing"
###################################################################################################################
# Ant
###################################################################################################################
# -- -------------------------------------------------------------------------------------------------------------------
# -- Ant
# -- -------------------------------------------------------------------------------------------------------------------
class Ant(threading.Thread):
""" The Ant object is a self living virtual creature that tries to simulate
@ -71,8 +68,7 @@ class Ant(threading.Thread):
'new_position': self.new_position,
'radius': config.ANT_RADIUS,
'color': self.color,
'outline': self.outline_color
}
'outline': self.outline_color}
def display(self, new=False):
""" Send Ant dict representation to Display """
@ -95,7 +91,7 @@ class Ant(threading.Thread):
def walk(self):
""" Set a new position.
If Ant already has a path to go, then the next position is picked up from this path.
Otherwise, a new position is randomly picked up.
Otherwise, a new position is randomly picked up.
"""
if self.is_busy():
self.new_position = self.pop_new_position()
@ -103,7 +99,7 @@ class Ant(threading.Thread):
self.new_position = self.set_new_position()
self.display()
self.position = self.new_position
def set_new_position(self):
""" Set a new position from the actual position.
A new position is randomly generated by adding -1, 0 or 1 to one of
@ -179,18 +175,18 @@ class Ant(threading.Thread):
Depending on the status of each the concerned Ants, some data are exchanged.
An Ant can not hail a dead Ant.
"""
todo = "\033[92mHail:\033[0m %s " % ant.ID
todo = "Hail: {}".format(ant.ID)
ant.wait()
# Fucking Hack: Compare a string representation of multiple boolean conditions
history_table = ['00110', '00011', '00001']
togo_table =['10111', '10010', '00111', '00010']
togo_table = ['10111', '10010', '00111', '00010']
truth = '%d%d%d%d%d' % (self.near_mine(), self.is_busy(), self.has_food(), ant.is_busy(), ant.has_food())
if truth in history_table:
todo += "033[92mUpdated:\033[0m Togo"
todo += "Updated: Togo"
self.togo = [ant.position] + list(reversed(ant.history))
self.pause(config.ANT_PAUSE_DELAY)
elif truth in togo_table:
todo += "033[92mUpdated:\033[0m History"
todo += "Updated: History"
self.togo = [ant.position] + ant.togo[:]
self.pause(config.ANT_PAUSE_DELAY)
# /Fucking hack
@ -200,7 +196,6 @@ class Ant(threading.Thread):
def store(self, farm):
""" Stores the carried food to the given farm. """
if farm.ID == self.farm_id and self.food > 0:
food = self.food
farm.store(self.food, self.ID)
self.food = 0
self.swap_histories()
@ -227,7 +222,6 @@ class Ant(threading.Thread):
The partial or complete path to home is in its history so the history is reverted then given has a path to go.
Once the path to go is set, the actual history is wiped out.
Same process occurs when an Ant comes back to home with food, so it can go back to the Mine.
"""
self.togo = list(reversed(self.history))
self.history = [self.position]
@ -267,12 +261,12 @@ class Ant(threading.Thread):
def wait(self):
""" Wait until restart() is called."""
logging.warning('\033[92mStatus:\033[0m Waiting', extra=self.data)
logging.warning("Status: Waiting", extra=self.data)
self.waiting = True
def restart(self):
""" Restart after wait() """
logging.warning('\033[92mStatus:\033[0m Restarted', extra=self.data)
logging.warning("Status: Restarted", extra=self.data)
self.waiting = False
def pause(self, delay):
@ -287,7 +281,6 @@ class Ant(threading.Thread):
def run(self):
""" The Ant thread main loop """
while self.is_alive():
if not self.waiting:
self.check_around()
@ -299,10 +292,10 @@ class Ant(threading.Thread):
if not self.is_alive() and self.food > 0:
self.food -= 1
self.life += int(config.ANT_MAX_LIFE / 3)
logging.warning('\033[92mPosition:\033[0m %s, \033[92mLife:\033[0m %d, \033[92mFood:\033[0m %d, \033[92mBusy:\033[0m %s, \033[92mHistory:\033[0m %d' % (str(self.position), self.life, self.food, self.is_busy(), len(self.history)), extra=self.data)
logging.warning("Position: {}, Life: {}, Food: {}, Busy: {}, History: {}".format(self.position, self.life, self.food, self.is_busy(), len(self.history)), extra=self.data)
else:
time.sleep(config.ANT_HAIL_WAIT_DELAY)
time.sleep(config.ANT_TURN_SLEEP_DELAY)
self.outline_color = config.ANT_DEAD_OUTLINE_COLOR
self.display_q.put(self.to_dict())
logging.warning('\033[91mDied at:\033[0m %s, \033[95mHistory:\033[0m %d' % (str(self.position), len(self.history)), extra=self.data)
logging.warning("Died at: {}, History: {}".format(self.position, len(self.history)), extra=self.data)

+ 10
- 13
ants.py View File

@ -5,27 +5,24 @@
"""
import config
import ant
import farm
import mine
import playground
import display
import logging
import random
import utils
__author__ = "Doug Le Tough"
__copyright__ = "Copyright 2017, Doug Le Tough"
__credits__ = ["Doug Le Tough",]
__author__ = "Michaël Costa"
__copyright__ = "Copyright 2017, Michaël Costa"
__credits__ = ["Michaël Costa"]
__license__ = "WTFPL"
__version__ = "1.0.0"
__maintainer__ = "Doug Le Tough"
__email__ = "doug.letough@free.fr"
__maintainer__ = "Michaël Costa"
__email__ = "michael.costa@mcos.nc"
__status__ = "Testing"
###################################################################################################################
# App
###################################################################################################################
# -- -------------------------------------------------------------------------------------------------------------------
# -- App
# -- -------------------------------------------------------------------------------------------------------------------
if __name__ == '__main__':
# The display


+ 29
- 37
config.py View File

@ -1,39 +1,33 @@
#!/usr/bin/env python
# -*- coding:Utf-8 -*-
"""Provides basic configuration for the Ants application.
"""
import logging
__author__ = "Doug Le Tough"
__copyright__ = "Copyright 2017, Doug Le Tough"
__credits__ = ["Doug Le Tough",]
__author__ = "Michaël Costa"
__copyright__ = "Copyright 2017, Michaël Costa"
__credits__ = ["Michaël Costa"]
__license__ = "WTFPL"
__version__ = "1.0.0"
__maintainer__ = "Doug Le Tough"
__email__ = "doug.letough@free.fr"
__version__ = "2.0.0"
__maintainer__ = "Michaël Costa"
__email__ = "michael.costa@mcos.nc"
__status__ = "Testing"
###################################################################################################################
# CONFIG
###################################################################################################################
# -----------------------------------------------------------------------------------------------------------------
# LOGGING
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- Logging
# -- -------------------------------------------------------------------------------------------------------------------
# Logging string format
FORMAT = '%(asctime)-15s: \033[95m%(type)-10s:\033[0m %(message)s'
logging.basicConfig(format=FORMAT)
# -----------------------------------------------------------------------------------------------------------------
# GUI
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- GUI
# -- -------------------------------------------------------------------------------------------------------------------
WINDOW_TITLE = 'Ants: A Computer Assisted Bullshit for random based life form research'
# -----------------------------------------------------------------------------------------------------------------
# ANT
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- Ant
# -- -------------------------------------------------------------------------------------------------------------------
# Ant radius (Don't touch this)
ANT_RADIUS = 1
# Max number of moves for an ant
@ -63,24 +57,22 @@ ANT_TURN_SLEEP_DELAY = 0.2
ANT_HAIL_WAIT_DELAY = 0.5
# -----------------------------------------------------------------------------------------------------------------
# PLAYGROUND
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- Playground
# -- -------------------------------------------------------------------------------------------------------------------
# Playground dimension
PLAYGROUND_SIZE = (200, 200)
# -----------------------------------------------------------------------------------------------------------------
# DISPLAY
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- Display
# -- -------------------------------------------------------------------------------------------------------------------
DISPLAY_ANT_BY_WORKERS = 4
# -----------------------------------------------------------------------------------------------------------------
# FARM
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- Farm
# -- -------------------------------------------------------------------------------------------------------------------
# Farm poistion
FARM_POS = (PLAYGROUND_SIZE[0]/2 , PLAYGROUND_SIZE[0]/2)
FARM_POS = (PLAYGROUND_SIZE[0] / 2, PLAYGROUND_SIZE[0] / 2)
# How many ants by minute a farm can pop an ant
# MUST be <= 60
FARM_GROWTH_RATE = 60
@ -88,16 +80,16 @@ FARM_GROWTH_RATE = 60
FARM_SURVIVAL_TIMEOUT = 10
# Radius of a farm
FARM_RADIUS = 10
# Food stock of newly created farm
# Food stock of newly created farm
FARM_INITIAL_FOOD_STOCK = 50
# Farm body color
FARM_COLOR = '#4B1BB4'
# Farm outline color
FARM_OUTLINE_COLOR = '#FFFFFF'
# -----------------------------------------------------------------------------------------------------------------
# Mine
# -----------------------------------------------------------------------------------------------------------------
# -- -------------------------------------------------------------------------------------------------------------------
# -- Mine
# -- -------------------------------------------------------------------------------------------------------------------
# Radius of a mine
MINE_RADIUS = 10
# Mine body color


+ 34
- 35
display.py View File

@ -1,6 +1,3 @@
#!/usr/bin/env python
# -*- coding:Utf-8 -*-
"""Provides Worker and Display classes.
NumberList holds a sequence of numbers, and defines several statistical
@ -8,27 +5,25 @@ operations (mean, stdev, etc.) FrequencyDistribution holds a mapping from
items (not necessarily numbers) to counts, and defines operations such as
Shannon entropy and frequency normalization.
"""
import sys
import queue
import config
from Tkinter import *
import Queue
from tkinter import *
import threading
import logging
import time
__author__ = "Doug Le Tough"
__copyright__ = "Copyright 2017, Doug Le Tough"
__credits__ = ["Doug Le Tough",]
__author__ = "Michaël Costa"
__copyright__ = "Copyright 2017, Michaël Costa"
__credits__ = ["Michaël Costa"]
__license__ = "WTFPL"
__version__ = "1.0.0"
__maintainer__ = "Doug Le Tough"
__email__ = "doug.letough@free.fr"
__version__ = "2.0.0"
__maintainer__ = "Michaël Costa"
__email__ = "michael.costa@mcos.nc"
__status__ = "Testing"
###################################################################################################################
# Display
###################################################################################################################
# -- -------------------------------------------------------------------------------------------------------------------
# -- Display
# -- -------------------------------------------------------------------------------------------------------------------
class Worker(threading.Thread):
@ -55,14 +50,14 @@ class Worker(threading.Thread):
The Worker thread main loop:
- Get data from queue and give it to the process method
"""
logging.warning('\033[93mReport status:\033[0m \033[92mActive:\033[0m %s' % self.active, extra=self.data)
logging.warning("Report status: Active {}".format(self.active), extra=self.data)
while self.active:
try:
item = self.queue.get(False)
self.process(item)
except Queue.Empty:
except queue.Empty:
pass
logging.warning('\033[93mReport status:\033[0m \033[92mActive:\033[0m %s' % self.active, extra=self.data)
logging.warning("Report status: Active {}".format(self.active), extra=self.data)
def process(self, item):
"""
@ -86,6 +81,7 @@ class Worker(threading.Thread):
"""
self.active = False
class Display(object):
"""
The Display object is the main interface to TKInter display.
@ -106,8 +102,8 @@ class Display(object):
"""
# The display queue. Workers will write to it.
self.data = {'type': 'Display'}
self.display_q = Queue.Queue()
self.response_q = Queue.Queue()
self.display_q = queue.Queue()
self.response_q = queue.Queue()
self.width, self.height = size
# The main Tk window
self.master = Tk()
@ -135,7 +131,7 @@ class Display(object):
def build_gui(self):
""" Build the GUI with widgets from Tkinter module """
self.canvas_frame = LabelFrame(self.master, width=self.width+10, height=self.height+10, text='Ants')
self.canvas_frame = LabelFrame(self.master, width=self.width + 10, height=self.height + 10, text='Ants')
self.canvas = Canvas(self.canvas_frame, width=self.width, height=self.height, background='black', relief=SUNKEN)
self.num_ants_entry = Entry(self.canvas_frame, justify=RIGHT, width=10, textvariable=self.sv_num_ants)
self.num_ants_label = Label(self.canvas_frame, justify=LEFT, text='Number of ants')
@ -148,7 +144,6 @@ class Display(object):
"""
Draw an non existent ant according to data received.
If ant already exists, the ant is moved to new_pos coordinates.
ID: The ant ID
old_pos: The previous position of this ant
new_pos: The new position where this ant must be displayed
@ -158,7 +153,7 @@ class Display(object):
"""
try:
if len(self.canvas.find_withtag(ID)) > 0:
# Ant already exists so we compute the new_pos/old_pos offset
# Ant already exists so we compute the new_pos/old_pos offset
x_offset = new_pos[0] - old_pos[0]
y_offset = new_pos[1] - old_pos[1]
self.canvas.itemconfig(ID, fill=color, outline=outline)
@ -167,7 +162,13 @@ class Display(object):
# Ant is new
self.num_ants += 1
self.sv_num_ants.set(str(self.num_ants))
self.canvas.create_oval(new_pos[0] - radius, new_pos[1] - radius , new_pos[0] + radius , new_pos[1] + radius, tags=ID, fill=color, outline=outline)
self.canvas.create_oval(new_pos[0] - radius,
new_pos[1] - radius,
new_pos[0] + radius,
new_pos[1] + radius,
tags=ID,
fill=color,
outline=outline)
# Put the ant up in the higher layer
self.canvas.tag_raise(ID)
# create a new worker if needed
@ -176,13 +177,12 @@ class Display(object):
self.workers[len(self.workers) - 1].start()
self.update_gui()
except Exception as e:
logging.warning('\033[91mError:\033[0m %s' % str(e), extra=self.data)
logging.error("Error: [{}] {}".format(e.__class__.__name__, str(e)), extra=self.data)
exit(0)
def draw_mine(self, ID, pos, radius, color, outline):
"""
Draw an non existent mine according to data received.
ID: The mine ID
pos: The position of this mine
radius: The mine radius (see config.MINE_RADIUS)
@ -193,7 +193,7 @@ class Display(object):
uy = pos[1] - radius
dx = pos[0] + radius
dy = pos[1] + radius
logging.warning('\033[93mDraw mine:\033[0m %s, \033[92mux:\033[0m %d, \033[92muy:\033[0m %d, \033[92mdx:\033[0m %d, \033[92mdy:\033[0m %d' % (ID, ux, uy, dx, dy), extra=self.data)
logging.warning("Draw mine: {}, mux: {}, muy: {}, mdx: {}, mdy: {}".format(ID, ux, uy, dx, dy), extra=self.data)
self.canvas.create_oval(ux, uy, dx, dy, tags=ID, fill=color, outline=outline)
# Put the mine down in the lower layer
self.canvas.tag_lower(ID)
@ -202,7 +202,6 @@ class Display(object):
def draw_farm(self, ID, pos, radius, color, outline):
"""
Draw an non existent farm according to data received.
ID: The farm ID
pos: The position of this farm
radius: The farm radius (see config.FARM_RADIUS)
@ -213,7 +212,7 @@ class Display(object):
uy = pos[1] - radius
dx = pos[0] + radius
dy = pos[1] + radius
logging.warning('\033[93mDraw farm:\033[0m %s, \033[92mux:\033[0m %d, \033[92muy:\033[0m %d, \033[92mdx:\033[0m %d, \033[92mdy:\033[0m %d' % (ID, ux, uy, dx, dy), extra=self.data)
logging.warning("Draw farm: {}, fux: {}, fuy: {}, fdx: {}, fdy: {}".format(ID, ux, uy, dx, dy), extra=self.data)
self.canvas.create_oval(ux, uy, dx, dy, tags=ID, fill=color, outline=outline)
# Put the farm down in the lower layer
self.canvas.tag_lower(ID)
@ -229,11 +228,11 @@ class Display(object):
def stop(self):
""" Send stop signal to all objects (ants, farms, mines, workers)"""
logging.warning('\033[91mSending kill signal\033[0m', extra=self.data)
logging.warning("Sending kill signal", extra=self.data)
self.response_q.put({'type': 'kill'})
for worker in self.workers:
self.workers[worker].stop()
self.master.destroy()
logging.warning('\033[91mMaster window destroyed\033[0m', extra=self.data)
logging.warning('\033[91mExiting\033[0m', extra=self.data)
exit(0)
logging.warning("Master window destroyed", extra=self.data)
logging.warning("Exiting", extra=self.data)
sys.exit(0)

+ 0
- 250
doc/ant.html View File

@ -1,250 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ant</title>
<meta charset="utf-8">
</head><body bgcolor="#f0f0f8">
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>ant</strong></big></big> (version 1.0.0)</font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/doug/projets/python/ants/ant.py">/home/doug/projets/python/ants/ant.py</a></font></td></tr></table>
<p><tt>Provides&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;class&nbsp;for&nbsp;the&nbsp;ants&nbsp;module.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="config.html">config</a><br>
<a href="logging.html">logging</a><br>
</td><td width="25%" valign=top><a href="multiprocessing.html">multiprocessing</a><br>
<a href="random.html">random</a><br>
</td><td width="25%" valign=top><a href="threading.html">threading</a><br>
<a href="time.html">time</a><br>
</td><td width="25%" valign=top><a href="utils.html">utils</a><br>
<a href="uuid.html">uuid</a><br>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="threading.html#Thread">threading.Thread</a>(<a href="threading.html#_Verbose">threading._Verbose</a>)
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ant.html#Ant">Ant</a>
</font></dt></dl>
</dd>
</dl>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Ant">class <strong>Ant</strong></a>(<a href="threading.html#Thread">threading.Thread</a>)</font></td></tr>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>The&nbsp;<a href="#Ant">Ant</a>&nbsp;object&nbsp;is&nbsp;a&nbsp;self&nbsp;living&nbsp;virtual&nbsp;creature&nbsp;that&nbsp;tries&nbsp;to&nbsp;simulate<br>
some&nbsp;ant's&nbsp;basic&nbsp;behaviour.<br>
The&nbsp;<a href="#Ant">Ant</a>&nbsp;object&nbsp;runs&nbsp;its&nbsp;own&nbsp;thread.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="ant.html#Ant">Ant</a></dd>
<dd><a href="threading.html#Thread">threading.Thread</a></dd>
<dd><a href="threading.html#_Verbose">threading._Verbose</a></dd>
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="Ant-__init__"><strong>__init__</strong></a>(self, playground, display_q, position, farm_id)</dt><dd><tt>-&nbsp;playground:&nbsp;The&nbsp;Playground&nbsp;in&nbsp;which&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;lives<br>
-&nbsp;display_q:&nbsp;The&nbsp;FIFO&nbsp;queue&nbsp;in&nbsp;wich&nbsp;data&nbsp;are&nbsp;sent&nbsp;to&nbsp;the&nbsp;Display&nbsp;object<br>
-&nbsp;position:&nbsp;A&nbsp;tuple&nbsp;seen&nbsp;as&nbsp;initial&nbsp;position&nbsp;(x,&nbsp;y)<br>
-&nbsp;farm_id:&nbsp;The&nbsp;Farm&nbsp;ID&nbsp;to&nbsp;which&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;belongs</tt></dd></dl>
<dl><dt><a name="Ant-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;representation&nbsp;of&nbsp;the&nbsp;<a href="#Ant">Ant</a>.</tt></dd></dl>
<dl><dt><a name="Ant-check_around"><strong>check_around</strong></a>(self)</dt><dd><tt>Process&nbsp;actions&nbsp;according&nbsp;to&nbsp;what&nbsp;is&nbsp;around&nbsp;the&nbsp;present&nbsp;position.<br>
Object&nbsp;around&nbsp;the&nbsp;present&nbsp;position&nbsp;are&nbsp;given&nbsp;bay&nbsp;the&nbsp;Playground.scan(position)&nbsp;method.</tt></dd></dl>
<dl><dt><a name="Ant-clean_history"><strong>clean_history</strong></a>(self)</dt><dd><tt>Delete&nbsp;oldest&nbsp;position&nbsp;in&nbsp;history&nbsp;when&nbsp;history&nbsp;length&nbsp;is&nbsp;larger&nbsp;than&nbsp;&lt;max_history&gt;.<br>
See&nbsp;config.ANT_MAX_HISTORY</tt></dd></dl>
<dl><dt><a name="Ant-display"><strong>display</strong></a>(self, new<font color="#909090">=False</font>)</dt><dd><tt>Send&nbsp;<a href="#Ant">Ant</a>&nbsp;dict&nbsp;representation&nbsp;to&nbsp;Display</tt></dd></dl>
<dl><dt><a name="Ant-hail"><strong>hail</strong></a>(self, ant)</dt><dd><tt>Hails&nbsp;the&nbsp;given&nbsp;<a href="#Ant">Ant</a>.<br>
Whenever&nbsp;an&nbsp;<a href="#Ant">Ant</a>&nbsp;encounter&nbsp;an&nbsp;another,&nbsp;it&nbsp;hails&nbsp;it.<br>
Depending&nbsp;on&nbsp;the&nbsp;status&nbsp;of&nbsp;each&nbsp;the&nbsp;concerned&nbsp;Ants,&nbsp;some&nbsp;data&nbsp;are&nbsp;exchanged.<br>
An&nbsp;<a href="#Ant">Ant</a>&nbsp;can&nbsp;not&nbsp;hail&nbsp;a&nbsp;dead&nbsp;<a href="#Ant">Ant</a>.</tt></dd></dl>
<dl><dt><a name="Ant-has_food"><strong>has_food</strong></a>(self)</dt><dd><tt>Returns&nbsp;whether&nbsp;or&nbsp;not&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;carries&nbsp;food</tt></dd></dl>
<dl><dt><a name="Ant-in_range"><strong>in_range</strong></a>(self, position)</dt><dd><tt>Returns&nbsp;if&nbsp;wheter&nbsp;or&nbsp;not&nbsp;the&nbsp;given&nbsp;position&nbsp;is&nbsp;aside&nbsp;the&nbsp;<a href="#Ant">Ant</a>.<br>
-&nbsp;Position:&nbsp;A&nbsp;tuple&nbsp;seen&nbsp;as&nbsp;coordinates&nbsp;(x,&nbsp;y)</tt></dd></dl>
<dl><dt><a name="Ant-is_alive"><strong>is_alive</strong></a>(self)</dt><dd><tt>Returns&nbsp;wether&nbsp;or&nbsp;not&nbsp;<a href="#Ant">Ant</a>&nbsp;&lt;life&gt;&nbsp;is&nbsp;&gt;&nbsp;0</tt></dd></dl>
<dl><dt><a name="Ant-is_busy"><strong>is_busy</strong></a>(self)</dt><dd><tt>Returns&nbsp;wheter&nbsp;or&nbsp;not&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;is&nbsp;busy.<br>
An&nbsp;<a href="#Ant">Ant</a>&nbsp;is&nbsp;busy&nbsp;when&nbsp;the&nbsp;length&nbsp;of&nbsp;its&nbsp;path&nbsp;to&nbsp;go&nbsp;is&nbsp;&gt;&nbsp;0.</tt></dd></dl>
<dl><dt><a name="Ant-mine"><strong>mine</strong></a>(self, mine)</dt><dd><tt>Pick&nbsp;the&nbsp;maximum&nbsp;food&nbsp;amount&nbsp;from&nbsp;the&nbsp;given&nbsp;mine.</tt></dd></dl>
<dl><dt><a name="Ant-near_mine"><strong>near_mine</strong></a>(self)</dt><dd><tt>Returns&nbsp;wether&nbsp;or&nbsp;not&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;is&nbsp;near&nbsp;a&nbsp;mine</tt></dd></dl>
<dl><dt><a name="Ant-pause"><strong>pause</strong></a>(self, delay)</dt><dd><tt>Wait&nbsp;time&nbsp;seconds</tt></dd></dl>
<dl><dt><a name="Ant-pop_new_position"><strong>pop_new_position</strong></a>(self)</dt><dd><tt>Pick&nbsp;the&nbsp;next&nbsp;position&nbsp;in&nbsp;the&nbsp;path&nbsp;to&nbsp;go.</tt></dd></dl>
<dl><dt><a name="Ant-record"><strong>record</strong></a>(self)</dt><dd><tt>Record&nbsp;the&nbsp;actual&nbsp;position&nbsp;in&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;history.<br>
For&nbsp;each&nbsp;new&nbsp;record,&nbsp;the&nbsp;history&nbsp;is&nbsp;recreated&nbsp;in&nbsp;a&nbsp;way&nbsp;that&nbsp;the&nbsp;shortest&nbsp;path<br>
from&nbsp;the&nbsp;oldest&nbsp;position&nbsp;to&nbsp;the&nbsp;current&nbsp;position&nbsp;is&nbsp;retained.<br>
Still,&nbsp;the&nbsp;new&nbsp;shortest&nbsp;path&nbsp;will&nbsp;only&nbsp;use&nbsp;position&nbsp;wihin&nbsp;the&nbsp;history.<br>
The&nbsp;shortest&nbsp;path&nbsp;from&nbsp;within&nbsp;the&nbsp;history&nbsp;is&nbsp;rarely&nbsp;(who&nbsp;said&nbsp;never&nbsp;?)&nbsp;the&nbsp;shortest&nbsp;path&nbsp;on&nbsp;the&nbsp;play&nbsp;ground.</tt></dd></dl>
<dl><dt><a name="Ant-restart"><strong>restart</strong></a>(self)</dt><dd><tt>Restart&nbsp;after&nbsp;<a href="#Ant-wait">wait</a>()</tt></dd></dl>
<dl><dt><a name="Ant-run"><strong>run</strong></a>(self)</dt><dd><tt>The&nbsp;<a href="#Ant">Ant</a>&nbsp;thread&nbsp;main&nbsp;loop</tt></dd></dl>
<dl><dt><a name="Ant-set_colors"><strong>set_colors</strong></a>(self)</dt><dd><tt>Adjust&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;colors&nbsp;depending&nbsp;on&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;status.</tt></dd></dl>
<dl><dt><a name="Ant-set_new_position"><strong>set_new_position</strong></a>(self)</dt><dd><tt>Set&nbsp;a&nbsp;new&nbsp;position&nbsp;from&nbsp;the&nbsp;actual&nbsp;position.<br>
A&nbsp;new&nbsp;position&nbsp;is&nbsp;randomly&nbsp;generated&nbsp;by&nbsp;adding&nbsp;-1,&nbsp;0&nbsp;or&nbsp;1&nbsp;to&nbsp;one&nbsp;of<br>
the&nbsp;actual&nbsp;position&nbsp;componant&nbsp;(x&nbsp;or&nbsp;y).<br>
If&nbsp;the&nbsp;new&nbsp;position&nbsp;is&nbsp;out&nbsp;of&nbsp;the&nbsp;playground&nbsp;then&nbsp;the&nbsp;position&nbsp;is<br>
adjusted.&nbsp;Thus&nbsp;an&nbsp;ant&nbsp;can&nbsp;not&nbsp;walk&nbsp;out&nbsp;of&nbsp;the&nbsp;play&nbsp;ground&nbsp;which&nbsp;is&nbsp;finite.</tt></dd></dl>
<dl><dt><a name="Ant-stop"><strong>stop</strong></a>(self)</dt><dd><tt>Kill&nbsp;the&nbsp;<a href="#Ant">Ant</a>.<br>
this&nbsp;will&nbsp;exit&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;thread.</tt></dd></dl>
<dl><dt><a name="Ant-store"><strong>store</strong></a>(self, farm)</dt><dd><tt>Stores&nbsp;the&nbsp;carried&nbsp;food&nbsp;to&nbsp;the&nbsp;given&nbsp;farm.</tt></dd></dl>
<dl><dt><a name="Ant-swap_histories"><strong>swap_histories</strong></a>(self)</dt><dd><tt>Swap&nbsp;history&nbsp;and&nbsp;path&nbsp;to&nbsp;go.<br>
When&nbsp;an&nbsp;<a href="#Ant">Ant</a>&nbsp;find&nbsp;food,&nbsp;it&nbsp;needs&nbsp;to&nbsp;go&nbsp;back&nbsp;home.<br>
The&nbsp;partial&nbsp;or&nbsp;complete&nbsp;path&nbsp;to&nbsp;home&nbsp;is&nbsp;in&nbsp;its&nbsp;history&nbsp;so&nbsp;the&nbsp;history&nbsp;is&nbsp;reverted&nbsp;then&nbsp;given&nbsp;has&nbsp;a&nbsp;path&nbsp;to&nbsp;go.<br>
Once&nbsp;the&nbsp;path&nbsp;to&nbsp;go&nbsp;is&nbsp;set,&nbsp;the&nbsp;actual&nbsp;history&nbsp;is&nbsp;wiped&nbsp;out.<br>
Same&nbsp;process&nbsp;occurs&nbsp;when&nbsp;an&nbsp;<a href="#Ant">Ant</a>&nbsp;comes&nbsp;back&nbsp;to&nbsp;home&nbsp;with&nbsp;food,&nbsp;so&nbsp;it&nbsp;can&nbsp;go&nbsp;back&nbsp;to&nbsp;the&nbsp;Mine.</tt></dd></dl>
<dl><dt><a name="Ant-to_dict"><strong>to_dict</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;dict&nbsp;representation&nbsp;of&nbsp;the&nbsp;<a href="#Ant">Ant</a>&nbsp;object.&nbsp;This&nbsp;representation&nbsp;is<br>
used&nbsp;by&nbsp;the&nbsp;Display&nbsp;workers&nbsp;to&nbsp;display&nbsp;the&nbsp;<a href="#Ant">Ant</a>.</tt></dd></dl>
<dl><dt><a name="Ant-wait"><strong>wait</strong></a>(self)</dt><dd><tt>Wait&nbsp;until&nbsp;<a href="#Ant-restart">restart</a>()&nbsp;is&nbsp;called.</tt></dd></dl>
<dl><dt><a name="Ant-walk"><strong>walk</strong></a>(self)</dt><dd><tt>Set&nbsp;a&nbsp;new&nbsp;position.<br>
If&nbsp;<a href="#Ant">Ant</a>&nbsp;already&nbsp;has&nbsp;a&nbsp;path&nbsp;to&nbsp;go,&nbsp;then&nbsp;the&nbsp;next&nbsp;position&nbsp;is&nbsp;picked&nbsp;up&nbsp;from&nbsp;this&nbsp;path.<br>
Otherwise,&nbsp;a&nbsp;new&nbsp;position&nbsp;is&nbsp;randomly&nbsp;picked&nbsp;up.</tt></dd></dl>
<hr>
Methods inherited from <a href="threading.html#Thread">threading.Thread</a>:<br>
<dl><dt><a name="Ant-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
<dl><dt><a name="Ant-getName"><strong>getName</strong></a>(self)</dt></dl>
<dl><dt><a name="Ant-isAlive"><strong>isAlive</strong></a>(self)</dt><dd><tt>Return&nbsp;whether&nbsp;the&nbsp;thread&nbsp;is&nbsp;alive.<br>
&nbsp;<br>
This&nbsp;method&nbsp;returns&nbsp;True&nbsp;just&nbsp;before&nbsp;the&nbsp;<a href="#Ant-run">run</a>()&nbsp;method&nbsp;starts&nbsp;until&nbsp;just<br>
after&nbsp;the&nbsp;<a href="#Ant-run">run</a>()&nbsp;method&nbsp;terminates.&nbsp;The&nbsp;module&nbsp;function&nbsp;enumerate()<br>
returns&nbsp;a&nbsp;list&nbsp;of&nbsp;all&nbsp;alive&nbsp;threads.</tt></dd></dl>
<dl><dt><a name="Ant-isDaemon"><strong>isDaemon</strong></a>(self)</dt></dl>
<dl><dt><a name="Ant-join"><strong>join</strong></a>(self, timeout<font color="#909090">=None</font>)</dt><dd><tt>Wait&nbsp;until&nbsp;the&nbsp;thread&nbsp;terminates.<br>
&nbsp;<br>
This&nbsp;blocks&nbsp;the&nbsp;calling&nbsp;thread&nbsp;until&nbsp;the&nbsp;thread&nbsp;whose&nbsp;<a href="#Ant-join">join</a>()&nbsp;method&nbsp;is<br>
called&nbsp;terminates&nbsp;--&nbsp;either&nbsp;normally&nbsp;or&nbsp;through&nbsp;an&nbsp;unhandled&nbsp;exception<br>
or&nbsp;until&nbsp;the&nbsp;optional&nbsp;timeout&nbsp;occurs.<br>
&nbsp;<br>
When&nbsp;the&nbsp;timeout&nbsp;argument&nbsp;is&nbsp;present&nbsp;and&nbsp;not&nbsp;None,&nbsp;it&nbsp;should&nbsp;be&nbsp;a<br>
floating&nbsp;point&nbsp;number&nbsp;specifying&nbsp;a&nbsp;timeout&nbsp;for&nbsp;the&nbsp;operation&nbsp;in&nbsp;seconds<br>
(or&nbsp;fractions&nbsp;thereof).&nbsp;As&nbsp;<a href="#Ant-join">join</a>()&nbsp;always&nbsp;returns&nbsp;None,&nbsp;you&nbsp;must&nbsp;call<br>
<a href="#Ant-isAlive">isAlive</a>()&nbsp;after&nbsp;<a href="#Ant-join">join</a>()&nbsp;to&nbsp;decide&nbsp;whether&nbsp;a&nbsp;timeout&nbsp;happened&nbsp;--&nbsp;if&nbsp;the<br>
thread&nbsp;is&nbsp;still&nbsp;alive,&nbsp;the&nbsp;<a href="#Ant-join">join</a>()&nbsp;call&nbsp;timed&nbsp;out.<br>
&nbsp;<br>
When&nbsp;the&nbsp;timeout&nbsp;argument&nbsp;is&nbsp;not&nbsp;present&nbsp;or&nbsp;None,&nbsp;the&nbsp;operation&nbsp;will<br>
block&nbsp;until&nbsp;the&nbsp;thread&nbsp;terminates.<br>
&nbsp;<br>
A&nbsp;thread&nbsp;can&nbsp;be&nbsp;<a href="#Ant-join">join</a>()ed&nbsp;many&nbsp;times.<br>
&nbsp;<br>
<a href="#Ant-join">join</a>()&nbsp;raises&nbsp;a&nbsp;RuntimeError&nbsp;if&nbsp;an&nbsp;attempt&nbsp;is&nbsp;made&nbsp;to&nbsp;join&nbsp;the&nbsp;current<br>
thread&nbsp;as&nbsp;that&nbsp;would&nbsp;cause&nbsp;a&nbsp;deadlock.&nbsp;It&nbsp;is&nbsp;also&nbsp;an&nbsp;error&nbsp;to&nbsp;<a href="#Ant-join">join</a>()&nbsp;a<br>
thread&nbsp;before&nbsp;it&nbsp;has&nbsp;been&nbsp;started&nbsp;and&nbsp;attempts&nbsp;to&nbsp;do&nbsp;so&nbsp;raises&nbsp;the&nbsp;same<br>
exception.</tt></dd></dl>
<dl><dt><a name="Ant-setDaemon"><strong>setDaemon</strong></a>(self, daemonic)</dt></dl>
<dl><dt><a name="Ant-setName"><strong>setName</strong></a>(self, name)</dt></dl>
<dl><dt><a name="Ant-start"><strong>start</strong></a>(self)</dt><dd><tt>Start&nbsp;the&nbsp;thread's&nbsp;activity.<br>
&nbsp;<br>
It&nbsp;must&nbsp;be&nbsp;called&nbsp;at&nbsp;most&nbsp;once&nbsp;per&nbsp;thread&nbsp;object.&nbsp;It&nbsp;arranges&nbsp;for&nbsp;the<br>
object's&nbsp;<a href="#Ant-run">run</a>()&nbsp;method&nbsp;to&nbsp;be&nbsp;invoked&nbsp;in&nbsp;a&nbsp;separate&nbsp;thread&nbsp;of&nbsp;control.<br>
&nbsp;<br>
This&nbsp;method&nbsp;will&nbsp;raise&nbsp;a&nbsp;RuntimeError&nbsp;if&nbsp;called&nbsp;more&nbsp;than&nbsp;once&nbsp;on&nbsp;the<br>
same&nbsp;thread&nbsp;object.</tt></dd></dl>
<hr>
Data descriptors inherited from <a href="threading.html#Thread">threading.Thread</a>:<br>
<dl><dt><strong>daemon</strong></dt>
<dd><tt>A&nbsp;boolean&nbsp;value&nbsp;indicating&nbsp;whether&nbsp;this&nbsp;thread&nbsp;is&nbsp;a&nbsp;daemon&nbsp;thread&nbsp;(True)&nbsp;or&nbsp;not&nbsp;(False).<br>
&nbsp;<br>
This&nbsp;must&nbsp;be&nbsp;set&nbsp;before&nbsp;start()&nbsp;is&nbsp;called,&nbsp;otherwise&nbsp;RuntimeError&nbsp;is<br>
raised.&nbsp;Its&nbsp;initial&nbsp;value&nbsp;is&nbsp;inherited&nbsp;from&nbsp;the&nbsp;creating&nbsp;thread;&nbsp;the<br>
main&nbsp;thread&nbsp;is&nbsp;not&nbsp;a&nbsp;daemon&nbsp;thread&nbsp;and&nbsp;therefore&nbsp;all&nbsp;threads&nbsp;created&nbsp;in<br>
the&nbsp;main&nbsp;thread&nbsp;default&nbsp;to&nbsp;daemon&nbsp;=&nbsp;False.<br>
&nbsp;<br>
The&nbsp;entire&nbsp;Python&nbsp;program&nbsp;exits&nbsp;when&nbsp;no&nbsp;alive&nbsp;non-daemon&nbsp;threads&nbsp;are<br>
left.</tt></dd>
</dl>
<dl><dt><strong>ident</strong></dt>
<dd><tt>Thread&nbsp;identifier&nbsp;of&nbsp;this&nbsp;thread&nbsp;or&nbsp;None&nbsp;if&nbsp;it&nbsp;has&nbsp;not&nbsp;been&nbsp;started.<br>
&nbsp;<br>
This&nbsp;is&nbsp;a&nbsp;nonzero&nbsp;integer.&nbsp;See&nbsp;the&nbsp;thread.get_ident()&nbsp;function.&nbsp;Thread<br>
identifiers&nbsp;may&nbsp;be&nbsp;recycled&nbsp;when&nbsp;a&nbsp;thread&nbsp;exits&nbsp;and&nbsp;another&nbsp;thread&nbsp;is<br>
created.&nbsp;The&nbsp;identifier&nbsp;is&nbsp;available&nbsp;even&nbsp;after&nbsp;the&nbsp;thread&nbsp;has&nbsp;exited.</tt></dd>
</dl>
<dl><dt><strong>name</strong></dt>
<dd><tt>A&nbsp;string&nbsp;used&nbsp;for&nbsp;identification&nbsp;purposes&nbsp;only.<br>
&nbsp;<br>
It&nbsp;has&nbsp;no&nbsp;semantics.&nbsp;Multiple&nbsp;threads&nbsp;may&nbsp;be&nbsp;given&nbsp;the&nbsp;same&nbsp;name.&nbsp;The<br>
initial&nbsp;name&nbsp;is&nbsp;set&nbsp;by&nbsp;the&nbsp;constructor.</tt></dd>
</dl>
<hr>
Data descriptors inherited from <a href="threading.html#_Verbose">threading._Verbose</a>:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#55aa55">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><strong>__author__</strong> = 'Doug Le Tough'<br>
<strong>__copyright__</strong> = 'Copyright 2017, Doug Le Tough'<br>
<strong>__credits__</strong> = ['Doug Le Tough']<br>
<strong>__email__</strong> = 'doug.letough@free.fr'<br>
<strong>__license__</strong> = 'WTFPL'<br>
<strong>__maintainer__</strong> = 'Doug Le Tough'<br>
<strong>__status__</strong> = 'Testing'<br>
<strong>__version__</strong> = '1.0.0'</td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#7799ee">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Author</strong></big></font></td></tr>
<tr><td bgcolor="#7799ee"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%">Doug&nbsp;Le&nbsp;Tough</td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#7799ee">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Credits</strong></big></font></td></tr>
<tr><td bgcolor="#7799ee"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%">['Doug&nbsp;Le&nbsp;Tough']</td></tr></table>
</body></html>

+ 0
- 243
doc/ant.txt View File

@ -1,243 +0,0 @@
index
ant (version 1.0.0) /home/doug/projets/python/ants/ant.py
Provides the Ant class for the ants module.
Modules
config multiprocessing threading utils
logging random time uuid
Classes
threading.Thread(threading._Verbose)
Ant
class Ant(threading.Thread)
The Ant object is a self living virtual creature that tries to simulate
some ant's basic behaviour.
The Ant object runs its own thread.
Method resolution order:
Ant
threading.Thread
threading._Verbose
__builtin__.object
-------------------------------------------------------------------------------------------------------------
Methods defined here:
__init__(self, playground, display_q, position, farm_id)
- playground: The Playground in which the Ant lives
- display_q: The FIFO queue in wich data are sent to the Display object
- position: A tuple seen as initial position (x, y)
- farm_id: The Farm ID to which the Ant belongs
__str__(self)
Returns a string representation of the Ant.
check_around(self)
Process actions according to what is aro