Posts: 414
Threads: 111
Joined: Apr 2020
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.
Posts: 6,779
Threads: 20
Joined: Feb 2020
Feb-20-2021, 05:20 AM
(This post was last modified: Feb-20-2021, 05:20 AM by deanhystad.)
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}
Posts: 1,583
Threads: 3
Joined: Mar 2020
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.
Posts: 6,779
Threads: 20
Joined: Feb 2020
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.
Posts: 101
Threads: 0
Joined: Jan 2021
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}")
Posts: 1,950
Threads: 8
Joined: Jun 2018
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
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.
Posts: 414
Threads: 111
Joined: Apr 2020
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!
|