LoginSignup
3
6

More than 1 year has passed since last update.

Python: Pythonista 3 on iPadでUIを使ってみる

Last updated at Posted at 2020-11-18

はじめに

最近出たばかりの、iPad Air 4 を買った。使用目的は主に手書きメモ作成なのだが、計算しながらメモを作成する場合も多い。手書きメモといってもテキストと数字だけなら、わざわざ手書きにしなくても、さっさとテキストエディタで打ち込めばいいのだが、説明図が必要となると、やはり手書きが便利である。計算が必要な場合には、これまでは iMac で Python を立ち上げて計算させながら iPad で手書きスケッチやメモを行っていたが、iPad があるのに iMac を立ち上げるのもなんかかっこ悪い、というかスマートでない。
そこで、最近はご無沙汰であったが、iPad mini 4 用に購入していた、Pythonista 3 を使ってみることにした。

Pythonista 3 は、numpy および matplotlib を含んでおり、これらはほぼ間違いなく動く。scipy や pandas など、その他のライブラリは使えないと思ったほうが良い。このため、複雑な計算でも numpy と matplotlib のみを使っているコードなら実用性がある。また GUI も使えるらしいのだが、これまで自分で使ったことはないので、使用頻度の高い簡単な計算プログラムを、アプリ風にして iPad で使えるようにしてみた。(要はiPad Air 4を買って嬉しいので、これを使っていろいろなことをやろうという趣旨である)

やっていること

やっていることは Mac に入れている「急勾配水路の等水深を求めるプログラム」を Pythonista 用に書き換えて GUI で動くようにしたものである。
もとのコードは以下の「はてな」に投稿したものである。

https://damyarou.hatenablog.com/entry/2020/10/23/073643

このプログラムは非線形方程式を解くため、Mac 用プログラムでは scipy を使っているが、Pythonista では scipy は使えないため、非線形方程式を解く二分法の部分は自前で書き換えている。
更に、ここからが自分にとって初めての挑戦であるが、アプリ風に GUI を使って仕上げてみた。

実行結果は以下の写真のようになる。上側4個の四角にデータを入力し、Execute というボタンを押すと結果が下側四角の中に示される。

IMG_0004.jpeg

プログラム作成に当たり以下のサイトを参考にさせていただいた。

Pythonista 3 では、UI プログラミングを指定すると、2つのファイルができる。下の写真では。py_uniflow.pypy_uniflow.pyui というファイルが確認できる。「xxx.py」はコードを書き込むプログラムで、「xxx.pyui」は、UI の配置や特性を定義するファイルである。

IMG_0003.jpeg

配置できるオブジェクトの一覧は、UIの配置と特性を定義する py_uniflow.pyui 上で、左上の四角で囲まれた+マークを押すと表示されるので、そこから使いたいものを選択する。

IMG_0007.jpeg

このプログラムでは、以下の4種類のオブジェクトを使っている。

  1. label
  2. textfield
  3. button
  4. textview

labelbuttan については、py_uniflow.pyui の中で行っている、特性値指定箇所の写真を示しておく。
textfieldtextview は、位置と大きさを調整しているだけなので、写真は省略。

IMG_0005.jpeg

IMG_0006.jpeg

こんな感じでプログラムをiPad上で仕上げていく。

コード

py_uniflow.py のコード全文は以下の通り。関数 def click_button の中に主な処理は全て詰め込んである。

# Calculation of normal depth
# (amended on 2022.05.15)
import ui
import numpy as np


def cal_hc(q,b,cs):
    # critical depth
    g=9.8
    hc=(q**2/g/b**2/cs)**(1/3)
    return hc


def func(h,q,b,n,sn):
    f=q-b*h/n*(b*h/(b+2*h))**(2/3)*sn**(1/2)    
    return f    


def bisection(q,b,n,sn,ha,hb):
    for k in range(100):
        hi=0.5*(ha+hb)
        fa=func(ha,q,b,n,sn)
        fb=func(hb,q,b,n,sn)
        fi=func(hi,q,b,n,sn)
        if fa*fi<0: hb=hi
        if fb*fi<0: ha=hi
        #print(fa,fi,fb)
        if np.abs(hb-ha)<1e-10: break
    return hi


def calc(q,b,n,i):
    theta=np.arctan(i)
    sn=np.sin(theta)
    cs=np.cos(theta)

    ha=0.0 # lower initial value for bisection method
    hb=10.0 # upper initial value for bisection method
    hn=bisection(q,b,n,sn,ha,hb)
    vn=q/b/hn
    hc=cal_hc(q,b,cs)

    # hn: normal depth
    # vn: flow velocity 
    # hc: critical depth
    ss='ang={0:.3f} deg.\n'.format(np.degrees(theta))
    ss=ss+'hn={0:.3f} m\n'.format(hn)
    ss=ss+'vn={0:.3f} m/s\n'.format(vn)   
    ss=ss+'hc={0:.3f} m'.format(hc)
    return ss


def click_button(sender):
    tf1=v['textfield1']
    tf2=v['textfield2']  
    tf3=v['textfield3']
    tf4=v['textfield4']
    q=float(tf1.text) # discharge
    b=float(tf2.text) # channel width
    n=float(tf3.text) # Manning's roughness coefficient
    i=float(tf4.text) # invert gradient
    ss=calc(q,b,n,i)
    v['textview1'].text=ss


v = ui.load_view()
v.name='Uniform flow'
v.present('sheet')

以 上

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6