0

Let me preface by saying I'm not 100% sure if using a dictionary is the best course of action for this task but that is what I believe I need to use to accomplish this.

I have a .txt file that is formatted like this:

first_name last_name rate hours
first_name last_name rate hours
first_name last_name rate hours
first_name last_name rate hours

There is a single space between each item. Each line represents a person.

For my program I need to be able to:

  • print out all the people at once
  • be able to search for a person by first or last name and print out their information
  • modify a person (first name, last name, hours, rate)
  • delete a person (all their information)

When it gets printed I DO NOT need to see the [rate] and [hours] but [gross pay] instead (gross pay = rate * hours).

I am fairly new to file processing with python so my first attempt at this was just to read every line from the file and print it out on the screen, but I came across the problem of being able to display [gross pay].

# 'print_emp', display only a single employee's data chosen by the user displayed as
# firstname, lastname, grosspay (on one line of output)
def print_emp():
    menu_name = ' '*int(OFFSET/2) + "EMPLOYEE LOOKUP"
    dotted = (OFFSET+len(menu_name))*'-'

    try:
        with open('employees.txt') as file:
            print('{} \n{} \n{}'.format(dotted, menu_name, dotted))
            emp_name = input("Employee Name: ")
            print('{0:20} {1:20} {2}'.format("First Name", "Last Name", "Gross Pay"))
            for line in file:
                if emp_name in line:
                    print (line.strip())

                #print("\nEmployee", emp_name, "does not exist. Try again.\n")
                #break
    except FileNotFoundError:
        print("Error: File not found.")


# 'print_all_emp', display all employee data in format firstname, lastname,
# grosspay (on one line of output per employee)
def print_all_emps():
    menu_name = ' '*int(OFFSET/2) + "EMPLOYEE LIST"
    dotted = (OFFSET+len(menu_name))*'-'

    try:
        with open('employees.txt', 'r') as file:
            print('{} \n{} \n{}'.format(dotted, menu_name, dotted))
            print('{0:20} {1:20} {2}'.format("First Name", "Last Name", "Gross Pay"))
            for line in file:
                print(line.strip())
            print(dotted)
    except FileNotFoundError:
        print("Error: File not found.")

I am not sure how I go about reading my .txt file into a dictionary (if that's what I need to do) where I assign a key to each person that includes their first name, last name, rate, and hours and then multiplying the rate * hours to create the gross pay and then displaying that gross pay.

I will be creating three more functions where I can add, delete, and modify the people in the .txt file.

EDIT :

I believe what I am going for as an end program looks something like this:

https://en.wikibooks.org/wiki/Non-Programmer%27s_Tutorial_for_Python_3/File_IO

But without the load and save functions...

ByteSettlement
  • 208
  • 1
  • 3
  • 14
  • Somewhat unrelated to your question, but how are you planning to handle names that have a space in them? – spectras Jul 06 '16 at 21:43
  • @spectras That wasn't really within the scope of my project so I had not put any thought into it. Lets just assume that my project will only be taking typical first and last names like John Smith – ByteSettlement Jul 06 '16 at 21:50
  • silly question, but are there actual brackets in your file, or are you just using them to make the format clear? – Hans Nelsen Jul 06 '16 at 21:54
  • Why aren't you using pandas? Simply replace your file with a csv file (e.g replace brackets with quotation and space with comma), read it with pandas and you will have everything that you need with only a few lines. – CentAu Jul 06 '16 at 21:59
  • @HansNelsen the brackets are used just for formatting, there aren't actually brackets in the file – ByteSettlement Jul 06 '16 at 22:09

4 Answers4

1

Presuming you have space delimited data, you can just use the csv library.

import csv

labels = ['first_name', 'last_name', 'rate', 'hours']
data = csv.DictReader(open('./test.txt'), delimiter=' ', fieldnames=labels)

result = []

for row in data:
  result.append(row)

print result

You will wind up with an array of dictionaries that each have the labels as key names.

Hans Nelsen
  • 297
  • 2
  • 4
0

i think the problem you are facing is how to find unique key
to create unique key, simply add all string together than hash it.

res = {}
with open('employees.txt') as file:
   for line in file:
       res[line] = line.split(' ')
galaxyan
  • 5,944
  • 2
  • 19
  • 43
0

You make some of the code easier by creating a Person class.

class Person:
    def __init__(self, first, last, rate, hours):
       self.first = first
       self.last = last
       self.rate = rate
       self.hours = hours

    def matches_name(self, name):
        return name.lower() == self.first.lower() or name.lower() == self.last.lower()

    def __str__(self):
        return '{} {} {}'.format(self.first, self.last, self.rate*self.hours)

This will simplify your code a bit. If you want to find out if someone has a specific name, you can just call something like:

a_person.matches_name(random_first_name)

If you want to print out the person and their gross pay, you just have to do

print(a_person)
arewm
  • 649
  • 3
  • 12
  • As a simplification, classes are a way to keep information related to a specific thing together. Here, you want to describe a person, so make a `Person` class. In this class, you can store information about any one person and you can use methods on the class to perform simple operations like "Am I the same person as another?", "What is my name?", and "What is a simple summary of myself?". – arewm Jul 07 '16 at 13:52
  • They are very useful, so I hope that in your learning Python that you will find out more about them. :) – arewm Jul 07 '16 at 13:57
0

You can easily achieve all the desired operations with pandas:

>>> import pandas as pd

First convert your file to csv format (comma separated text file), then:

assuming your file is in txt:

>>> txt = """                
    'FN','LN','rate','hours'
    'John','Doe','12','40'
    'Jane','Roe','20','35'
    """

>>> file = StringIO(txt)

>>> df = pd.read_csv(file, quotechar="'")

>>> df
Out: 
     FN   LN  rate  hours
0  John  Doe    12     40
1  Jane  Roe    20     35

print out all the people at once:

>>> df[['FN','LN']]
Out: 
     FN   LN
0  John  Doe
1  Jane  Roe

Search for a person by first or last name and print out their information:

>>> df.loc[df['FN'] == 'John']
Out: 
     FN   LN  rate  hours
0  John  Doe    12     40

>>> df.loc[df['LN'] == 'Roe']
Out: 
     FN   LN  rate  hours
1  Jane  Roe    20     35

Modify a person (first name, last name, hours, rate):

I'll show modifying the rate for a person whose name is 'John'

>>> df.loc[df['FN'] == 'John', 'rate'] = 14

>>> df
Out: 
     FN   LN  rate  hours
0  John  Doe    14     40
1  Jane  Roe    20     35

Delete a person (all their information):

I'll show deleting 'John Doe':

>>> df = df[(df['FN'] != 'John') & (df['LN'] != 'Doe')]

>>> df
Out: 
     FN   LN  rate  hours
1  Jane  Roe    20     35

Finally, if you want the gross pay you can add a new column pay that holds that information:

>>> values = df['rate'] * df['hours']

>>> df['pay'] = values

>>> df
Out[67]: 
     FN   LN  rate  hours  pay
0  John  Doe    12     40  480
1  Jane  Roe    20     35  700
CentAu
  • 10,660
  • 15
  • 59
  • 85