November 15, 2023
More Python strings - handy tricks
In a previous post I introduced strings - sequences of characters - in Python. I'd like to introduce a few handy features with an example. In this article, we will create a password generator tool that uses command-line inputs.
Purpose
This article will demonstrate the use of Python's pre-built strings constants and working with input arguments from the command line.
Audience
This article will appeal to newbies and anyone looking for cool, useful features in Python regarding strings and command line.
Prerequisites
- python interpreter - my starter article is a good place to start
- IDE or text editor
- if you are unfamiliar with Python's "if" statements, have a look at my article on conditional execution
- this article uses exception handling to help provide a smooth service. I have written an article on exceptions for those unfamiliar
Introduction
Most systems require strong passwords, strings that contain a mixture of upper and lower case letters, numbers, and special characters. Strong passwords should be random, not resembling words or names. In this tutorial, we will create a Python program that generates a strong, random password.
Our program will ask the user for two parameters:
- password length - the number of characters the password should have
- what the password should contain - we will allow the user to specify that the password should contain uppercase (u), lowercase (l), numbers (n), punctuation (p), or a combination of them
Step-by-step
If you are an aficionado of my previous tutorials, you will have seen that I tend to build up my programs in gradual pieces, sometimes line by line. In this tutorial, I will 'code dump' the finished product and then walk you through it.
- create a file called password.py - populate with the code below
import random
import string
import sys
def get_command_line_string_constants():
valid_options = ['u', 'l', 'd', 'p']
valid_argument_found = False
characters = ""
try:
for arg in (sys.argv[1]):
if arg in valid_options:
valid_argument_found = True
if arg == 'u':
characters += string.ascii_uppercase
if arg == 'l':
characters += string.ascii_lowercase
if arg == 'd':
characters += string.digits
if arg == 'p':
characters += string.punctuation
return characters, valid_argument_found
except IndexError:
print("At least one argument required")
exit()
def get_length_argument():
length = 8
try:
length = int(sys.argv[2])
if length > 32:
print("Length limit is 32")
length = 32
except IndexError:
print("Defaulting to eight digits")
except ValueError:
print("Defaulting to eight digits")
return length
def generate_password():
characters, valid_argument_found = get_command_line_string_constants()
length = get_length_argument()
if valid_argument_found:
password = ""
for i in range(length):
password += random.choice(characters)
return password
else:
return "no valid options provided"
print(generate_password())
- Save and close the file. Now let's test it out! Run the program with this command: python password.py uld 8
You should see a response such as:
SmDykSjj
In summary:
The program consists of four parts:
- function get_command_line_string_constants - this function's job is to take the first argument passed to the program - e.g., 'uld' and translate it to something that the program can use. If the user did not enter a valid option OR anything at all, it will print an message and terminate the program,
- function get_length_argument - this function takes the second argument and checks that it is an integer less than 32. If the user did not provide a valid number, it returns 8 as the default. If the user specified a number larger than 32, it prints a message and defaults to 32.
- function generate_password - this function does the work of generating the password. It uses the previous two functions.
the last part a single line that invokes the generate_password function and prints the output
NOTE: assigning various tasks into their own functions makes code more readable and easier to maintain. If you are new to the art of coding, now is the best time to learn about clean code.
You may glean everything you need simply from reading my (hopefully clean) code, otherwise do stay with me for a breakdown of each function!
get_command_line_string_arguments
- The function begins by listing the valid input characters in an array - they here are 'u', 'l', 'd', and 'p'.
- we then specify a Boolean flag called 'valid_argument_found' initialised to False
- the empty string 'characters' will hold the array of possible characters from which we can randomly generate our password
- the next block of code, wrapped in a try...except block, introduces a "for" loop. Look out for a tutorial on loops but for now understand that we are simply running though each character provided in the argument. For example, if the user keyed in 'ul', we will execute the nested code twice - once for 'u' and another for 'l'.
- for each input character, we check if it exists in our 'valid_options' array, if it does, we can set the valid_argument_found argument to True - so far so good!
- now we check each character's value. Notice that in our program's first three lines, we imported several libraries, one of them was simply called 'string'. This library gives us some useful stuff, specifically lists of all uppercase, lowercase, digit, and punctuation characters. It saves us a lot of typing out!
- now, for every valid input argument, for example, 'u', we add (+=)the corresponding list of characters to our 'characters' string.
- if all goes well, we return the 'valid_argument_found' and 'characters' fields.
get_length_argument
- initialise the length to 8
- now we check the second input parameter in the argv list
- we wrap the check in a try...except block, checking for two exceptions:
- IndexError - there is no second argument
- ValueError - the user didn't provide a valid number
- if the length is more than 32, we return a length of 32, otherwise, we return the value entered
generate_password
here's where we pull it all together
- call the get_command_line_string_arguments - store the outputs in fields called "characters" and "valid_argument_found fields"
- call get_length_argument - store the value in a field called "length"
- if valid_arguments_found is True
- create a password field
- the 'for' block adds one character at random from the list of selectable characters in our "characters" field, and we do this once for as long as the "length" field
- in the end, we we return our password, if no valid arguments were found, we print an error and exit.
266 views