Skip to content

Commit

Permalink
Various improvments, mostly formatting
Browse files Browse the repository at this point in the history
This commit includes changes which mostly just affect how the script
looks, I've made a few changes that get it closer to PEP-8 compliance.
And then a few changes are included which affect how decisions are made.
All tests are still passing so no major functional changes happened.
  • Loading branch information
LeonardMH committed Nov 23, 2015
1 parent d8aca94 commit 0a47200
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 78 deletions.
52 changes: 20 additions & 32 deletions namealizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,14 @@ def format_word_list_mixedcase(word_list):
return to_return


def format_string(string_to_format, wordstyle=None, separator=None):
def format_string(string_to_format, wordstyle="lowercase", separator=" "):
"""
Takes an un-formatted string and returns it in the desired format
Acceptable formats are defined in the function_map dictionary.
"""
# first split the string up into its constituent words
words = string_to_format.split(" ")

# then set the defaults for any arguments that are None
if wordstyle is None:
wordstyle = "lowercase"

if separator is None:
separator = " "

# format the individual words
function_map = {
"lowercase": format_word_list_lowercase,
Expand Down Expand Up @@ -124,35 +117,26 @@ def import_dictionary(opened_file):
return dictionary


def main(dictionary=None, count=None, initials=None, seed=None, wordstyle=None, separator=None, verbose=None):
# Seed the PRNG
def main(dictionary="dictionaries/all_en_US.dict", count=None, initials=None,
seed=None, wordstyle=None, separator=None):
# Generate seed for random number generator
if seed is None:
random.seed()
seed = random.randint(0, sys.maxsize)
random.seed(a=seed)

if verbose:
print("seed: {}".format(seed))

# open the file for the word list and read it into a nested list
# begin by checking for a dictionary location defined from command line option
if dictionary is None:
dictionary_location = "dictionaries/all_en_US.dict"
else:
dictionary_location = dictionary

# import the dictionary into a Python dictionary
if not os.path.isfile(dictionary_location):
message = "Could not find the dictionary at {}".format(dictionary_location)
# attempt to read in the given dictionary
try:
with open(dictionary) as dictionary_file:
dictionary = import_dictionary(dictionary_file)
except IOError:
message = "Could not find the dictionary at {}".format(dictionary)
raise DictionaryNotFoundError(message)

with open(dictionary_location) as dictionary_file:
dictionary = import_dictionary(dictionary_file)

# If count and initials are set at the same time let the user know that's a no-no
if count is not None and initials is not None:
print("ERROR: --count and --initials are mutually exclusive, pick one. Using initials.")
print("ERROR: --count and --initials are mutually exclusive")
print("Using initials.")

string_to_print = ""
if initials is not None:
Expand All @@ -169,6 +153,14 @@ def main(dictionary=None, count=None, initials=None, seed=None, wordstyle=None,
for index in range(ranger):
string_to_print += "{} ".format(get_random_word(dictionary))

# if the user didn't provide a wordstyle use the default
if wordstyle == None:
wordstyle = "lowercase"

# if the user didn't provide a separator then use the default
if separator == None:
separator = " "

return format_string(string_to_print.strip(), wordstyle, separator)


Expand All @@ -191,12 +183,8 @@ def main(dictionary=None, count=None, initials=None, seed=None, wordstyle=None,
parser.add_argument('-ws', '--wordstyle',
help="Specify how to style the individual words. Default is lowercase.")
parser.add_argument('-sep', '--separator', help="What to use to separate words. Default is space.")
parser.add_argument('-v', '--verbose',
help="""Make the program print extra information, can be useful especially if you would like
to know what seed was used for the random number generator.""",
action='store_true')

args = parser.parse_args()

print(main(dictionary=args.dictionary, count=args.count, initials=args.initials, seed=args.seed,
wordstyle=args.wordstyle, separator=args.separator, verbose=args.verbose))
wordstyle=args.wordstyle, separator=args.separator))
125 changes: 79 additions & 46 deletions test_namealizer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""unittest based tests for namealizer"""
import sys
import os
import unittest
Expand All @@ -13,39 +14,47 @@ def write_dictionary(file_name, words_to_write):


def are_two_seed_runs_equal(seed_to_use, **kwargs):
return namealizer.main(seed=seed_to_use, **kwargs) == namealizer.main(seed=seed_to_use, **kwargs)
first = namealizer.main(seed=seed_to_use, **kwargs)
second = namealizer.main(seed=seed_to_use, **kwargs)
return first == second


class TestDictionaryImport(unittest.TestCase):
"""
Test the ability of the tool to import dictionaries. This tests also serves as the specification for
how dictionaries should be formatted. This specification is also documented here.
Test the ability of the tool to import dictionaries. This tests
also serves as the specification for how dictionaries should be
formatted. This specification is also documented here.
Dictionary format (on-disk):
Dictionaries have a fairly simple format, each word is on it's own line. That's it.
Dictionaries have a fairly simple format, each word is on it's own
line. That's it.
Dictionary format (in memory):
Within the script dictionaries should be stored as a Python dictionary where each key is mapped to a unique first
character of the word and the value of each of these keys is a Python list of all the words that have that first
character.
Within the script dictionaries should be stored as a Python
dictionary where each key is mapped to a unique first character of
the word and the value of each of these keys is a Python list of all
the words that have that first character.
"""
well_formatted_all = "well-formatted-all.dict"
words_for_well_formatted_all = ["able", "boson", "cannon", "dog", "exxon", "foggy", "grand", "housing",
"interpreted", "joking", "king", "lemon", "michael", "nixon", "opening",
"pricing", "queen", "respected", "stuffing", "travis", "unopened", "very",
"washington", "xylophone", "yocto", "zebra"]
words_all = ["able", "boson", "cannon", "dog",
"exxon", "foggy", "grand", "housing",
"interpreted", "joking", "king",
"lemon", "michael", "nixon", "opening",
"pricing", "queen", "respected",
"stuffing", "travis", "unopened", "very",
"washington", "xylo", "yocto", "zebra"]

well_formatted_sparse = "well-formatted-sparse.dict"
words_for_well_formatted_sparse = ["able", "exxon", "washington", "xylophone"]
words_sparse = ["able", "exxon", "washington", "xylophone"]

def setUp(self):
# create and import the well formatted full dictionary
write_dictionary(self.well_formatted_all, self.words_for_well_formatted_all)
write_dictionary(self.well_formatted_all, self.words_all)
with open(self.well_formatted_all, "r") as dictionary_file:
self.well_formatted_all = namealizer.import_dictionary(dictionary_file)

# create and import the well formatted sparse dictionary
write_dictionary(self.well_formatted_sparse, self.words_for_well_formatted_sparse)
write_dictionary(self.well_formatted_sparse, self.words_sparse)
with open(self.well_formatted_sparse, "r") as dictionary_file:
self.well_formatted_sparse = namealizer.import_dictionary(dictionary_file)

Expand All @@ -58,7 +67,7 @@ def test_import_well_formatted_all_letters(self):
self.assertIsInstance(value, list)

# verify that this dictionary has all 26 letters specified
self.assertEqual(len(self.words_for_well_formatted_all), len(self.well_formatted_all))
self.assertEqual(len(self.words_all), len(self.well_formatted_all))

def test_import_well_formatted_sparse(self):
# first just make sure it is a dictionary
Expand All @@ -69,7 +78,7 @@ def test_import_well_formatted_sparse(self):
self.assertIsInstance(value, list)

# verify that this dictionary has all the letters specified
self.assertEqual(len(self.words_for_well_formatted_sparse), len(self.well_formatted_sparse))
self.assertEqual(len(self.words_sparse), len(self.well_formatted_sparse))

def tearDown(self):
# remove the dictionaries
Expand All @@ -78,79 +87,102 @@ def tearDown(self):


class TestStringFormatter(unittest.TestCase):
"""
Verifies that the string formatting functionality works as expected.
This function is the final thing that processes strings before they are printed so it takes
strings of the format "hello this is a string" and turns them into things like
"HelloThisIsAString"
"""Verifies string formatting functionality
This function is the final thing that processes strings before they
are printed so it takes strings of the format "hello this is a
string" and turns them into things like "HelloThisIsAString"
"""
# test all the base wordstyles
test_string = "all the world"
separators = ["", "_", "-", "*", "$", "@#$", "monkey"]
expected_lowercase = ["alltheworld", "all_the_world", "all-the-world", "all*the*world", "all$the$world",
expected_lowercase = ["alltheworld", "all_the_world",
"all-the-world", "all*the*world", "all$the$world",
"all@#$the@#$world", "allmonkeythemonkeyworld"]
expected_uppercase = ["ALLTHEWORLD", "ALL_THE_WORLD", "ALL-THE-WORLD", "ALL*THE*WORLD", "ALL$THE$WORLD",
expected_uppercase = ["ALLTHEWORLD", "ALL_THE_WORLD", "ALL-THE-WORLD",
"ALL*THE*WORLD", "ALL$THE$WORLD",
"ALL@#$THE@#$WORLD", "ALLmonkeyTHEmonkeyWORLD"]
expected_capitalize = ["AllTheWorld", "All_The_World", "All-The-World", "All*The*World", "All$The$World",
expected_capitalize = ["AllTheWorld", "All_The_World",
"All-The-World", "All*The*World", "All$The$World",
"All@#$The@#$World", "AllmonkeyThemonkeyWorld"]
expected_mixedcase = ["allTheWorld", "all_The_World", "all-The-World", "all*The*World", "all$The$World",
expected_mixedcase = ["allTheWorld", "all_The_World",
"all-The-World", "all*The*World", "all$The$World",
"all@#$The@#$World", "allmonkeyThemonkeyWorld"]

def test_lowercase(self):
self.assertEqual(self.test_string.lower(), namealizer.format_string(self.test_string, "lowercase"))
standard = self.test_string.lower()
test = namealizer.format_string(self.test_string, "lowercase")
self.assertEqual(standard, test)

def test_uppercase(self):
self.assertEqual(self.test_string.upper(), namealizer.format_string(self.test_string, "uppercase"))
standard = self.test_string.upper()
test = namealizer.format_string(self.test_string, "uppercase")
self.assertEqual(standard, test)

def test_capitalize(self):
self.assertEqual("All The World", namealizer.format_string(self.test_string, "capitalize"))
standard = "All The World"
test = namealizer.format_string(self.test_string, "capitalize")
self.assertEqual(standard, test)

def test_mixedcase(self):
self.assertEqual("all The World", namealizer.format_string(self.test_string, "mixedcase"))
standard = "all The World"
test = namealizer.format_string(self.test_string, "mixedcase")
self.assertEqual(standard, test)

# test some separators
def test_separators_lowercase(self):
for index, separator in enumerate(self.separators):
self.assertEqual(self.expected_lowercase[index],
namealizer.format_string(self.test_string, "lowercase", separator))
standard = self.expected_lowercase[index]
test = namealizer.format_string(self.test_string,
"lowercase",
separator)
self.assertEqual(standard, test)

def test_separators_uppercase(self):
for index, separator in enumerate(self.separators):
self.assertEqual(self.expected_uppercase[index],
namealizer.format_string(self.test_string, "uppercase", separator))
standard = self.expected_uppercase[index]
test = namealizer.format_string(self.test_string,
"uppercase",
separator)
self.assertEqual(standard, test)

def test_separators_capitalize(self):
for index, separator in enumerate(self.separators):
self.assertEqual(self.expected_capitalize[index],
namealizer.format_string(self.test_string, "capitalize", separator))
standard = self.expected_capitalize[index]
test = namealizer.format_string(self.test_string,
"capitalize",
separator)
self.assertEqual(standard, test)

def test_separators_mixedcase(self):
for index, separator in enumerate(self.separators):
self.assertEqual(self.expected_mixedcase[index],
namealizer.format_string(self.test_string, "mixedcase", separator))

standard = self.expected_mixedcase[index]
test = namealizer.format_string(self.test_string,
"mixedcase",
separator)
self.assertEqual(standard, test)


class TestRandomWordGrabber(unittest.TestCase):
"""
Checks the behavior of the function that grabs random words out of the dictionary
"""Verify the function that grabs words from the dictionary
"""
pass


class TestCommandLineParameters(unittest.TestCase):
"""
Verifies that the script responds to the appropriate command line parameters and responds as expected.
"""Verifies command line parameters are handled correctly
"""
pass


class TestActualUsage(unittest.TestCase):
"""
Performs a few tests that use the program as it is actually expected to be used
"""Test expected program usage
"""

def test_no_arguments(self):
# this test should return a two letter lowercase set
print(namealizer.main().split(" "))
self.assertEqual(2, len(namealizer.main().split(" ")))

def test_with_various_count_arguments(self):
Expand All @@ -175,11 +207,12 @@ def test_with_various_initials(self):
for _ in range(num_initials):
initials += random.choice(string.ascii_letters)

self.assertEqual(num_initials, len(namealizer.main(initials=initials).split(" ")))
self.assertEqual(num_initials,
len(namealizer.main(initials=initials).split(" ")))

def test_seed_option(self):
# perform a couple of tests and ensure that given everything else being constant, the same seed produces
# the same results
# perform a couple of tests and ensure that given everything
# else being constant, the same seed produces # the same results

# test for 0 seed
self.assertTrue(are_two_seed_runs_equal(0))
Expand Down

0 comments on commit 0a47200

Please sign in to comment.