Skript Testsieger

Das Skript ist per Menü (s.u.) gesteuert.
Es errechnet gewichtete Testergebnisse.
Datensätze können in das Skript hinein abgelegt und daraus gelesen werden.
Dies ist ganz am Ende zu sehen.
bish-Version ≥6.80 ist erforderlich.
Es kann sein, daß dieses Skript-Lesen und -Schreiben aus/in sich selbst
unter Windows nicht funktioniert.

Nachfolgend eine Ausgabe:

 xz-0 bzip2 gzip xz xz-T0 xz-0-T0
 < 60.0 size    49941772.0 57273254.0 61148843.0 40579988.0 40723416.0 49942636.0
 < 40.0 time    12.46 19.71 9.47 103.33 61.04 6.73

                          xz-0  70.3579
                         bzip2  56.1702
                          gzip  68.2443
                            xz  62.6053
                         xz-T0  64.1989
                       xz-0-T0  88.752

        Hilfe           : h
        Ruecksetzen     : R
        Daten speichern : s
        Daten anzeigen  : ed
        Daten laden     : l [#]
        Kandidaten-Namen: n name1 name2 ...
        Leistungswerte  : w 88888 44.44 ... {>|<}{gew}{bez}
        Berechnung      : b
        Beenden         : E
                        : _ 

#!/u/bin/bish

set -Bf
ARITH_FMT='%Lg'
Skript="$0"
alias edit='gvim +'

Help='
Zuerst müssen die Namen der Test-Kandidaten angegeben werden.
Dadurch steht die Anzahl der Datensätze fest.

Danach müssen n-mal gleich viele Leistungswerte folgen.
Hinter den Leistungswerten müssen jeweils ein > oder ein <,
eine Gewichtung und ein Bezeichner angegeben werden.
Beispiele:  >60Leistung    > 15.5 Leistung

> < geben an, ob größere oder kleinere Werte besser zu bewerten sind.
Die Gewichtung muß größer 0 und kleiner 100 sein.
Die Summe der Gewichtungen muß 100.0 (mit geringer Toleranz) ergeben.

Das Skript schreibt in und liest aus sich selbst.
Die diversen Eingabe-Wörter dürfen keine Zwischenraumzeichen enthalten.
'


Err()  { print -u2 "*** $1 ***"; return; }


Reset()  {
   set DATw:' '${#DATw} DAT3:' '${#DAT3} DATn:' '${#DATn} DATm:' '${#DATm}
   N=0 W=0 G=0.0
}


GetMaxNum()  {
   local z:.300 n:09 max:09
   <$Skript
   while readl z
   do
      expr "$z" :n '^#\([0-9]\{1,9}\)|[0-9n]\{1,3}|.' || continue
      [ n -gt max ] && max=$n
   done
   ><
   [ "$1" = p -a max -gt 0 ] && print " max=$max"
   return $max
}


Speichern()  {
   [ N -le 0 -o W -le 0 ] && return 1
   local o:09 n:03 w:03 max:09 tmp:.30
   GetMaxNum; max=$?
   [ max -le 0 ]
   run? 'max=1' 'let ++max'
   >>$Skript
   print -nr "#$max|n|"
   for n from 0 to $((N-1)) repeat
   do
      let "o=30*n"
      catv o,30,DATn =tmp:
      prints sb- $tmp
   done
   echo
   for w from 0 to $((W-1)) repeat
   do
      let "o=30*w"
      catv o,30,DAT3 =tmp:
      print -nr "#$max|$((w+1))|"$tmp'  '
      for n from 0 to $((N-1)) repeat
      do
         let "o=$O*n+30*w"
         catv o,30,DATw =tmp:
         prints sb- $tmp
      done
      echo
   done
   ><
   return 0
}


Laden()  {
   local o:09 z:.300 n:03 w:03 r=0 num:09 tmp:.30 dgb:.30 lz:' '30
   if [ $# -eq 1 ]
   then  expr "$1" :: '^[0-9]\{1,9}$' || { Err "Syntax $1"; return 1; }
         let "num=$1+0"
   else  GetMaxNum p; num=$?
   fi
   let "n+=0; w+=0"
   [ num -le 0 ] && return 0
   <$Skript
   while readl z
   do
      expr "$z" :: '^#'$num'|n|.' || continue
      expr "$z" :z '^#'$num'|n|\(.\{1,}\)$'
      for tmp in $z
      do
         let "o=30*n" "++n>20" && break
         catv lz =o,30,DATn
         catv tmp =o,30,DATn
      done
      break
   done
   [ n -lt 2 -o n -gt 20 ] && { ><; Err "Anzahl Namen = $n"; return 1; }
   N=$n G=0.0
   while readl z
   do
      expr "$z" :: '^#'$num'|[0-9]\{1,3}|.' || break
      expr "$z" :z '^#'$num'|[0-9]\{1,3}|\(.\{1,}\)$'
      expr "$z" :dgb '^\(.\{1,}\)  [^ ]' || r=2 break
      let "o=30*w" "++w>20" && break
      catv lz =o,30,DAT3
      catv dgb =o,30,DAT3
      for 3 - tmp - in $dgb; do ; done
      let "G+=tmp" "G>=100.01" && break
      n=0
      expr "$z" :z '  \(.\{1,}\)$'
      for tmp in $z
      do
         let "o=$O*n+30*(w-1)" "++n>20" && break
         catv lz =o,30,DATw
         catv tmp =o,30,DATw
      done
      let "n!=N" && break
   done
   ><
   let "G>=100.01" && r=1 Err "Gewichtung = $G"
   [ n -ne N -o n -gt 20 -o w -gt 20 -o w -lt 1 ] && r=1 Err "Anzahlen N=$N n=$n w=$w"
   W=$w
   [ r -gt 0 ] && N=0 W=0 G=0.0
   return $r
}
#2%n%xz-0 bzip2 gzip xz 
#2%1%< 60.0 size  49941772.0 57273254.0 61148843.0 40579988.0 
#2%2%< 40.0 time  12.46 19.71 9.47 103.33 


Namen()  {
   [ N -ne 0 ] && { Err "Bereits $N Namen gesetzt"; return 1; }
   [ $# -lt 2 ] && { Err "Zu wenig Namen"; return 1; }
   local nam:.30 o:09
   for nam in $*
   do
      [ ${#nam} -gt 30 ] && { Err "Name '$nam' zu lang"; return 1; }
      let "o+30>${#DATn}" && { Err "Pufferende n"; return 1; }
      catv nam =o,30,DATn
      let "o+=30" "++N"
   done
   return 0
}


WertePrep()  {
   [ N -lt 2 ] && { Err "Keine Namen gesetzt"; return 1; }
   local cfg:.30 d=. g:09 b:.30
   expr "${{1}}" :g '[><][^><]\{2,}$' || { Err "Format <>#a"; return 1; }
   let "g>28" && { Err "Format <>#a zu lang: $g"; return 1; }
   expr "${{1}}" :cfg '\([><][^><]\{2,}\)$'
   conv -d"${Tab}d " cfg
   expr "$cfg" :d '^\([><]\)' || { Err "Format ><"; return 1; }
   expr "$cfg" :g '^[><]\([0-9.]\{1,5}\)' || { Err "Format Gewichtung"; return 1; }
   expr "$cfg" :b '\([a-zA-Z_].\{0,}\)$' || { Err "Format Bezeichnung"; return 1; }
   if expr "$g" :: '\.'
   then  expr "$g" :: '^\.' && g="0$g"
         expr "$g" :: '\.$' && g="${g}0"
         let "g<0.1||g>99.9" && { Err "Gewichtung '$g'"; return 1; }
   else  [ g -lt 1 -o g -ge 100 ] && { Err "Gewichtung '$g'"; return 1; }
         g="$g.0"
   fi
   let "G+g>=100.01" && { Err "Gewichtung $((G+g))"; return 1; }
   let "G+=g"
   expr "${{1}}" :$1 '[><][^><]\{2,}$' = ''
   $2="$d $g $b"
   return 0
}

Werte()  {
   [ N -lt 2 ] && { Err "Keine Namen gesetzt"; return 1; }
   let "$# != N+3" && { Err "Anzahl Argumente $# != $((N+3))"; return 1; }
   let "W>=20" && { Err "Anzahl Werteketten maximal: $W"; return 1; }
   local val:030 o:09 w:03 wp=00$W cfg:.30
   cfg="$1 $2 $3"
   shift 3
   let "o=30*wp"
   let "o+30>${#DAT3}" && { Err "Pufferende 3"; return 1; }
   catv cfg =o,30,DAT3
   for val in $*
   do
      [ ${#val} -gt 30 ] && { Err "Wert '$val' zu lang"; return 1; }
      if expr "$val" :: '\.'
      then
         expr "$val" :: '^[0-9.]\{2,20}$' || { Err "Wert '$val'"; return 1; }
         expr "$val" :: '^\.' && val="0$val"
         expr "$val" :: '\.$' && val="${val}0"
      else
         expr "$val" :: '^[0-9]\{1,20}$' || { Err "Wert '$val'"; return 1; }
         val="$val.0"
      fi
      [ ${#val} -gt 30 ] && { Err "Wert '$val' zu lang"; return 1; }
      let "val<0.1" && { Err "Wert '$val' zu klein"; return 1; }
      let "o=$O*w+30*wp" "++w"
      let "o+30>${#DATw}" && { Err "Pufferende w"; return 1; }
      catv val =o,30,DATw
   done
   let "W= ++wp"
   return 0
}


Rechnen()  {
   [ $# -eq 1 -a "${{1}}" = p ] || return 0
   local o:09 n:03 w:03 d=. g:09 gs:09 b:.30
   local nam:.30 tmp:.30 max:030 val:030
   $1=0
   for w from 0 to $((W-1)) repeat
   do
      let "o=30*w"
      catv o,30,DAT3 =tmp:
      for 3 d g b in $tmp; do ; done
      max=0.0 let "gs+=g"
      for n from 0 to $((N-1)) repeat
      do
         let "o=$O*n+30*w"
         catv o,30,DATw =tmp:
         tmp=$tmp
         [ $d = '<' ] && let "tmp=1.0e5/tmp"
         let "tmp>max" && max=$tmp
      done
      let "o=30*w"
      let "o+30>${#DATm}" && { Err "Pufferende m"; return 1; }
      catv max =o,30,DATm
   done
   let "gs<=99.99||gs>=100.01" && Err "Gewichtung = $gs"
   for n from 0 to $((N-1)) repeat
   do
      let "o=30*n"
      catv o,30,DATn =tmp:
      nam=$tmp val=0.0
      for w from 0 to $((W-1)) repeat
      do
         let "o=30*w"
         catv o,30,DATm =max:
         catv o,30,DAT3 =tmp:
         for 3 d g b in $tmp; do ; done
         let "o=$O*n+30*w"
         catv o,30,DATw =tmp:
         tmp=$tmp max=$max
         [ $d = '<' ] && let "tmp=1.0e5/tmp"
         let "val+=g*tmp/max"
      done
      prints s30b2s $nam $val
   done
   return 0
}

#xz-0 bzip2 gzip xz
#49941772 57273254 61148843 40579988 <60size
#12.46 19.71 9.47 103.33 <40time
#4.523 3.944 3.694 5.566 >60faktor
#225873920


Zeigen()  {
   [ N -gt 0 ] || return 0
   local o:09 n:03 w:03 tmp:.30
   echo
   for n from 0 to $((N-1)) repeat
   do
      let "o=30*n"
      catv o,30,DATn =tmp:
      print -n ' '$tmp
   done
   echo
   [ W -gt 0 ] || return 0
   for w from 0 to $((W-1)) repeat
   do
      let "o=30*w"
      catv o,30,DAT3 =tmp:
      print -n ' '$tmp '  '
      for n from 0 to $((N-1)) repeat
      do
         let "o=$O*n+30*w"
         catv o,30,DATw =tmp:
         print -n ' '$tmp
      done
      echo
   done
   echo
   return 0
}


O=$((20*30))
set DATw:' '$((20*O)) DAT3:' '$O DATn:' '$O DATm:' '$O
set N:03 W:03 G:09 Tab:9.1
set Val:.300 Tmp:.100
local cmd:.9
G=0.0 B=0 N=0 W=0


while Zeigen; Rechnen B; print -n "
\tHilfe           : h
\tRuecksetzen     : R
\tDaten speichern : s
\tDaten anzeigen  : ed
\tDaten laden     : l [#]
\tKandidaten-Namen: n name1 name2 ...
\tLeistungswerte  : w 88888 44.44 ... {>|<}{gew}{bez}
\tBerechnung      : b
\tBeenden         : E
\t                : _\b"
do
   read cmd Val
   conv -t"$Tab " Val
   case "$cmd" in
     h)  print -r "$Help";;
     R)  Reset;;
     s)  Speichern;;
    ed)  edit $Skript;;
     l)  Laden $Val && print " N=$N W=$W";;
     n)  Namen $Val;;
     w)  WertePrep Val Tmp || continue
         Werte $Tmp $Val;;
     b)  B=p;;
     E)  break;;
     *)  print -u2 "\t\t\t'$cmd'?"; continue;;
   esac
done

exit 0



#1|n|xz-0 bzip2 gzip xz 
#1|1|< 60.0 size  49941772.0 57273254.0 61148843.0 40579988.0 
#1|2|< 40.0 time  12.46 19.71 9.47 103.33 
#2|n|xz-0 bzip2 gzip xz 
#2|1|< 80.0 size  49941772.0 57273254.0 61148843.0 40579988.0 
#2|2|< 20.0 time  12.46 19.71 9.47 103.33 
#3|n|xz-0 bzip2 gzip xz xz-T0 xz-0-T0
#3|1|< 60.0 size  49941772.0 57273254.0 61148843.0 40579988.0 40723416.0 49942636.0 
#3|2|< 40.0 time  12.46 19.71 9.47 103.33 61.04 6.73