Python Forum
splitting lines, need to add element of same kind
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
splitting lines, need to add element of same kind
#1
Hi,
I need to 'sum' all elements by their kind.
All dogs, cats, and fishes.
I Cannot wrap around my mind around this small task.
Here is a kind of file as an example:

line01,P,2,dog
line02,P,1,dog
line33,P,7,dog
line03,P,3,cat
line04,P,5,cat
line11,P,8,fish
line12,P,3,dog
line16,P,2,dog
line04,P,2,cat
line11,P,12,fish

I need to print out a number of Dogs, Cats, and fishes and replace the first line with a time stamp.
19/02/2021,P,15 dog
19/02/2021,P,10,cat
19/02/2021,P,20,fish
I scanned the file and made a list of the animals --- 'list'.
And I thought I would use the list to filter 'animals' by its kind and 'sum' them, for some reason it does not work.
Code:
from datetime import datetime

now = datetime.now()
date_time = now.strftime("%m/%d/%Y")
to_app ='C:/02/All_an.txt'

list = ['dog','cat','fish']

with open (to_app, 'r+') as app : 
    for ln_in_file in app :
        ln_in_file=ln_in_file.strip()

        for ech_element in list :
            Sum = 0
            if ech_element in ln_in_file :
                spel =ln_in_file.split(",")
                spel[2]=int(spel[2])
                print ("======================== ",spel[2])
                
                Sum=(spel[2]+spel[2])
                break
        print (Sum)  
I'm opening my file with 'r+' for some reason the file is not readable if I open it with 'append'
Thank you.
Reply
#2
A dictionary makes this easy.
source = [
    '5, cat',
    '3, dog',
    '1, cat',
    '1, fish',
    '2, dog',
    '3, bird']

animals = {}

for line in source:
    count, animal = line.split(',')
    animals[animal] = animals.get(animal, 0) + int(count)

print(animals)
Output:
{' cat': 6, ' dog': 5, ' fish': 1, ' bird': 3}
If you only want to count certain animals:
source = [
    '5, cat',
    '3, dog',
    '1, cat',
    '1, fish',
    '2, dog',
    '3, bird']

animals = {'cat':0, 'dog':0}

for line in source:
    count, animal = line.split(',')
    if animal in animals:
        animals[animal] += int(count)

print(animals)
Output:
{'cat': 0, 'dog': 0}
tester_V likes this post
Reply
#3
On line 20 you change Sum to be (spel[2] + spel[2]), so it doesn't depend on any previous value. It's not summing up anything. Also, you're not keeping a separate value for each animal.
Reply
#4
Using a list you would need two lists, animals and animal counts.
to_app ='C:/02/All_an.txt'
 
animals = ['dog','cat','fish']  # Never use list as a variable name
counts = [0, 0, 0]
 
with open (to_app, 'r+') as app: 
    for line in app :
        line = line.strip()

        for index, animal in enumerate(animals):
            if animal in line:
                parts = line.split(",")
                count[index] += int(parts[2])
                break

for animal, count in zip(animals, counts):
    print(animal, count)
This code is hideous because there is no association between the count and the animal other than the position in the list. Since Python provides a datatype who's entire reason for existing is to provide a tight coupling, may as well use that.
tester_V likes this post
Reply
#5
Without any assumption about the number of different animals in the file maybe something like this.
from datetime import datetime
 
now = datetime.now()
date_time = now.strftime("%m/%d/%Y")
to_app ='C:/02/All_an.txt'
 
animals = dict()

with open (to_app, 'r+') as app:
    for ln_in_file in app :
        ln_in_file=ln_in_file.strip()

        line, P, num, animal = ln_in_file.split(',')
        if animal in animals:
            animals[animal]['count'] += int(num)
        else:
            animals[animal] = {'count': int(num), 'P': P, 'date': date_time}

for animal in animals:    
    print(f"{animals[animal]['date']},{animals[animal]['count']},{animals[animal]['P']},{animal}")
As I don't know anything about the function of 'P' and 'lineNN', I omitted the 'lineNN' and replaced it with the date, but kept the rest. If this is not necessary, the code can be much simplified:
from datetime import datetime
 
now = datetime.now()
date_time = now.strftime("%m/%d/%Y")
to_app ='C:/02/All_an.txt'
 
animals = dict()

with open (to_app, 'r+') as app:
    for ln_in_file in app :
        ln_in_file=ln_in_file.strip()

        line, P, num, animal = ln_in_file.split(',')
        if animal in animals:
            animals[animal] += int(num)
        else:
            animals[animal] = int(num)

for animal, count in animals.items():
    print(f"{date_time},{count},P,{animal}")
tester_V likes this post
Reply
#6
If anything is to be counted my first thought is to go for Counter which happens to be Python's data type for counting.

Assuming that file data.csv containing sample data one can achieve desired output (in descending order):

from collections import Counter
from datetime import datetime as dt


with open('data.csv', 'r') as f:
    count = Counter()
    for line in f:
        _, marker, qty, item = line.strip().split(',')
        count.update({item: int(qty)})

timestamp = dt.today().date().strftime("%d/%m/%Y")

for item, qty in count.most_common():              # for ascending order: count.most_common()[::-1]
    print(f'{timestamp},{marker},{qty},{item}')     

20/02/2021,P,20,fish
20/02/2021,P,15,dog
20/02/2021,P,10,cat
tester_V likes this post
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#7
I think you need to know that many of us here in this forum think guys are great!

Just to clarify, the list of (animals) could hold any number of animals.
First, I'm scanning the file just to create the list,
I thought it will help me to get the sum of each "animal" from the list.
The file is not .CSV.

I'm going to try all of your suggestions later tonight.
Thank you again!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What kind of object is this? Moris526 5 742 Dec-27-2020, 06:41 AM
Last Post: Gribouillis
  Iterate 2 large text files across lines and replace lines in second file medatib531 13 1,780 Aug-10-2020, 11:01 PM
Last Post: medatib531
  How to do this kind of IF STATEMENT? glennford49 4 920 Jun-17-2020, 09:45 AM
Last Post: glennford49
  Splitting lines ang grouping three at once samsonite 5 1,171 Jun-21-2019, 05:19 PM
Last Post: ichabod801
  Unable to locate element no such element gahhon 6 1,899 Feb-18-2019, 02:09 PM
Last Post: gahhon
  How to write a code to get this kind of output in IDLE kavindu 5 1,734 Oct-28-2018, 07:46 PM
Last Post: wavic
  Newbie question for a kind of rolling average of list of lits zydjohn 3 1,885 Dec-16-2017, 11:41 PM
Last Post: ezdev
  Change single element in 2D list changes every 1D element AceScottie 9 6,789 Nov-13-2017, 07:05 PM
Last Post: Larz60+
  Compiler fault or some kind of weird referencing bug? Joseph_f2 11 5,788 May-09-2017, 08:50 PM
Last Post: volcano63

Forum Jump:

User Panel Messages

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