2009-07-09 4 views
5

私は次の操作を行うために私を必要とPerlでのプログラミングの割り当てを持っている:どのようにしてPerlでファミリーツリーを構築できますか?

  1. は、MySQLデータベースのテーブルを作成し、それにこれらのレコードを挿入します。

  2. がテーブルからデータをロードしますSonクラスのインスタンスの配列に変換します。

  3. 配列を使用して、父と息子のツリーを表すHTMLコードを作成し、htmlコードをSTDOUTに出力します。ツリーを見栄え良くする必要はありません。このような何かは大丈夫だと思う:

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

私はアイデアを実行しているよ、助けてください。私のコードは次のとおりです。、私が見て考え出し

#!/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

「アイデアが足りない」というアイデアは何ですか?ここに質問はありません。あなたの割り当てだけです。そして、「ここで、私のために行ってください」。 –

+0

あなたの質問は本当にCGIやMySQLについてではありません。適切なデータ構造を選択して表示することです。あなたのコードには、手元にあるタスクのための余分な細部がたくさん含まれています。 –

+0

私が完全にオフになっているのか、正しいトラックにいるのか不思議です。ごめんなさい/ありがとう。 –

答えて

5

問題が何であるかに関して、明確化を待っている間、あなたがPerlの関連割り当てを与えられたばかりの学習機関のいくつかの並べ替えにいる、私が紹介するには良い時間がありません推論しました現実の世界で実際に使っているはずのもの、MooseとCPANへ

これとそのさまざまな拡張機能は、あなたの人生を楽にし、オブジェクト指向のデザインをより単純で保守的なものにします。

#!/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

手元にあるタスクをよりうまく達成する方法について、誰かが提案しているのかどうか疑問に思っていました。私は手を探していませんでした。しかし、MooseとCPANのレッスンに感謝します。私はperlの初心者であり、実際の世界最高の方法が何であるかを知るのに非常に役立ちます。再度、感謝します。 –

1

私はKent Fredric's answerからの学習楽しんだよう(参照、私はかろうじてムースを使用して、簡単な演習を超えて何を書かれている)限り、私はあなたが表示の問題に幾分、より伝統的な解決策を見て、多くを学ぶかもしれません把握データ構造。 あなたの質問を直接解決するものではありません(あなたの質問は宿題に基づいていると仮定します)。コードが役立つことが判明した場合は、あなたが受け取った外部からの助けを引用すれば、インストラクターがそれを感謝すると確信しています。

#!/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__ 

出力:

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

これは、自分自身のようにperlを学ぶ人にとって最も理解しやすいようです。私は昨夜一緒に回答をまとめることができましたが、私の問題は解決しました。これは私の問題に対するもっと簡単な答えです。ありがとう!私はこの例から学びます! –

3

使用GraphViz。それはあなた自身の写真を作るよりもずっと簡単です。

関連する問題