Python Forum
How to change from printFacts ( ) to return a list & Loop over list when writing CSV
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to change from printFacts ( ) to return a list & Loop over list when writing CSV
#1
I am new to Python and have modified below code to return various data points including below data point for each company. However, in cases where there are two values for the same data point, the code only writes one value to CSV. For example, the following will be returned on my Mac terminal:

Entity Common Stock Shares Outstanding 70852076
Entity Common Stock Shares Outstanding 3900903065
Common Stock Shares Issued 71000000
Common Stock Shares Issued 3986000000

But the CSV file only contains:
Entity Common Stock Shares Outstanding 3900903065
Common Stock Shares Issued 3986000000

CSV file does not contain:
Entity Common Stock Shares Outstanding 70852076
Common Stock Shares Issued 71000000

I have been told that this is because printFacts() prints all the facts that match the given target date, but it only returns the last one, and that's the one that gets written to the CSV file.

I have been advised to change it to return a list, and then loop over the list when writing to the CSV.

The problem is that I do not know how to change the code to return a list and then to loop over the list as am new to Python and coding in general. I have been spending hours trying to do this but no luck.

Appreciate if someone can show me what I need to change and where - thank you.

# Copyright 2014 Altova GmbH
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os, re, sys
from altova import xml, xsd, xbrl

sec_ns =  '/dei/'       # was: 'http:'
fasb_ns = '/us-gaap/'   # was: 'http:'

# We need to implement a simple locking class that allows us to avoid having 
# on_xbrl_valid called from multiple threads in RaptorXML at the same time.

if sys.platform == 'win32':
    import msvcrt

    # fcntl is not available under Windows, so we'll use a 
    # file locking function from the msvcrt library instead...

    class Lock:

        def __init__(self, filename):
            self.filename = filename
            # This will create it if it does not exist already
            self.handle = open(filename, 'w')

        # Bitwise OR fcntl.LOCK_NB if you need a non-blocking lock
        def acquire(self):
            msvcrt.locking(self.handle.fileno(), msvcrt.LK_LOCK, 1)

        def release(self):
            msvcrt.locking(self.handle.fileno(), msvcrt.LK_UNLCK, 1)

        def __del__(self):
            self.handle.close()

else:
    import fcntl

    # Under Linux and MacOS we can use the fcntl library to implement
    # the simple file locking mechanism...

    class Lock:

        def __init__(self, filename):
            self.filename = filename
            # This will create it if it does not exist already
            self.handle = open(filename, 'w')

        # Bitwise OR fcntl.LOCK_NB if you need a non-blocking lock
        def acquire(self):
            fcntl.flock(self.handle, fcntl.LOCK_EX)

        def release(self):
            fcntl.flock(self.handle, fcntl.LOCK_UN)

        def __del__(self):
            self.handle.close()

def camelToSpaces( label ):
    # Utility for pretty-printing the labels
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1 \2', label)
    return re.sub('([a-z0-9])([A-Z])', r'\1 \2', s1)

def factFinder( instance, namespace, label ):
    # Locate facts in the instance document by namespace and label, ignoring facts that have a context with a segment_element
    l = []
    for f in instance.items:
        if f.qname.namespace_name.find( namespace ) and f.qname.local_name == label:
            l.append( f )
    if not l:
        print('### NOT FOUND', label, type(l))
    return l

def printFacts( facts, indent=1, targetDate=None ):
    # Find the fact for the relevant target date and print it
    factValue = 0
    for fact in facts:
        if targetDate==None or fact.context.period.instant == targetDate:
            if fact.concept.item_type==fact.concept.MONETARY_ITEM_TYPE:
                factValue = fact.effective_numeric_value
                print( indent * "\t", camelToSpaces( fact.qname.local_name ).ljust(100-indent*8), "$", '{0:>16,}'.format( factValue ) )
            else:
                factValue = fact.normalized_value
                print( indent * "\t", camelToSpaces( fact.qname.local_name ).ljust(100-indent*8), factValue )
    return factValue

def on_xbrl_valid( job, instance ):

    try:
        # a portable solution to get the tmp dir
        import tempfile
        tmp = tempfile.gettempdir()
        tmplk = os.path.join( tmp, "extract_ratios_lock.tmp" )
        lock = Lock(tmplk)
        lock.acquire()

        # Create output CSV file if it doesn't exist yet
        if not os.path.isfile( "ratios.csv" ):
            with open("ratios.csv", "a") as ratiofile:
                ratiofile.write( "TradingSymbol,EntityRegistrantName,EntityCentralIndexKey,CurrentFiscalYearEndDate,DocumentType,DocumentPeriodEndDate,DocumentFiscalYearFocus,DocumentFiscalPeriodFocus,EntityCommonStockSharesOutstanding,DocumentCreationDate,CommonStockSharesIssued,TreasuryStockShares,CommonStockSharesOutstanding\n" )
                ratiofile.close()

        # Extract some basic facts from the filing, such as the effective end-date for balance sheet etc.
        tradingSymbol = factFinder( instance, sec_ns, "TradingSymbol" )
        entityRegistrantName = factFinder( instance, sec_ns, "EntityRegistrantName" )
        entityCentralIndexKey = factFinder( instance, sec_ns, "EntityCentralIndexKey" )
        currentFiscalYearEndDate = factFinder( instance, sec_ns, "CurrentFiscalYearEndDate" )
        documentType = factFinder( instance, sec_ns, "DocumentType" )
        documentPeriodEndDate = factFinder( instance, sec_ns, "DocumentPeriodEndDate" )
        documentFiscalYearFocus = factFinder( instance, sec_ns, "DocumentFiscalYearFocus" )
        documentFiscalPeriodFocus = factFinder( instance, sec_ns, "DocumentFiscalPeriodFocus" )
        entityCommonStockSharesOutstanding = factFinder( instance, sec_ns, "EntityCommonStockSharesOutstanding" )
        documentCreationDate = factFinder( instance, sec_ns, "DocumentCreationDate" )
        commonStockSharesIssued = factFinder( instance, sec_ns, "CommonStockSharesIssued" )
        treasuryStockShares = factFinder( instance, sec_ns, "TreasuryStockShares" )
        commonStockSharesOutstanding = factFinder( instance, sec_ns, "CommonStockSharesOutstanding" )
        docEndDate = "2017-07-31"
        if len(documentPeriodEndDate) > 0:
            docEndDate = documentPeriodEndDate[0].normalized_value

        # Print information about filing and entity
        print( "Document and Entity Information:" )
        tradingSymbol = printFacts( tradingSymbol ) if tradingSymbol else ""
        entityRegistrantName = printFacts( entityRegistrantName ) if entityRegistrantName else ""
        entityCentralIndexKey = printFacts( entityCentralIndexKey ) if entityCentralIndexKey else ""
        currentFiscalYearEndDate = printFacts( currentFiscalYearEndDate ) if currentFiscalYearEndDate else ""
        docType = printFacts( documentType )
        documentPeriodEndDate = printFacts( documentPeriodEndDate ) if documentPeriodEndDate else ""
        documentFiscalYearFocus = printFacts( documentFiscalYearFocus ) if documentFiscalYearFocus else ""
        documentFiscalPeriodFocus = printFacts( documentFiscalPeriodFocus ) if documentFiscalPeriodFocus else ""
        entityCommonStockSharesOutstanding = printFacts( entityCommonStockSharesOutstanding, 3 ) if entityCommonStockSharesOutstanding else ""
        documentCreationDate = printFacts( documentCreationDate ) if documentCreationDate else ""
        commonStockSharesIssued = printFacts( commonStockSharesIssued, 3, docEndDate ) if commonStockSharesIssued else ""
        treasuryStockShares = printFacts( treasuryStockShares, 3, docEndDate ) if treasuryStockShares else ""
        commonStockSharesOutstanding = printFacts( commonStockSharesOutstanding, 3, docEndDate ) if commonStockSharesOutstanding else ""

        # Append ratios to a CSV file for further analysis
        with open("ratios.csv", "a") as ratiofile:
            ratiofile.write( tradingSymbol + "," + entityRegistrantName + "," + entityCentralIndexKey + "," + currentFiscalYearEndDate + "," + docType + "," + documentPeriodEndDate + "," + documentFiscalYearFocus + "," + documentFiscalPeriodFocus + "," + entityCommonStockSharesOutstanding + "," + documentCreationDate + "," + commonStockSharesIssued + "," + treasuryStockShares + "," + commonStockSharesOutstanding + "\n")
            ratiofile.close()

    finally:
        lock.release()
Reply


Messages In This Thread
How to change from printFacts ( ) to return a list & Loop over list when writing CSV - by Ivan1 - Aug-27-2017, 08:45 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Help with writing monitored data to mysql upon change of one particular variable donottrackmymetadata 3 179 Yesterday, 09:55 PM
Last Post: deanhystad
  How do I calculate a ratio from 2 numbers and return an equivalent list of about 1000 Pleiades 8 15,636 Jan-05-2024, 08:30 PM
Last Post: sgrey
  No matter what I do I get back "List indices must be integers or slices, not list" Radical 4 1,156 Sep-24-2023, 05:03 AM
Last Post: deanhystad
  Change font in a list or tuple apffal 4 2,670 Jun-16-2023, 02:55 AM
Last Post: schriftartenio
  Delete strings from a list to create a new only number list Dvdscot 8 1,511 May-01-2023, 09:06 PM
Last Post: deanhystad
  List all possibilities of a nested-list by flattened lists sparkt 1 915 Feb-23-2023, 02:21 PM
Last Post: sparkt
  Сheck if an element from a list is in another list that contains a namedtuple elnk 8 1,833 Oct-26-2022, 04:03 PM
Last Post: deanhystad
  convert this List Comprehensions to loop jacklee26 8 1,503 Oct-21-2022, 04:25 PM
Last Post: deanhystad
  How to change the datatype of list elements? mHosseinDS86 9 1,955 Aug-24-2022, 05:26 PM
Last Post: deanhystad
Question Keyword to build list from list of objects? pfdjhfuys 3 1,556 Aug-06-2022, 11:39 PM
Last Post: Pedroski55

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020