310 likes | 440 Views
References & Complex Data Structures. Variable types in PERL. $number -3.54. @array. $string "hi<br>". $reference 0x225d14. Scalar. Array. Hash. %hash. %hash. @array1. @array2. @array3. Referencing – Dereferencing Arrays. @grades. @arr. A. A. A. B. B. B. C. C. C. $gradesRef.
E N D
Variable types in PERL $number-3.54 @array $string"hi\n" $reference0x225d14 Scalar Array Hash %hash %hash @array1 @array2 @array3
Referencing – Dereferencing Arrays @grades @arr A A A B B B C C C $gradesRef $arrRef Referencing array : $arrayRef = [@grades]; $gradesRef = \@grades; (careful) Dereferencing array : @arr = @{$arrRef}; $element1 = $arrRef->[0]; $element1 = $arrRef->[0] = A
References example @grades @grades @grades 85 100 56 56 85 100 82 99 91 91 82 99 67 77 67 77 A reference to a variable is a scalar value that “points” to another variable. [@array] creates a copy of the array and return a referenceto this copy: my @grades = (85,91,67); my %gradeHash; $gradeHash{"Eyal"} = [@grades]; @grades = (100,82); $gradeHash{"Neta"} = [@grades]; @grades = (56,99,77); $gradeHash{"Era"} = [@grades]; %gradesHash %gradesHash %gradesHash "Neta" "Neta" "Era" "Eyal" "Eyal" "Eyal"
References (bad) example @grades @grades @grades 56 100 85 99 82 91 77 67 A reference to a variable is a scalar value that “points” to another variable. \@array return a reference to the array itself. THIS MIGHT BE DANGEROUS. my @grades = (85,91,67); my %gradeHash; $gradeHash{"Eyal"} = \@grades; @grades = (100,82); $gradeHash{"Neta"} = \@grades; @grades = (56,99,77); $gradeHash{"Era"} = \@grades; Just don't do that… %gradesHash %gradesHash %gradesHash "Neta" "Neta" "Era" "Eyal" "Eyal" "Eyal"
De-referencing examples To get the array use @{$reference} Get all the grades of Eyal: print $gradeHash{"Eyal"}; ARRAY(0x316c23) my @EyalGrades = @{$gradeHash{"Eyal"}} Get second grade of Neta: my $Neta2 = $gradeHash{"Neta"}->[1]; Change first grade of Era: $gradeHash{"Era"}->[0] = 72; %gradesHash 85 91 67 "Eyal" "Neta" 100 82 "Era" 56 72 99 77 Use ->[x] to get to the x element of the referenced array
More de-referencing examples Get sorted grades of Eyal: my @sortedGrades = sort(@{$gradeHash{"Eyal"}}); Push another grade to Neta: my $grade = 97; push (@{$gradeHash{"Neta"}},$grade); %gradesHash 85 91 67 "Eyal" "Neta" 100 82 97 "Era" 56 72 99 77
Referencing – Dereferencing Hashes %hash A X B Y C Z Referencing hash : $hashRef = {%phoneBook}; $bookRef = \%phoneBook; (careful) Dereferencing hash : %hash = %{$hashRef}; $myVal = $hashRef->{"A"}; %phoneBook $bookRef A X B Y C Z $myVal = $hashRef->{"A"} = "X" $hashRef A X B Y C Z
References example %details 6023 "phone" 5012 my %details; $details{"phone"} = 5012; $details{"address"} = "Swiss"; my %bookHash; $bookHash{"Eyal"} = {%details}; $details{"phone"} = 6023; $details{"address"} = "Yavne"; $bookHash{"Neta"} = {%details}; "addrs" "Swiss" "Yavne" "phone" "phone" 5012 6023 %bookHash %bookHash "addrs" "addrs" "Swiss" "Yavne" "Eyal" "Neta"
De-referencing examples Get all the details of Neta: my %NetaDetails= %{$bookHash{"Neta"}} Get the phone of Eyal: my $EyalPhone = $bookHash{"Eyal"}->{"phone"}; To get the hash use %{$reference} "phone" 5012 "addrs" "Swiss" Use ->{key} to get the value of key in the referenced hash %bookHash %bookHash "phone" 6023 "Eyal" "Neta" "addrs" "Yavne"
References You can think of it as folders that contain inner folders that contains some data… $bookHash{"Eyal"}->{"phone"} = 5012; $bookHash{"Eyal"}->{"address"} = "Swiss"; $bookHash{"Neta"}->{"phone"} = 6023; $bookHash{"Neta"}->{"address"} = "Yavne"; $bookHash{"Eyal"}{"phone"} = 5012; $bookHash{"Eyal"}{"address"} = "Swiss"; $bookHash{"Neta"}{"phone"} = 6023; $bookHash{"Neta"}{"address"} = "Yavne"; Change Neta's address: $bookHash{"Neta"}{"address"} = "Tel-Aviv"; Change Eyal's phone: $bookHash{"Eyal"}{"phone"} = 2209; "phone" 5012 "addrs" "Swiss" "phone" 6023 %bookHash %bookHash "addrs" "Yavne" "Eyal" "Neta"
De-referencing examples The general structure of the data structure: # $bookHash{$name}{"address"} = $address # $bookHash{$name}{"phone"} = $phone Get all the phones: @names= keys(%bookHash) foreach my $name (@names){ print "Phone of $name: "; print $bookHash{$name}{"phone"}."\n"; }
Class exercise 10a (=9b) • Write a script that reads a file with a list of protein names, lengths and location(such as in proteinLengthsAndLocation.txt ), with lines such as:AP_000081 181 Nuc AP_000174 104 CytStores the names of the sequences as hash keys, and use "length" and "location" as keys in an internal hash for each protein. For example:$proteins{"AP_000081"}{"length"} should be 181$proteins{"AP_000081"}{"location"} should be "Nuc". • Ask the user for a protein name and print its length and location. • Print for each protein its name and location. • Read the adenovirus GenBank file and build a hash of genes, where the key is the product name: For each gene store an internal hash with two keys, one contains the protein_id and the other contains the db_xref. • Ask the user for a product, and print its protein_id and db_xref. • Use the CDS line to decide whether the coding sequence is on the positive or negative stands ("complement" before the coordinates marks a sequence coded on the negative strand). Add a key strand to the hash of each gene that contains "+" if the coding sequence is coded on the positive strand or "-" if it is on the negative. print all the product names of the proteins coded on the negative strand.
More complex data structures The general structure of the data structure: # $bookHash{$name}{"address"} = $address # {"phone"} = $phone # {"grades"} = [ @grades ] my %bookHash; $bookHash{"Eyal"}{"phone"} = 5012; $bookHash{"Eyal"}{"address"} = "Swiss"; my @grades = (85,91,67); $bookHash{"Eyal"}{"grades"} = [@grades];
More complex data structures The general structure of the data structure: # $bookHash{$name}{"address"} = $address # {"phone"} = $phone # {"grades"} = [ @grades ] my %bookHash; $bookHash{"Eyal"}{"phone"} = 5012; $bookHash{"Eyal"}{"address"} = "Swiss"; $bookHash{"Eyal"}{"grades"}[0] = 85; $bookHash{"Eyal"}{"grades"}[1] = 91; $bookHash{"Eyal"}{"grades"}[2] = 67;
More complex data structures The general structure of the data structure: # $bookHash{$name}{"address"} = $address # {"phone"} = $phone # {"grades"} = [ @grades ] $bookHash{"Neta"}{"phone"} = 6023; $bookHash{"Neta"}{"address"} = "Yavne"; @grades = (100,82); $bookHash{"Neta"}{"grades"} = [@grades];
More complex data structures The general structure of the data structure: # $bookHash{$name}{"address"} = $address # {"phone"} = $phone # {"grades"} = [ @grades ] $bookHash{"Era"}{"phone"} = 2209; $bookHash{"Era"}{"address"} = "Tel-Aviv"; @grades = (56,99,77); $bookHash{"Era"}{"grades"} = [@grades];
More complex data structures The general structure of the data structure: # $bookHash{$name}{"address"} = $address # {"phone"} = $phone # {"grades"} = [ @grades ] Now let's print the phone and average of each one…
More complex data structures Now let's print the phone and average of each one…my @names = keys (%bookHash); foreach my $name (@names){ print "Phone of $name: ".$bookHash{$name}{"phone"}."\n"; my @grades = @{ $bookHash{$name}{"grades"}}; my $sum = 0; foreach my $grade (@grades){ $sum = $sum + $grade; } my $avr = $sum / scalar(@grades); print "Average of $name: $avr\n"; } Phone of Era: 2209 Average of Era: 77.3333 Phone of Eyal: 5012 Average of Eyal: 81 Phone of Neta: 6023 Average of Neta: 91
Class exercise 10b • Write a script that reads a file with a list of protein names, lengths, location and expression levels (such as in proteinFullData.txt ), with lines such as:AP_000081 181 Nuc 0.02,0.41,0.34,0.05,0.04 AP_000138 145 Cyt 0.27,0.43,0.20 Stores the names of the sequences as hash keys, and use "length", "location" and "levels"as keys in an internal hash for each protein. For example:$proteins{"AP_000081"}{"length"} should be 181$proteins{"AP_000081"}{"location"} should be "Nuc".$proteins{"AP_000081"}{"levels"} should be an arraywith 0.02 in its first element 0.41 in its second element, and so on. • Ask the user for a protein name and print its length and location and sorted levels. • Print for each protein its name, location and the average of its levels.
Class exercise 10b • Add to the script of 10a question 2b a key to the inner hash containing the CDScoordinates, such that the structure of the data structure is as follows: $gbHash{"product"}{"protein_id"} = $protein_id $gbHash{"product"}{"db_xref"} = $db_xref $gbHash{"product"}{"strand"} = $strand (+/-) $gbHash{"product"}{"CDS"} = [ @CDS ] • Ask the user for a product, and print its protein_id, db_xref and CDS coordinates. NOTE: for protein coded on the negative strand print the coordinates reversed. • print all the product names of the proteins coded on the positive strand that starts after coordinate
To Infinity and Beyond!! • What about even more levels of hashes? • For example: • Hash of names in which there are: • phone • address and the address has: • street name • number of house • city
To Infinity and Beyond!! What about even more levels of hashes? # $book{$name} {"phone"} = $phone # {"address"}{"street"} = $street # {"number"} = $number # {"city"} = $city
To Infinity and Beyond!! What about even more levels of hashes? my %bookHash; $bookHash{"Eyal"}{"phone"} = 5012; $bookHash{"Eyal"}{"address"}{"street"} = "Baugenhof St."; $bookHash{"Eyal"}{"address"}{"number"} = "31"; $bookHash{"Eyal"}{"address"}{"city"} = "Lausanne";
To Infinity and Beyond!! What about an array of addresses?? Well… we know how to do that… # $book{$name} {"phone"} = $phone # {"address"} = [@addresses]
To Infinity and Beyond!! What about an array of addresses?? Well… we know how to do that… # $book{$name} {"phone"} = $phone # {"address"}[$i] = $address_i
To Infinity and Beyond!! What about an array of addresses?? Well… we know how to do that… my %bookHash; $bookHash{"Eyal"}{"phone"} = 5012; $bookHash{"Eyal"}{"address"}[0] = "Swiss"; $bookHash{"Eyal"}{"address"}[1] = "Yavne";
To Infinity and Beyond!! What about an array of addresses, each containing data of street and city ??!!??! # $book{$name} {"phone"} = $phone # {"address"}[$i] = $address_i
To Infinity and Beyond!! What about an array of addresses, each containing data of street and city ??!!??! # $book{$name} {"phone"} = $phone # {"address"}[$i]{"street"} = $street_i # {"address"}[$i]{"city"} = $city_i
To Infinity and Beyond!! What about an array of addresses, each containing data of street and city ??!!??! my %bookHash; $bookHash{"Eyal"}{"address"}[0]{"street"} = "Baugenhof 7"; $bookHash{"Eyal"}{"address"}[0]{"city"} = "Lausanne"; $bookHash{"Eyal"}{"address"}[1]{"street"} = "Hetzel 21"; $bookHash{"Eyal"}{"address"}[1]{"city"} = "Yavne";
The matrix 7 1 4 2 5 8 3 6 9 1 2 3 Do you think it is possible to make matrices in Perl? # $matrix[$i][$j] = $a_ij; my @matrix; $matrix[0][0] = 1; $matrix[0][1] = 2; $matrix[0][2] = 3; $matrix[1][0] = 4; $matrix[1][1] = 5; $matrix[1][2] = 6; $matrix[2][0] = 7; $matrix[2][1] = 8; $matrix[2][2] = 9; Three dimensional matrices? 4 5 6 7 8 9 @matrix