В этом есть две ключевые части. Первый - получить столбец данных из файла, а второй - рассчитать стандартное отклонение этих данных. Поскольку у нас есть легко идентифицируемые детали, это отличная возможность выполнить некоторые процедуры.
Есть несколько способов написания загрузчика столбцов. Вот один из них:
proc LoadColumn {filename columnIndex} {
set f [open $filename]
set column {}
while {[gets $f line] >= 0} {
set datum [lindex [split $line] $columnIndex]
if {$datum != ""} {
lappend column $datum
}
}
close $f
return $column
}
Теперь, вычисление стандартного отклонения достаточно просто, теперь нам не нужно смешивать ввод-вывод с ним. В конце концов, формула просто скопирована прямо из Википедии:
proc StandardDeviation {data} {
set n [expr {double([llength $data])}]
set sum [tcl::mathop::+ {*}$data]
set mean [expr {$sum / $n}]
set sum2 [tcl::mathop::+ {*}[lmap x $data {expr {($x - $mean) ** 2}}]]
return [expr {sqrt($sum2 / ($n - 1))}]
}
(Единственный настоящий продвинутый метод - это [tcl::mathop::+ {*}…]
для вычисления суммы списка. Вместо этого вы можете использовать foreach
и expr
, но для этого требуется больше кода.)
Тогда мы можем соединить части:
set file "myfile.dat"
set column [LoadColumn $file 1]; # Column indices count from zero
set sd [StandardDeviation $column]
puts "The standard deviation is $sd"
Разделение проблем жизненно важно для создания программ, которые вы можете понять.