Skip to content

Instantly share code, notes, and snippets.

@kantale
Last active May 6, 2019 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kantale/97c297ddf6e4a4f45fddd74baac4e01a to your computer and use it in GitHub Desktop.
Save kantale/97c297ddf6e4a4f45fddd74baac4e01a to your computer and use it in GitHub Desktop.
5th assignment python

ΣΗΜΑΝΤΙΚΟ Προσπαθήστε να λύσετε τις ασκήσεις 1,2,3,4,5 χωρίς for και while. Εκτός από τη 5 δεν θα κοπεί βαθμός αν χρησιμοποιήσετε for. Αν κάνετε τη 3 χωρίς for, bonus 10 βαθμούς (Δηλαδή θα πάρει 20/10).

Άσκηση 1

Φτιάξτε μία συνάρτηση που θα παίρνει δύο ορίσματα Χ, Υ. Θα επιστρέφει έναν πίνακα numpy με διαστάσεις Χ και Υ όπου το στοιχείο i,j του πίνακα θα είναι ίσο με ij. Το i θα παίρνει τιμές από το 1 μέχρι ΚΑΙ το Χ, το j θα παίρνει τιμές από το 1 μέχρι ΚΑΙ το Υ.

Άσκηση 2

Φτιάξτε μία συνάρτηση η οποία θα παίρνει έναν numpy πίνακα και θα επιστρέφει έναν νέο πίνακα, όπου όλα τα στοιχεία θα είναι 0 εκτός τα στοιχεία της περιμέτρου τα οποία θα είναι τα ίδια. Δηλαδή αν έχουμε τον πίνακα:

Α = np.array([
[1,2,3,4],
[5,6,7,8],
[9,0,1,2],
[3,4,5,6],])

Τότε ο πίνακας που θα επιστρέφει η συνάρτησή σας θα πρέπει να είναι:

array([[1, 2, 3, 4],
       [5, 0, 0, 8],
       [9, 0, 0, 2],
       [3, 4, 5, 6]])

Άσκηση 3

Φτιάξτε μία συνάρτηση η οποία θα παίρνει έναν πίνακα numpy 9X9. Η συνάρτηση θα πρέπει να επιστρέφει True/False ανάλογα με το αν ο πίνακας περιέχει ένα λυμένο sudoku ή όχι.

Ένα λυμένο sudoku είναι παρακάτω (το έκλεψα από την Άσπα):

import numpy as np
valid_sudoku_matrix = np.array([
  [4,3,5,2,6,9,7,8,1],
  [6,8,2,5,7,1,4,9,3],
  [1,9,7,8,3,4,5,6,2],
  [8,2,6,1,9,5,3,4,7],
  [3,7,4,6,8,2,9,1,5],
  [9,5,1,7,4,3,6,2,8],
  [5,1,9,3,2,6,8,7,4],
  [2,4,8,9,5,7,1,3,6],
  [7,6,3,4,1,8,2,5,9]])

Και ένα παράδειγμα sudoku που είναι λάθος!:

this_is_not_a_sudoku = np.array([
    [1,2,3,4,5,6,7,8,9],
    [2,3,4,5,6,7,8,9,1],
    [3,4,5,6,7,8,9,1,2],
    [4,5,6,7,8,9,1,2,3],
    [5,6,7,8,9,1,2,3,4],
    [6,7,8,9,1,2,3,4,5],
    [7,8,9,1,2,3,4,5,6],
    [8,9,1,2,3,4,5,6,7],
    [9,1,2,3,4,5,6,7,8],
])

Η συνάρτησή σας θα πρέπει να βγάζει False στο this_is_not_a_sudoku και True στο valid_sudoku_matrix.

ΠΡΟΣΟΧΗ Αν κάνετε αυτή την άσκηση χωρίς for (ή while), bonus 10 βαθμούς (Δηλαδή θα πάρει 20/10).

Άσκηση 4

Φτιάξτε 10.000 τυχαίους πίνακες 3Χ3 όπου ο κάθε ένας να έχει 4 φορές το 0 και 5 φορές το 1. Αν ο κάθε πίνακας ήταν το αποτέλεσμα ενός παιχνιδιού τρίλιζας, τότε ποιό από τα παρακάτω ενδεχόμενα συμβαίνει τις περισσότερες φορές; (1) κερδίζει το "0", (2) κερδίζει το "1", (3) κερδίζουν και οι δύο, ή (4) δεν κερδίζει κανένας;

Παράδειγματα:

Κερδίζει το 1

1 1 0
0 1 1
0 0 1

Κερδίζει το 0

0 1 1
1 0 1
1 0 0

Κερδίζουν και οι δύο:

0 0 0
1 1 1
0 1 1

Δεν κερδίζει κανένας:

1 0 1
0 0 1
1 1 0

Άσκηση 5

Φτιάξτε μία συνάρτηση η οποία θα παίρνει έναν numpy από ακέραιους. Θα επιστρέφει έναν νέο numpy πίνακα όπου οι μονοί αριθμοί θα έχουν μετατραπεί σε άρτιοι προσθέτοντάς τους κατά 1 και οι άρτιοι θα έχουν μετατραπεί σε μονούς αφαιρώντας τους κατά 1. Για παράδειγμα:

Έστω ότι ο αρχικός πίνακας είναι:

array([[1, 2, 3],
       [4, 5, 6]])

Η συνάρτηση πρέπει να επιστρέφει:

array([[2, 1, 4],
       [3, 6, 5]])

Απαργορεύεται η χρήση for και while (και οποιοδίποτε iteration σε όλα τα στοιχεία του πίνακα)

Άσκηση 6

Για αυτή την άσκηση θα χρειαστεί να κατεβάσετε από το Human Genome Resources at NCBI το αρχείο RefSeq Reference Genome Annotation GRCh38. Μπορείτε να το κάνετε και με την εντολή:

wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/annotation/GRCh38_latest/refseq_identifiers/GRCh38_latest_genomic.gff.gz

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

import gzip
fn = 'GRCh38_latest_genomic.gff.gz'

with gzip.open(fn, 'rt') as f1, open('genes.csv', 'w') as f2:
    for l in f1:
        if l[0] == '#':
            continue
            
        ls = l.split()
        if ls[1] != 'BestRefSeq' or ls[2] != 'gene':
            continue
        
        data = {y[0]: y[1] for y in [x.split('=') for x in ls[8].split(';')]}
                
        start = ls[3]
        end = ls[4]
        name = data['Name']
        
        f2.write('\t'.join([name, start, end])+'\n')

Για να επιβεβαιώσετε ότι έτρεξε σωστά μπορείτε να κάνετε:

head genes.csv

Το αποτέλεσμα πρέπει να είναι:

MIR6859-1	17369	17436
MIR1302-2	30366	30503
FAM138A	34611	36081
OR4F5	69091	70008
LOC729737	134773	140566
MIR6859-2	187891	187958
OR4F29	450740	451678
LOC100132287	490756	495445
LOC101928626	627380	629009
MIR6723	632325	632413

Το αρχείο έχει τρεις στήλες. Η πρώτη είναι το όνομα του γονιδίου, η δεύτερη η αρχή τους και η τρίτη το τέλος του. Το μέγεθος του γονιδίου ορίζεται ως τέλος-αρχή. Φτιάχτε ένα ιστόγραμμα με τα μεγέθη όλων των γονιδίων. Μπορείτε να χρησιμοποιήσετε τη matplotlib τη seaborn ή όποια άλλη βιβλιοθήκη θέλετε. Δοκιμάστε τα παρακάτω:

  • Κάντε ένα απλό histogram μόνο για τα γονίδια που έχουν μέγεθος <200.
  • Κάντε ένα histogram με όλα τα γονίδια αλλά ο άξονας y να έχει λογαριθμική κλίμακα (ax.set_yscale('log'))

Άσκηση 7

Για αυτή την άσκηση πρέπει να εγκαταστήσετε τη βιβλιοθήκη requests. Αυτό μπορείτε να το κάνετε με την ακόλουθη εντολή:

pip install requests

Στη συνέχεια δίνεται ο παρακάτω κώδικας ο οποίος επιστρέφει πόσα paper έχουν δημοσιευθεί στο pubmed κατά τη διάρκεια κάποιου χρόνου τα οποία να περιέχουν στο abstract τους μία λέξη.

import requests

def pubmed_results(year, search):
    
    url_p = 'https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=(ABSTRACT:%22{search}%22)+AND+(FIRST_PDATE:[{year}-01-01+TO+{year}-12-31])&format=JSON'
    url = url_p.format(
        year = year,
        search = search,
    )
    r = requests.get(url)
    if not r.ok:
        r.raise_for_status()
        
    j = r.json()
    hit_count = int(j['hitCount'])
    return hit_count

Για παράδειγμα: Πόσα paper δημοσιεύτηκαν το 2013 που είχαν στο abstract τους τη λέξη "CRISPR";

pubmed_results(2013, "CRISPR")
>>> 255

Χρησιμοποιώντας τον κώδικα αυτό, φτιάξτε ένα barplot το οποίο να εμφανίζει για κάθε χρονιά από το 2000 μέχρι το 2018 το πλήθος από papers που έχουν δημοσιευθεί για τους όρους: "python" και "perl". Προσοχή, θα πρέπει να φτιάξετε ΕΝΑ plot! To plot σας θα πρέπει να έχει (περίπου) αυτή το μορφή:

img

Άσκηση 8

Με τα ίδια δεδομένα με την άσκηση 7, φτιάχτε ένα scatter plot. Στον άξονα x θα είναι οι χρονιές (2010, 2011, ..., 2018). Στο άξονα y θα είναι το πλήθος από publications. Βάλτε μπλε τελίτσες για python και κόκκινες για perl. Στη συνέχεια πλοτάρετε τα regression lines. Μπορείτε να χρησιμοποιήσετε τη seaborn για αυτό. Προσοχή θα πρέπει να κάνετε ένα plot με 2 regression lines (μπλε και κόκκινη αντίστοιχα). Η μορφή του plot σας θα πρέπει να είναι (περίπου) έτσι:

img

Άσκηση 9

Προφανώς θα θυμάστε την άσκηση 18 από τη 4η σειρά ασκήσεων. Ας υποθέσουμε λοιπόν ότι έχετε έτοιμη κάποια συνάρτηση f(N, pAA, pAB, pBB, T) η οποία βρίσκει την ελάχιστη συχνότητα p που πρέπει να έχει ένα αλληλόμορφο (το B π.χ.) έτσι ώστε να μπορούμε να επιβεβαιώσουμε τη συσχέτισή του με την ασθένεια σε έναν πληθυσμό με N άτομα, με False Discovery Rate = 0.05 μετά από T επαναλήψεις. Τα pAA, pAB, pBB είναι οι πιθανότητες να έχει την ασθένεια ένας άνθρωπος του πληθυσμού δεδομένου ότι ο γονότυπός του είναι Α/Α, Α/Β και Β/Β αντίστοιχα. Φτιάχνουμε τώρα μία δεύτερη συνάρτηση:

def f2(pAA, m):
   return f(1000, pAA, pAA + (pAA*m), pAA + (pAA*2*m), 2000)

Δηλαδή αυτή η συνάρτηση παίρνει δύο παραμέτρους. Το pAA και το m. Το m είναι πόσο αυξημένες είναι οι πιθανότητες (ποσοστιαία) να έχει την ασθένεια ο ΑΒ από τον ΑΑ. ο ΒΒ θεωρείται ότι έχει διπλάσια αύξηση της πιθανότητας από τον ΑΒ. Για παράδειγμα, αν pAA=0.1 και m=0.2, τότε η πιθανότητα ο AB να έχει την ασθένεια είναι 20% μεγαλύτερη από τον ΑΑ (άρα 0.1+(0.1*0.2)) και η πιθανότητα ο ΒΒ να έχει την ασθένεια είναι 2*20% μεγαλύτερη από τον ΑΑ (άρα 0.1+(0.1*2*0.2)). Η συνάρτηση επιστρέφει ό,τι και η f. Φτιάχνουμνε τώρα τον παρακάτω κώδικα:

import np
def f3():
   for pAA in np.arange(0.05, 0.2, 0.01):
      for m in np.arange(0.1, 2, 0.1):
         p = f2(pAA, m)
         print ('m={}'.format(m), ' p={}'.format(p), 'pAA={}'.format(pAA))

Η συνάρτηση αυτή βρίσκει διάφορες τιμές του p για ένα εύρος του pAA (από το 0.05 μέχρι το 0.2 με βήμα 0.01) και του m (από το 0.1 μέχρι το 2 με βήμα 0.1) και τυπώνει τη τριπλέτα των τιμών (m,p,pAA). Εσείς θα πρέπει να τρέξετε τον κώδικα αυτόν με τις δικές σας υλοποιήσεις και θα πρέπει να κάνετε το εξής plot:

Για κάθε διαφορετική τιμή του pAA, φτιάξτε τη καμπύλη που σχηματίζεται αν βάλουμε στον άξονα χ τις τιμές του p και στον άξονα y τις τιμές του m για αυτό το pAA. Δηλαδή θα πρέπει να φτιάξετε τόσες καμπύλες όσες είναι και οι διαφορετικές τιμές του pAA. Κάθε καμπύλη θα πρέπει να έχει διαφορετικό χρώμα ανάλογα με τη τιμή του pAA (δικής σας επιλογής). Εννοείται ότι αν θέλετε να "πλοτάρετε" αυτές τις τιμές για μεγαλύτερο εύρος δεδομένων ή μεγαλύτερη πυκνότητα (δηλαδή μικρότερο step), μπορείτε να το κάνετε!

Άσκηση 10

Για να κάνετε αυτή την άσκηση πρέπει να φορτώσετε στο pandas το αρχείο protein-coding_gene.txt το οποίο περιγράψαμε στη 3η σειρά ασκήσεων. Επειδή έχει αλλάξει πρόσφατα αυτό το αρχείο κατεβάστε μια παλαιότερη έκδοση με αυτόν τον τρόπο:

wget -O protein-coding_gene.txt "https://www.dropbox.com/s/c1fnpycsmqiumqd/efdd662887286b0ae3b49cacd8adc5f3.txt?dl=1"

Μπορείτε να φορτώσετε αυτό το αρχείο ως εξής:

import pandas as pd
df = pd.read_csv('protein-coding_gene.txt', sep='\t')

Το αρχείο αυτό περιέχει μία στήλη με τίτλο "Cosmic". Κάποιες από τις τιμές αυτής της στήλης είναι NaN (Not a Number). Μπορείτε να βρείτε ποιες τιμές είναι Nan με τη συνάρτηση isnull. Πόσα είναι λοιπόν τα γονίδια που ΔΕΝ έχουν NaN τιμές στη στήλη Cosmic; H Cosmic είναι μία βάση δεδομένων που περιέχει μεταλλάξεις που έχουν συσχετιστεί με τον καρκίνο. Απαντήστε επίσης στην ερώτηση: Πόσο είναι το ποσοστό των γονιδίων που υπάρχουν στη Cosmic;

Άσκηση 11

(Επίσης χρειάζεστε το αρχείο protein-coding_gene.txt)

wget -O protein-coding_gene.txt "https://www.dropbox.com/s/c1fnpycsmqiumqd/efdd662887286b0ae3b49cacd8adc5f3.txt?dl=1"

Το αρχείο αυτό έχει τη στήλη gene_family. Πόσες διαφορετικές τιμές παίρνει αυτή η στήλη; Ποιες είναι οι 10 ποιο κοινές τιμές αυτής της στήλης; (Hint value_counts). Φτιάξτε ένα bar πλοτ με τις συχνότητες αυτές. Το πλοτ που θα βγάζετε πρέπει να είναι αυτό (ή παρόμοιο): https://imgur.com/a/MlPyh8A

Άσκηση 12

(Επίσης χρειάζεστε το αρχείο protein-coding_gene.txt)

wget -O protein-coding_gene.txt "https://www.dropbox.com/s/c1fnpycsmqiumqd/efdd662887286b0ae3b49cacd8adc5f3.txt?dl=1"

Το αρχείο επίσης έχει τη στήλη date_modified, η οποία περιέχει το πότε έγινε η τελευταία αλλαγή στα στοιχεία αυτού του γονιδίου. ΠΡΟΣΟΧΗ! Ο τύπος της τιμής αυτής είναι string. Θα πρέπει να τη μετατρέψετε σε date. Αυτό γίνεται με τη συνάρτηση to_datetime. Ποιο είναι το όνομα του γονιδίου (στήλη name) το οποίο έχει αλλαχθεί πιο πρόσφατα;

Άσκηση 13

(Επίσης χρειάζεστε το αρχείο protein-coding_gene.txt)

wget -O protein-coding_gene.txt "https://www.dropbox.com/s/c1fnpycsmqiumqd/efdd662887286b0ae3b49cacd8adc5f3.txt?dl=1"

Η στήλη pubmed_id περιέχει λίστα από pubmed_ids (duh..) με δημοσιεύσεις για τα γονίδια αυτά. Για παράδειγμα:

df['pubmed_id'][:10]

Τυπώνει:

0              2591067
1    11815617|11072063
2      2408344|9697696
3             16298998
4    10854427|18630988
5    10854428|20971946
6             10430883
7    11062474|12196509
8    12623130|17762044
9              8063807
Name: pubmed_id, dtype: object

Αν πάρουμε το πρώτο (2591067) βλέπουμε ότι αντιστοιχεί σε αυτή τη δημοσίευση: https://www.ncbi.nlm.nih.gov/pubmed/2591067

Αν δηλαδή προσθέσουμε στο string: https://www.ncbi.nlm.nih.gov/pubmed/ το id τότε θα πάρουμε το link το οποίο μας πάει στο pubmed με τη δημοσίευση.

Φτιάξτε μία καινούργια στήλη στο DataFrame το οποίο να έχει το link με τη πιο πρόσφατη δημοσίευση για κάθε γονίδιο. Θεωρήστε ότι όσο πιο μεγάλο είναι ένα id, τόσο πιο πρόσφατη η δημοσίευση. Αν ένα γονίδιο δεν έχει pubmed_id τότε πρέπει να έχει τη τιμή None. Ονομάστε τη καινούργια στήλη: pubmed_link.

Για επαλήθευση, αν τρέξετε το παρακάτω:

df['pubmed_link'][:10]

Θα πρέπει να να τυπώσει:

0     https://www.ncbi.nlm.nih.gov/pubmed/2591067
1    https://www.ncbi.nlm.nih.gov/pubmed/11815617
2     https://www.ncbi.nlm.nih.gov/pubmed/9697696
3    https://www.ncbi.nlm.nih.gov/pubmed/16298998
4    https://www.ncbi.nlm.nih.gov/pubmed/18630988
5    https://www.ncbi.nlm.nih.gov/pubmed/20971946
6    https://www.ncbi.nlm.nih.gov/pubmed/10430883
7    https://www.ncbi.nlm.nih.gov/pubmed/12196509
8    https://www.ncbi.nlm.nih.gov/pubmed/17762044
9     https://www.ncbi.nlm.nih.gov/pubmed/8063807

Άσκηση 14

(Επίσης χρειάζεστε το αρχείο protein-coding_gene.txt)

wget -O protein-coding_gene.txt "https://www.dropbox.com/s/c1fnpycsmqiumqd/efdd662887286b0ae3b49cacd8adc5f3.txt?dl=1"
  • Πάρτε τις 10 ποιο κοινές τιμές της στήλης gene_family.
  • Για κάθε μία από αυτές υπολογίστε το πιο πρόσφατο και πιο παλιό date_modified

Το αποτέλεσμα πρέπει να είναι:

                                                 max         min
gene_family                                                     
Ankyrin repeat domain containing          2018-12-06  2013-01-10
Armadillo-like helical domain containing  2018-12-06  2008-08-01
Basic helix-loop-helix proteins           2018-12-06  2013-05-21
EF-hand domain containing                 2018-12-06  2013-01-10
Endogenous ligands                        2018-12-06  2013-02-28
RNA binding motif containing              2018-12-06  2013-02-12
Ring finger proteins                      2018-12-06  2013-01-09
Solute carriers                           2018-12-06  2014-11-19
WD repeat domain containing               2018-12-06  2013-01-09
Zinc fingers C2H2-type                    2018-12-06  2013-01-08

Άσκηση 15

(Επίσης χρειάζεστε το αρχείο protein-coding_gene.txt)

wget -O protein-coding_gene.txt "https://www.dropbox.com/s/c1fnpycsmqiumqd/efdd662887286b0ae3b49cacd8adc5f3.txt?dl=1"

Το αρχείο περιέχει μία στήλη με το όνομα location. Για παράδειγμα:

df['location'][:10]

Τυπώνει

0    19q13.43
1    10q11.23
2    12p13.31
3    12p13.31
4      1p35.1
5     22q13.2
6      3q22.3
7    12q13.13
8    12q24.31
9      3q25.1

Για παράδειγμα το 19q13.43 δηλώνει ότι το γονίδιο βρίσκεται στο μεγάλο (q) άκρο, του χρωμοσώματος 19. Κάθε χρωμόσωμα έχει ένα μεγάλο (q) και ένα μικρό (p) άκρο. Συγκεκριμμένα:

Origin of p and q as chromosome arms: The symbol "p" was chosen to designate the short arm because "p" stands for "petit", "small" in French. The letter "q" was selected to signify the long arm merely because "q" is the next letter in the alphabet. πηγή

Θα πρέπει λοιπόν να φτιάξετε ένα pandas DataFrame το οποίο να περιέχει πόσα γονίδια υπάρχουν στο μεγάλο και πόσα στο μικρό άκρο κάθε χρωμοσώματος.

Για διευκόλυνσή σας σας δίνω το DataFrame το οποίο θα πρέπει να τυπώνει η υλοποίησή σας:

                                Genes   
chromosome   arm                           
1            p                   1049  
             q                    953   
10           p                    154   
             q                    560   
11           p                    436   
             q                    836   
12           p                    279   
             q                    721   
13           q                    313   
14           p                      1     
             q                    595   
15           q                    565   
16           p                    446   
             q                    361   
17           p                    328   
             q                    809   
18           p                     65    
             q                    197   
19           p                    594   
             q                    788   
2            p                    459   
             q                    751   
20           p                    176   
             q                    346   
21           p                     13    
             q                    210   
22           q                    425   
3            p                    490   
             q                    553   
4            p                    229   
             q                    509   
5            p                    136   
             q                    664   
6            p                    592   
             q                    417   
7            p                    281   
             q                    595   
8            p                    255   
             q                    401   
9            p                    210   
             q                    544   
X            p                    329   
             q                    503   
Y            p                     13    
             q                     32    
mitochondria mitochondria          13    

Φτιάξετε επίσηε ένα plot το οποίο θα περιέχει μία τελεία για κάθε χρωμόσωμα. Η Χ συντεταγμένη της τελείας θα είναι το πλήθος από γονίδια που έχει στο άκρο p και το Y θα είναι το πλήθος από γονίδια που έχει στο άκρο q. To plot σας θα πρέπει να είναι κάπως έτσι: https://imgur.com/a/bLvkt9u

Άσκηση 16

Όπως βλέπετε από την άσκηση 16, υπάρχει το γονίδιο: FAM138A 34611 36081 το οποίο έχει όνομα FAM138A έχει αρχή: 34611 και τέλος: 36081.

Φτιάξτε μία κλάση με το όνομα Gene. Θα πρέπει να μπορώ να γράψω:

my_fabulous_gene = Gene(name='FAM138A', start=34611, end=36081)
print ('The name of my favorite gene is:', my_fabulous_gene.get_name())
>>> FAM138A
print (my_fabulous_gene)
>>> "Name: FAM138A   Start:34611   End:36081"

Άσκηση 17

Στη κλάσση της άσκησης 16 προσθέστε τη μέθοδο len η οποία καλείτε εσωτερικά σε οποιοδίποτε αντικείμενο κάνουμε len(). Για παράδειγμα:

class Country:
    def __init__(self, name, population):
        self.name = name
        self.population = population
    def __len__(self, ):
        # Ορίζουμε αυθαίρετα ότι το μέγεθος μιας χώρας είναι ο πληθυσμός της.
        return self.population

Greece = Country('Greece', 10000000)
print (len(Greece))
>>> 10000000

Στη δική σας υλοποίηση η __len__ θα επιστρέφει το μήκος (end-position) του γονιδίου. Θα πρέπει δηλαδή να μπορώ να κάνω:

my_fabulous_gene = Gene(name='FAM138A', start=34611, end=36081)
print (len(my_fabulous_gene))
>>> 1470

Άσκηση 18

Φτιάξτε τη κλάση Gene_List η οποία θα διαχειρίζεται μία λίστα με γονίδια. Η αρχικοποίησή της θα γίνεται με το όνομα ενός αρχείου. Το αρχείο αυτό θα πρέπει να έχει το ίδιο φορμάτ όπως το αρχείο genes.csv στην άσκηση 6. Θα πρέπει δηλαδή να μπορώ να κάνω:

my_fabulous_gene_list = Gene_List('genes.csv')

Η κλάση θα πρέπει να έχει υλοποιημένη τη __len__ η οποία θα περιέχει το πλήθος των γονιδίων που έχει το αρχείο:

print(len(my_fabulous_gene_list))
>>> 18646 

Επίσης θα πρέπει να έχει υλοποιημένη τη μέθοδο get η οποία παίρνει το όνομα ενός γονιδίου και επιστρέφει ένα αντικείμενο της κλάσης Gene. Αν αυτό το γονίδιο δεν υπάρχει, τότε πετάει exception. Δηλαδή θα πρέπει να μπορώ να κάνω:

my_gene = my_fabulous_gene_list.get('FAM138A')
len(my_gene)
>>> 1470

print (my_fabulous_gene_list.get('FAM138A'))
>>> "Name: FAM138A   Start:34611   End:36081"

Πρσοσοχή στο αρχείο genes.csv, κάποια γονίδια υπάρχουν πολλές φορές (π.χ. το ABHD16A). Μπορείτε να αγνοήσετε αυτά τα γονίδια.

Άσκηση 19

Δίνεται ο παρακάτω κώδικας:

import ftplib
def download_ftp(ip, directory, remote_filename, local_filename):
    '''
    Adapted from:
    https://stackoverflow.com/questions/11573817/how-to-download-a-file-via-ftp-with-python-ftplib/11573992
    '''
    ftp = ftplib.FTP(ip)
    ftp.login("", "")
    ftp.cwd(directory)
    
    with open(local_filename, 'wb') as f:
        ftp.retrbinary('RETR {}'.format(remote_filename), f.write)
    print (f'Downloading {remote_filename} completed!')

def download_GRCh38_genomic():
    download_ftp(
        ip = "ftp.ncbi.nlm.nih.gov",
        directory = "/refseq/H_sapiens/annotation/GRCh38_latest/refseq_identifiers",
        remote_filename = "GRCh38_latest_genomic.gff.gz",
        local_filename = "GRCh38_latest_genomic.gff.gz"

    )
    
download_GRCh38_genomic()

Ο κώδικας αυτός κατεβάζει στον υπολογιστή σας το αρχείο GRCh38_latest_genomic.gff.gz που αναφέρεται στην άσκηση 6. Αλλάξτε λίγο τη κλάση Gene_List έτσι ώστε αν στην αρχικοποίηση δεν υπάρχει κανένα όρισμα, η κλάση να κατεβάζει το αρχείο (με τον κώδικα που δόθηκε παραπάνω), το αποσυμπιέζει και το μετατρέπει σε genes.csv (με τον κώδικα που δόθηκε στην άσκηση 6) και το φορτώνει (όπως στην άσκηση 18). Θα πρέπει δηλαδή να μπορώ να γράφω:

my_fabulous_gene_list = Gene_List() #Δεν έχει κανένα όρισμα η αρχικοποίηση. Κατεβάζει και φορτώνει το αρχείο GRCh38_latest_genomic.gff.gz
print (my_fabulous_gene_list.get('FAM138A'))
>>> "Name: FAM138A   Start:34611   End:36081" 

Υλοποιήστε και τη static συνάρτηση download_ftp_arguments η οποία επιτρέφει τις παραμέτρους της συνάρτησης download_ftp. Θα πρέπει δηλαδή να μπορώ να γράφω:

parameters = Gene_List.download_ftp_arguments()
print (parameters)
## Τυπώνει:
{'ip': 'ftp.ncbi.nlm.nih.gov',
 'directory': '/refseq/H_sapiens/annotation/GRCh38_latest/refseq_identifiers',
 'remote_filename': 'GRCh38_latest_genomic.gff.gz',
 'local_filename': 'GRCh38_latest_genomic.gff.gz'}

download_ftp(**parameters) # Κατεβάζει το αρχείο GRCh38_latest_genomic.gff.gz . 

Άσκηση 20

Παρατηρούμε ότι στο αρχείο genes.csv έχει ονόματα γωνιδίων όπως: LOC729737, LOC105378586, κτλ. Αυτά είναι γονίδια το οποία δεν έχουν χαρακτηριστεί πλήρως και δεν τους έχεις δοθεί "επίσημο" όνομα. Τα ονόματα γονιδίων που ξεκινάν από LOC και ακολουθούντε από έναν αριθμό είναι "μη-χαρακτηρισμένα". Φτιάξτε μία κλάση με το όνομα Characterizable η οποία θα έχει μόνο μία μέθοδο με το όνομα is_characterized η οποία θα κοιτάει αν το όνομα του γονιδίου (το οποίο θα πρέπει να είναι στη μεταβλητή self.name) είναι "χαρακτηρισμένο" ή "μη-χαρακτηρισμένο". Η συνάρτηση θα επιστρέφει True/False ανάλογα (True αν είναι χαρακτηρισμένο). Στη συνέχεια κάντε τη κλάση Gene να κάνει inherit τη κλάση Characterizable. Στη συνέχεια χρησιμοποιώντας τη κλάση Gene_list απαντήστε στο ερώτημα πόσο είναι το ποσοστό των γονιδίων που ΔΕΝ είναι χαρακτηρισμένα. Θα πρέπει δηλαδή να μπορείτε να γράψετε:

my_fabulous_genes = Gene_List('genes.csv')
percentage = sum(not gene.is_chacterized() for gene in my_fabulous_genes) / len(my_fabulous_genes)

print ('The percentage of genes that are NOT characterized is {0.2%}'.format(percentage)

Δίνεται ο παρακάτω κώδικας που δείχνει πως μπορείς να κάνεις iterate σε μία κλάση. Οι κλάσεις που έχουν αυτή την ιδιότητα ονομάζονται iterators. Ο παρακάτω iterator, κάνει iterate με τις λέξεις μίας πρότασης:

class Sentence:
    def __init__(self, sentence):
        self.l = sentence.split()
    def __iter__(self,):
        self.n = 0
        return self
    
    def __next__(self,):
        if self.n == len(self.l):
            raise StopIteration
        self.n += 1
        return self.l[self.n-1]

my_sentence = Sentence('So Long, and Thanks for All the Fish')
for word in my_sentence:
    print (word)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment