The NATO-Phonetic Name Generation Project

Understand Python List & Dictionary Comprehensions and apply these concepts to a real project.

TechNotes by Abby
8 min readSep 6, 2021

Project based learning has long proven to be one of the most effective code-learning techniques. I have come across a lot of people pouring through hours of tutorials unsuccessfully, and at the end they are unable to put together some code to create a working project.

The NATO-Phonetic project explained in this blog is a beginner-intermediate project that puts together some concepts of python programming and working with data.

Some of the concepts that this project will teach include

  • List Comprehensions
  • Dictionary comprehensions
  • Dealing with dictionaries (such as how to index dictionaries)
  • Using pandas to work with data

So, lets start from the beginning.

What Project are we building?

Photo from hackaday.com

First, a little bit of a background here. You have probably been in situations where you need to spell your name. Depending on where you come from, it might be hard for the person on the other end of the line to tell whether you are referencing to a “p” or a “b”. As a result you might have to give a corresponding code name so that the spelling is correctly understood.

This is what the NATO-Alphabet was invented to solve . It consists of 26 code words for every letter of the alphabet to ensure that each letter is easily and distinctly understood regardless of language or geographic differences.

Taking an example: If I enter the name : “Abby”

The output i receive will be a list : [“Alfa”, “Bravo”, “Bravo”, “Yankee”]. By reading these words, the person on the other end of the line will be able to get the correct spelling of the name.

One of the files that will be used in this project is a csv file that contains two columns: The letter and the corresponding code name. The file can be viewed here.

First,import the file data into the python environment. To do that, you will have to use the pandas library that is a library in python that is used when working with data.

# Import the pandas library
import pandas
#import/read the data file
data = pandas.read_csv('nato_phonetic_alphabet.csv')
#To view what the data looks like, print the imported data
print(data)

The output:

      letter   code
0 A Alfa
1 B Bravo
2 C Charlie
3 D Delta
4 E Echo
5 F Foxtrot
6 G Golf
7 H Hotel
8 I India
9 J Juliet
10 K Kilo
11 L Lima
12 M Mike
13 N November
14 O Oscar
15 P Papa
16 Q Quebec
17 R Romeo
18 S Sierra
19 T Tango
20 U Uniform
21 V Victor
22 W Whiskey
23 X X-ray
24 Y Yankee
25 Z Zulu

The output has the index(row number) and two columns : The letter and the code.

The first thing to do is to ask the user to give a name they need code words for.

name = input("Please enter the name").upper()# The upper() function is used because python is case sensitive and looking at the data we have, the letter column is in upper case. This ensures that in case the user inputs their name in all lowercase,they are changed to uppercase.  

Once the user inputs their name, the next thing will be to come up with a list of code words corresponding each letter of the name. Therefore, we are required to match each letter of the name to the corresponding code word in the csv data file we have.

The first logical thing to do therefore will be to convert the data frame into a dictionary, with the key being the letter and the value being the code name. Then we will look up each letter in the user’s name and output the corresponding code name

In order to fully understand how to complete this mini project, we need to understand the logic behind list and dictionary comprehensions.

Dealing with lists — Introduction

Example:

If you are given a list of numbers[1,2,3,4] and you are asked to double the numbers, the process of solving that would look like:

num_list = [1,2,3,4]doubled_list = []     
# Create an empty list that will contain the doubled numbers
for number in num_list: #Loop through all the numbers in the list
new_num = number*2 #for each number, double it(multiply by 2)
doubled_list.append(new_num) #append it to an empty list
print(doubled_list) # Print out the new list

a) List Comprehensions

From the illustration above to double the list, we have to create an empty list, loop through each of the given numbers, double it and then append the numbers to an empty list. This is a long process that can be done in one line of code. This is what is referred to as a list comprehension.

The syntax of a list comprehension looks like this:

new_list = [new_item for item in list]

To explain this further, the (new_list) is the list we are trying to create. In this case, that is the doubled_list.

The new_item is what we need to do in order to achieve the final list. In this case, we need to multiply each of the numbers by 2.(number* 2)

The last part of the equation is to iterate through the list. And remember the square brackets because it is a list that is being created.

Now, taking all that into consideration, substitute the key words with the code.

doubled_list = [number * 2 for number in range(1,5)]
print(doubled_list)

The code above will produce the same result as the code before but its more elegant and the lines are few.

Note: The range function takes the numbers from the first number to the number before the last number. For instance, if I were to write the code below

for number in range(1,5):
print(number)

The output will be:

1
2
3
4

The numbers displayed will not include the number 5.

b) Dictionary Comprehensions

Dictionary comprehensions are very similar to the list comprehensions.

  • If you are not familiar with dictionaries, a dictionary is a a set of keys and values in curly braces. For example, a good situation where a dictionary would be useful would be for instance when you have a group of people and you would like to have their corresponding ages.
nameAge_dict = {
"Abby":39,
"Steve":45,
"Edwin":22,
"Alex":18,
"Alice":15
}

Above is an example of a list of people’s names and their ages. Now it is good to note that dictionaries can take in various data types. The names for instance are strings and as a result are in quotation marks. The ages on the other hand are integers. These are connected through a colon. The names in this case are known as the keys and the ages are the values.

If for instance, given the dictionary above, you are asked to print out the list of people who are 25 and below. How would you go about it?

  1. First, you need to check the values and check whether the age is less than or equal to 25. But how do you do that exactly, will need understand on iterating/looping through dictionaries.
  • Check the code below.
for x in nameAge_dict:
print(x)

The output it will give will be:

Abby
Steve
Edwin
Alex
Alice

Note that only the keys get printed. The values part of he dictionary is not printed.

In order to get a hold of the ages, the syntax, we will include the function values(). This will tap into the dictionaries and print out the values.

for age in nameAge_Dict.values():
print(age)

The output will be:

39
45
22
18
15

However, if we want to print out each name and its corresponding ages. Then the keyword to introduce will be items()

for new_dict in nameAge_dict.items():
print(new_dict)

The result will be as follows:

  • It is a tuple with the name and the age. This means that when iterating through a dictionary, the items will take the format of a tuple: (key, value)
('Abby', 39)
('Steve', 45)
('Edwin', 22)
('Alex', 18)
('Alice', 15)

Now that you know how to iterate through a dictionary, if we are to print the people who are 25 and below, the syntax will look like:

for (name, age) in nameAge_Dict.items():
if age <= 25:
print (dict(name, age))

The output will be:

Edwin 22
Alex 18
Alice 15

When using a dictionary comprehension, the logic is still the same. Just that it is a one-liner that is meant to simplify things.

The syntax is:

new_dict = {key, value for (key, value) in dictionary if condition}

Substituting that with the correct code:

new_dict = {name:age for (name, age) in nameAge_Dict.items() if age <=25}

The output will be:

{'Edwin': 22, 'Alex': 18, 'Alice': 15}

And that is how dictionary comprehensions work.

c) NATO-Phonetic Project

Now that I believe the basics are clear, we will go back to creating a dictionary from the data that we have.

As you remember, the data frame looks like this:

      letter   code
0 A Alfa
1 B Bravo
2 C Charlie
3 D Delta
4 E Echo
5 F Foxtrot
6 G Golf
7 H Hotel
8 I India
9 J Juliet
10 K Kilo
11 L Lima
12 M Mike
13 N November
14 O Oscar
15 P Papa
16 Q Quebec
17 R Romeo
18 S Sierra
19 T Tango
20 U Uniform
21 V Victor
22 W Whiskey
23 X X-ray
24 Y Yankee
25 Z Zulu

We will loop through each row of the data set provided and create a dictionary. The columns you see are the index(which is basically the row number), the letter and the code.

When dealing with dictionaries, we used the items() function to loop through each set of keys and values. When dealing with data frames, the function that does the same thing is called iterrows()

The syntax looks like:

index, row for(index, row) in dataframe.iterrows()

The index is the row number.

The row in the given data frame will represent the two rows (letter and code)

The iterrows() function basically loops through each row in the data frame.

However, you realize that we dont need the index as part of the dictionary. As a result, we will tap into the row part and get hold of the letter column and the row column.

# Create the dictionary word_dict = {row.letter:row.code for (index, row) in dataframe.iterrows()}

An explanation of the code:

The dataframe.iterrows() will produce one row per loop that contains the index, the letter and code.

In the first part of the code, look into the row part that has two columns. If you want to extract the value for the letter, one way to do it is:

row["letter"]  # This is the same as row.letter# I opted for the second version because it looks more elegant. 

Once the code is run, the results are:

{'A': 'Alfa', 'B': 'Bravo', 'C': 'Charlie', 'D': 'Delta', 'E': 'Echo', 'F': 'Foxtrot', 'G': 'Golf', 'H': 'Hotel', 'I': 'India', 'J': 'Juliet', 'K': 'Kilo', 'L': 'Lima', 'M': 'Mike', 'N': 'November', 'O': 'Oscar', 'P': 'Papa', 'Q': 'Quebec', 'R': 'Romeo', 'S': 'Sierra', 'T': 'Tango', 'U': 'Uniform', 'V': 'Victor', 'W': 'Whiskey', 'X': 'X-ray', 'Y': 'Yankee', 'Z': 'Zulu'}

And now all that we need to do is match the letters in the user’s name to the code names

name_list = [word_dict[letter] for letter in name]
print(name_list)

An explanation for the code above:

for letter in name #This part of the code prints out each letter in the user's name 

The next part of the code:

word_dict[letter] # This part of the code goes into the dictionary, and for each letter fetches the corresponding code word. finally, print out the code word. 

To fully understand that, using the example dictionary earlier:

nameAge_dict = {
"Abby":39,
"Steve":45,
"Edwin":22,
"Alex":18,
"Alice":15
}

if you wanted to find Abby's age: The code will be:

nameAge_dict["Abby"]# Tap into the dictionary and look up the key with the name "Abby" This code if printed, will output : 39

That is the same logic applied.

Thank you for reading my painfully long blog. And Happy Learning!!

The complete version of the code can be found on my GitHub here.

--

--

TechNotes by Abby

Student at Michigan State University; writing about all things tech!