Skip to content

Commit 8d15537

Browse files
authored
Merge pull request #14 from clemsciences/runes
Germanic runes tutorial
2 parents 299dc5a + 05f4184 commit 8d15537

1 file changed

Lines changed: 357 additions & 0 deletions

File tree

languages/old-norse/runes.ipynb

Lines changed: 357 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Runes\n",
8+
"Note: in order to use this Jupyter notebook, you need at least python 3.6 or above."
9+
]
10+
},
11+
{
12+
"cell_type": "markdown",
13+
"metadata": {},
14+
"source": [
15+
"Install required modules.\n",
16+
"```bash\n",
17+
"$ sudo pip3.6 install requests lxml \n",
18+
"```"
19+
]
20+
},
21+
{
22+
"cell_type": "markdown",
23+
"metadata": {},
24+
"source": [
25+
"Configure ipython.\n",
26+
"\n",
27+
"```bash\n",
28+
"$ ipython profile create\n",
29+
"$ ipython locate\n",
30+
"$ nano .ipython/profile_default/ipython_config.py\n",
31+
"```\n",
32+
" Add it a the end of the file (without '#'):\n",
33+
"```bash\n",
34+
"c.InteractiveShellApp.exec_lines = [\n",
35+
" 'import sys; sys.path.append(\"/home/<username>/<path to runes-analyzer>\")'\n",
36+
"]\n",
37+
"```\n",
38+
" And... It's done!"
39+
]
40+
},
41+
{
42+
"cell_type": "markdown",
43+
"metadata": {},
44+
"source": [
45+
"In a shell, install the module **runesanalyzer**\n",
46+
"```bash\n",
47+
"$ git clone https://github.com/cltk/runes-analyzer.git\n",
48+
"$ cd runes-analyzer\n",
49+
"$ python3.6 setup.py install \n",
50+
"```\n",
51+
"Install the kernel associated with python3.6 [https://ipython.readthedocs.io/en/stable/install/kernel_install.html](https://ipython.readthedocs.io/en/stable/install/kernel_install.html) "
52+
]
53+
},
54+
{
55+
"cell_type": "markdown",
56+
"metadata": {},
57+
"source": [
58+
"Let's test if the import is correct:\n",
59+
"```bash\n",
60+
"$ python3.6\n",
61+
"```"
62+
]
63+
},
64+
{
65+
"cell_type": "code",
66+
"execution_count": 1,
67+
"metadata": {},
68+
"outputs": [],
69+
"source": [
70+
"from cltk.corpus.old_norse import runes"
71+
]
72+
},
73+
{
74+
"cell_type": "markdown",
75+
"metadata": {},
76+
"source": [
77+
"First of all, let's see what runes are:"
78+
]
79+
},
80+
{
81+
"cell_type": "code",
82+
"execution_count": 2,
83+
"metadata": {},
84+
"outputs": [
85+
{
86+
"name": "stdout",
87+
"output_type": "stream",
88+
"text": [
89+
"[ᚠ, ᚢ, ᚦ, ᚨ, ᚱ, ᚲ, ᚷ, ᚹ, ᚺ, ᚾ, ᛁ, ᛃ, ᛇ, ᛈ, ᛉ, ᛊ, ᛏ, ᛒ, ᛖ, ᛗ, ᛚ, ᛜ, ᛟ, ᛞ]\n",
90+
"[ᚠ, ᚢ, ᚦ, ᚭ, ᚱ, ᚴ, ᚼ, ᚾ, ᛁ, ᛅ, ᛋ, ᛏ, ᛒ, ᛖ, ᛘ, ᛚ, ᛦ]\n",
91+
"[ᚠ, ᚢ, ᚦ, ᚭ, ᚱ, ᚴ, ᚽ, ᚿ, ᛁ, ᛅ, ᛌ, ᛐ, ᛓ, ᛖ, ᛙ, ᛚ, ᛧ]\n"
92+
]
93+
}
94+
],
95+
"source": [
96+
"for alphabet in [runes.ELDER_FUTHARK, runes.YOUNGER_FUTHARK, runes.SHORT_TWIG_YOUNGER_FUTHARK]:\n",
97+
" print(alphabet)"
98+
]
99+
},
100+
{
101+
"cell_type": "markdown",
102+
"metadata": {},
103+
"source": [
104+
"The oldest runic inscriptions found are from 200 AC. They have always denoted Germanic languages. Until the 8th century, the elder *futhark* alphabet was used. It was compouned with 24 characters: ᚠ, ᚢ, ᚦ, ᚨ, ᚱ, ᚲ, ᚷ, ᚹ, ᚺ, ᚾ, ᛁ, ᛃ, ᛇ, ᛈ, ᛉ, ᛊ, ᛏ, ᛒ, ᛖ, ᛗ, ᛚ, ᛜ, ᛟ, ᛞ. The word *Futhark* comes from the 6 first characters of the alphabet: ᚠ (f), ᚢ (u), ᚦ (th), ᚨ (a), ᚱ (r), ᚲ (k). Later, this alphabet was reduced to 16 runes, the *younger futhark* ᚠ, ᚢ, ᚦ, ᚭ, ᚱ, ᚴ, ᚼ, ᚾ, ᛁ, ᛅ, ᛋ, ᛏ, ᛒ, ᛖ, ᛘ, ᛚ, ᛦ, with more ambiguity on sounds. Shapes of runes may vary according to which matter they are carved on, that is why there is a variant of the *younger futhark* like this: ᚠ, ᚢ, ᚦ, ᚭ, ᚱ, ᚴ, ᚽ, ᚿ, ᛁ, ᛅ, ᛌ, ᛐ, ᛓ, ᛖ, ᛙ, ᛚ, ᛧ."
105+
]
106+
},
107+
{
108+
"cell_type": "code",
109+
"execution_count": 3,
110+
"metadata": {},
111+
"outputs": [],
112+
"source": [
113+
"from cltk.corpus.old_norse import runes"
114+
]
115+
},
116+
{
117+
"cell_type": "markdown",
118+
"metadata": {},
119+
"source": [
120+
"Get the available runic alphabets"
121+
]
122+
},
123+
{
124+
"cell_type": "code",
125+
"execution_count": 4,
126+
"metadata": {},
127+
"outputs": [],
128+
"source": [
129+
"from cltk.corpus.old_norse.runes import RunicAlphabetName"
130+
]
131+
},
132+
{
133+
"cell_type": "code",
134+
"execution_count": 5,
135+
"metadata": {},
136+
"outputs": [
137+
{
138+
"name": "stdout",
139+
"output_type": "stream",
140+
"text": [
141+
"elder_futhark\n",
142+
"younger_futhark\n",
143+
"short_twig_younger_futhark\n"
144+
]
145+
}
146+
],
147+
"source": [
148+
"for name in RunicAlphabetName:\n",
149+
" print(name.value)"
150+
]
151+
},
152+
{
153+
"cell_type": "markdown",
154+
"metadata": {},
155+
"source": [
156+
"Some famous runic inscriptions like the Jelling stones."
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"execution_count": 6,
162+
"metadata": {},
163+
"outputs": [
164+
{
165+
"data": {
166+
"text/plain": [
167+
"'᛬ᚴᚢᚱᛘᛦ᛬ᚴᚢᚾᚢᚴᛦ᛬ᚴ(ᛅᚱ)ᚦᛁ᛬ᚴᚢᛒᛚ᛬ᚦᚢᛋᛁ᛬ᛅ(ᚠᛏ)᛬ᚦᚢᚱᚢᛁ᛬ᚴᚢᚾᚢ᛬ᛋᛁᚾᛅ᛬ᛏᛅᚾᛘᛅᚱᚴᛅᛦ᛬ᛒᚢᛏ᛬'"
168+
]
169+
},
170+
"execution_count": 6,
171+
"metadata": {},
172+
"output_type": "execute_result"
173+
}
174+
],
175+
"source": [
176+
"little_jelling_stone = '᛬ᚴᚢᚱᛘᛦ᛬ᚴᚢᚾᚢᚴᛦ᛬ᚴ(ᛅᚱ)ᚦᛁ᛬ᚴᚢᛒᛚ᛬ᚦᚢᛋᛁ᛬ᛅ(ᚠᛏ)᛬ᚦᚢᚱᚢᛁ᛬ᚴᚢᚾᚢ᛬ᛋᛁᚾᛅ᛬ᛏᛅᚾᛘᛅᚱᚴᛅᛦ᛬ᛒᚢᛏ᛬'\n",
177+
"little_jelling_stone"
178+
]
179+
},
180+
{
181+
"cell_type": "code",
182+
"execution_count": 7,
183+
"metadata": {},
184+
"outputs": [],
185+
"source": [
186+
"big_jelling_stone = 'ᚼᛅᚱᛅᛚᛏᚱ᛬ᚴᚢᚾᚢᚴᛦ᛬ᛒᛅᚦ᛬ᚴᛅᚢᚱᚢᛅ ᚴᚢᛒᛚ᛬ᚦᛅᚢᛋᛁ᛬ᛅᚠᛏ᛬ᚴᚢᚱᛘ ᚠᛅᚦᚢᚱ ᛋᛁᚾ ᛅᚢᚴ ᛅᚠᛏ᛬ᚦᚭᚢᚱᚢᛁ᛬ᛘᚢᚦᚢᚱ᛬ᛋᛁᚾᛅ᛬ᛋᛅ ᚼᛅᚱᛅᛚᛏᚱ(᛬)ᛁᛅᛋ᛬ᛋᚭᛦ᛫ᚢᛅᚾ᛫ᛏᛅᚾᛘᛅᚢᚱᚴ\\nᛅᛚᛅ᛫ᛅᚢᚴ᛫ᚾᚢᚱᚢᛁᚴ\\n᛫ᛅᚢᚴ᛫ᛏ(ᛅ)ᚾᛁ(᛫ᚴᛅᚱᚦᛁ᛫)ᚴᚱᛁᛋᛏᚾᚭ'"
187+
]
188+
},
189+
{
190+
"cell_type": "markdown",
191+
"metadata": {},
192+
"source": [
193+
"Runes are encoded in UTF-8 from \\u16A0 ᚠ to \\u16FF ᛪ. See https://en.wikipedia.org/wiki/Runic_(Unicode_block)"
194+
]
195+
},
196+
{
197+
"cell_type": "markdown",
198+
"metadata": {},
199+
"source": [
200+
"Interesting, but why a Python module for runes? This module provides:\n",
201+
"* metadata attached to runes (runic alphabet which it is in, its representation, the approximate sound it describes, the transcription, the name)\n",
202+
"* a rune to latin character transcriber \n",
203+
"* a unified method to retrieve corpora of runic inscriptions "
204+
]
205+
},
206+
{
207+
"cell_type": "code",
208+
"execution_count": 8,
209+
"metadata": {},
210+
"outputs": [
211+
{
212+
"data": {
213+
"text/plain": [
214+
""
215+
]
216+
},
217+
"execution_count": 8,
218+
"metadata": {},
219+
"output_type": "execute_result"
220+
}
221+
],
222+
"source": [
223+
"runes.ELDER_FUTHARK[0]"
224+
]
225+
},
226+
{
227+
"cell_type": "markdown",
228+
"metadata": {},
229+
"source": [
230+
"Runes are defined with the **Rune** class in the *rune* module."
231+
]
232+
},
233+
{
234+
"cell_type": "code",
235+
"execution_count": 9,
236+
"metadata": {},
237+
"outputs": [
238+
{
239+
"data": {
240+
"text/plain": [
241+
""
242+
]
243+
},
244+
"execution_count": 9,
245+
"metadata": {},
246+
"output_type": "execute_result"
247+
}
248+
],
249+
"source": [
250+
"runes.Rune(runes.RunicAlphabetName.elder_futhark, \"\\u16A0\", \"f\", \"f\", \"fehu\")"
251+
]
252+
},
253+
{
254+
"cell_type": "markdown",
255+
"metadata": {},
256+
"source": [
257+
"Use the **Transcriber** class to get a basic transcription of a runic inscription."
258+
]
259+
},
260+
{
261+
"cell_type": "code",
262+
"execution_count": 10,
263+
"metadata": {},
264+
"outputs": [
265+
{
266+
"data": {
267+
"text/plain": [
268+
"'᛫kurmR᛫kunukR᛫k(ar)þi᛫kubl᛫þusi᛫a(ft)᛫þurui᛫kunu᛫sina᛫tanmarkaR᛫but᛫'"
269+
]
270+
},
271+
"execution_count": 10,
272+
"metadata": {},
273+
"output_type": "execute_result"
274+
}
275+
],
276+
"source": [
277+
"runes.Transcriber.transcribe(little_jelling_stone, runes.YOUNGER_FUTHARK)"
278+
]
279+
},
280+
{
281+
"cell_type": "code",
282+
"execution_count": 11,
283+
"metadata": {},
284+
"outputs": [],
285+
"source": [
286+
"from runesanalyzer import scraper"
287+
]
288+
},
289+
{
290+
"cell_type": "markdown",
291+
"metadata": {},
292+
"source": [
293+
"If you want to import all the Sweden runic inscriptions, call the following function."
294+
]
295+
},
296+
{
297+
"cell_type": "code",
298+
"execution_count": 12,
299+
"metadata": {},
300+
"outputs": [
301+
{
302+
"data": {
303+
"text/plain": [
304+
"<function runesanalyzer.scraper.retrieve_sweden_runic_inscription()>"
305+
]
306+
},
307+
"execution_count": 12,
308+
"metadata": {},
309+
"output_type": "execute_result"
310+
}
311+
],
312+
"source": [
313+
"scraper.retrieve_sweden_runic_inscription"
314+
]
315+
},
316+
{
317+
"cell_type": "markdown",
318+
"metadata": {},
319+
"source": [
320+
"Future tasks:\n",
321+
"* normalizing runic inscriptions and transcriptions\n",
322+
"* making a statistics module to analyze frequencies of words, runes, spellings in runic inscriptions.\n",
323+
"* getting more runic inscriptions from Norway, Denmark, etc\n",
324+
"* using phonetical rules [module](https://github.com/cltk/cltk/blob/master/cltk/phonology/utils.py) to get a normalized pronunciation of Old norse inscriptions written with runes.\n",
325+
" "
326+
]
327+
},
328+
{
329+
"cell_type": "markdown",
330+
"metadata": {},
331+
"source": [
332+
"By Clément Besnier, email address: clemsciences@aol.com, web site: https://clementbesnier.pythonanywhere.com/, twitter: clemsciences"
333+
]
334+
}
335+
],
336+
"metadata": {
337+
"kernelspec": {
338+
"display_name": "Python 3.6",
339+
"language": "python",
340+
"name": "python3"
341+
},
342+
"language_info": {
343+
"codemirror_mode": {
344+
"name": "ipython",
345+
"version": 3
346+
},
347+
"file_extension": ".py",
348+
"mimetype": "text/x-python",
349+
"name": "python",
350+
"nbconvert_exporter": "python",
351+
"pygments_lexer": "ipython3",
352+
"version": "3.6.3"
353+
}
354+
},
355+
"nbformat": 4,
356+
"nbformat_minor": 1
357+
}

0 commit comments

Comments
 (0)