2

I have a long string of farmAnimals that looks like this: it has \n\n\n and a \t in front of the Farm Animals

                Farm Animals

                    F

                    M

                Total




Cow


                        11

                        10


                        21





Horse


                        3

                        6


                        9





Sheep


                        4

                        8


                        12





Goat


                        3

                        4


                        7





Chicken


                        1

                        1


                        2





Hen


                        5

                        7


                        12





Pig


                        3

                        7


                        10





Turkey


                        0

                        5


                        5





Cattle


                        1

                        1


                        2





Llama


                        3

                        5


                        8





Donkey


                        5

                        9


                        14





Duck


                        1

                        1


                        2




Total


                    40

                    64

104

I want to make the output look like this:

              Farm Animals     F     M    Total
                       Cow    11    12       23
                     Horse     5     5       10
                     Sheep     4    12       16
                                        .......
                     Total   108   134      242

what I did so far is

print(farmAnimalsString.strip().replace('\n\n','').replace('\t',' ').replace('\n\n\n','').replace('\n\n\n\n',''))

My current solution doesn't necessarily produce the correct output but its close. There are different amounts of \n between each field, which makes it tricky for me. So, I am wondering if there is a better way to do this because all I can think about is this brute force way, and I think by doing this I won't be able to get the output that I want.. Thanks in advance!

Edit: I just realized that one of the animal names are two words such as "Jack Rabbit" So when it printed, it looks like

Farm Animals F            M        Total       Jack
Rabbit       1            2           3        Snow
Bunny        0            1           1         Cow
0            1            1        Total          1
4            5

2 Answers 2

2

It's a bit tricky if you need to recognize animals with names more than one words. However, if we take advantage of the fact that all remaining fields are numbers, we can distinguish cases by using this. Following code does exactly that:

words = animal_str.split()[5:]
headers = ['Farm Animals', 'F', 'M', 'Total']
fields = []

it = iter(words)
try:
    while True:
        row = []
        animal = []
        while True:
            n = next(it)
            try:
                x = int(n)
                row.append(' '.join(animal))
                row.append(x)
                break
            except ValueError:
                animal.append(n)

        row.append(int(next(it)))
        row.append(int(next(it)))
        fields.append(row)
except StopIteration:
    pass

each outer while loop generates one single row and store the results into fields.


Regarding how to generate tabularized output. It's much easier if you delegate the work to some existent libraries, such as tabulate: https://pypi.python.org/pypi/tabulate

The effect is demonstrated as following:

In [9]: import tabulate

In [16]: fields
Out[16]: 
[['Cow', 11, 10, 21],
 ['Horse', 3, 6, 9],
 ['Sheep', 4, 8, 12],
 ['Goat', 3, 4, 7],
 ['Chicken', 1, 1, 2],
 ['Hen', 5, 7, 12],
 ['Pig', 3, 7, 10],
 ['Turkey', 0, 5, 5],
 ['Cattle', 1, 1, 2],
 ['Llama', 3, 5, 8],
 ['Donkey', 5, 9, 14],
 ['Duck', 1, 1, 2],
 ['Jack Rabbit', 1, 2, 3],
 ['Total', 40, 64, 104]]

In [18]: print tabulate.tabulate(fields, headers=headers, tablefmt='plain', stralign='right')
  Farm Animals    F    M    Total
           Cow   11   10       21
         Horse    3    6        9
         Sheep    4    8       12
          Goat    3    4        7
       Chicken    1    1        2
           Hen    5    7       12
           Pig    3    7       10
        Turkey    0    5        5
        Cattle    1    1        2
         Llama    3    5        8
        Donkey    5    9       14
          Duck    1    1        2
   Jack Rabbit    1    2        3
         Total   40   64      104

This should achieves your requirement.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is another suggestion:

inString = inString.split()
for i in range(len(inString)-1):
  if inString[i].isalpha() and inString[i+1].isalpha() and len(inString[i])>=4 and len(inString[i+1])>=4:
    inString[i] = " ".join([inString[i], inString[i+1]])
    inString[i+1] = ""

inString = [i.replace("\n","").rjust(12, ' ') for i in inString if not i==""]

inString = "\n".join([" ".join(inString[i*4:i*4+4]) for i in range(len(inString))]).replace("\n\n","")
print(inString)

Output:

Farm Animals            F            M        Total
         Cow           11           10           21
       Horse            3            6            9
       Sheep            4            8           12
        Goat            3            4            7
     Chicken            1            1            2
         Hen            5            7           12
         Pig            3            7           10
      Turkey            0            5            5
      Cattle            1            1            2
       Llama            3            5            8
      Donkey            5            9           14
        Duck            1            1            2
       Total           40           64          104

where inString is your farmAnimalsString.

2 Comments

I just realized that there are animals with two letter names, I included the update on my edit
@Gus I edited my answer to concatenate all the adjacent words that fullfill the if condition. It should work for your case, however, let me know if something's not working properly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.