missing required positional arguments for a named tuple

Viewed 204

I am a newbie in programming. I am writing a Python script that extracts data from a pdf. I am having trouble with tuple. I am not able to provide its argument. I think it is my logic that is not correct including indentation, sequence, or something else.

I am hoping to get some explanation on why I am getting the error.

This is the sample of my PDF (i have to block some sensitive info) enter image description here

This is what I am trying to achieveenter image description here

I am getting this error:

Traceback (most recent call last):
  File "/Users/jeff/PycharmProjects/extractFreightInvoice/main.py", line 79, in <module>
    lines.append(Line('invDate, invNumber, poNumber, contactName, jobNumber, '
TypeError: <lambda>() missing 11 required positional arguments: 'invNumber', 'poNumber', 'contactName', 'jobNumber', 'jobName', 'invDescription', 'siteAddress', 'invItemsDesc', 'invItemsQty', 'invItemsUnitPrice', and 'invItemsAmount'

My code is as per below:

# This is a pdf extractor
import re
import pdfplumber
import pandas as pd
from collections import namedtuple

Line = namedtuple('Line', 'invDate, invNumber, poNumber, contactName, jobNumber, '
                          'jobName, invDescription, siteAddress, invItemsDesc, invItemsQty, invItemsUnitPrice, '
                          'invItemsAmount ')

invDate_re = re.compile(r'(Clever Core NZ Limited\s)(\d{1,2}/\d{1,2}/\d{4})(.+)')
invNumber_re = re.compile(r'(IN\d{6})')
poNumber_re = re.compile(r'\d{4}')
contactNameBen_re = re.compile(r'(Jordan\s.+)')
contactNameCraig_re = re.compile(r'(Lorna\s.+)')
jobNumber_re = re.compile(r'(J[\d]{6})')
jobName_re = re.compile(r'(Job Name)')
invDescription_re = re.compile(r'(Invoice Description)')
siteAddress_re = re.compile(r'(Site address.*)')
colHeading_re = re.compile(r'((Description)(.* Quantity.* Unit Price.*))')
invItems_re = re.compile(
    r'(.+) (([0-9]*[.])?[0-9]+) (([0-9]*[.])?[0-9]+) (\d*\?\d+|\d{1,3}(,\d{3})*(\.\d+)?)')
# quoteLines_re = re.compile(r'(.+)(:\s*)(.+)')
# clevercorePriceLine_re = re.compile(r'(.* First .*\s?)(-\s?.*\$)(\s*)(.+)')

file = 'CombinedInvoicePdf.pdf'

lines = []

with pdfplumber.open(file) as myPdf:
    for page in myPdf.pages:
        text = page.extract_text()
        lines = text.split('\n')
        index = 0
        for i in range(len(lines)):

            line = lines[i]

            invDateLine = invDate_re.search(line)
            invNumberLine = invNumber_re.search(line)
            poNumberLine = poNumber_re.search(line)
            contactNameJordanLine = contactNameJordan_re.search(line)
            contactNameLornaLine = contactNameLorna_re.search(line)
            jobNumberLine = jobNumber_re.search(line)
            jobNameLine = jobName_re.search(line)
            invDescriptionLine = invDescription_re.search(line)
            colHeadingLine = colHeading_re.search(line)
            siteAddressLine = siteAddress_re.search(line)
            invItemsLine = invItems_re.search(line)

            if invDateLine:
                invDate = invDateLine.group(2)
            if invNumberLine:
                invNumber = invNumberLine.group(1)
            if poNumberLine and len(line) == 4:
                poNumber = poNumberLine.group(0)
            if contactNameBenLine:
                contactName = 'Jordan Michael'
            if contactNameCraigLine:
                contactName = 'Lorna Tolentin'
            if jobNumberLine:
                jobNumber = lines[i]
            if jobNameLine:
                jobName = (lines[i + 1])
            if invDescriptionLine:
                invDescription = lines[i + 1]
            if siteAddressLine:
                if len(lines[i + 1]) > 0 and len(lines[i + 1]) == 0:
                    siteAddress = lines[i + 1]
                elif len(lines[i + 1]) > 0 and len(lines[i + 1]) > 0:
                    siteAddress = lines[i + 1] + ' ' + lines[i + 2]
                else:
                    siteAddress = 'check invoice'
            if invItemsLine and invItemsLine[2] != '06':
                invItemsDesc = invItemsLine.group(1)
                invItemsQty = invItemsLine.group(2)
                invItemsUnitPrice = invItemsLine.group(4)
                invItemsAmount = invItemsLine.group(6)
            lines.append(Line('invDate, invNumber, poNumber, contactName, jobNumber, '
                              'jobName, invDescription, siteAddress, invItemsDesc, invItemsQty, invItemsUnitPrice, '
                              'inItemsAmount'))
df = pd.DataFrame(lines)
print(df)
print(df.head())
df.to_csv('freightCharges.csv')

1 Answers

Line is a tuple subclass with parameters and fields

<class 'Example_test.Lines'>

You need to fill them with separate parameters, not a single string

lines.append(Line('invDate', 'invNumber', 'poNumber', 'contactName', 'jobNumber', 'jobName', 'invDescription',
                  'siteAddress', 'invItemsDesc', 'invItemsQty', 'invItemsUnitPrice', 'inItemsAmount'))
Related