Commit 73e91d13 authored by Jeroen F.J. Laros's avatar Jeroen F.J. Laros

Basic implementation of a trie using dictionaries.

parents
*.pyc
.cache/
.tox/
build/
dist/
dict_trie.egg-info/
"""
dict-trie: Basic implementation of a trie.
Copyright (c) 2017 Leiden University Medical Center <humgen@lumc.nl>
Copyright (c) 2017 Jeroen F.J. Laros <J.F.J.Laros@lumc.nl>
Licensed under the MIT license, see the LICENSE file.
"""
from .dict_trie import Trie
__version_info__ = ('0', '0', '1')
__version__ = '.'.join(__version_info__)
__author__ = 'LUMC, Jeroen F.J. Laros'
__contact__ = 'J.F.J.Laros@lumc.nl'
__homepage__ = 'https://git.lumc.nl/j.f.j.laros/dict-trie'
usage = __doc__.split('\n\n\n')
def doc_split(func):
return func.__doc__.split('\n\n')[0]
def version(name):
return '{} version {}\n\nAuthor : {} <{}>\nHomepage : {}'.format(
name, __version__, __author__, __contact__, __homepage__)
class Trie(object):
def __init__(self, words):
"""
Initialise the class.
:arg list words: List of words.
"""
self.root = {}
self._build(words)
def _build(self, words):
"""
Build the trie.
:arg list words: List of words.
"""
for word in words:
self.add(word)
def _find(self, word):
"""
Find the node after following the path in the trie given by {word}.
:arg str word: A word.
:returns dict: The node if found, None otherwise.
"""
node = self.root
for character in word:
if character not in node:
return {}
node = node[character]
return node
def __contains__(self, word):
if '' in self._find(word):
return True
return False
def add(self, word):
"""
Add a word to the trie.
"""
node = self.root
for character in word:
if character not in node:
node[character] = {}
node = node[character]
node[''] = {}
def has_prefix(self, word):
if self._find(word) != {}:
return True
return False
import os
import sys
from setuptools import setup
package = 'dict_trie'
package_name = 'dict-trie'
description = '{}: Basic implementation of a trie.'.format(package_name)
documentation = 'README.md'
license = 'MIT License'
keywords = []
dependencies = []
develop_dependencies = ['pytest', 'tox']
supported = [(2, 7), (3, 3), (3, 4)]
classifiers = [
'Development Status :: 3 - Alpha',
'Intended Audience :: Science/Research',
'Intended Audience :: Developers',
'Topic :: Scientific/Engineering',
]
if sys.version_info < supported[0]:
raise Exception('{} requires Python {}.{} or higher.'.format(
package, *supported[0]))
if sys.version_info[:2] == supported[0]:
dependencies.extend(['argparse', 'importlib'])
# This is quite the hack, but we don't want to import our package from here
# since that's recipe for disaster (it might have some uninstalled
# dependencies, or we might import another already installed version).
distmeta = {}
for line in open(os.path.join(package, '__init__.py')):
try:
field, value = (x.strip() for x in line.split('='))
except ValueError:
continue
if field == '__version_info__':
value = value.strip('[]()')
value = '.'.join(x.strip(' \'"') for x in value.split(','))
else:
value = value.strip('\'"')
distmeta[field] = value
try:
with open(documentation) as readme:
long_description = readme.read()
except IOError:
long_description = 'See ' + distmeta['__homepage__']
language_string = 'Programming Language :: Python'
classifiers += [
'License :: OSI Approved :: {}'.format(license),
'Operating System :: OS Independent',
language_string,
'{} :: {}'.format(language_string, supported[0][0]),
'{} :: {}'.format(language_string, supported[-1][0])] + \
['{} :: {}.{}'.format(language_string, *version) for version in supported]
setup(
name=package_name,
version=distmeta['__version_info__'],
description=description,
long_description=long_description,
author=distmeta['__author__'],
author_email=distmeta['__contact__'],
url=distmeta['__homepage__'],
license=license,
platforms=['any'],
packages=[package],
install_requires=dependencies,
tests_require=develop_dependencies,
classifiers=classifiers,
keywords=' '.join(keywords)
)
"""
Tests for the trie library.
"""
#from __future__ import (
# absolute_import, division, print_function, unicode_literals)
#from future.builtins import str, zip
from dict_trie import Trie
class TestTrie(object):
def setup(self):
self._trie = Trie(['abc', 'abd', 'test', 'te'])
def test_full_trie(self):
assert self._trie.root == {
'a': {
'b': {
'c': {'': {}},
'd': {'': {}}}},
't': {'e': {
'': {},
's': {'t': {'': {}}}}}}
def test_prefix_not_in_trie(self):
assert 'ab' not in self._trie
def test_word_in_trie(self):
assert 'abc' in self._trie
def test_suffix_not_in_trie(self):
assert 'abcd' not in self._trie
def test_word_not_in_trie(self):
assert 'abe' not in self._trie
def test_has_prefix(self):
assert self._trie.has_prefix('ab')
def test_word_is_prefix(self):
assert self._trie.has_prefix('abc')
def test_has_prefix_not(self):
assert not self._trie.has_prefix('ac')
def test_has_prefix_not_long(self):
assert not self._trie.has_prefix('abcd')
def test_prefix_order(self):
assert Trie(['test', 'te']).root == Trie(['te', 'test']).root
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment