Portál AbcLinuxu, 11. května 2025 10:36

Dotaz: Bash aritmeticky priemer

6.8.2007 10:50 Mountains
Bash aritmeticky priemer
Přečteno: 945×
Odpovědět | Admin
Zdravim, potreboval by som urobit skript ktory nacita hodnoty zo suboru a urobi s nich aritmeticky priemer. Dakujem za pomoc.
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

6.8.2007 11:40 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tady máš tři různé algoritmy včetně generování testovacího souboru a měření doby výpočtu.
#!/usr/bin/python
import random, time

print 'Wait ...'
fw = file('cisla.txt', 'w')
for i in range(1000000):
    fw.write('%f\n' %(random.random()))
fw.close()

start = time.time()
s = 0
lines = 0
for line in file('cisla.txt'):
    s += float(line)
    lines += 1
print s/lines
print time.time() - start

start = time.time()
s = 0
for i, line in enumerate(file('cisla.txt')):
    s += float(line)
print s/(i + 1)
print time.time() - start

start = time.time()
numbers = [float(line) for line in file('cisla.txt')]
print sum(numbers)/len(numbers)
print time.time() - start
6.8.2007 11:47 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Algoritmus vidím jen jeden, zato ve třech implementacích (z toho jedné tak zoufale paměťově neefektivní (aniž by to bylo vyváženo časovou náročností), že by se to dalo používat při výuce jako odstrašující příklad).
6.8.2007 12:19 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Odpovědět | | Sbalit | Link | Blokovat | Admin
Pro případ, že by se někdo špatně vyspal, uvádím ještě tohle (bez ošetřování chyb):
#include<stdio.h>

int main(void){
    FILE* fr;
    double f, s = 0, lines = 0;

    fr = fopen("cisla.txt", "r");
    while (fscanf(fr, "%lf\n", &f) != EOF){
        s += f;
        lines += 1;
    }
    printf("%12.12f\n", s/lines);
    fclose(fr);
    return 0;
}
Je to cca 3-4 krát rychlejší než v pythonu.
6.8.2007 12:23 Mountains
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Odpovědět | | Sbalit | Link | Blokovat | Admin
Dakujem za Vasu ochotu a pomoc
6.8.2007 12:44 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Odpovědět | | Sbalit | Link | Blokovat | Admin
No, kedze su prazdniny, tak to domaca asi nebude, hoci to inak vykazuje vsetky jej znaky.

Najvacsi problem je dostat hodnotu z podshellu von a trik je spocitat priemer na desatinne miesta, hoci to bash nevie.
#!/bin/bash
set -- `while read n; do
  sucet=$((sucet + n))
  lines=$((lines + 1))
  echo $sucet $lines
done <subor.in | tail -n -1`

sucet=$1
lines=$2

echo $((sucet / lines))
# # ak to chces na 2 destinne miesta:
# avgfrac=$((sucet * 100 / lines))
# echo ${avgfrac%??}.${avgfrac: -2}

If you hold a Unix shell up to your ear, you can you hear the C.
6.8.2007 12:47 lada
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Odpovědět | | Sbalit | Link | Blokovat | Admin
pokud to ma byt ciste v shellu tak asi takto: #!/bin/sh

text=`cat soubor_dat |tr '\n' '+'`0
pocet=`cat soubor_dat |wc -l`
prumer=`echo "($text)/$pocet"|bc -l`
echo $prumer
6.8.2007 13:24 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Tak tomu říkám řešení čistě v shellu… :-)
6.8.2007 13:49 Zdenek
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Zatim je to ovsem nejbliz k zadani. A nepochybne to spravne *nix reseni :-)
6.8.2007 14:35 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Potrebuje to tr a bc. Riesenie CISTO v bashi mam zatial iba ja :-)
If you hold a Unix shell up to your ear, you can you hear the C.
6.8.2007 14:50 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Dá se to napsat třeba i takhle:
#!/bin/awk -f
BEGIN{lines=0;s=0;}
{lines++;s+=$1;}
END{print "prumer je", s/lines;}
no a awk už tak skoro "v shellu" je, že? Nebo teda v posixu. Teda *nixu. Teda ... no prostě je to víc v shellu než třeba bc. A určitě je to mnohem blíž shellu než python. Ale asi je to trochu dál shellu než třeba "tail". To jsou problémy ...
6.8.2007 15:24 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Já si hlavně myslím, že zadání typu "udělejte XY v ZW" jsou dobrá akorát tak pro školní úlohy. V praxi je daleko užitečnější umět zvolit vhodný nástroj pro danou úlohu (zde podle okolností např. awk, bc, perl, python nebo C), než se snažit ji za každou cenu udolat nevhodně zvoleným nástrojem.
6.8.2007 14:24 pavel
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Já řeším podobný problém, ale data mám ve sloupcích s oddělovačem ; Jak sčítat data ve sloupci?
6.8.2007 14:47 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
awk(1)
6.8.2007 15:26 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Takže bude tolik průměrů, kolik je sloupců?
#!/usr/bin/python
# -*- coding:utf-8 -*-
import random, time

radky = 5
sloupce = 10

fw = file('cisla.txt', 'w')
for i in range(radky):
    cisla_str = ['%f' %(i*j) for j in range(sloupce)]
    radek = ';'.join(cisla_str)
    fw.write('%s\n' %radek)
fw.close()

fr = file('cisla.txt')
sums = [float(x) for x in fr.readline().split(';')]
for i, line in enumerate(fr):
    for j, val_str in enumerate(line.split(';')):
        sums[j] += float(val_str)
i += 2
avgs = [x/i for x in sums]
print sums
print avgs
A na začátku se neví, kolik těch sloupců je, že?
6.8.2007 17:50 pavel
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Sloupců se ví (je to druhý až patnáctý), ale počet řádků mám pokaždé jiný...
6.8.2007 17:54 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Bash aritmeticky priemer
Aha. Ale snad by mělo jít použít to, co jsem napsal, protože to funguje univerzálně pro libovolný (rozumný) počet sloupců i řádků. Samo si to příslušná čísla zjistí.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.