Created
November 5, 2012 14:07
-
-
Save mjlassila/4017345 to your computer and use it in GitHub Desktop.
ITIA41 - Viikkoharjoitusten esimerkkiratkaisuja 7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Tehtävä 1 ## | |
### ASCII | |
'''ASCII on 7-bittinen eli 128 merkkiä käsittävä merkistö, joka sisältää | |
amerikanenglannin suur ja pienaakkoset, numerot, välilyönnin sekä joitain väli- | |
ja erikoismerkkejä. Merkkien järjestys perustuu englantilaiseen aakkostoon.''' | |
### UTF-8, hyötyjä ja haittoja | |
#### Hyviä puolia #### | |
'''- Yksinomaan Unicode-merkistön 128 ensimmäistä merkkiä sisältävät UTF-8 | |
-esitysmuotoa noudattavat tiedostot ovat indenttisiä vastaavien | |
ASCII-tiedostojen kanssa. Tämä säästää tilaa ja parantaa yhteensopivuutta | |
vanhojen ASCII-standardia noudattavien järjestelmien kanssa. | |
- UTF-8 riittää ilmaisemaan kaikki tämänhetkisen Unicode-merkistön sisältämät | |
noin 110 000 merkkiä. Jos samassa tekstissä tarvitaan eri kirjoitusjärjestelmistä | |
peräisin olevia merkkejä -- kuvitellaan vaikkapa asiakirjaa, jossa on sekä | |
suomen, ruotsin ja venäjänkielistä tekstiä -- UTF-8 mahdollistaa näiden | |
esittämisen rinnakkain saman dokumentin sisällä.''' | |
#### Huonoja puolia #### | |
'''- Aasialaisia merkkejä käyttäessä UTF-8 esitysmuoto vie enemmän tilaa kuin | |
UTF-16. UTF-8 muotoa käytettäessä yhtä merkkiä vastaa kolme tavua, kun taas | |
UTF-16 -koodaus vaatii merkkiä kohti kaksi tavua | |
Unicode-merkistön kohdassa joka on varattu aasialaisille merkeille. | |
- Merkkien vaihtelevamittaisuus (1-4 tavua) voi tehdä niiden käsittelystä | |
monimutkaisempaa. Harvinaisessa virhetilanteessa merkkiä ilmaiseva tavujen | |
yhdistelmä voi katketa väärästä kohtaa, jolloin tuloksena merkki näytetään | |
väärin. Mikäli UTF-8 käsittely on toteutettu oikein, tällaisten tilanteiden | |
syntyminen on estetty.''' | |
### ISO 8859-1 ### | |
'''ISO 8859-1 (Latin1) on 8-bittinen merkistö, joka sisältää Unicode-merkistön | |
256 ensimmäistä koodipistettä, kattaen muun muassa suomea kirjoitettaessa | |
tarvittavat merkit. Se ei kuitenkaan kata kaikkia eurooppalaisia kieliä ja | |
erikoismerkkien (kuten typografisten lainausmerkkien) tuki on puutteellinen. | |
Windowsin käyttämä Windows-1252 -merkistökoodaus perustuu ISO 8859-1 | |
-standardiin. Mikäli todellisuudessa Windows 1252 -standardia noudattava | |
tiedosto avataan ISO 8859-1 -muodossa, jotkut erikoismerkeistä -- kuten | |
heittomerkit ja lainausmerkit, näkyvät väärin.''' | |
## Tehtävä 2 ## | |
'''Tässä tehtävässä tarkoitus oli tutustua Python-ympäristössä hyödylliseen | |
työskentelytapaan, jossa kaikki käsiteltävät merkkijonot muutetaan | |
mahdollisimman varhaisessa vaiheessa Unicode-muotoon. Vastaavasti muunnos | |
Unicodesta haluttuun tallennusmuotoon on viisasta tehdä vasta lopuksi, | |
tallennettaessa tiedostoa. | |
Tehtävä demonstroi myös Pythonin käytäntöä esittää Unicode-muotoiset | |
merkkijonot ASCII-merkkien yhdistelminä. Näytöllä erikoismerkit näkyivät | |
merkkijonon \xe1szl\xf3 -kaltaisena siansaksana. | |
Jos Pythonissa haluaa tulostaa Unicode-merkkejä puretussa esitysmuodossaan | |
(l. erikoismerkit sellaisenaan), voidaan käyttää komentoa print(). | |
Tällöin SSH-ohjelman tulee noudattaa UTF-8 koodausta, jotta merkit tulostuivat | |
näytölle oikein.''' | |
### Esimerkki: | |
# UTF-8 koodausta noudattava merkkijono Pythonin ASCII-esitysmuodossa | |
>>> utf8_text | |
'L\xc3\xa1szl\xc3\xb3 Moholy-Nagy' | |
# Tulostetaan merkkijono UTF-8 koodausta noudattavassa SSH-ohjelmassa. | |
>>> print(utf8_text) | |
László Moholy-Nagy | |
'''Jos kokeilemme tulostaa UTF-16 esitysmuodossa olevan merkkijon UTF-8 | |
ympäristössä, saamme seuraavan tuloksen:''' | |
# Aluksi UTF-16-koodattu merkkijono Pythonin ASCII-esitysmuodossa | |
>>> unicode_in_utf16 | |
'\xff\xfeL\x00\xe1\x00s\x00z\x00l\x00\xf3\x00 \x00M\x00o\x00h\x00o\x00l\x00y\x00 | |
-\x00N\x00a\x00g\x00y\x00 \x00o\x00n\x00 \x00u\x00n\x00k\x00a\x00r\x00i\x00l\x00 | |
a\x00i\x00n\x00e\x00n\x00 \x00v\x00a\x00l\x00o\x00k\x00u\x00v\x00a\x00a\x00j\x00 | |
a\x00.\x00' | |
# Koitetaan tulostaa näytölle | |
>>> print(unicode_in_utf16) | |
??L?szl? Moholy-Nagy on unkarilainen valokuvaaja. | |
# ==> Huomataan merkkien tulostuvan väärin. | |
## Tehtävä 3 ## | |
'''Tehtävä demonstroi Unicode-merkistön kattavuutta. Charbase.com -sivusto on | |
mainio apu merkistön selailuun - sivustolta voi tarkistaa muun muassa jokaisen | |
Unicode-merkin Python-esitysmuodon, nimen, sijainnin merkistössä sekä | |
merkistöryhmän.''' | |
# Merkit charbase-sivustolla | |
# http://www.charbase.com/0f00-unicode-tibetan-syllable-om | |
# http://www.charbase.com/263a-unicode-white-smiling-face | |
# http://www.charbase.com/2603-unicode-snowman | |
# http://www.charbase.com/2615-unicode-hot-beverage | |
# http://www.charbase.com/2638-unicode-wheel-of-dharma | |
# Eräs ratkaisu: | |
>>> import unicodedata | |
>>> import chardet | |
>>> unknown_characters = open('/home/courses/itima41/erikoismerkit.txt', 'r').read() | |
{'confidence': 0.96906250000000005, 'encoding': 'utf-8'} | |
>>> unicode_characters = unknown_characters.decode('utf8') | |
>>> characters_as_tokens = unicode_characters.split('\n') | |
>>> characters_as_tokens | |
[u'\u263a', u'\u0f00', u'\u2603', u'\u2615', u'\u2638'] | |
>>> for token in characters_as_tokens: | |
... print(unicodedata.name(token)) | |
... | |
WHITE SMILING FACE | |
TIBETAN SYLLABLE OM | |
SNOWMAN | |
HOT BEVERAGE | |
WHEEL OF DHARMA | |
## Tehtävä 4 ## | |
'''Tämän tehtävän tarkoituksena oli havainnollistaa merkistön ja merkistön | |
esityskoodauksen käsitteellistä eroa. | |
Unicode on merkistö -- sopimus joka määrittelee vastaavuuden merkin symbolin ja | |
Unicode-koodipisteen välillä. Koodipiste on merkin sijainti Unicode-merkistössä. | |
Unicode-merkistön voi mieltää valtavaksi taulukoksi, jossa kullakin merkillä | |
on oma paikkansa, johon koodipiste viittaa. | |
UTF-8, UTF-16, UTF-32 ovat taas Unicode-merkistön esityskoodauksia, tapoja | |
esittää nämä merkit bittijonoina. On varsin yleistä että käsitteitä merkistö, | |
merkistökoodaus ja esityskoodaus käytetään toistensa synonyymeinä, vaikka | |
kyseessä ovat eri asiat. Jukka K. Korpela on laatinut tästä erinomaisen | |
esityksen, joka selventää käsitteiden eroja selkokielellä: | |
Jukka K. Korpela: A tutorial on character code issues | |
<http://www.cs.tut.fi/~jkorpela/chars.html> | |
Python-ympäristössä - ja myös tekstinkäsittelyohjelmassa - työskentelyä | |
helpottaa jos työnkulun hahmottaa seuraavalla tavalla: | |
1) Levyllä on tallennettu teksti, jonka merkit on enkoodattu (encode) levylle | |
tiettyä esitystapaa noudattaen | |
2) Teksti avataan ja se dekoodataan (decode) ohjelman sisäiseen esitysmuotoon. | |
Jos tämä vaihe menee pieleen, tavallisesti näytöllä näkyy merkkiroskaa. | |
3) Kun teksti tallennetaan, se enkoodataan (encode) haluttuun muotoon. | |
Tallennusmuoto voi olla sama, kuin tekstiä avattaessa tai tarvittaessa se | |
voidaan tallentaa jotain muuta esityskoodausta käyttäen. Tärkeää on kuitenkin | |
muistaa, että esityskoodauksen on tuettava tekstin sisältämiä merkkejä. | |
Esimerkiksi, jos yrittää tallentaa skandinaavisia merkkejä sisältävää | |
tekstiä ASCII-muotoon, merkistöenkoodaus tulee menemään pieleen jos | |
tallentaminen ylipäätänsä onnistuu. | |
Esimerkkiratkaisussa kyrillisten merkkien KOI-8 -esitysmuodossa tallennetun | |
tekstin lataaminen ja tallentaminen UTF-8 -muotoon:''' | |
text1 = open('/home/courses/itima41/enkoodausharjoitus-01.txt').read() | |
text2 = open('/home/courses/itima41/enkoodausharjoitus-02.txt').read() | |
text3 = open('/home/courses/itima41/enkoodausharjoitus-03.txt').read() | |
text4 = open('/home/courses/itima41/enkoodausharjoitus-04.txt').read() | |
text5 = open('/home/courses/itima41/enkoodausharjoitus-05.txt').read() | |
>>> chardet.detect(text1) | |
{'confidence': 0.98756803475891264, 'encoding': 'KOI8-R'} | |
>>> chardet.detect(text2) | |
{'confidence': 0.91635421768622582, 'encoding': 'ISO-8859-2'} | |
>>> chardet.detect(text3) | |
{'confidence': 0.85359795046648712, 'encoding': 'ISO-8859-2'} | |
>>> chardet.detect(text4) | |
{'confidence': 0.98999999999999999, 'encoding': 'utf-8'} | |
>>> chardet.detect(text5) | |
{'confidence': 1.0, 'encoding': 'UTF-16BE'} | |
# Dekoodataan KOI8-muotoon tallennettu teksti Unicodeksi. | |
text1_unicode = text1.decode('KOI8-R') | |
# Enkoodataan Unicode-teksti UTF-8 esitysmuotoon | |
text1_utf8 = text1_unicode.encode('utf8') | |
# Avataan tiedosto kirjoittamista varten | |
file = open('enkoodausharjoitus-01.txt', 'w') | |
# Kirjoitetaan tiedostoon | |
file.write(text1_utf8) | |
# Suljetaan tiedosto | |
file.close() | |
## Tehtävä 5 ## | |
'''Aiemmissa tehtävissä käytettiin chardet-työkalua, joka helpottaa tuntemattomassa | |
muodossa tallennettujen tiedostojen käsittelyä. Chardet ei ole kuitenkaan erehtymätön. | |
Tehtävässä käytetyt enkoodausharjoitus-06.txt ja enkoodausharjoitus-08.txt | |
tiedostot olivat nimittäin merkistökoodaukseltaan identtiset (ISO 8859-15), | |
vaikka chardet-työkalun mukaan tiedostot noudattaisivat ISO 8859-2 -muotoa | |
85% todennäköisyydellä. Mikäli ISO 8859-15 merkistökoodausta noudattava tiedosto | |
avataan ISO 8859-2 muodossa, näkyvin muutos on merkistökoodauksen kohdassa | |
0xA4 olevan € -merkin korvautuminen valuuttamerkillä ¤ . | |
SSH-ohjelmassa ja shellissä käytössä oleva merkistöjen esitysmuoto saattoi | |
aiheuttaa tässä tehtävässä hankaluuksia. Koska tiedostot tallennettiin UTF-8 | |
-muotoon, niiden katseleminen cat-komennolla jotain muuta merkistökoodausta | |
noudattavassa ympäristössä saa aikaan erikoismerkkien tulostumisen väärin. | |
Windows käyttää oletusarvoisesti Windows-1252 -koodausta, joka on muunnos | |
ISO 8859-1 -standardista. Jos Windows-ohjelmissa haluaa käyttää UTF-8 koodausta, | |
se tulee tyypillisesti kytkeä erikseen päälle. | |
Esimerkiksi Putty SSH-ohjelmassa UTF-8 -koodauksen saa otettua käyttöön | |
valitsemalla valikoista: | |
Window → Translation → Character set → UTF-8''' | |
## Tehtävä 6 ## | |
'''Tehtävässä annettua merkkijonoa "väisälä" vastaava sana luonnollisessa | |
kielessä on todennäköisesti (suuraakkosella kirjoitettu) vastaava erisnimi Väisälä. | |
Merkkijonon "vaisala" ilmentymä lähdetekstissä on myös todennäköisesti | |
erisnimi (yrityksen nimi). Myös merkkijono "visala" assosioituu todennäköisesti | |
erisnimeen. Tiedonhaun näkökulmasta annetut kolme samaa eivät välttämättä tuntuisi ole | |
kovinkaan "lähellä toisiaan" (toisin kuin esimerkiksi | |
merkkijono "vaisala" ja sen tarkoitettu generiivimuoto "vaisalan"). | |
Kehiteltäessä samankaltaisuuden laskentaa voidaan pohtia samuuden | |
mittauksen käyttötarkoitusta ja esim. seuraavia aspekteja: | |
-kieli: vertaillaanko merkkijonoja yksikielisessä tilanteessa vai | |
eri kielten välillä (vrt. "Chechnya"/"Tshetshenia"/"Tshetshenian#) | |
-kuinka tokenisaatio on toteutettu vertailtavana oleville merkkijonoille | |
-ortografia kielten välillä ("ks"/"x", "oo"/"o" jne.?) | |
-kielen ortografia, esim. | |
--yhdyssanat ("vero"/"tulovero") | |
--sanojen taipuminen ("tulovero"/"tuloveron") | |
--derivatiivit ("vero"/"verottaminen"/"verottaa") | |
--suuraakkoset ("suomalainen"/"suomalaisten"/"Suomalainen"; "US" vrt."us") | |
--välimerkit ("u.s."/"us"/"1000"/"1,000"/"1,0"/"10"/"1.0" - eri tulkintoja | |
esim. suomen- vs. englanninkielisessä tekstissä). | |
Matemaattisesti merkkijonojen samankaltaisuutta kuvataan tavallisesti nk. | |
etäisyysmetriikoiden avulla. Tunnettuja ovat esimerkiksi | |
Levenšteinin etäisyys, Jaccardin etäisyys sekä Jaro-Winklerin etäisyys. | |
Erinomainen englanninkielinen esitys etäisyysmetriikoista löytyy osoitteesta | |
http://alias-i.com/lingpipe/demos/tutorial/stringCompare/read-me.html | |
johon kannattaa tutustua, jos aihe herätti syvempää mielenkiintoa. | |
UTF-8 ja ISO 8859-1 -merkistöillä koodatut merkkijonot voivat tuottaa erilaisia | |
samankaltaisuustuloksia. | |
Jos tietty sana koodataan eri merkistöjä käyttäen, | |
syntyvät esitysmuodot (bittijonot) saattavat olla erilaiset, vaikka | |
abstraktissa mielessä sanat ovatkin identtiset. Merkkijonojen | |
pituuden laskennassa on erityisesti vaihtelevamittaisissa merkistöissä | |
otettava huomioon mahdolliset monitavuiset merkit.''' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment