sootzly
sootzly

Reputation: 3

How do I improve my random string generator

I managed to create a simple random string generator that prints a random string of letters, x number of times, with each iteration in the list having a random length between 3-10 characters. I'm new to Python, and am still learning the very basics, so bear with me. My program works as intended, but I am pretty sure my code can be optimized. I'm really looking to learn best practices and expand my knowledge. This is my first post. Apologies if I'm in the wrong place.

import random

class Randomize:
    alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    choice1 = random.choice(alphabet)
    choice2 = random.choice(alphabet)
    choice3 = random.choice(alphabet)
    choice4 = random.choice(alphabet)
    choice5 = random.choice(alphabet)
    choice6 = random.choice(alphabet)
    choice7 = random.choice(alphabet)
    choice8 = random.choice(alphabet)
    choice9 = random.choice(alphabet)
    choice10 = random.choice(alphabet)
    three_letters = choice1 + choice2 + choice3
    four_letters = choice1 + choice2 + choice3 + choice4
    five_letters = choice1 + choice2 + choice3 + choice4 + choice5
    six_letters = choice1 + choice2 + choice3 + choice4 + choice5 + choice6
    seven_letters = choice1 + choice2 + choice3 + choice4 + choice5 + choice6 + choice7
    eight_letters = choice1 + choice2 + choice3 + choice4 + choice5 + choice6 + choice7 + choice8
    nine_letters = choice1 + choice2 + choice3 + choice4 + choice5 + choice6 + choice7 + choice8 + choice9
    ten_letters = choice1 + choice2 + choice3 + choice4 + choice5 + choice6 + choice7 + choice8 + choice9 + choice10
    word_length = [three_letters, four_letters, five_letters, six_letters, seven_letters, eight_letters, nine_letters, ten_letters]
    word = random.choice(word_length)

def gen(self):
    for i in range(10):
        print (Randomize.word)
        Randomize.choice1 = random.choice(Randomize.alphabet)
        Randomize.choice2 = random.choice(Randomize.alphabet)
        Randomize.choice3 = random.choice(Randomize.alphabet)
        Randomize.choice4 = random.choice(Randomize.alphabet)
        Randomize.choice5 = random.choice(Randomize.alphabet)
        Randomize.choice6 = random.choice(Randomize.alphabet)
        Randomize.choice7 = random.choice(Randomize.alphabet)
        Randomize.choice8 = random.choice(Randomize.alphabet)
        Randomize.choice9 = random.choice(Randomize.alphabet)
        Randomize.choice10 = random.choice(Randomize.alphabet)
        Randomize.three_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3
        Randomize.four_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4
        Randomize.five_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4 + Randomize.choice5
        Randomize.six_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4 + Randomize.choice5 + Randomize.choice6
        Randomize.seven_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4 + Randomize.choice5 + Randomize.choice6 + Randomize.choice7
        Randomize.eight_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4 + Randomize.choice5 + Randomize.choice6 + Randomize.choice7 + Randomize.choice8
        Randomize.nine_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4 + Randomize.choice5 + Randomize.choice6 + Randomize.choice7 + Randomize.choice8 + Randomize.choice9
        Randomize.ten_letters = Randomize.choice1 + Randomize.choice2 + Randomize.choice3 + Randomize.choice4 + Randomize.choice5 + Randomize.choice6 + Randomize.choice7 + Randomize.choice8 + Randomize.choice9 + Randomize.choice10
        Randomize.word_length = [Randomize.three_letters, Randomize.four_letters, Randomize.five_letters, Randomize.six_letters, Randomize.seven_letters, Randomize.eight_letters, Randomize.nine_letters, Randomize.ten_letters]
        Randomize.word = random.choice(Randomize.word_length)

name = Randomize()
name.gen()
print('Generated 10 names.')

EDIT*

I found that a combination of the advice I recieved worked best. Here is the new version that is vastly superior to my first attempt. Using .join and the parameter k to set the length of each string generation was a massive revelation for me. Thanks.

import random

def gen():
    ltrs = list('abcdefghijklmnopqrstuvwxyz')
    word = "".join(random.choices(ltrs, k=random.randint(3,10)))
    for i in range(1000):
        print(word)
        word = "".join(random.choices(ltrs, k=random.randint(3,10)))

gen()

Upvotes: 0

Views: 91

Answers (4)

neutrino_logic
neutrino_logic

Reputation: 1299

Python has some interesting syntax shortcuts that, once learned, can do a lot in a few lines of code. Assignments by hand can be automated with loops and loops can be condensed into comprehensions, one of Python's best features.

First, you can generate your alphabetical string without needing to import a separate module like string, using ascii ordering. Here ''.join() makes a string out of a list, not strictly necessary, and the list is constructed using the chr() and ord() methods (watch out for off-by-one errors)

ltrs = ''.join([chr(x) for x in range(ord('a'), ord('z') + 1)])   
>>> 'abcdefghijklmnopqrstuvwxyz'

You can import just the one function randint you need from the library, and use another list comprehension to generate a word:

from random import randint
def gen_word(minlen, maxlen, ltrs):
    wordlen = randint(minlen, maxlen + 1)
    return ''.join([ltrs[randint(len(ltrs)] for _ in range(wordlen)])

To use another list comprehension to generate 10 words:

mywordlist = [gen_word(3,10,ltrs) for _ in range(10)]

With this function, ltrs can be any string or sequence of characters. The '_' is standard syntax that indicates the variable is a throwaway, just used for running the loop in this case. The real key thing to learn is how to take for loops and convert them to list comprehensions. You might try practicing this using the code supplied by M. Iduoad above.

Upvotes: 0

Iduoad
Iduoad

Reputation: 985

this

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

is equivalent to this

import string
alphabet = string.ascii_lowercase

Then you can use a method to generate random string giving a length

def get_random_string(length):
    alphabet = string.ascii_lowercase
    result_str = ""
    for i in length:
        result_str += random.choice(alphabet) 
    return result_str

Finally use it to generate you random string undefinetely

for i in range(10):
    length = random.randint(3,9)
    random_string = get_random_string(length)
    print(random_string)

The resulting script will be

import string
import random
alphabet = string.ascii_lowercase

def get_random_string(length):
    alphabet = string.ascii_lowercase
    result_str = ""
    for i in length:
        result_str += random.choice(alphabet) 
    return result_str

for i in range(10):
    length = random.randint(3,9)
    random_string = get_random_string(length)
    print(random_string)

Upvotes: 0

Atto Allas
Atto Allas

Reputation: 610

There are a few things here which might be improved.

First, in this example, "Randomize" does not need to be a class and can instead just be replaced by a single function (let's call it randomWord()). Secondly, a you can choose the number of letters to use using the same random library you are already using, just with a different function (random.randint). Finally, there's a built-in way to get the lowercase alphabet (string.ascii_lowercase), so there's no need to type it yourself.

Here is some example code you could use:

import random
from string import ascii_lowercase as alphabet

def randomWord():
    length = random.randint(3, 10) # randint gives you a random number between the two arguments, inclusive
    word = "" # initialises an empty string that we will build up with letters
    for i in range(length): # iterates 'length' times
        word += random.choice(alphabet) # this appends a new random letter to the word we're building up
    return word

print(randomWord())
print("We printed a random word between 3 and 10 characters!")

You could of course put randomWord() in a for loop to get 10 random words.

Upvotes: 0

AirSquid
AirSquid

Reputation: 11903

Welcome to the site!

There are several ways to select things randomly from a collection. You can check the dox on:

random.choice()
random.choices()
random.sample()

for inspiration. Also, the numpy library has some options.

If you want to sample with replacement then random.choices is a good pick

In [7]: from random import choices   

In [11]: a = list('abcdefghijklmnopqrstuvwxyz')                                                             

In [12]: choices(a, k=10)                                                                                   
Out[12]: ['l', 'a', 'c', 'y', 's', 'u', 'c', 'n', 'g', 'n']

In [13]:  

Upvotes: 1

Related Questions