2009-07-09 5 views
5

Ich habe eine Programmieraufgabe in Perl, die mir folgendes zu tun erfordert:Wie kann ich einen Familienstammbaum mit Perl erstellen?

  1. Erstellt eine Tabelle in einer MySQL-Datenbank und fügt diese Datensätze hinein:

  2. Lädt die Daten aus der Tabelle in eine Reihe von Instanzen der Klasse Son.

  3. Mithilfe des Arrays wird HTML-Code erstellt, der einen Vater-Sohn-Baum darstellt, und der HTML-Code wird in STDOUT ausgegeben. Es ist nicht notwendig, dass der Baum gut aussieht. So etwas wie dies wäre schön:

tree http://i25.tinypic.com/314t177.png

ich die Ideen ausgehen, bitte helfen Sie. Mein Code ist wie folgt:

#!/usr/bin/perl 

use strict; 
use Son; 
use CGI; 
use Data::Dumper; 
use DBI; 
my $q = new CGI; 

#DB connect vars 
my $user = "##"; 
my $pass = "##"; 
my $db = "##"; 
my $host = "localhost"; 

my $dsn = "DBI:mysql:database=$db;host=$host"; 

my $dbh = DBI->connect($dsn,$user,$pass); 
eval { $dbh->do("DROP TABLE sons") }; 
print "Drop failed: [email protected]\n" if [email protected]; 

$dbh->do("CREATE TABLE sons (son VARCHAR(30) PRIMARY KEY, father VARCHAR(30))"); 

my @rows = (["bill", "sam"], 
     ["bob", ""], 
     ["jack", "sam"], 
     ["jone", "mike"], 
     ["mike", "bob"], 
     ["sam", "bob"] 
); 

for my $i (0 .. $#rows) { 
    $dbh->do("INSERT INTO sons (son, father) VALUES (?,?)", {}, $rows[$i][0], $rows[$i][1]); 
} 

our @sons_array; 
my $sth = $dbh->prepare("SELECT * FROM sons"); 
$sth->execute(); 
while (my $ref = $sth->fetchrow_hashref()) { 
    $sons_array[++$#sons_array] = Son->new($ref->{'son'}, $ref->{'father'}); 
} 
$sth->finish(); 
$dbh->disconnect(); 


print $q->header("text/html"),$q->start_html("Perl CGI"); 
print "\n\n"; 
constructFamilyTree(@sons_array, ''); 
print $q->end_html; 

sub constructFamilyTree { 
    my @sons_array = @_[0..$#_ -1]; 
    my $print_father; 
    my $print_son; 
    my $print_relation; 
    my $current_parent = @_[$#_]; 
    my @new_sons_array; 
    my @new_siblings; 

    #print $current_parent."\n"; 
    foreach my $item (@sons_array){ 
     if(!$item->{'son'} || $item->{'son'} eq $item->{'father'}) { # == ($item->{'son'} eq '') 
      print "\n List contains bad data\n"; 
      return 0; 
     } 

     if($item->{'father'} eq $current_parent) { 
      my $temp_print_relation; 
      foreach my $child (@sons_array) { 
       if($child->{'father'} eq $item->{'son'}) { 
        if(!$temp_print_relation) { 
         $temp_print_relation .= ' |'; 
        } 
        else { 
         $temp_print_relation .= '-----|'; 
        } 
       } 
      } 
      $print_relation .= $temp_print_relation." "; 
      $print_son .= '('.$item->{'son'}.') '; 
      @new_siblings[++$#new_siblings] = $item; 
      $print_father = $item->{'father'}; 
     } 
     else { 
      $new_sons_array[++$#new_sons_array] = $item; 
     } 
    } 

    print $print_son. "\n". $print_relation."\n"; 
    #print $print_father."\n"; 
    #print $print_relation . "\n". $print_son; 
    foreach my $item (@new_siblings) { 
     constructFamilyTree(@new_sons_array, $item->{'son'}); 
    } 
} 


perl module: 
#File Son.pm, module for class Son 

package Son; 

sub new { 
    my($class, $son, $father) = @_; 
    my $self = {'son' => $son, 
       'father' => $father}; 

    bless $self, $class; 
    return $self; 
} 

1; 
+4

"Keine Ideen mehr", Ideen für was genau? Hier ist keine Frage, nur deine Aufgabe, und ein "hier, mach es für mich". –

+0

Ihre Frage geht wirklich nicht um CGI oder MySQL. Es geht darum, eine geeignete Datenstruktur auszuwählen und anzuzeigen. Ihr Code enthält zu viele überflüssige Details für die jeweilige Aufgabe. –

+0

Ich frage mich nur, ob ich komplett oder auf dem richtigen Weg bin. Entschuldigung/Danke. –

Antwort

5

Während Klärung warten, was die Frage ist, ich dachte, sehen Sie in einer Art Lerninstitution sind immer Perl verwandte Aufgaben gegeben, ich begründete es gibt keine bessere Zeit vorstellen Sie zu Moose und CPAN, Dinge, die Sie wirklich in der realen Welt verwenden sollten.

Es und seine verschiedenen Erweiterungen werden Ihr Leben einfacher machen und objektorientiertes Design einfacher und wartbarer machen.

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 
use Moose::Autobox; 
use 5.010; 

sub Moose::Autobox::SCALAR::sprintf { 
    my $self = shift; 
    sprintf($self, @_); 
} 

{ 

    package Son; 
    use Moose; 
    use MooseX::Types::Moose qw(:all); 
    use MooseX::ClassAttribute; 
    use MooseX::Has::Sugar 0.0300; 
    use Moose::Autobox; 

    class_has 'Ancestry' => (isa => HashRef, rw, default => sub { {} }); 
    class_has 'People' => (isa => HashRef, rw, default => sub { {} }); 
    has 'name'   => (isa => Str,  rw, required); 
    has 'father'   => (isa => Str,  rw, required); 

    sub BUILD { 
    my $self = shift; 
    $self->Ancestry->{ $self->name } //= {}; 
    $self->Ancestry->{ $self->father } //= {}; 
    $self->People->{ $self->name }  //= $self; 
    $self->Ancestry->{ $self->father }->{ $self->name } = $self->Ancestry->{ $self->name }; 
    } 

    sub children { 
    my $self = shift; 
    $self->subtree->keys; 
    } 

    sub subtree { 
    my $self = shift; 
    $self->Ancestry->{ $self->name }; 
    } 

    sub find_person { 
    my ($self, $name) = @_; 
    return $self->People->{$name}; 
    } 

    sub visualise { 
    my $self = shift; 
    '<ul><li class="person">%s</li></ul>'->sprintf($self->visualise_t); 
    } 

    sub visualise_t { 
    my $self = shift; 
    '%s <ul>%s</ul>'->sprintf(
     $self->name, 
     $self->children->map(
     sub { 
      '<li class="person">%s</li>'->sprintf($self->find_person($_)->visualise_t); 
     } 
     )->join('') 
    ); 
    } 
    __PACKAGE__->meta->make_immutable; 
} 

my @rows = ([ "bill", "sam" ], [ "bob", "" ], [ "jack", "sam" ], [ "jone", "mike" ], [ "mike", "bob" ], [ "sam", "bob" ],); 

for (@rows) { 
    Son->new(
    father => $_->at(1), 
    name => $_->at(0), 
); 
} 

<<'EOX'->sprintf(Son->find_person('bob')->visualise)->say; 
<html> 
    <head> 
    <style> 
     li.person { 
border: 1px solid #000; 
padding: 4px; 
margin: 3px; 
background-color: rgba(0,0,0,0.05); 
     } 
    </style> 
    </head> 
    <body> 
    %s 
    </body> 
</html> 
EOX 
+0

Ich habe mich nur gefragt, ob irgendjemand irgendwelche Vorschläge hatte, wie man diese Aufgabe besser erledigen könnte. Ich suchte nicht nach einer Hand. Danke für die Elch- und CPAN-Lektion! Ich bin neu in Perl und es ist EXTREM hilfreich zu wissen, was die beste Methode der realen Welt ist. Danke noch einmal. –

1

So viel wie ich von Kent Fredric's answer Lernen genossen (siehe, ich habe kaum etwas über einfache Übungen geschrieben mit Moose), ich meine, Sie könnten mehr lernen, indem sie bei einer etwas traditionelleren Lösung für das Problem suchen die der Anzeige Datenstruktur. Es löst nicht direkt Ihre Frage (ich nehme an, Ihre Frage basiert auf einer Hausaufgabe). Wenn sich der Code als hilfreich erweist, bin ich mir sicher, dass Ihr Lehrer es begrüßen würde, wenn Sie Hilfe von außen nennen, die Sie erhalten haben.

#!/usr/bin/perl 

use strict; 
use warnings; 

my @rows = (
    [ bill => 'sam' ], 
    [ bob => ''  ], 
    [ jack => 'sam' ], 
    [ jone => 'mike' ], 
    [ mike => 'bob' ], 
    [ sam => 'bob' ], 
    [ jim => ''  ], 
    [ ali => 'jim' ], 
); 

my %father_son; 

for my $pair (@rows) { 
    push @{ $father_son{ $pair->[1] } }, $pair->[0]; 
} 

for my $root (@{ $father_son{''} }) { 
    print_branch($root, 0); 
} 

sub print_branch { 
    my ($branch, $level) = @_; 
    print "\t" x $level, $branch, "\n"; 
    if (exists $father_son{$branch}) { 
     for my $next_branch (@{ $father_son{$branch} }) { 
      print_branch($next_branch, $level + 1); 
     } 
    } 
    return; 
} 

__END__ 

Ausgang:

C:\Temp> tkl 
bob 
     mike 
       jone 
     sam 
       bill 
       jack 
jim 
     ali 
+0

Dies scheint am leichtesten zu verstehen für eine Person, die nur Perl lernt (wie ich). Obwohl es mir gestern Nacht gelungen ist, eine Antwort zusammenzustellen, hat das mein Problem gelöst. Dies ist auch eine viel einfachere Antwort auf mein Problem. Vielen Dank! Ich werde von diesem Beispiel lernen! –

3

Verwendung GraphViz. Das ist viel einfacher als das Bild selbst zu machen.

Verwandte Themen