08. Subroutines and Randomization

BIO494-05: Υπορουτίνες (subroutines) και Τυχαιοποίηση

Υπορουτινές. Κρατώντας τον έλεγχο της δομής.

Καθώς οι εφαρμογές γίνονται όλο και πιο σύνθετες πολλά από τα προγράμματα που γράφουμε ενσωματώνουν παλιότερα που έχουμε ήδη γραψει. Μια πρακτική που μας γλυτώνει από τον κόπο και τους κινδύνους του copy-paste και που μας βοηθάει να ελέγχουμε τη δομή του προγράμματος μας είναι η συγγραφή υπορουτινών ή συναρτήσεων (subroutines). Μπορούμε να φανταστούμε τις υπορουτίνες σαν ξεχωριστά προγράμματα που δημιουργούμε και ενσωματώνουμε σε άλλα μεγαλύτερα όποτε το επιθυμούμε.

Δημιουργία μιας Υπορουτίνας

Η δημιουργία της γίνεται με την εντολή sub ακολουθούμενη από το όνομα της υπορουτίνας (που το δίνουμε εμείς)

Οι υπορουτίνες συνήθως γράφονται στο τέλος ενός προγράμματος. Στην πραγματικότητα τις επικολλούμε εμείς εκεί καθώς τις περισσότερες φορές είναι ήδη γραμμένες. Θα πρέπει όμως να βρίσκονται μετά το κύριο σώμα του προγραμμάτος. Π.χ.:

...

exit;

# subroutines start here

sub mysubroutine {

....

return $something

}

Κλήση μιας Υπορουτίνας

Τη στιγμή που τη χρειαζόμαστε οπουδήποτε μέσα στο πρόγραμμα καλούμε με το όνομά της δίνοντας το/τα όρισμα/τα της μέσα σε παρένθεση:

mysubroutine(...)

Mέσα στην παρένθεση βάζουμε τα ορίσματα της υπορουτίνας, τις μεταβλητές δηλαδή που χρειάζεται η υπορουτίνα για να λειτουργήσει. Αυτά μπορεί να είναι:

  • Tίποτα (πολύ απλές υπορουτίνες)
  • Μία μεταβλητή, (βαθμωτή, πίνακας, hash)
  • Πολλές μεταβλητές

Ας δούμε ένα απλό παράδειγμα μιας υπορουτίνας που υπολογίζει τον αριθμό καταλοίπων μιας βιολογικής αλληλουχίας.

#! /usr/bin/perl

print "Provide DNA sequence (in uppercase)\n";

$DNA = <STDIN>;

chomp($DNA);

print $DNA,"\n";

COUNTDNA($DNA); #calling subroutine COUNTDNA providing $sequence as argument

print "The composition of your sequence is:\n";

foreach $nuc (sort keys(%count)) {

print $nuc,":",$count{$nuc},"\n";

}

exit;

#========================

# Subroutines here

# Subroutine to count bases in an upper case DNA sequence

sub COUNTDNA {

#υπολογίζει τις συχνότητες των βάσεων

$A="A";

$G="G";

$C="C";

$T="T";

while ($DNA =~/A/g) {$count{$A}++}

while ($DNA =~/T/g) {$count{$T}++}

while ($DNA =~/G/g) {$count{$G}++}

while ($DNA =~/C/g) {$count{$C}++}

return %count; # result returned in the form of a hash

}

Σαν άσκηση, σκεφτείτε έναν τρόπο για να υπολογίσετε τη συχνότητα εμφάνισης οποιασδήποτε αλληλουχίας (π.χ. πρωτεϊνικής) ανεξαρτήτως της αναγραφής μικρών ή κεφαλαίων.

Tυχαιοποίηση και η συνάρτηση rand()

Η συνάρτηση rand() aποδίδει έναν τυχαίο αριθμό μέσα σε κάποιο όριο. Η χρήση της είναι η εξής:

rand( ) # Default χρήση. Αποδίδει έναν τυχαίο δεκαδικό αριθμό μεταξύ 0 και 1.

rand(N) #Ειδική χρήση. Αποδίδει έναν δεκαδικό αριθμό μεταξύ 0 και Ν

int(rand(N)) #Ακέραιη χρήση. Αποδίδει έναν ακέραιο μεταξύ 0 και Ν

int(rand(Ν)) + Μ #Χρήση με όρια. Αποδίδει έναν ακέραιο μεταξύ Μ και Ν

Εκκίνηση "γεννήτριας" τυχαίων αριθμών (seeding)

Όλες οι γεννήτριες τυχαίων αριθμών χρειάζονται μια τιμή εκκίνησης. Αυτή είναι καλό να αποδίδεται κάθε φορά εκ νέου για πιο ασφαλή αποτελέσματα. Αν η αρχική τιμή (seed) είναι ίδια, τότε η σειρά των τυχαίων αριθμών θα είναι επίσηςη ίδια. Σε μοντέρνες εκδόσεις της Perl αρκεί να γράψουμε:

srand()

Ας δούμε καλύτερα τη χρήση της με ένα παράδειγμα:

Nα δημιουργήσετε μια τυχαία αλληλουχία DNA 1000 βάσεων στην οποία το κάθε κατάλοιπο εμφανίζεται με πιθανότητα 0.25 (κατά προσέγγιση).