I need to get line numbers of a standard output

Question:

I found a solution of a problem and is a recursive function that gives me multiple combinations of numbers like:

  • 2 2 3
  • 2 4 2
  • 2 3 3
  • 2 2 4

and I need to find the number of combinations that the functions provides me but the function uses a print to return the values and I cannot find a way to count the number of lines of the output which gives me the solution.

Thanks!

code:

def box_extraction(vec, index, target, reducedNum):
        if (reducedNum < 0):
           return
        if (reducedNum == 0):
            for i in range(index):
               print(vec[i], end = " ")
            print("")
            return 
        prev = 1 if(index == 0) else vec[index - 1]
        for k in [2,3,4]:
            vec[index] = k
            box_extraction(vec, index + 1, target, reducedNum - k)

def findSums(n):
    vector = [0] * n
    box_extraction(vector, 0, n, n)
 
n = 8;
findSums(n)
Asked By: Mario Fernandez

||

Answers:

Assuming you can’t just change the original function, you could always capture the data output to stdout into a list then work with the list, something like:

from unittest.mock import patch
from io import StringIO

def fn(a, b, c):
    print(a, b, c)

def do():
    l = []
    with patch('sys.stdout', new=StringIO()) as output:
        fn(2, 3, 4)
        l.append(output.getvalue())

    print(f'Captured output: {l}')

do()
Answered By: John M.

You can get the number of combinations by converting the functions to a generator as follows.

Code

def box_extraction(vec, index, target, reducedNum):
        if (reducedNum < 0):
           return
        if (reducedNum == 0):
            result = [vec[i] for i in range(index)]
            #for i in range(index):
            #   print(vec[i], end = " ")
            #print("")
            yield result
        prev = 1 if(index == 0) else vec[index - 1]
        for k in [2,3,4]:
            vec[index] = k
            yield from box_extraction(vec, index + 1, target, reducedNum - k)

def findSums(n):
    vector = [0] * n
    yield from box_extraction(vector, 0, n, n)

Usage

n = 8;

# To get the number of items:
print(f"Number of items: {len(list(findSums(n)))}")
print("items with an index")
# To generate result with an index
for i, result in enumerate(findSums(n), start = 1):
    print(f"{i}: {' '.join(str(x) for x in result)}")

Output

Number of items: 8
items with an index
1: 2 2 2 2
2: 2 2 4
3: 2 3 3
4: 2 4 2
5: 3 2 3
6: 3 3 2
7: 4 2 2
8: 4 4
​
Answered By: DarrylG
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.