Alien Name Generator (using blocks of consonants and vowels)
All of your code is top-level, there are no functions and the only way to understand this programme is reading it all, also it is not tested so developing it was probably difficult.

Here is how I would go about it, with extensive comments.



"""
Block based alien name generator.
"""


This is a module level docstring, the first thing that gets displayed when the user types help(your_module) it usually describes concisely the purpose of the whole script.

import doctest
import itertools
import random
import string
import time


The Python Standard Library is extensive, many modules make devoloping programs easier.

MIN_BLOCK_LENGTH = 1
MAX_BLOCK_LENGTH = 2
MIN_BLOCKS_NUMBER = 2
MAX_BLOCKS_NUMBER = 3
VOWELS = "aeiou"
CONSONANTS = ''.join(i for i in string.ascii_lowercase if i not in  VOWELS)
TARGET_FILENAME = "nice_alien_names.txt"


These are module level constants, they either contain values that would be meaningless to change such as VOWELS or configuration options such as MAX_BLOCK_LENGTH that I modified as I like best short names. They are written SHOUTCASE and should not be changed (Python won't stop you from doing so though).

def random_string(length, pool):
    """
    &gt;&gt;&gt; random.seed(0)
    &gt;&gt;&gt; random_string(5, "abc")
    'bbabc'
    """
    return ''.join(random.choice(pool) for _ in range(length))


Now we get to the real meat. This is a function, an individual block of code with a name that performs one task and only that, return gives that value back into the programme. You may see the use of a generator expression, it can greatly shorten and simplify code. It is also tested, and the tests serve also as documentation.

def random_vowel_block():
    return random_string(random.randint(MIN_BLOCK_LENGTH, MAX_BLOCK_LENGTH), VOWELS)

def random_consonant_block():
    return random_string(random.randint(MIN_BLOCK_LENGTH, MAX_BLOCK_LENGTH), CONSONANTS)


Two small helper functions, to have function names near to the specification.

def alternate(func_1, func_2, times):
    """
    Returns a list containing `times` results
    of the two functions alternated.

    &gt;&gt;&gt; list(alternate(lambda: 1, lambda: 2, 3))
    [1, 2, 1]
    """
    return list(itertools.chain(
        * zip( (func_1() for _ in range(times)),
               (func_2() for _ in range(times)))))[0:times]


This function is probably more complex than it should be ;P, anyhow docstring and test simplify understanding. As you can see I abstracted the concept of alternation into a higher order function (a function that takes functions as input) that I will use in the main alien_name function.

def alien_name():
    """
    Generates a random alien name by concatenating a random
    number (between MIN_BLOCKS_NUMBER and MAX_BLOCKS_NUMBER)
    of random all-vowel and all-consonant blocks, of which each one
    has a length between MIN_BLOCK_LENGTH and MAX_BLOCK_LENGTH.

    &gt;&gt;&gt; random.seed(0)
    &gt;&gt;&gt; alien_name()
    'aiqmiu'
    &gt;&gt;&gt; alien_name()
    'wtaa'
    """
    name = ''.join(alternate(random_vowel_block, random_consonant_block,
                     random.randint(MIN_BLOCKS_NUMBER, MAX_BLOCKS_NUMBER)))
    return name if random.randint(0, 1) else ''.join(reversed(name))


The most important function, as you can see it is very small, as we have already defined all the building blocks needed. It reads almost as plain English. The last line implies that is a 50% chance of reversal to allow names starting with consonants.

def save_liked_ones():
    print("Enter nothing to ignore, `l` or `like` to save and `end` to terminate and save.\n")
    good_names = []
    while True:
        candidate_name = alien_name()
        choice = input("{}: ".format(candidate_name)).lower()
        if not choice:
            pass
        if choice.startswith('l'):
            good_names.append(candidate_name)
        if choice == 'end':
            with open(TARGET_FILENAME, 'a+') as f:
                f.write('\n'.join(good_names))
            return


I took the liberty of writing a user interface to avoid saving dull or uninteresting names, as you can see the logic is being performed all inside alien_name() this function only handles user interface.

if __name__ == "__main__":
    doctest.testmod()
    random.seed(time.time())
    save_liked_ones()


This runs the tests that you see in the docs and shows the user interface if this file is run as a script, importing it will only cause the functions to be defined. Please note that random.seed is needed as I seeded the Random Number Generator before for ease of testing.



And the full programme, in case you want to play and experiment with it:

"""
Block based alien name generator.
"""

import doctest
import itertools
import random
import string
import time

MIN_BLOCK_LENGTH = 1
MAX_BLOCK_LENGTH = 2
MIN_BLOCKS_NUMBER = 2
MAX_BLOCKS_NUMBER = 3
VOWELS = "aeiou"
CONSONANTS = ''.join(i for i in string.ascii_lowercase if i not in  VOWELS)
TARGET_FILENAME = "nice_alien_names.txt"

def random_string(length, pool):
    """
    &gt;&gt;&gt; random.seed(0)
    &gt;&gt;&gt; random_string(5, "abc")
    'bbabc'
    """
    return ''.join(random.choice(pool) for _ in range(length))


def random_vowel_block():
    return random_string(random.randint(MIN_BLOCK_LENGTH, MAX_BLOCK_LENGTH), VOWELS)


def random_consonant_block():
    return random_string(random.randint(MIN_BLOCK_LENGTH, MAX_BLOCK_LENGTH), CONSONANTS)


def alternate(func_1, func_2, times):
    """
    Returns a list containing `times` results
    of the two functions alternated.

    &gt;&gt;&gt; list(alternate(lambda: 1, lambda: 2, 3))
    [1, 2, 1]
    """
    return list(itertools.chain(
        * zip( (func_1() for _ in range(times)),
               (func_2() for _ in range(times)))))[0:times]


def alien_name():
    """
    Generates a random alien name by concatenating a random
    number (between MIN_BLOCKS_NUMBER and MAX_BLOCKS_NUMBER)
    of random all-vowel and all-consonant blocks, of which each one
    has a length between MIN_BLOCK_LENGTH and MAX_BLOCK_LENGTH.

    &gt;&gt;&gt; random.seed(0)
    &gt;&gt;&gt; alien_name()
    'aiqmiu'
    &gt;&gt;&gt; alien_name()
    'wtaa'
    """
    name = ''.join(alternate(random_vowel_block, random_consonant_block,
                     random.randint(MIN_BLOCKS_NUMBER, MAX_BLOCKS_NUMBER)))
    return name if random.randint(0, 1) else ''.join(reversed(name))


def save_liked_ones():
    print("Enter nothing to ignore, `l` or `like` to save and `end` to terminate and save.\n")
    good_names = []
    while True:
        candidate_name = alien_name()
        choice = input("{}: ".format(candidate_name)).lower()
        if not choice:
            pass
        if choice.startswith('l'):
            good_names.append(candidate_name)
        if choice == 'end':
            with open(TARGET_FILENAME, 'a+') as f:
                f.write('\n'.join(good_names))
            return


if __name__ == "__main__":
    doctest.testmod()
    random.seed(time.time())
    save_liked_ones()