Correcting python code for using functions

Question:

So huge disclaimer first: I am very new to python and programing in general, and this is my first time using functions. I would be very glad for any help, but the end goal here is not to have the prettiest or the most efficient code. I just want it to somehow work.

I have written the program below but I can’t get it to work properly.

Because this is a graded exercise for Uni I have certain restrictions that I am supposed to follow:

This is my code:


import re
import sys
# get the filename
filename = sys.argv[1]

# open a file for reading
infile = open(filename, 'r')


########################################################################################
# function to return just the consonants in a given namecdef get_consonants(y):
def get_consonants(y):
    only_consonants_sep = re.findall('[^W_aeiou]', y)
    only_consonants = ''.join(only_consonants_sep)
    return only_consonants


########################################################################################
# function to return first and last name according to all rules
def parse_name(input_y):
        
    # Parse the names to first (meaning first+middle, if it exists) and last names
    for element in input_y:
    
        # define last name for later use
        last_namegroup = re.search('(w*)t', element)
        last_name = last_namegroup.group(1)
        
        # define what the middle name is for later use
        middle_namegroup = re.search('s(w)', element)
        middle_name = middle_namegroup.group(1)
        
        # define what first name is for later use
        first_namegroup = re.search('^(S*)', element)
        first_name1 = first_namegroup.group(1) 
            
        
                # if length of consonant_first_middle is still larger than 8
                # take the consonants of only the first name
                # and add the first letter of the middle name defined above 
                if len(consonant_first_middle) > 8:
                    consonant_first_name = get_consonants(first_name1)
                    first_name = (f'{consonant_first_name}{middle_name}')
        
        # if there is no middle name, i.e. only ones white space in the line
        # then just take the word until the space and store it as first_name
        else:
            first_namegroup = re.search('^(S*)', element)
            first_name = first_namegroup.group(1)   
        
                    
    return(first_name, last_name)
    

########################################################################################
# creating the email addresses
def create_email_address(first_name, last_name):
    
    for lines in infile:
        if re.search('tstu', lines):
            domain = (f'{first_name}.{last_name}@uzh.ch')
        else:
            domain_part = re.search('t(.*)$',lines)
            domain = (f'{first_name}.{last_name}@{domain_part.group(1)}.uzh.ch')
    return domain

########################################################################################
# function as the "top level" of the program that calls all other functions as needed.

def main():
  
    ####### Receive a file name from the command line
    # get the filename
    filename = sys.argv[1]
    # open a file for reading
    infile = open(filename, 'r')
    
    ####### Normalise the input
    input_normalized = normalize(infile)
    
    ####### Parse the names as needed
    input_first, input_last = parse_name(input_normalized)
    
    ####### Create email addresses
    email_output = create_email_address(input_first, input_last)
    
    ####### Print the result
    for line in infile:
        print(f'{line} --> {email_output}')

main_function = main()
print(main_function)


As you can see, I think I did somethinf wrong with how the file is iterating through my code, but I simply can't figure out what I am doing wrong.

I appreciate everything you could point out to me!




Asked By: zara.b

||

Answers:

In my first answer, I tried not to change too much code, but I think it will be easier to re-think the logic, and rewrite the code. Here’s what I came up with, I think this does what you need?

import sys, re


def normalize(name):
    name = name.lower()
    name = re.sub('ä', 'ae', name)
    name = re.sub('ü', 'ue', name)
    name = re.sub('ö', 'oe', name)
    name = re.sub('é|ë', 'e', name)
    return name


def remove_vowels(name):
    return re.sub('a|e|i|o|u', '', name)
    

def main(filename):
    # a list to store our output
    people = []

    # let's loop through each line, looking at
    # just one person at a time
    for line in open(filename, "r"):
        # remove trailing n from each line
        line = re.sub("n", "", line)

        # separate the name and domain
        name, domain = re.split("t", line)

        # remove the accents and capitals
        normalized_name = normalize(name)

        # separate the name
        # we use a "*" so that the first and last names
        # are selected correctly, and then any remaining
        # characters in between are put into the middle name.
        first_name, *middle_name, last_name  = re.split(" ", normalized_name)
        middle_name = "".join(middle_name)

        full_first_name = first_name + middle_name

        # this is where we check for how
        # long the first and middle names are
        if len(full_first_name) > 8:
            full_first_name = remove_vowels(full_first_name)

            # now we check if this is still too long
            if len(full_first_name) > 8:
                full_first_name = remove_vowels(first_name)

                # check if they actually have a middle name
                if middle_name:
                    full_first_name += middle_name[0]
        
        # now let's grab the domain
        subdomain = ""
        if domain != "stu":
            subdomain = domain + "."
        
        host = subdomain + "uzh.ch"

        
        # now let's format this into an address
        address = f"{full_first_name}.{last_name}@{host}"

        people.append((name, address))

    return people



filename = sys.argv[1]
people = main(filename)

for name, address in people:
    print(name, "-->", address)

Output:

Raphael Fritz Bernasconi --> [email protected]
Frédéric Piero --> [email protected]
Sören Thaddäus Favre --> [email protected]
Regula Aegerter --> [email protected]
Noël Äbiger --> [email protected]
Inés Desirée Muff --> [email protected]
Sébastien Merian --> [email protected]
Liam Cereghetti --> [email protected]
Björn Michael Crivelli --> [email protected]
Joëlle Fürrer --> [email protected]

Hopefully the comments in the code do a good job of explaining what’s going on.

Answered By: Ed Ward