IndexError after running program multiple times
<p>After running my program that generates passwords multiple times I get an IndexError: list Index out of range. I am not sure what is causing the problem</p>

<pre><code>import string
import random

def random_pass(length):
    alphabet = list(string.ascii_letters + string.digits + string.punctuation)
    password = []
    upper_case = list(string.ascii_uppercase)
    count = 0
    while count &lt; length:
            random_num = random.randint(0,len(alphabet))
            password.append(alphabet[random_num])
            #Checks to see if first character is a uppercase Letter
            if password[0] not in upper_case:
                first_letter = random.randint(0,len(upper_case))
                password[0] = upper_case[first_letter]
            count += 1
    return ''.join(password)
def welcome():
  print("*****************************************************************")
  print("*****************************************************************")


def main(): 
    try:
        get_length = int(input("Please enter the length of your password "))
    except ValueError:
        print("Please enter numbers only")
        main()
    else:
        print("Your {} character password is {}".format(get_length, random_pass(get_length)))
        restart = input("Do you wish to create another password? y/n")
        password = []
    if restart.lower() == 'y':
        main()
    else:
        exit()
main()
</code></pre>

<p>Antti Haapala's answers your question but I see a few things that could be improved in your code. The idea is to make your code clearer.</p>

<p>First of all here's my version of your code:</p>

<pre><code>import string
import random

alphabet = string.ascii_letters + string.digits + string.punctuation

def random_pass(length):
    first_character = random.choice(string.ascii_uppercase)
    password = ''.join(random.choice(alphabet) for x in range(length - 1))
    return first_character + password

another_password = True
while another_password:
    try:
        length_requested = int(input("Please enter the length of your password "))
    except ValueError:
        print("Please enter numbers only")
        another_password = True
    else:
        print("Your {} character password is {}".format(length_requested, random_pass(length_requested)))
        restart = input("Do you wish to create another password (Y/N)? ")
        another_password = restart.lower() == 'y'
</code></pre>

<p>The modifications I made of you code:</p>

<ul>
<li>Since <code>alphabet</code> is never modified, you don't need to recreate it each time you call <code>random_pass()</code>. I have put it in the global scope outside of every functions</li>
<li>Since you can access a character inside a string the same way you access an element in a list you don't need to create a list with the content of <code>alphabet</code> or <code>string.ascii_uppercase</code>.</li>
<li>You don't gain more understanding defining a variable with the same content of <code>string.ascii_uppercase</code></li>
<li>Instead of choosing a random number that you use to choose a character in <code>alphabet</code>, you can directly choose a random character with <a href="https://docs.python.org/3.5/library/random.html#random.choice" rel="nofollow"><code>random.choice(alphabet)</code></a></li>
<li>It looks like you have a requirement that the first character of the password has to be an upper case letter. In your code you check this inside your while-loop for each new character but that first character won't change once you set it. So I dragged it outside of this loop.

<ul>
<li>Since your first character is going to chosen inside <code>string.ascii_uppercase</code>, I used <a href="https://docs.python.org/3.5/library/random.html#random.choice" rel="nofollow"><code>random.choice(string.ascii_uppercase)</code></a> for it.</li>
</ul></li>
<li>To build the rest of the password, I used a <a href="https://docs.python.org/3.5/tutorial/classes.html#generator-expressions" rel="nofollow">generator expression</a> to choose a random character from <code>alphabet</code> and the <a href="https://docs.python.org/3/library/stdtypes.html#str.join" rel="nofollow"><code>.join()</code></a> string method. Since I have already chosen the first character I only need <code>length - 1</code> random characters.</li>
<li>You don't need to define <code>main()</code> if all you do is call it later.

<ul>
<li>Even if you define <code>main()</code> it's not a good idea to call it recursively because for every new password requested (and every time an invalid input is entered by the user), your code has to create a new small scope environment for this function call and, more importantly, it has to keep of all previous small scope environment. You risk exhausting memory eventually. I have used instead a while-loop.</li>
</ul></li>
<li><code>restart.lower() == 'y'</code> will give a boolean value I have used to change <code>another_password</code> which controls whether we continue to ask the user if it wants a new password</li>
<li>You don't need to call <code>exit()</code> unless you want to return an exit code to the environment.</li>
</ul>

<p>If you have more questions, don't hesitate to ask. And continue experimenting.</p>

python