Python – read txt file into list – display contents of the new list

Tags:



I did ask this before on a different account but i lost the account and didnt see most comment or answers people gave so i have asked on this older account of mine

Im new to python and programming in general so i am not understanding what i should be doing to get the output that is expected. I think i got the read_file function correct but im not sure.

I have been looking at this for a while and im no closing to understanding how exactly to do this part.

The goal here is to display profiles from a text file but in a specific way.

the rules are:

Your solutions MAY make use of the following:
•   Built-in functions int(), input(), print(), range(), open(), close(), len() and str().
•   Concatenation (+) operator to create/build new strings.
•   The list_name.append(item) method to update/create lists.
•   Access the individual elements in a string with an index (one element only).  i.e. string_name[index].
•   Access the individual elements in a list with an index (one element only).  i.e. list_name[index].
•   Profile objects and methods (as appropriate).  
•   The list_function.py module (that you wrote in part A of this assignment).  You may like to make use of some of the functions defined in the list_function.py module for this part of the assignment (as appropriate).  Not all will be suitable or appropriate.

Your solutions MUST NOT use:
•   Built-in functions (other than the int(), input(), print(), range(), open(), close() len() and str() functions).
•   Slice expressions to select a range of elements from a string or list.  i.e. name[start:end].
•   String or list methods (i.e. other than those mentioned in the 'MAY make use' of section above.
•   Global variables as described in week 8 lecture.
•   The use break, return or continue statements (or any other technique to break out of loops) in your solution – doing so will result in a significant mark deduction.

here are some descriptions i have been given:

o   display_summary(profile_list)
This function will take the list of profile objects as a parameter and will output the contents of the list to the screen.  This function displays the information to the screen in the format specified in the assignment specifications under the section - 'Screen Format'.  You must use a loop in your solution.

o   read_file(filename, profile_list)
This function takes a file name and reads the contents of that file into the profile_list (list) passed as a parameter into the function.  The function returns the list of profile objects.  You must use a loop in your solution.  You may use String and/or List methods in this function only.  You may find the String methods split() and strip() useful here.

the expected output is:

Please enter choice [summary|add|remove|search|update|quit]: summary

==============================================================================
Profile Summary
==============================================================================
------------------------------------------------------------------------------
Fox Mulder (m | fox@findthetruth.com)
- The truth is out there!
- Friends (1):
    Tony Stark
------------------------------------------------------------------------------
Tony Stark (m | tony@ironman.com)
- Saving the world is hard work - no time for friends.
- No friends yet...
------------------------------------------------------------------------------
Phil Dunphy (m | phil@dunphy.com)
- wtf? = why the face?
- Friends (2):
    Robbie Gray
    Fox Mulder
------------------------------------------------------------------------------
John Mayer (m | john@guitar.com)
- Waiting on the world to change!
- Friends (2):
    Katy Perry
    David Guetta
------------------------------------------------------------------------------
Katy Perry (f | katy@perry.com)
- Waiting on John to change.
- Friends (3):
    John Mayer
    David Guetta
    Jimmy Fallon
------------------------------------------------------------------------------
David Guetta (m | dguetta@willworkwithanyone.org)
- Will collaborate with anyone who has a heartbeat.
- Friends (5):
    Katy Perry
    John Mayer
    Tony Stark
    Fox Mulder
    Robbie Gray
------------------------------------------------------------------------------
Jimmy Fallon (m | jimmy@tonightshow.com)
- I wish I was as good as Letterman, thank goodness he's retiring.
- Friends (2):
    Robbie Gray
    Tony Stark
------------------------------------------------------------------------------
Robbie Gray (m | robbie@football.com)
- Training hard... can we win?  Yes we Ken!
- Friends (4):
    Jimmy Fallon
    Fox Mulder
    John Mayer
    Tony Stark
------------------------------------------------------------------------------
==============================================================================

The text is being read from a text file that looks like this:

Fox Mulder fox@findthetruth.com m
The truth is out there!
1
tony@ironman.com
Tony Stark tony@ironman.com m
Saving the world is hard work - no time for friends.
0
Phil Dunphy phil@dunphy.com m
wtf? = why the face?
2
robbie@football.com
fox@findthetruth.com
John Mayer john@guitar.com m
Waiting on the world to change!
2
katy@perry.com
dguetta@willworkwithanyone.org
Katy Perry katy@perry.com f
Waiting on John to change.
3
john@guitar.com
dguetta@willworkwithanyone.org
jimmy@tonightshow.com
David Guetta dguetta@willworkwithanyone.org m
Will collaborate with anyone who has a heartbeat.
5
katy@perry.com
john@guitar.com
tony@ironman.com
fox@findthetruth.com
robbie@football.com
Jimmy Fallon jimmy@tonightshow.com m
I wish I was as good as Letterman, thank goodness he's retiring.
2
robbie@football.com
tony@ironman.com
Robbie Gray robbie@football.com m
Training hard... can we win?  Yes we Ken!
4
jimmy@tonightshow.com
fox@findthetruth.com
john@guitar.com
tony@ironman.com

I have made this so far:

import profile

def get_menu_choice():
    list_choice = ['summary', 'add', 'remove', 'search', 'update', 'quit']
    #User inputs an option
    choice = input(str('nPlease enter choice [summary|add|remove|search|update|quit]: '))
    #Start a loop if they enter an invalid input
    while choice not in list_choice:
        print('nNot a valid command - please try again.')
        choice = input(str('nPlease enter choice [summary|add|remove|search|update|quit]: '))
        #end of loop here
    return choice


# Function read_file() - place your own comments here...  : )
def read_file(filename, profile_list):

profile_list = []  
filename = open("profiles.txt", "r")


for line in filename:
    stripped_line = line.strip()
    profile_list = stripped_line.split()
    filename.append(profile_list)

filename.close()

print(profile_list)


# Function display_summary() - place your own comments here...  : )
def display_summary(profile_list):

print('========================================')
print('Profile Summary')
print('========================================')

display_details()
active = 'y'
while active == 'y':
    choice = get_menu_choice()
    if choice == 'summary':
        display_summary()
    elif choice == 'quit':
        active = 'n'

the import profile is referring to this file:

class Profile:

    # The __init__ method initializes the data attributes of the Profile class
    def __init__(self, given_name='', family_name='', email='', gender='', status=''):
        self.__given_name = given_name
        self.__family_name = family_name
        self.__email = email
        self.__gender = gender
        self.__status = status
        self.__number_friends = 0
        self.__friends_list = []

    
    def set_given_name(self, name):
        self.__given_name = name
        
    def get_given_name(self):
        return self.__given_name

    def set_family_name(self, name):
        self.__family_name = name

    def get_family_name(self):
        return self.__family_name

    def set_email(self, email):
        self.__email = email

    def get_email(self):
        return self.__email

    def set_gender(self, gender):
        self.__gender = gender

    def get_gender(self):
        return self.__gender

    def set_status(self, status):
        self.__status = status

    def get_status(self):
        return self.__status

    def set_number_friends(self, no_friends):
        self.__number_friends = no_friends

    def get_number_friends(self):
        return self.__number_friends

    def set_friends_list(self, friends_list):
        self.set_number_friends(len(friends_list))
        self.__friends_list = friends_list

    def get_friends_list(self):
        return self.__friends_list


    # The __str__ method returns a string representation of the object
    def __str__(self):
        string = self.__given_name + ' ' + self.__family_name + ' ' + self.__email + ' ' + self.__gender + 'n'
        string += self.__status + 'n'
        string += str(self.__number_friends) + 'n'
        for friend_email in self.get_friends_list():
            string += friend_email + 'n'
        return string


    # The method add_friend adds an email address to the friends_list only if the email doesn't already exist.
    # No duplicate entries allowed.  The method returns True if successful and False otherwise.
    def add_friend(self, email):
      
        # Check to see whether email already exists in the friends list
        if self.is_friend(email) == True:
            return False;

        # Otherwise, okay to add friend and increment number of friends count
        self.__friends_list.append(email)
        self.__number_friends += 1

        return True

    # The method remove_friend removes an email address from the friends_list (if found).
    # Method returns True if successful and False otherwise.
    def remove_friend(self, email):

        # Check to see whether email exists in the friends list
        if self.is_friend(email) == False:
            return False;

        # Otherwise, okay to remove friend and decrement number of friends count
        self.__friends_list.remove(email)
        self.__number_friends -= 1

        return True


    # The method is_friend determines whether the email passed in as a parameter
    # exists in the friends_list, i.e. they are friends.
    # If the email is found in the friends_list, the method will return True.
    # If the email is not found, the function returns False.
    def is_friend(self, email):        
        found = False

        for email_address in self.__friends_list:
            if email == email_address:
                found = True
            
        return found


    # The __eq__ method allows for a test for equality (is equal to) on email address i.e. == operator.
    def __eq__(self, email):
        if self.__email == email:
            return True
        elif self.__email != email:
            return False
        return NotImplemented

Im so confused by this. Would anyone be able to explain it or give any pointers.

Ive tried to make this question as easy to understand as i could.

Thanks.

Answer

Updated code with both read_file() and display_summary() function

Output is the same as before. Packaged the code into two functions per the original requirement.

Please review this and see how to implement it in your code.

# Function read_file()
def read_file(filename, profile_list):

    profile_list = []
    people = {}
    temp = []

    f1 = open(filename, "r")

    for line in f1:
        
        stripped_line = line.strip()
        temp = stripped_line.split()

        #check if line has name, email, and sex (profile info)
        if (temp[-1] == 'm') or (temp[-1] == 'f'):
            ln = len(temp)
            temp_concat = ''
            for i in range(ln-3):
                temp_concat = temp_concat + temp[i] + ' '
            temp_concat = temp_concat + temp[ln-3]

            #store name, email, and sex as separate values into the list
            profile_list.append([temp_concat, temp[-2], temp[-1]])

            #store into dict: email as key, name as value for ease of lookup
            people[temp[-2]] = temp_concat
        else:
            profile_list.append(stripped_line)

    f1.close()

    #add people dictionary as last item into the profile_list list
    profile_list.append(people)

    return profile_list

# Function display_summary()    
def display_summary(profile_list):
    #now we are ready to print the profiles
    print ('=' * 78)
    print ('Profile Summary')
    print ('=' * 78)

    #print_line will determine what kind of data to print
    #profile: name (sex | email id) will be printed
    #desc: description from second line will be printed
    #friends: will print the Friends(#) where # is number of friends
    #if no friends, No friends yet... will be printed
    #if there are friends, friend_count will be set to # of friends
    #friend_list: will print the friends. email id will be looked up for print
    #for every friend printed from friend_list, the counter will be reduced
    #when the last friend is printed, we will set the print_line back to 'profile'

    print_line = 'profile'
    friend_count = 0

    people = profile_list[-1]

    ln = len(profile_list)

    c = 1
    
    for data in profile_list:
        if c != ln:
            c += 1
            if print_line == 'profile':
                print ('-' * 78)
                print (f'{data[0]} ({data[2]} | {data[1]})')
                print_line = 'desc'
            elif print_line == 'desc':
                print (f'- {data}')
                print_line = 'friends'
            elif print_line == 'friends':
                if data == '0':
                    print ('- No friends yet...')
                    print_line = 'profile'
                else:
                    print (f'- Friends ({data})')
                    friend_count = int(data)
                    print_line = 'friend_list'
            elif print_line == 'friend_list':
                if data in people:
                    print(f'    {people[data]}')
                else:
                    print(f'    {data}')
                if friend_count == 1:
                    print_line = 'profile'
                else:
                    friend_count -= 1
    print ('-' * 78)
    print ('=' * 78)    


profile_list = []
profile_list = read_file("abc.txt", profile_list)
display_summary(profile_list)

Review of your code:

1. read_file() function:

The ask: This function takes a file name and reads the contents of that file into the profile_list (list) passed as a parameter into the function. The function returns the list of profile objects. You must use a loop in your solution. You may use String and/or List methods in this function only. You may find the String methods split() and strip() useful here.

Let’s review your read_file() function. Below is your code.

# Function read_file() - place your own comments here...  : )
def read_file(filename, profile_list):

    profile_list = []  
    filename = open("profiles.txt", "r")

    for line in filename:
        stripped_line = line.strip()
        profile_list = stripped_line.split()
        filename.append(profile_list)

    filename.close()

    print(profile_list)

Review comments:

  1. The function receives the filename (string) and profile_list (empty list). Why are you not using the filename to open the file?
  2. profile_list = [] – good job in resetting the list.
  3. filename = open ("profiles.txt", "r") -> you are required to use the name of the file passed in the function parameter. You should rewrite this as f1 = open(filename, 'r')
  4. for loop is good. change it to for line in f1:
  5. stripped_line = line.strip() -> good
  6. profile_list = stripped_line.split() -> why do you not taking advantage of splitting each line? Also you cannot store it into profile_list. This is your final list into which all lines need to be stored.
  7. Split the line into a temp variable. Then check if (temp[-1] == 'm') or (temp[-1] == 'f'). If so, then that line has profile name, email id, and profile sex.
  8. If temp does not meet this criteria, then its safe to store the data as is into the profile_list list.

Updated code with fix to read_file(filename, profile_list) function

# Function read_file() - place your own comments here...  : )
def read_file(filename, profile_list):

    profile_list = []
    temp = []

    f1 = open(filename, "r")

    for line in f1:
        stripped_line = line.strip()
        temp = stripped_line.split()
        if (temp[-1] == 'm') or (temp[-1] == 'f'):
            ln = len(temp)
            temp_concat = ''

            for i in range(ln-3): #process the first few and ignore last 3 values
                temp_concat = temp_concat + temp[i] + ' '
            temp_concat = temp_concat + temp[ln-3] #concat 3rd from last value as its part of the name
            profile_list.append([temp_concat, temp[-2], temp[-1]]) #store as separate items within a list. it will help you retrieve them quickly
        else:
            profile_list.append(stripped_line)

    f1.close()

    print(profile_list)

    return profile_list

profile_list = []
profile_list = read_file("profiles.txt", profile_list)

Working code to print Profile Summary

Here’s the code that will print the Profile Summary. Look at this code and compare it with yours.

Tomorrow, I will review your code and provide you recommendations to improve code. If you can review the below code and see how I have done it, it may help you understand the processing logic.

#step 1: create an empty list to hold the contents of the file
file_data = []
people = {}

#step 2: read the file into a list
with open('profiles.txt','r') as f1:
    for line in f1:
        #file_data.append(line.strip('n'))

        #if strip('n') is not allowed, then use below code
        ln = len(line)
        line_concat = ''
        space_pos = []

        #if line is just a number, add to list
        if ln == 2:
            file_data.append(line[0])

        #if line is name + email + sex (m or f), then figure out name, email, sex
        elif (line[-3] == ' ' and (line[-2] == 'm' or line[-2] == 'f')):
            #find out the spaces. last space + 1 is sex
            #start of line till second last space is profile name
            #second last space to last space is profile email id
            for i in range(ln):
                if line[i] == ' ':
                    space_pos.append(i)

            actor_name = ''
            actor_email = ''
            for i in range (0, space_pos[-2]):
                actor_name = actor_name + line[i]
            
            for i in range (space_pos[-2]+1,space_pos[-1]):
                actor_email = actor_email + line[i]

            #store into dict: email as key, name as value for ease of lookup
            people[actor_email] = actor_name

            #also store name email, sex into file_data list
            file_data.append([actor_name,actor_email,line[-2]])
        else:
            #all other values just store into file_data list
            #concat from position 0 thru len - 2. Note: len - 1 will be n
            for i in range (ln-1):
                line_concat = line_concat + line[i]

            #store this into file_data list
            file_data.append(line_concat)

#now we are ready to print the profiles
print ('=' * 78)
print ('Profile Summary')
print ('=' * 78)

#print_line will determine what kind of data to print
#profile: name (sex | email id) will be printed
#desc: description from second line will be printed
#friends: will print the Friends(#) where # is number of friends
#if no friends, No friends yet... will be printed
#if there are friends, friend_count will be set to # of friends
#friend_list: will print the friends. email id will be looked up for print
#for every friend printed from friend_list, the counter will be reduced
#when the last friend is printed, we will set the print_line back to 'profile'

print_line = 'profile'
friend_count = 0

for i in file_data:
    if print_line == 'profile':
        print ('-' * 78)
        print (f'{i[0]} ({i[2]} | {i[1]})')
        print_line = 'desc'
    elif print_line == 'desc':
        print (f'- {i}')
        print_line = 'friends'
    elif print_line == 'friends':
        if i == '0':
            print ('- No friends yet...')
            print_line = 'profile'
        else:
            print (f'- Friends ({i})')
            friend_count = int(i)
            print_line = 'friend_list'
    elif print_line == 'friend_list':
        if i in people:
            print(f'    {people[i]}')
        else:
            print(f'    {i}')
        if friend_count == 1:
            print_line = 'profile'
        else:
            friend_count -= 1
print ('-' * 78)
print ('=' * 78)

The output of this will be:

==============================================================================
Profile Summary
==============================================================================
------------------------------------------------------------------------------
Fox Mulder (m | fox@findthetruth.com)
- The truth is out there!
- Friends (1)
    Tony Stark
------------------------------------------------------------------------------
Tony Stark (m | tony@ironman.com)
- Saving the world is hard work - no time for friends.
- No friends yet...
------------------------------------------------------------------------------
Phil Dunphy (m | phil@dunphy.com)
- wtf? = why the face?
- Friends (2)
    Robbie Gray
    Fox Mulder
------------------------------------------------------------------------------
John Mayer (m | john@guitar.com)
- Waiting on the world to change!
- Friends (2)
    Katy Perry
    David Guetta
------------------------------------------------------------------------------
Katy Perry (f | katy@perry.com)
- Waiting on John to change.
- Friends (3)
    John Mayer
    David Guetta
    Jimmy Fallon
------------------------------------------------------------------------------
David Guetta (m | dguetta@willworkwithanyone.org)
- Will collaborate with anyone who has a heartbeat.
- Friends (5)
    Katy Perry
    John Mayer
    Tony Stark
    Fox Mulder
    Robbie Gray
------------------------------------------------------------------------------
Jimmy Fallon (m | jimmy@tonightshow.com)
- I wish I was as good as Letterman, thank goodness he's retiring.
- Friends (2)
    Robbie Gray
    Tony Stark
------------------------------------------------------------------------------
Robbie Gray (m | robbie@football.com)
- Training hard... can we win?  Yes we Ken!
- Friends (4)
    Jimmy Fallon
    Fox Mulder
    John Mayer
    Tony Stark
------------------------------------------------------------------------------
==============================================================================


Source: stackoverflow