Apa itu

PyMini ialah penterjemah subset Python yang ditulis dalam Swift dan terbina dalam papan kekunci. Setiap panel dan setiap tindakan anda berjalan padanya. Ia membaca bentuk Python yang anda sudah kenal, dan bahasa yang sama berkhidmat sama ada skrip melukis antara muka atau menulis semula satu perkataan.

# an action: text in, text out
def transform(text):
    return text.upper()

# a panel: a view, and what a tap does
def view(state):
    return button("Shout", "shout")

def on_action(action, state):
    insert(context()["word"].upper())
    return state
Satu bahasa, dua kontrak: transform(text) untuk tindakan, view(state) untuk panel.

Mengapa menggunakannya

Kami membina PyMini kerana Clink memerlukan cara untuk orang menulis skrip bagi papan kekunci mereka sendiri, dan tiada apa yang kami temui muat di dalamnya. Namun tiada apa pun padanya yang terikat pada papan kekunci, jadi kini ia sumber terbuka sebagai pakej Swift tersendiri, untuk mana-mana apl yang mahu membenarkan penggunanya menulis sedikit Python.

Ia bukan CPython, dan tidak membenamkannya. Sambungan papan kekunci mendapat sepersekian daripada memori sebuah apl, dan binari serta timbunan CPython akan menghabiskan belanjawan itu sebelum skrip anda sempat berjalan. PyMini ialah beberapa ratus kilobait Swift, tanpa kebergantungan binari.

Gunakannya di mana sahaja pengguna mahukan logik mereka sendiri: penukaran teks dalam apl penulisan, peraturan dalam apl senarai tugasan atau belanjawan, formula, automasi, mod permainan, atau sistem plugin untuk apl yang mempunyai komuniti. Ramai orang sudah tahu sedikit Python, jadi tiada bahasa baharu untuk diajar, dan skrip ialah teks biasa yang boleh anda simpan, segerakkan dan kongsi seperti tetapan lain.

import PyMini

let py = PyRuntime(modules: ["math", "json", "re"])

// your app, as a Python function
py.define("shout") { call in
    try call.argument(0, as: String.self).uppercased()
}

// a script one of your users wrote
try py.load("""
def tidy(text):
    return shout(" ".join(text.split()))
""")

try py.call("tidy", "  hello    there ")  // HELLO THERE
Berikan skrip satu fungsi Swift, muatkan skrip, dan panggil ia.
PanggilanApa yang dilakukan
import PyMiniTiada kebergantungan dan tiada apa yang perlu dibungkus sendiri. Tambah pakej Swift dan ia berjalan pada iOS 15, macOS 12, tvOS 15, watchOS 8 dan visionOS 1 atau lebih baharu.
py.define("shout") { call in ... }Ciri apl anda menjadi fungsi dan modul Python. Argumen tiba sebagai jenis Swift, dan apa yang anda pulangkan kembali kepada skrip sebagai nilai Python.
PyLimits(steps: 200_000)Setiap panggilan berjalan dengan belanjawan langkah, dan kehabisannya ialah ralat yang tidak boleh ditangkap oleh mana-mana skrip. while True yang cuai berakhir dengan mesej, bukan apl yang beku.
PyRuntime(modules: ["math"])Skrip tidak mendapat fail, rangkaian atau proses. Ia hanya mencapai fungsi yang anda takrifkan dan modul standard yang anda biarkan hidup.
py.call(hook: "on_open")Panggil skrip apabila sesuatu berlaku dalam apl anda. Cangkuk yang tidak ditakrifkan oleh skrip akan dilangkau, jadi setiap cangkuk boleh menjadi pilihan.
catch let error as PyErrorRalat kembali dengan nama pengecualian Python dan nombor baris, sedia untuk ditunjukkan kepada orang yang menulis skrip itu.
import syssys.version menyebut nama penterjemah dan versinya, dan perintah pymini mencetak baris yang sama. Skrip boleh melaporkan versi yang dibawa oleh apl di sekelilingnya.

Kod sumber, rujukan bahasa dan ujian ada di GitHub.

Apa yang dijanjikannya

Tiada sistem fail, tiada rangkaian dan tiada proses yang boleh dicapai oleh skrip: kotak pasir itu ialah bentuk penterjemah, bukan senarai perkara yang ditolaknya. import ialah satu-satunya pintu keluar, dan ia terbuka kepada senarai pendek ruang nama yang hanya mengira. Selain itu semuanya memakan langkah. Setiap ungkapan, setiap pusingan gelung, setiap langkah ungkapan biasa dan setiap baris JSON membelanjakan satu daripada 2,000,000, dan rentetan serta senarai dihadkan sambil membesar.

Boleh diimport dalam panel yang dikongsi

  • json
  • math
  • random
  • re
  • sys
  • time

Belanjawan itu tidak boleh ditangkap. Klausa except menangkap KeyError, tetapi bukan pengguguran yang menamatkan gelung terlepas kawalan, kerana menangkapnya itulah caranya skrip terlepas kawalan akan terus berjalan.

Log perubahan

Setiap versi PyMini, yang terbaharu dahulu, dan apa yang ditambah olehnya.

PyMini 2.0

Versi pertama boleh menjadikan satu perkataan huruf besar dan menyusun grid butang. Versi kedua ialah bahasa untuk menulis program kecil, dan panel yang menjawab ketikan, bukan sekadar membawa satu jawapan tetap.

ContohApa yang berubah
[word for word in words if word]Pemahaman senarai, lambda, tupel, set, dan try / except / finally / raise.
f"{total:,.2f}"Penukaran f-string dan spesifikasi format penuh, dikongsi dengan str.format dan format().
f"""Hello {name}"""Rentetan dalam tanda petik tiga, rentetan mentah, dan f-string yang merentas beberapa baris.
import math, random, time, json, reLima ruang nama, dan tiada yang lain, semuanya tulen.
re.sub(r"\s+", " ", text)Ungkapan biasa pada enjin Clink sendiri, yang membelanjakan belanjawan langkah yang sama.
on_action(action, value, state)Panel mengendalikan ketikannya sendiri, menyimpan keadaan sebenar, dan mempunyai sebelas kawalan lagi.
replace(len(word), word.upper())Skrip boleh meminta papan kekunci bertindak, dan membaca apa yang ada di sekeliling kursor.
Current sentenceTindakan membaca mana-mana bahagian medan, bukan sekadar perkataan dan apa yang mendahuluinya.
import re

def initial():
    return {"words": []}

def view(state):
    top = sorted(set(state["words"]), key=lambda w: -len(w))[:3]
    return vstack([text(f"{len(state['words']):,} words", mono=True)]
                  + [row(w, detail=f"{len(w)}") for w in top])

def on_open(state):
    state["words"] = re.findall(r"\w+", context()["before"])
    return state
Panel yang membaca apa yang anda tulis, mengiranya, dan menyenaraikan perkataan terpanjang.

PyMini 1.0

Versi pertama. Tindakan menukar satu rentetan kepada rentetan lain, dan panel hanyalah beberapa kawalan yang butangnya menaip rentetan tetap atau menetapkan nilai.

ContohApa yang berubah
def transform(text):int, float, str, bool, None, list dan dict, dengan if, while, for, serta def dengan argumen lalai dan argumen kata kunci.
f"{n} words"f-string tanpa spesifikasi format, serta pengindeksan dan penghirisan dengan indeks negatif.
sorted(text.split())24 fungsi terbina dalam dan kaedah biasa untuk str, list dan dict.
button("+", set={"count": 1})Teks, butang, medan, tindanan dan grid. Butang hanya boleh menaip teks atau menetapkan keadaan.
while True:Tiada import langsung, belanjawan langkah untuk setiap skrip, dan had setakat mana rentetan dan senarai boleh membesar.

Ke mana seterusnya

Keseluruhan permukaan bahasa, perbendaharaan kata panel, dan pembina yang menulis kedua-duanya tanpa anda menaip satu baris pun.

Tindakan ›Panel ›Plugin ›Pencipta ›
Muat turun di App Store