Musique vs other programming languages cheatsheet
This commit is contained in:
parent
34eb56ac50
commit
f42e700747
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,3 +10,4 @@ drafts.cc
|
|||||||
.cache
|
.cache
|
||||||
release_*
|
release_*
|
||||||
*.zip
|
*.zip
|
||||||
|
*.html
|
||||||
|
121
doc/musique-vs-languages-cheatsheet.template
Normal file
121
doc/musique-vs-languages-cheatsheet.template
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
TITLE Porównanie Musique z typowymi językami programowania
|
||||||
|
|
||||||
|
BEGIN CSS
|
||||||
|
table, tr, td {
|
||||||
|
font-size: 12pt;
|
||||||
|
border: 1pt solid #DDDDDD;
|
||||||
|
border-collapse: collapse;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
END CSS
|
||||||
|
|
||||||
|
BEGIN INTRO
|
||||||
|
<h1>Ściągawka Musique, a Python i Ruby</h1>
|
||||||
|
Ponieważ Musique jest kierowany do osób posiadających doświadczenie z muzyką algorytmiczną, szybkim sposobem na podstawowe poznanie języka jest porównanie z innymi technologiami w tej dziedzinie. Ten dokument służy bardziej ukazaniu różnic niż omówieniu samego języka.
|
||||||
|
END INTRO
|
||||||
|
|
||||||
|
BEGIN TABLE
|
||||||
|
|
||||||
|
n Kategoria
|
||||||
|
m Musique
|
||||||
|
p Python
|
||||||
|
r Ruby (SonicPi)
|
||||||
|
c Komentarz
|
||||||
|
|
||||||
|
n Deklaracja
|
||||||
|
m x := 0
|
||||||
|
p x = 0
|
||||||
|
r x = 0
|
||||||
|
c Zmienne należy zadeklarować by móc z nich korzystać
|
||||||
|
|
||||||
|
n Aktualizacja
|
||||||
|
m x = 1
|
||||||
|
r x = 1
|
||||||
|
p x = 1
|
||||||
|
|
||||||
|
n Operacje matematyczne
|
||||||
|
m x = 10 * 30 - 40 ** 2
|
||||||
|
p x = 10 * 30 - 40 ** 2
|
||||||
|
r x = 10 * 30 - 40 ** 2
|
||||||
|
c Zarówno Python, Ruby jak i Musique posiadają operator potęgi **
|
||||||
|
|
||||||
|
n Funkcja anonimowa
|
||||||
|
m add := [x y | x + y]
|
||||||
|
p add = lambda x, y: x + y
|
||||||
|
r add = ->(x, y) { x + y }
|
||||||
|
|
||||||
|
n Deklaracja funkcji
|
||||||
|
m add := [x y |
|
||||||
|
m say x y;
|
||||||
|
m x + y
|
||||||
|
m ]
|
||||||
|
p def add(x, y):
|
||||||
|
p print(x, y)
|
||||||
|
p return x + y
|
||||||
|
r def add(x, y)
|
||||||
|
r puts x, y
|
||||||
|
r return x + y
|
||||||
|
r end
|
||||||
|
c Musique nie rozróżnia funkcji anonimowych i zadeklarowanych
|
||||||
|
|
||||||
|
n Tablice
|
||||||
|
m x = [1; 2; 3; 4]
|
||||||
|
p x = [1, 2, 3, 4]
|
||||||
|
r x = [1, 2, 3, 4]
|
||||||
|
|
||||||
|
n Nty element tablicy
|
||||||
|
m x.n
|
||||||
|
p x[n]
|
||||||
|
r x[n]
|
||||||
|
|
||||||
|
n Aktualizacja ntego elementu tablicy
|
||||||
|
m x = update x n 10
|
||||||
|
p x[n] = 10
|
||||||
|
r x[n] = 10
|
||||||
|
|
||||||
|
n Tablica od 0 do 9 włącznie
|
||||||
|
m x = up 10
|
||||||
|
p x = range(10)
|
||||||
|
r x = [*0..9]
|
||||||
|
|
||||||
|
n Tablica od 1 do 10 włącznie
|
||||||
|
m x = 1 + up 10
|
||||||
|
m lub x = range 1 11
|
||||||
|
p x = range(1, 11)
|
||||||
|
r x = [*1..10]
|
||||||
|
|
||||||
|
n Iloczyn elementów tablicy
|
||||||
|
m fold '* (1 + up 5)
|
||||||
|
p functools.reduce(
|
||||||
|
p operator.mul, range(1, 6), 1)
|
||||||
|
r [*1..5].inject(:*)
|
||||||
|
c Musique pozwala zmienić dowolny operator w funkcję
|
||||||
|
c poprzez zapis 'operator jak '* w przykładzie
|
||||||
|
|
||||||
|
n Instrukcja warunkowa
|
||||||
|
m if (n == 42)
|
||||||
|
m [ say 1 ]
|
||||||
|
m [ say 2 ]
|
||||||
|
p if n == 42:
|
||||||
|
p print(1)
|
||||||
|
p else:
|
||||||
|
p print(2)
|
||||||
|
r if n == 42
|
||||||
|
r puts 1
|
||||||
|
r else
|
||||||
|
r puts 2
|
||||||
|
r end
|
||||||
|
c Musique nie posiada instrukcji warunkowej, a funkcję if,
|
||||||
|
c która przyjmuje wartość logiczną i dwa bloki (funkcje anonimowe)
|
||||||
|
c - jeden z nich zostanie wykonany jeśli warunek jest prawdziwy,
|
||||||
|
c a drugi jeśli jest fałszywy.
|
||||||
|
n Wyrażenie warunkowe
|
||||||
|
m x := if (n == 42) [1] [2]
|
||||||
|
p x = 1 if n == 42 else 2
|
||||||
|
r x = n == 42 ? 1 : 2
|
||||||
|
END TABLE
|
140
scripts/language-cmp-cheatsheet.py
Normal file
140
scripts/language-cmp-cheatsheet.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
import collections
|
||||||
|
|
||||||
|
Directive = collections.namedtuple("Directive", "line_number type content")
|
||||||
|
|
||||||
|
HTML_TEMPLATE = string.Template("""<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>$title</title>
|
||||||
|
<style>$css</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>$intro</p>
|
||||||
|
<table> $table </table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""")
|
||||||
|
|
||||||
|
def parse_table(lines: list):
|
||||||
|
previus_column_type = None
|
||||||
|
rows, order = [{}], []
|
||||||
|
current_row = rows[0]
|
||||||
|
|
||||||
|
# Each nonblank matches this regular expression /(\S*)\s(.*)/
|
||||||
|
# where first capture is type of column (essentialy column id) and
|
||||||
|
# second capture is given cell content. Where column type repeats not in row
|
||||||
|
# we have new row.
|
||||||
|
for line in lines:
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
sep = line.find(' ')
|
||||||
|
column_type, cell_content = line[:sep].strip(), line[sep:]
|
||||||
|
|
||||||
|
if column_type not in order:
|
||||||
|
order.append(column_type)
|
||||||
|
|
||||||
|
if previus_column_type != column_type and column_type in current_row:
|
||||||
|
rows.append({})
|
||||||
|
current_row = rows[-1]
|
||||||
|
|
||||||
|
cell = current_row.get(column_type, [])
|
||||||
|
cell.append(cell_content)
|
||||||
|
current_row[column_type] = cell
|
||||||
|
previus_column_type = column_type
|
||||||
|
|
||||||
|
# Eliminate common whitespace prefix in given column type (not all whitespace
|
||||||
|
# prefix since examples in Python may have significant whitespace)
|
||||||
|
for row in rows:
|
||||||
|
for cell in row.values():
|
||||||
|
prefix_whitespace = min(len(s) - len(s.lstrip()) for s in cell)
|
||||||
|
for i, s in enumerate(cell):
|
||||||
|
cell[i] = s[prefix_whitespace:]
|
||||||
|
|
||||||
|
return rows, order
|
||||||
|
|
||||||
|
def compile_template(*, template_path: str, target_path: str):
|
||||||
|
# Read template file and separate it into lines
|
||||||
|
with open(template_path) as f:
|
||||||
|
template = [line.strip() for line in f.readlines()]
|
||||||
|
|
||||||
|
directives = []
|
||||||
|
for i, line in enumerate(template):
|
||||||
|
s = line.split()
|
||||||
|
if s and s[0] in ("BEGIN", "END", "TITLE"):
|
||||||
|
directives.append(Directive(i, s[0], line[len(s[0]):].strip()))
|
||||||
|
|
||||||
|
title, css_source, table_source, intro_source = 4 * [None]
|
||||||
|
|
||||||
|
for directive in directives:
|
||||||
|
if directive.type == "TITLE":
|
||||||
|
title = directive.content
|
||||||
|
continue
|
||||||
|
|
||||||
|
if directive.type == "BEGIN":
|
||||||
|
start_line = directive.line_number
|
||||||
|
for end in directives:
|
||||||
|
if end.type == "END" and end.content == directive.content:
|
||||||
|
end_line = end.line_number
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert False, "Begin without matching end"
|
||||||
|
|
||||||
|
span = template[start_line+1:end_line]
|
||||||
|
|
||||||
|
if directive.content == "CSS":
|
||||||
|
css_source = span
|
||||||
|
elif directive.content == "TABLE":
|
||||||
|
table_source = span
|
||||||
|
elif directive.content == "INTRO":
|
||||||
|
intro_source = span
|
||||||
|
|
||||||
|
assert css_source is not None
|
||||||
|
assert table_source is not None
|
||||||
|
assert intro_source is not None
|
||||||
|
assert title is not None
|
||||||
|
|
||||||
|
rows, columns_order = parse_table(lines=table_source)
|
||||||
|
|
||||||
|
table = ""
|
||||||
|
|
||||||
|
for i, row in enumerate(rows):
|
||||||
|
if i == 0:
|
||||||
|
line = ["<th>" + ' '.join(row[k]) + "</th>" for k in columns_order]
|
||||||
|
else:
|
||||||
|
line = []
|
||||||
|
for column in columns_order:
|
||||||
|
val = row.get(column, [])
|
||||||
|
line.append('<td><pre><code>' + '<br/>'.join(val) + '</code></pre></td>')
|
||||||
|
|
||||||
|
table += "<tr>\n" + '\n'.join(line) + "\n</tr>\n"
|
||||||
|
|
||||||
|
|
||||||
|
final = HTML_TEMPLATE.substitute({
|
||||||
|
"title": title,
|
||||||
|
"css": "\n".join(css_source),
|
||||||
|
"table": table,
|
||||||
|
"intro": "\n".join(intro_source)
|
||||||
|
})
|
||||||
|
|
||||||
|
with open(target_path, "w") as f:
|
||||||
|
f.write(final)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Build language comparison chart")
|
||||||
|
parser.add_argument(nargs='+', metavar="TEMPLATE", dest="templates", help="Template file that will be converted to HTML page")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
for template in args.templates:
|
||||||
|
dst, _ = os.path.splitext(template)
|
||||||
|
dst += ".html"
|
||||||
|
compile_template(template_path=template, target_path=dst)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user