1

I am very new to Python and am working on a random name generator.

I take First Name and Last Name strings and randomly combine them.

My problem is that I am getting the same name a lot. However, I want the program to give me every combination of names. Here is the basic program:

import random
FirstName = "jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul",
"ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren",
"ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet",
"lydia", "charles", "pedro", "bradley"
LastName = "barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers",
"warren", "keller"
First = random.choice(FirstName)
Last = random.choice(LastName)
print (First + " " + Last)

I think I just realized a second problem I have. Some first names can be last names, and vice versa. For example, Bradley can be a first name and a last name. Is it possible to put Bradley in FirstName and LastName and then put some logic in so that I never get the same exact name, like Bradley Bradley?

boardrider
  • 5,882
  • 7
  • 49
  • 86
Pockets2Deep
  • 21
  • 1
  • 3
  • Check this http://stackoverflow.com/questions/9755538/how-do-i-create-a-list-of-unique-random-numbers you will get an idea – Bhargav Rao Jun 11 '15 at 14:50

7 Answers7

1

I want the program to give me every combination of names and then ending.

Instead of using random, you should iterate over the combinations using for loops or use a list comprehension and filter out the undesirable results where first and last are the same, see https://docs.python.org/2/library/itertools.html#itertools.product:

from itertools import product

first_name = "jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul",
"ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren",
"ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet",
"lydia", "charles", "pedro", "bradley"
last_name = "barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers",
"warren", "keller"

full_names = ["{} {}".format(f, l) for f, l in product(first_name, last_name) if f != l]

if you want them in psuedo random order with no repeats, you can use random.shuffle

random.shuffle(full_names)
dting
  • 38,604
  • 10
  • 95
  • 114
0

Trivial implementation: use sets for first and last name, drop the possible conflicting choice while selecting for last name. Unfortunately - due to choice() implementation a workaround is required to get one random element from set. So we take single element sample and use first element from single-element found group.

import random
first_names = {"jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul", "ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren", "ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet", "lydia", "charles", "pedro", "bradley"}
last_names = {"barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers", "warren", "keller"}

first = random.sample(first_names, 1)[0]
last = random.sample(last_names - {first}, 1)[0]
print (first + " " + last)
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
0
import random
first_name = "jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul",
"ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren",
"ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet",
"lydia", "charles", "pedro", "bradley"
last_name = "barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers",
"warren", "keller"

_all = [ f + " " + l for f in first_name for l in last_name ]

for i in xrange(len(_all)): # print a few choices
    print random.choice(_all)
boardrider
  • 5,882
  • 7
  • 49
  • 86
0

It can be like this. "i" defines how many combinations you expect. I tried i=1000 and i=1000000, The result is the same: 288.

#!/usr/bin/python

import random

first_names = {"jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul", "ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren", "ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet", "lydia", "charles", "pedro", "bradley"}
last_names = {"barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers", "warren", "keller"}

def Name(first_names, last_names):
    first = random.sample(first_names, 1)[0]
    last = random.sample(last_names - {first}, 1)[0]
    return (first + " " + last)

OUT=[]

i=1000
while i > 0:
    name=Name(first_names, last_names)
    if name not in OUT:
        OUT.append(name)
        print name
    i-=1

print len(OUT), 'unique names generated.'

Output

janet spirits
bradley spirits
axel style
ringo keller
pedro blacker
ringo spirits
...
ally warren
arthur barker
lauren spirits
nicky keller
288 unique names generated.
Alex Ivanov
  • 695
  • 4
  • 6
  • Running this code doesn't consistently give you all the combinations. – dting Jun 11 '15 at 16:07
  • It doesn't mean to give all combinations. It outputs just expected ones. – Alex Ivanov Jun 11 '15 at 16:14
  • That isn't entirely correct. It outputs the number of unique ones it was able to find within the constraint of `i` loops, which varies depending on "luck". With a sufficiently high `i` you have a high probability of returning all the combinations. – dting Jun 11 '15 at 16:29
  • This seems to work pretty well. I appreciate the help! What if I just wanted to output one name at a time, but still not get any duplicates? I want to use this when I create test accounts at work and a full list might be overwhelming. But, is it possible to output one name at a time and it still be random and have a count of what has been outputted so I don't get the same name again? Sorry, I have no clue if that is possible. – Pockets2Deep Jun 12 '15 at 00:28
  • Yes. You need to save names outside in a file or a database and when you pick one out you mark it as being in use and next time it won't show up. But that will be another script. – Alex Ivanov Jun 12 '15 at 00:51
0

For all possible combinations the script can be this. It also gives 288. No random stuff is involved.

#!/usr/bin/python

first_names = {"jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul", "ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren", "ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet", "lydia", "charles", "pedro", "bradley"}
last_names = {"barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers", "warren", "keller"}

OUT=[]

for a in first_names:
    for b in last_names:
        name=a+' '+b
        if name not in OUT:
            OUT.append(name)
            print name

print len(OUT), 'unique names generated.'

Output

ashley style
ashley spirits
ashley rogers
...
cal blacker
cal bleacher
cal warren
288 unique names generated.

If you need a random name you can choose it randomly from OUT.

import random

...

random.shuffle(OUT)

if len(OUT)>0:
    print OUT[0]

Output

floyd rogers
Alex Ivanov
  • 695
  • 4
  • 6
  • Can you explain a little more for your second part about it being chosen randomly? I can't figure out where that would go in the program. – Pockets2Deep Jun 12 '15 at 01:34
0

It goes to the bottom. I corrected it a bit for your project. This script makes a file that is used by the next script.

#!/usr/bin/python

import random

'''  The script generates "names.txt" containg names, one per line. '''


first_names = {"jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul", "ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren", "ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet", "lydia", "charles", "pedro", "bradley"}
last_names = {"barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers", "warren", "keller"}

OUT=[]

with open('names.txt', 'w') as f:
    for a in first_names:
        for b in last_names:
            name=a+' '+b
            if name not in OUT:
                OUT.append(name)
                f.write(name+'\n')

print len(OUT), 'unique names generated.'
print 'Saved into "names.txt"'

#-----------------------
random.shuffle(OUT)

if len(OUT)>0:
    print 'Random name:', OUT[0]
    print

This script uses a text file made by the previous script. Or you can open "names.txt" in OpenOffice Calc and shuffle the names there. Make sure to mark a name with something to indicate that it has been used. In my script the mark is a dot. When no more unused names are left it exits.

#!/usr/bin/python

import os, sys, random

''' The script uses a text file with names listed one per line. '''

path='names.txt'
L=[]

if os.path.exists(path)==False:
    print 'Not found: names.txt'
    print 'Exit.'
    sys.exit()
else:
    f=open('names.txt', 'r')
    s=f.read()
    f.close()
    L=s.split('\n')
    random.shuffle(L)
    x=len(L)
    while x > 0:
        i=0
        for n in L:
            if len(n)>0:
                name=n
                if name[0] != '.':
                    print
                    print name
                    print
                    a=raw_input('"y" to use, "n" to skip: ')

                    if a=='y':
                        name='.'+name # Marking name as used with a dot
                        L[i]=name
                        f=open('names.txt', 'w')
                        for n in L:
                            f.write(n+'\n')
                        f.close()
                        x -= 1
                i += 1

print 'No more names left.'
print 'Exit.'
Alex Ivanov
  • 695
  • 4
  • 6
-1

In this example I generate random combinations of complete names and check for their uniqueness.

from random import choice

names = ["jay", "jim", "roy", "axel", "billy", "charlie", "jax", "gina", "paul",
"ringo", "ally", "nicky", "cam", "ari", "trudie", "cal", "carl", "lady", "lauren",
"ichabod", "arthur", "ashley", "drake", "kim", "julio", "lorraine", "floyd", "janet",
"lydia", "charles", "pedro", "bradley"]
surnames = ["barker", "style", "spirits", "murphy", "blacker", "bleacher", "rogers",
"warren", "keller"]

def gen_unique_names(names,surnames,how_many):
    answer = []
    while how_many > 0:
        combo = choice(names)+' '+choice(surnames)
        if combo not in answer:
            answer.append(combo)
            how_many -= 1
    return answer

mynamelist = gen_unique_names(names,surnames,20)
for item in mynamelist:
    print item

This is the output:

ashley rogers
trudie spirits
lauren barker
floyd blacker
lauren bleacher
gina spirits
paul style
jax blacker
bradley murphy
ringo style
carl warren
carl spirits
cam murphy
lydia spirits
jax murphy
carl murphy
bradley style
lorraine blacker
charlie murphy
nicky barker
alec_djinn
  • 10,104
  • 8
  • 46
  • 71
  • 1
    Using a list to store the found answers will make the check for uniqueness linear time complexity. Even if you use a set and that check is O(1), when the number of answers you want approaches the total possibilities finding a new answer becomes less and less likely. The probability of random finding the last answer when you want all the names becomes (1/total combinations). – dting Jun 11 '15 at 15:39
  • Hundreds of combinations found in fraction of a second... A dict can be used in case of long list of names. However this code is an example, of course need to be optimised if you wanna generate thousands of names. – alec_djinn Jun 11 '15 at 15:44
  • I didn't down vote. Your answer is correct. I just wanted to point out some of the more subtle points in using this method to accomplish the task, for @The Sleestak. Anyways here are some numbers: http://nbviewer.ipython.org/gist/anonymous/f8d320e9780e9685497c – dting Jun 11 '15 at 16:26
  • It's ok, I liked your comment. I think it's good to discuss about other ways of getting things done. I don't know why the down vote, at the end is just another option to take in consideration. – alec_djinn Jun 12 '15 at 07:21