Universität Ulm, Fakultät für Mathematik und Wirtschaftswissenschaften, SAI

Lösung zu Blatt 4 --- Software Engineering Praxis (SS 2002)

Was mag ich denn?

#!/usr/local/bin/perl -w

use strict;

sub vq {
   my $res = 0;
   return 0 if scalar(@_) == 0;
   foreach (@_) {
      $res += $_;
   }
   return $res / scalar(@_);
}

sub p {
   my ($user, $film, $votes) = @_;
   my ($k, $sum, $w) = (0, 0, 0);
   while (my ($cuser, $cvotes) = each %{$votes}) { # Alle Stimmen
      next unless defined $cvotes->{$film};        # Film bewertet?
      $w = w($user, $cuser, $votes);
      $k += abs($w);
      $sum += $w * ($cvotes->{$film} - vq(values %{$cvotes}));
   }
   return 0 if $k == 0;
   return vq(values %{$votes->{$user}}) + $sum / $k;
}

sub w {  # Pearson
   my ($user, $cuser, $votes) = @_;
   my $vq1 = vq(values %{$votes->{$user}});
   my $vq2 = vq(values %{$votes->{$cuser}});
   my $votes1 = $votes->{$user};
   my $votes2 = $votes->{$cuser};
   return 0 unless ($vq1 and $vq2);
   my ($num, $denum1, $denum2) = (0, 0, 0);
   foreach my $films (keys %{$votes1}) {
      next unless defined $votes2->{$films};
      $num += ($votes1->{$films} - $vq1) * ($votes2->{$films} - $vq2);
      $denum1 += ($votes1->{$films} - $vq1) ** 2;
      $denum2 += ($votes2->{$films} - $vq2) ** 2;
   }
   return 0 if ($denum1 * $denum2) == 0;
   return $num * ($denum1 * $denum2) ** (-0.5);
}

sub readvotes {
   my ($file) = @_;
   open(FH, "$file") or die "Cannot open $file\n";
   my %user = ();
   while (<FH>) {
      chomp;
      my ($name, $film, $vote) = split /\|/;
      $user{$name}->{$film} = $vote;
   }
   close FH;
   return \%user;
}

my $filename = "/www/turing/htdocs/sai/ss02/sep/votes";
my $votes = readvotes($filename);
my $login = shift || "melzer";
print p("melzer", 'Psycho (1960)', $votes), "\n";
print p("borchert", 'Casablanca (1942)((aka Casablanca (1942)))', $votes), "\n";
foreach my $film (<>) {
   chomp $film;
   print "$film: ", p($login, $film, $votes), "\n";
}

Universität Fakultät SAI

Ingo Melzer, 10. Mai 2002