C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

数値を切り上げる

タイトルの意味ですが、こんな事です。

製品サイズの幅が97mmだとした場合、
"加工する材料がピッタリでは行いたくない上、細かな数値も
面倒なので10mm単位で考えると100mmで発注しようかな。"
って事です。5mm単位でも0.1mm単位でも良いのですが、
必ず切り上げて大きなサイズにしたいんです。

今時の言語であればズバッとした関数が有るのだろうと思っていたのですが
イマイチ見付けきれませんでした。

四捨五入の場合、パッと思い付くのはroundですがちょっと用途が違う。
続いて調べて見ると math.ceil が見つかりましたが、小数点以下のお話のようなので
これも違う。
小数点以下の切り上げだとformatも有りそうです。(個人的に盲点だった)

文字列で処理させるdecimal.ROUND_UPもありました。
Decimal.quantize() による端数処理 (四捨五入など)
文字列であることは構わないのですが、書き方に戸惑いが・・・。

例えば10mm単位で処理したい場合、

from decimal import Decimal, ROUND_UP
Decimal('12.345').quantize(Decimal('10'), rounding=ROUND_UP)

ではNGで

from decimal import Decimal, ROUND_UP
Decimal('12.345').quantize(Decimal('1E1'), rounding=ROUND_UP)

と書かなきゃならないらしいです。
5mm単位とかだと、どうやって書けば良いのかも不明・・・。


悩んだ挙句、自作の関数で昔ながらの方法にしました。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        # 目的の数値
        values = [
            10,
            12.345,
            1.2345,
            1,
            0.12345,
            0.012345,
        ]

        # 切り上げ単位
        roundUpUnits = [
            0.1,
            1,
            5,
            10
        ]

        for v in values:
            for r in roundUpUnits:
                print(f'{v}[{r}] -> {roundUp(v, r)}')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def roundUp(v, roundUpUnit):
    # 商と余り
    q, mod = divmod(v ,roundUpUnit)

    if mod > 0:
        # 割り切れていない場合、0で判断して良いのかな・・・
        q += 1

    return q * roundUpUnit

結局N88BASIC時代と変わらないじゃない。