Excel, VisualBasic ir goto

Universitete tenka man retkarčiais prisėsti prie Visual
Basic
ir suprogramuoti vieną kitą Excel makrosą (kaip
sakant tenka iš tikrųjų pažinti VBasic blogybes :). Tiesą pasakius,
pati kalba neatrodo ten per daug baisi ir bloga (na, jei tik
apsiriboji makrosų rašymu ir viską taikai neprogramuojantiems
ekonomistams… nors ir čia turbūt Python ar Ruby būtų
aiškiau ir suprantamiau). Vienas blogiausių dalykų tas, kad kodo
pavyzdžiai, kuriuos gaunu iš dėstytojų (t.y jie rašyti dėstytojų) yra
ganėtinai košmariški – pilni painių goto
(taip, taip, goto!) ir kitokių įdomybių. Na, todėl ir nekeista,
kad kai ateina laikas atsiskaitymui, programa būna nukopijuojama nuo
pavyzdžių ir tuo viskas baigiasi. Štai pavyzdukas VBasic kodo, kuris
buvo duotas per paskaitą, aiškinant kirstinių metodą funkcijos
šaknims rasti:

sub .......
...........
a = 0.0001
b = 1
1 x = F(a)
 y = F(b)
If (x * y) > 0 Then
Cells(1, 2) = "nera saknu"
GoTo 2
End If
c = a - (b - a) * x / (y - x)
If (Abs(F(c)) < 0.001) Then
Cells(1, 1) = c
GoTo 2
End If
If F(a) * F(c) > 0 Then
a = c
Else: b = c
End If
GoTo 1
2 end sub

Ypač gražiai atrodo tie pora goto. O juk jau
1968 metais Djikstra sakė jog „Goto is
considered harmful
“. Perrašiau tą kodo gabaliuką Perlu
(naudojau rekursiją… gal ekonomistams čia jau ir per sudėtinga, bet
galima tą viršutinį algoritmą perrašyt panaudojant keletą
while. Be to ir nuorodos į subus nėra būtinos,
galima supaprastint ;):

sub kirst {
        # $fja yra kodo gabalas (nuoroda i suba)
        my ($fja, $a, $b) = @_;
        die "Nera saknu?" if ($fja->($a) * $fja->($b) > 0);
        my $c = $a - (($b - $a) * $fja->($a)) / ($fja->($b) - $fja->($a));
        if (abs($fja->($c)) < 0.00001) { # 0.00001 yra epsilon
                return $c;
        } elsif ($fja->($a) * $fja->($c) < 0) {
                return kirst($fja, $a, $c);
        } else {
                return kirst($fja, $c, $b);
        }
}

Atrodo kad čia daugiau kodo? Taip, tiesa, nes čia pilnas
subas, kurį galit imt ir naudot. Be to perlo stilium galima dar jį
žymiai sutraukt iki kokių trijų eilučių :)

Kad ir kaip ten bebūtų, dėstytoja mane išklausė, ir lyg ir ruošiasi
atsisakyti goto vardan while.

Comments Closed

7 Comments

  1. Nu daug kas turi goto… Pats Perlas turi goto, tik tikrai tuo nesididžiuoja :)

    Iš Perl manualo:

    The author of Perl has never felt the need to use this form of goto (in Perl, that is–C is another matter). (The difference being that C does not offer named loops combined with loop control. Perl does, and this replaces most structured uses of goto in other languages.)

  2. na taip, bet ish C# propaguotuju tarpo tai pasigirsta lyg privalumas priesh Java :))

  3. na taip, bet ish C# propaguotuju tarpo tai pasigirsta lyg privalumas priesh Java :))

  4. Mmmjo.. reik kodą peržiūrėt dėl to double-postingo ;) Kažką pridirbau ;)

  5. Taip biškį pamąsčiau kad dar savo Perliniam skriptuke per daug dažnai iškvietinėju $fja->(). Jei optimizuot, tai reiktų tik vieną kartą funkcijoje apsiskaičiuot $fja->($a), $fja->($b) ir $fja->($c).

Comments are closed.