Fix 02
This commit is contained in:
parent
5de86ecb81
commit
515f0edb56
1386
wyk/02_Jezyki.ipynb
1386
wyk/02_Jezyki.ipynb
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
* Języki i ich prawa
|
* Języki i ich prawa statystyczne
|
||||||
|
|
||||||
Jakim rozkładom statystycznym podlegają języki?
|
Jakim rozkładom statystycznym podlegają języki?
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ Używać będziemy generatorów.
|
|||||||
|
|
||||||
*Pytanie* Dlaczego generatory zamiast list?
|
*Pytanie* Dlaczego generatory zamiast list?
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
url = 'https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt'
|
url = 'https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt'
|
||||||
@ -31,7 +31,7 @@ Powrót pani
|
|||||||
|
|
||||||
*** Znaki
|
*** Znaki
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
|
|
||||||
def get_characters(t):
|
def get_characters(t):
|
||||||
@ -45,7 +45,7 @@ Powrót pani
|
|||||||
['K', 's', 'i', 'ę', 'g', 'a', ' ', 'p', 'i', 'e', 'r', 'w', 's', 'z', 'a', '\r', '\n', '\r', '\n', '\r', '\n', '\r', '\n', 'G', 'o', 's', 'p', 'o', 'd', 'a', 'r', 's', 't', 'w', 'o', '\r', '\n', '\r', '\n', 'P', 'o', 'w', 'r', 'ó', 't', ' ', 'p', 'a', 'n', 'i']
|
['K', 's', 'i', 'ę', 'g', 'a', ' ', 'p', 'i', 'e', 'r', 'w', 's', 'z', 'a', '\r', '\n', '\r', '\n', '\r', '\n', '\r', '\n', 'G', 'o', 's', 'p', 'o', 'd', 'a', 'r', 's', 't', 'w', 'o', '\r', '\n', '\r', '\n', 'P', 'o', 'w', 'r', 'ó', 't', ' ', 'p', 'a', 'n', 'i']
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
|
||||||
c = Counter(get_characters(pan_tadeusz))
|
c = Counter(get_characters(pan_tadeusz))
|
||||||
@ -65,7 +65,7 @@ Napiszmy pomocniczą funkcję, która zwraca *listę frekwencyjną*.
|
|||||||
Counter({' ': 63444, 'a': 30979, 'i': 29353, 'e': 25343, 'o': 23050, 'z': 22741, 'n': 15505, 'r': 15328, 's': 15255, 'w': 14625, 'c': 14153, 'y': 13732, 'k': 12362, 'd': 11465, '\r': 10851, '\n': 10851, 't': 10757, 'm': 10269, 'ł': 10059, ',': 9130, 'p': 8031, 'u': 7699, 'l': 6677, 'j': 6586, 'b': 5753, 'ę': 5534, 'ą': 4794, 'g': 4775, 'h': 3915, 'ż': 3334, 'ó': 3097, 'ś': 2524, '.': 2380, 'ć': 1956, ';': 1445, 'P': 1265, 'W': 1258, ':': 1152, '!': 1083, 'S': 1045, 'T': 971, 'I': 795, 'N': 793, 'Z': 785, 'J': 729, '—': 720, 'A': 698, 'K': 683, 'ń': 651, 'M': 585, 'B': 567, 'O': 567, 'C': 556, 'D': 552, '«': 540, '»': 538, 'R': 489, '?': 441, 'ź': 414, 'f': 386, 'G': 358, 'L': 316, 'H': 309, 'Ż': 219, 'U': 184, '…': 157, '*': 150, '(': 76, ')': 76, 'Ś': 71, 'F': 47, 'é': 43, '-': 33, 'Ł': 24, 'E': 23, '/': 19, 'Ó': 13, '8': 10, '9': 8, '2': 6, 'v': 5, 'Ź': 4, '1': 4, '3': 3, 'x': 3, 'V': 3, '7': 2, '4': 2, '5': 2, 'q': 2, 'æ': 2, 'à': 1, 'Ć': 1, '6': 1, '0': 1})
|
Counter({' ': 63444, 'a': 30979, 'i': 29353, 'e': 25343, 'o': 23050, 'z': 22741, 'n': 15505, 'r': 15328, 's': 15255, 'w': 14625, 'c': 14153, 'y': 13732, 'k': 12362, 'd': 11465, '\r': 10851, '\n': 10851, 't': 10757, 'm': 10269, 'ł': 10059, ',': 9130, 'p': 8031, 'u': 7699, 'l': 6677, 'j': 6586, 'b': 5753, 'ę': 5534, 'ą': 4794, 'g': 4775, 'h': 3915, 'ż': 3334, 'ó': 3097, 'ś': 2524, '.': 2380, 'ć': 1956, ';': 1445, 'P': 1265, 'W': 1258, ':': 1152, '!': 1083, 'S': 1045, 'T': 971, 'I': 795, 'N': 793, 'Z': 785, 'J': 729, '—': 720, 'A': 698, 'K': 683, 'ń': 651, 'M': 585, 'B': 567, 'O': 567, 'C': 556, 'D': 552, '«': 540, '»': 538, 'R': 489, '?': 441, 'ź': 414, 'f': 386, 'G': 358, 'L': 316, 'H': 309, 'Ż': 219, 'U': 184, '…': 157, '*': 150, '(': 76, ')': 76, 'Ś': 71, 'F': 47, 'é': 43, '-': 33, 'Ł': 24, 'E': 23, '/': 19, 'Ó': 13, '8': 10, '9': 8, '2': 6, 'v': 5, 'Ź': 4, '1': 4, '3': 3, 'x': 3, 'V': 3, '7': 2, '4': 2, '5': 2, 'q': 2, 'æ': 2, 'à': 1, 'Ć': 1, '6': 1, '0': 1})
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ OrderedDict([(' ', 63444), ('a', 30979), ('i', 29353), ('e', 25343), ('o', 23050
|
|||||||
:end:
|
:end:
|
||||||
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
#+BEGIN_SRC ipython :session mysession :results file
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ Co rozumiemy pod pojęciem słowa czy wyrazu, nie jest oczywiste. W praktyce zal
|
|||||||
Załóżmy, że przez wyraz rozumieć będziemy nieprzerwany ciąg liter bądź cyfr (oraz gwiazdek
|
Załóżmy, że przez wyraz rozumieć będziemy nieprzerwany ciąg liter bądź cyfr (oraz gwiazdek
|
||||||
— to za chwilę ułatwi nam analizę pewnego tekstu…).
|
— to za chwilę ułatwi nam analizę pewnego tekstu…).
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
import regex as re
|
import regex as re
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ Załóżmy, że przez wyraz rozumieć będziemy nieprzerwany ciąg liter bądź
|
|||||||
Zobaczmy 20 najczęstszych wyrazów.
|
Zobaczmy 20 najczęstszych wyrazów.
|
||||||
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
#+BEGIN_SRC ipython :session mysession :results file
|
||||||
rang_freq_with_labels('pt-words-20', get_words(pan_tadeusz), top=20)
|
rang_freq_with_labels('pt-words-20', get_words(pan_tadeusz), top=20)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ Zobaczmy 20 najczęstszych wyrazów.
|
|||||||
|
|
||||||
Zobaczmy pełny obraz, już bez etykiet.
|
Zobaczmy pełny obraz, już bez etykiet.
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
#+BEGIN_SRC ipython :session mysession :results file
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from math import log
|
from math import log
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ Zobaczmy pełny obraz, już bez etykiet.
|
|||||||
Widać, jak różne skale obejmuje ten wykres. Zastosujemy logarytm,
|
Widać, jak różne skale obejmuje ten wykres. Zastosujemy logarytm,
|
||||||
najpierw tylko do współrzędnej $y$.
|
najpierw tylko do współrzędnej $y$.
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
#+BEGIN_SRC ipython :session mysession :results file
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from math import log
|
from math import log
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ logarytmicznej dla **obu** osi, otrzymamy kształt zbliżony do linii prostej.
|
|||||||
|
|
||||||
Tę własność tekstów nazywamy **prawem Zipfa**.
|
Tę własność tekstów nazywamy **prawem Zipfa**.
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
#+BEGIN_SRC ipython :session mysession :results file
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from math import log
|
from math import log
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ Tę własność tekstów nazywamy **prawem Zipfa**.
|
|||||||
Powiązane z prawem Zipfa prawo językowe opisuje zależność między
|
Powiązane z prawem Zipfa prawo językowe opisuje zależność między
|
||||||
częstością użycia słowa a jego długością. Generalnie im krótsze słowo, tym częstsze.
|
częstością użycia słowa a jego długością. Generalnie im krótsze słowo, tym częstsze.
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
#+BEGIN_SRC ipython :session mysession :results file
|
||||||
def freq_vs_length(name, g, top=None):
|
def freq_vs_length(name, g, top=None):
|
||||||
freq = freq_list(g)
|
freq = freq_list(g)
|
||||||
|
|
||||||
@ -268,229 +268,3 @@ częstością użycia słowa a jego długością. Generalnie im krótsze słowo,
|
|||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
[[file:02_Jezyki/pt-lengths.png]]
|
[[file:02_Jezyki/pt-lengths.png]]
|
||||||
|
|
||||||
** N-gramy
|
|
||||||
|
|
||||||
W modelowaniu języka często rozpatruje się n-gramy, czyli podciągi o
|
|
||||||
rozmiarze $n$.
|
|
||||||
|
|
||||||
Na przykład /digramy/ (/bigramy/) to zbitki dwóch jednostek, np. liter albo wyrazów.
|
|
||||||
|
|
||||||
|$n$| $n$-gram| nazwa |
|
|
||||||
|---+---------+---------------|
|
|
||||||
| 1 | 1-gram | unigram |
|
|
||||||
| 2 | 2-gram | digram/bigram |
|
|
||||||
| 3 | 3-gram | trigram |
|
|
||||||
| 4 | 4-gram | tetragram |
|
|
||||||
| 5 | 5-gram | pentagram |
|
|
||||||
|
|
||||||
|
|
||||||
*Pytanie:* Jak nazywa się 6-gram?
|
|
||||||
|
|
||||||
Jak widać, dla symetrii mówimy czasami o unigramach, jeśli operujemy
|
|
||||||
po prostu na jednostkach, nie na ich podciągach.
|
|
||||||
|
|
||||||
*** N-gramy z Pana Tadeusza
|
|
||||||
|
|
||||||
Statystyki, które policzyliśmy dla pojedynczych liter czy wyrazów, możemy powtórzyć dla n-gramów.
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
|
||||||
def ngrams(iter, size):
|
|
||||||
ngram = []
|
|
||||||
for item in iter:
|
|
||||||
ngram.append(item)
|
|
||||||
if len(ngram) == size:
|
|
||||||
yield tuple(ngram)
|
|
||||||
ngram = ngram[1:]
|
|
||||||
|
|
||||||
list(ngrams("kotek", 3))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
:results:
|
|
||||||
[('k', 'o', 't'), ('o', 't', 'e'), ('t', 'e', 'k')]
|
|
||||||
:end:
|
|
||||||
|
|
||||||
Zauważmy, że policzyliśmy wszystkie n-gramy, również częściowo pokrywające się.
|
|
||||||
|
|
||||||
Zawsze powinniśmy się upewnić, czy jest jasne, czy chodzi o n-gramy znakowe czy wyrazowe
|
|
||||||
|
|
||||||
*** 3-gramy znakowe
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
log_rang_log_freq('pt-3-char-ngrams-log-log', ngrams(get_characters(pan_tadeusz), 3))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/pt-3-char-ngrams-log-log.png]]
|
|
||||||
|
|
||||||
*** 2-gramy wyrazowe
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
log_rang_log_freq('pt-2-word-ngrams-log-log', ngrams(get_words(pan_tadeusz), 2))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/pt-2-word-ngrams-log-log.png]]
|
|
||||||
|
|
||||||
** Tajemniczy język Manuskryptu Wojnicza
|
|
||||||
|
|
||||||
[[https://pl.wikipedia.org/wiki/Manuskrypt_Wojnicza][Manuskrypt Wojnicza]] to powstały w XV w. manuskrypt spisany w
|
|
||||||
tajemniczym alfabecie, do dzisiaj nieodszyfrowanym. Rękopis stanowi
|
|
||||||
jedną z największych zagadek historii (i lingwistyki).
|
|
||||||
|
|
||||||
[[./02_Jezyki/voynich135.jpg][Źródło: https://commons.wikimedia.org/wiki/File:Voynich_Manuscript_(135).jpg]]
|
|
||||||
|
|
||||||
Sami zbadajmy statystyczne własności tekstu manuskryptu. Użyjmy
|
|
||||||
transkrypcji Vnow, gdzie poszczególne znaki tajemniczego alfabetu
|
|
||||||
zamienione na litery alfabetu łacińskiego, cyfry i gwiazdkę. Jak
|
|
||||||
transkrybować manuskrypt, pozostaje sprawą dyskusyjną, natomiast wybór
|
|
||||||
takiego czy innego systemu transkrypcji nie powinien wpływać
|
|
||||||
dramatycznie na analizę statystyczną.
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
|
||||||
import requests
|
|
||||||
|
|
||||||
voynich_url = 'http://www.voynich.net/reeds/gillogly/voynich.now'
|
|
||||||
voynich = requests.get(voynich_url).content.decode('utf-8')
|
|
||||||
|
|
||||||
voynich = re.sub(r'\{[^\}]+\}|^<[^>]+>|[-# ]+', '', voynich, flags=re.MULTILINE)
|
|
||||||
|
|
||||||
voynich = voynich.replace('\n\n', '#')
|
|
||||||
voynich = voynich.replace('\n', ' ')
|
|
||||||
voynich = voynich.replace('#', '\n')
|
|
||||||
|
|
||||||
voynich = voynich.replace('.', ' ')
|
|
||||||
|
|
||||||
voynich[100:150]
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
:results:
|
|
||||||
9 OR 9FAM ZO8 QOAR9 Q*R 8ARAM 29 [O82*]OM OPCC9 OP
|
|
||||||
:end:
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
rang_freq_with_labels('voy-chars', get_characters(voynich))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/voy-chars.png]]
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
log_rang_log_freq('voy-log-log', get_words(voynich))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/voy-log-log.png]]
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
rang_freq_with_labels('voy-words-20', get_words(voynich), top=20)
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/voy-words-20.png]]
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
log_rang_log_freq('voy-words-log-log', get_words(voynich))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/voy-words-log-log.png]]
|
|
||||||
|
|
||||||
** Język DNA
|
|
||||||
|
|
||||||
Kod genetyczny przejawia własności zaskakująco podobne do języków naturalnych.
|
|
||||||
Przede wszystkim ma charakter dyskretny, genotyp to ciąg symboli ze skończonego alfabetu.
|
|
||||||
Podstawowe litery są tylko cztery, reprezentują one nukleotydy, z których zbudowana jest nić DNA:
|
|
||||||
a, g, c, t.
|
|
||||||
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
|
||||||
import requests
|
|
||||||
|
|
||||||
dna_url = 'https://raw.githubusercontent.com/egreen18/NanO_GEM/master/rawGenome.txt'
|
|
||||||
dna = requests.get(dna_url).content.decode('utf-8')
|
|
||||||
|
|
||||||
dna = ''.join(dna.split('\n')[1:])
|
|
||||||
dna = dna.replace('N', 'A')
|
|
||||||
|
|
||||||
dna[0:100]
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
:results:
|
|
||||||
TATAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTA
|
|
||||||
:end:
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
rang_freq_with_labels('dna-chars', get_characters(dna))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/dna-chars.png]]
|
|
||||||
|
|
||||||
*** Tryplety — znaczące cząstki genotypu
|
|
||||||
|
|
||||||
Nukleotydy rzeczywiście są jak litery, same w sobie nie niosą
|
|
||||||
znaczenia. Dopiero ciągi trzech nukleotydów, /tryplety/, kodują jeden
|
|
||||||
z dwudziestu aminokwasów.
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
genetic_code = {
|
|
||||||
'ATA':'I', 'ATC':'I', 'ATT':'I', 'ATG':'M',
|
|
||||||
'ACA':'T', 'ACC':'T', 'ACG':'T', 'ACT':'T',
|
|
||||||
'AAC':'N', 'AAT':'N', 'AAA':'K', 'AAG':'K',
|
|
||||||
'AGC':'S', 'AGT':'S', 'AGA':'R', 'AGG':'R',
|
|
||||||
'CTA':'L', 'CTC':'L', 'CTG':'L', 'CTT':'L',
|
|
||||||
'CCA':'P', 'CCC':'P', 'CCG':'P', 'CCT':'P',
|
|
||||||
'CAC':'H', 'CAT':'H', 'CAA':'Q', 'CAG':'Q',
|
|
||||||
'CGA':'R', 'CGC':'R', 'CGG':'R', 'CGT':'R',
|
|
||||||
'GTA':'V', 'GTC':'V', 'GTG':'V', 'GTT':'V',
|
|
||||||
'GCA':'A', 'GCC':'A', 'GCG':'A', 'GCT':'A',
|
|
||||||
'GAC':'D', 'GAT':'D', 'GAA':'E', 'GAG':'E',
|
|
||||||
'GGA':'G', 'GGC':'G', 'GGG':'G', 'GGT':'G',
|
|
||||||
'TCA':'S', 'TCC':'S', 'TCG':'S', 'TCT':'S',
|
|
||||||
'TTC':'F', 'TTT':'F', 'TTA':'L', 'TTG':'L',
|
|
||||||
'TAC':'Y', 'TAT':'Y', 'TAA':'_', 'TAG':'_',
|
|
||||||
'TGC':'C', 'TGT':'C', 'TGA':'_', 'TGG':'W',
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_triplets(t):
|
|
||||||
for triplet in re.finditer(r'.{3}', t):
|
|
||||||
yield genetic_code[triplet.group(0)]
|
|
||||||
|
|
||||||
rang_freq_with_labels('dna-aminos', get_triplets(dna))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/dna-aminos.png]]
|
|
||||||
|
|
||||||
*** „Zdania” w języku DNA
|
|
||||||
|
|
||||||
Z aminokwasów zakodowanych przez tryplet budowane są białka.
|
|
||||||
Maszyneria budująca białka czyta sekwencję aż do napotkania
|
|
||||||
trypletu STOP (_ powyżej). Taka sekwencja to /gen/.
|
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :results file
|
|
||||||
def get_genes(triplets):
|
|
||||||
gene = []
|
|
||||||
for ammino in triplets:
|
|
||||||
if ammino == '_':
|
|
||||||
yield gene
|
|
||||||
gene = []
|
|
||||||
else:
|
|
||||||
gene.append(ammino)
|
|
||||||
|
|
||||||
plt.figure().clear()
|
|
||||||
plt.hist([len(g) for g in get_genes(get_triplets(dna))], bins=100)
|
|
||||||
|
|
||||||
fname = '02_Jezyki/dna_length.png'
|
|
||||||
|
|
||||||
plt.savefig(fname)
|
|
||||||
|
|
||||||
fname
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:02_Jezyki/dna_length.png]]
|
|
||||||
|
Loading…
Reference in New Issue
Block a user