350 likes | 460 Views
56. 85. 100. 99. 91. 82. 77. 67. Complex data structures revision - references to arrays. %gradesHash. %gradesHash. %gradesHash. "Neta". "Neta". "Era". "Eyal". "Eyal". "Eyal". Variable types in PERL. $number -3.54. @array. $string "hi<br>". $reference 0x225d14. Scalar. Array.
E N D
56 85 100 99 91 82 77 67 Complex data structuresrevision - references to arrays %gradesHash %gradesHash %gradesHash "Neta" "Neta" "Era" "Eyal" "Eyal" "Eyal"
Variable types in PERL $number-3.54 @array $string"hi\n" $reference0x225d14 Scalar Array Hash %hash %hash $arr_ref_1 @array1 $arr_ref_2 @array2 $arr_ref_3 @array3
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 returns 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"
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
Syntactic Sugar This: $gradeHash{"Neta"}->[1] And this: $gradeHash{"Neta"}[1] Are equivalent!!! Syntactic Sugar is syntax within a programming language designed to make things easier to read. It makes the language "sweeter" for humans to use. Above is an example in Perl
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 $hashRef • A reference to a variable is a scalar value that “points” to another variable. • {%hash} creates a copy of the hash and returns a referenceto this copy: • my %details; • $details{"Phone"} = 5012; • $details{"Addrs"} = "Swiss"; • my $hashRef = {%details}; %details "Phone" 5012 "Addrs" "Swiss" "Phone" 5012 "Addrs" "Swiss"
Example: phone book • A reference to a variable is a scalar value that “points” to another variable. • {%hash} creates a copy of the hash and return a referenceto this copy: • my %details; • $details{"Phone"} = 5012; • $details{"Addrs"} = "Swiss"; • my %bookHash; • $ bookHash{"Eyal"} = {%details}; %details "Phone" 5012 "Addrs" "Swiss" "Phone" 5012 "Addrs" "Swiss" %bookHash "Eyal"
Example: phone book %details 6023 "Phone" 5012 my %details; $details{"Phone"} = 5012; $details{"Addrs"} = "Swiss"; my %bookHash; $bookHash{"Eyal"} = {%details}; $details{"Phone"} = 6023; $details{"Addrs"} = "Yavne"; $bookHash{"Neta"} = {%details}; "Addrs" "Swiss" "Yavne" "Phone" "Phone" 5012 6023 %bookHash %bookHash "Addrs" "Addrs" "Swiss" "Yavne" "Eyal" "Neta"
Example: phone book Another way to build the same data structure: $bookHash{"Eyal"}->{"Phone"} = 5012; $bookHash{"Eyal"}->{"Addrs"} = "Swiss"; $bookHash{"Neta"}->{"Phone"} = 6023; $bookHash{"Neta"}->{"Addrs"} = "Yavne"; "Phone" 5012 "Addrs" "Swiss" "Phone" 6023 %bookHash %bookHash "Addrs" "Yavne" "Eyal" "Neta"
De-referencing “%{}” To access the data from a reference we need to dereference it: my $hashRef; $hashRef->{"Phone"} = 5012; $hashRef->{"Addrs"} = "Swiss"; my %details = %{$hashRef}; my @vals = values (%details); print "@vals"; 5012 Swiss %details "Phone" 5012 "Addrs" "Swiss" $hashRef "Phone" 5012 "Addrs" "Swiss" To get the hash use %{$reference}
De-referencing “%{}” To access the data from a reference we need to dereference it: my $hashRef; $hashRef->{"Phone"} = 5012; $hashRef->{"Addrs"} = "Swiss; my $phone = $hashRef->{"Phone"}; print $phone; 5012 $hashRef "Phone" 5012 Use ->{key} to get the value of key in the referenced hash "Addrs" "Swiss"
De-referencing examples Get all the details of Neta: my %NetaDetails= %{$bookHash{"Neta"}} Get the phone of Eyal: my $EyalPhone = $bookHash{"Eyal"}->{"Phone"}; "Phone" 5012 "Addrs" "Swiss" %bookHash %bookHash "Phone" 6023 "Eyal" "Neta" "Addrs" "Yavne"
References – the simple version… You can think of it as folders that contain inner folders that contains some data… $bookHash{"Eyal"}->{"Phone"} = 5012; $bookHash{"Eyal"}->{"Addrs"} = "Swiss"; $bookHash{"Neta"}->{"Phone"} = 6023; $bookHash{"Neta"}->{"Addrs"} = "Yavne"; $bookHash{"Eyal"}{"Phone"} = 5012; $bookHash{"Eyal"}{"Addrs"} = "Swiss"; $bookHash{"Neta"}{"Phone"} = 6023; $bookHash{"Neta"}{"Addrs"} = "Yavne"; Change Neta's address: $bookHash{"Neta"}{"Addrs"} = "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}{"Addrs"} = $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"; }
Referencing – Dereferencing Hashes - summary %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
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. • 2*. 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_idand the other contains the db_xref. • Ask the user for a product, and print its protein_id and db_xref. • b*) 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}{"Addrs"} = $address # {"Phone"} = $phone # {"grades"} = [ @grades ] my %bookHash; $bookHash{"Eyal"}{"Phone"} = 5012; $bookHash{"Eyal"}{"Addrs"} = "Swiss"; my @grades = (85,91,67); $bookHash{"Eyal"}{"grades"} = [@grades];
More complex data structures The general structure of the data structure: # $bookHash{$name}{"Addrs"} = $address # {"Phone"} = $phone # {"grades"} = [ @grades ] my %bookHash; $bookHash{"Eyal"}{"Phone"} = 5012; $bookHash{"Eyal"}{"Addrs"} = "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}{"Addrs"} = $address # {"Phone"} = $phone # {"grades"} = [ @grades ] $bookHash{"Neta"}{"Phone"} = 6023; $bookHash{"Neta"}{"Addrs"} = "Yavne"; @grades = (100,82); $bookHash{"Neta"}{"grades"} = [@grades];
More complex data structures The general structure of the data structure: # $bookHash{$name}{"Addrs"} = $address # {"Phone"} = $phone # {"grades"} = [ @grades ] $bookHash{"Era"}{"Phone"} = 2209; $bookHash{"Era"}{"Addrs"} = "Tel-Aviv"; @grades = (56,99,77); $bookHash{"Era"}{"grades"} = [@grades];
More complex data structures The general structure of the data structure: # $bookHash{$name}{"Addrs"} = $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 uses "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 levels. • Print for each protein its name, location and the average of its levels.
Class exercise 10b (cont.) • 2*. Add to the script of 10a question 2b a key to the inner hash containing the CDScoordinates, with the following data structure: $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 proteins coded on the negative strand print the coordinates reversed. • print all the product names of the proteins coded on the positive strand which start after coordinate 2000
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 # {"Addrs"}{"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"}{"Addrs"}{"street"} = "Baugenhof St."; $bookHash{"Eyal"}{"Addrs"}{"number"} = "31"; $bookHash{"Eyal"}{"Addrs"}{"city"} = "Lausanne";
To Infinity and Beyond!! What about an array of addresses?? Well… we know how to do that… # $book{$name}{"Phone"} = $phone # {"Addrs"} = [@addresses]
To Infinity and Beyond!! What about an array of addresses?? Well… we know how to do that… # $book{$name}{"Phone"} = $phone # {"Addrs"}[$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"}{"Addrs"}[0] = "Swiss"; $bookHash{"Eyal"}{"Addrs"}[1] = "Yavne";
To Infinity and Beyond!! What about an array of addresses, each containing data of street and city ??!!??! # $book{$name}{"Phone"} = $phone # {"Addrs"}[$i]{"street"} = $street_i # {"Addrs"}[$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"}{"Addrs"}[0]{"street"} = "Baugenhof 7"; $bookHash{"Eyal"}{"Addrs"}[0]{"city"} = "Lausanne"; $bookHash{"Eyal"}{"Addrs"}[1]{"street"} = "Hetzel 21"; $bookHash{"Eyal"}{"Addrs"}[1]{"city"} = "Yavne";
The matrix 7 1 4 2 5 8 3 6 9 1 2 3 Is it possible to represent 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