質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

振り子運動のシミュレーションにおいて、わからないエラーメッセージの意味(とそのデバッグ法)を教えてほしい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 514

hirashun

score 5

前提・実現したいこと

初心者です。Pythonで振り子運動をアニメーション表示するシステムを作っています。エラーメッセージの意味(とそのデバッグ法)がわからないため、教えていただきたいと考えています。

発生している問題・エラーメッセージ

エラーメッセージの後半以降、data[i][j][k] = ・・・以下の内容の意味が調べましたがよくわかりません。また最後のエラーメッセージついて、floatが文字や数値に使うもので配列には使えないということはわかったのですが、コード内でfloatをどこで使っているのかがわかりません。

Traceback (most recent call last):
  File "C:/Users/hirah/OneDrive/python/振り子運動 python.py", line 69, in <module>
    Ani = ita.plot.animation_show(ani)
  File "C:\Users\hirah\Anaconda3\lib\site-packages\ita\plot.py", line 54, in animation_show
    image_preprocess(tmp)
  File "C:\Users\hirah\Anaconda3\lib\site-packages\ita\plot.py", line 28, in image_preprocess
    data[i][j][k] = imv_normalize(data[i][j][k])
  File "C:\Users\hirah\Anaconda3\lib\site-packages\ita\plot.py", line 19, in imv_normalize
    return min(max(0.0, float(v)), 1.0)
TypeError: float() argument must be a string or a number, not 'list'

該当のソースコード

import ita
import math

def diffusion_motion(T, time_stride):
    g = 9.8 #重力加速度
    l = 0.1 #棒の長さ
    steps = round(T / time_stride) #繰り返し回数
    result = ita.array.make1d(steps) #結果格納用の配列
    result[0] = math.pi/ 3 #初期条件
    for i in range(1, steps):
        if i ==1:
            result[i] = - g/l*time_stride**2*math.sin(result[i-1])
            + result[i-1]
        else:
            result[i] = - g/l*time_stride**2*math.sin(result[i-1])
            + 2*result[i-1] - result[i-2]
    return result

def diffusion_anime_ball(ang):
    images = ita.array.make1d(len(ang))
    #アニメーション用の配列を準備
    for i in range(0, len(ang)):
        image = ita.array.make3d(100,200, 3)
        cur_y = 0 + 30*math.cos(ang[i]) #物体のy座標
        cur_x = 50 + 30*math.sin(ang[i]) #物体のx座標
        draw_circle(5, round(cur_y), round(cur_x), [0, 0, 0], image)
        #その時刻の物体の座標に半径5の白い円を描く
        draw_stick(0, 50, round(cur_y), round(cur_x), [1,1, 0], image)
        #その時刻の物体と天井を結ぶ棒を描く
        images[i] = image
    return images

def draw_circle(r, center_y, center_x, color, image):
    #点(center_x, center_y)上に半径rの円を描く
    for i in range(center_y - r, center_y + r):
        for j in range(center_x - r, center_x + r):
            if (0 <= i < len(image) and 0 <= j < len(image[i]) and
                distance(i, j, center_y, center_x) < r):
                image[i][j] = color

def distance(x1, y1, x2, y2):
    #2点間の距離を求める
    d = ((x2 - x1)**2 + (y2 - y1)**2)**0.5
    return d

def draw_stick(y1, x1, y2, x2, color, image):
    #2点(x1, y1),(x2, y2)を結ぶ線分を描く
    if y1 > y2:
        c = y1
        y1 = y2
        y2 = c
    if x1 > x2:
        c = x1
        x1 = x2
        x2 = c    #座標の大小関係により入れ替えを行う
    for i in range(y1, y2 +1):
        for j in range(x1, x2 + 1):
            a = (y2 - y1)/(x2-x1) #傾き
            if i - y1 == a*(j - x1):
                #2点(x1, y1),(x2, y2)を結ぶ直線上に点(j, i)があるとき色を打つ
                image[i][j] = color

def diffusion(T, time_stride):
    ang = diffusion_motion(T, time_stride)
    ani = [[diffusion_anime_ball(ang)]]
    return ani

ani = diffusion(2, 0.3)
Ani = ita.plot.animation_show(ani)
print(Ani)

試したこと

関数diffusion_anime_ball(ang)において、imageの次元を色々変えてみたりしましたが、正直何をしたらよいのかわかりません。

補足情報(FW/ツールのバージョンなど)

Python version3
AnacondaのIDLEを使っています。
振り子運動の状況設定としては、長さlの棒に重りをつるしたものを考えています。重りの円弧方向の微分方程式を差分化して得られる式、
(θ(t+ Δt)-2θ(t)+ θ(t- Δt))/(Δt^2 )= -g/l  sinθ(t)
をもとに、
Δt= time_stride = 0.3 として、2秒間の運動のシミュレーションを行っています。
以下はエラーが起きているitaのコードです。

# -*- encoding: utf-8 -*-

from . import array
from . import plot
from . import bench
from . import excheck

def lifegame_glider():
    return [[0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0],
            [0,0,0,0,1,1,1,0],
            [0,0,0,0,1,0,0,0],
            [0,0,0,0,0,1,0,0],
            [0,0,0,0,0,0,0,0]]

def lifegame_acorn():
     # Corderman's Acorn
    image = array.make2d(60,80)
    x = 60
    y = 30
    for i in [[0,1],[1,3],[2,0],[2,1],[2,4],[2,5],[2,6]]:
        image[y + i[0]][x + i[1]] = 1
    return image

import random as rnd

# 身長体重データ疑似生成用
def gen_hw_data():
    s = rnd.randint(0,1)
    h = int(rnd.gauss(155+s*18, 10))
    t = rnd.randint(0,1)
    wd = (h/100) ** 2 * (19+3*t)
    w = int(wd + rnd.betavariate(2,10) * 200 - 15)
    return (h,w)

# バネの延びデータ疑似生成用
def gen_spring_data():
    w = rnd.randint(0,200)
    l = int(2 * w * rnd.gauss(1, 0.1))
    return (w,l)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2020/02/10 02:03 編集

    エラーが発生しているitaというパッケージの詳細(ソース、インストール手順など)は提示できますか?
    また、diffusion_anime_ball関数の最後のreturnのインデントは意図した位置にありますか?

    キャンセル

  • hirashun

    2020/02/10 02:33

    メッセージありがとうございます。

    itaについてはソースコードを追加で提示しましたが、僕自身どういうものなのかよく理解しておりません。自分が使っている参考書に従って、配列を新しく取得するときやアニメーションを表示する時にitaをとりあえずimport して使っているという状況です。申し訳ありません。

    diffusion_anime_ball関数のインデントについては、ご指摘いただいた通り位置が間違っておりましたので修正いたしました。ありがとうございます。

    キャンセル

  • hoshi-takanori

    2020/02/10 07:57

    ita パッケージについて調べたところ、「Pythonによるプログラミング入門 東京大学教養学部テキスト」という本 http://www.utp.or.jp/book/b470446.html のために公開されているもののようですね。「自分が使っている参考書」と言われても他の人には分からないので、ちゃんと本の名前を書きましょう。

    また、float を使ってるのは ita パッケージ内の plot.py というファイルです。(補足情報として __init__.py の内容を貼り付けたようですが、これはあまり関係ありません。)エラーメッセージを読めば、該当のソースコードの最後から 2 行目で plot.py の中にある animation_show を呼び出し、そこから image_preprocess → imv_normalize → float と呼ばれてエラーになっているのが分かるはずです。

    ちなみに diffusion_motion などの処理の内容はちゃんと理解されてますか? また、参考書の目次には「幕間:テストとデバッグの基本」や「付録A Python言語の簡易ガイド」の「A.5 基本的な値と型」「A.6 ライブラリ」「A.7 エラーと例外」などの役に立ちそうな項目があるので、読んでみてはいかがでしょうか。

    キャンセル

回答 1

checkベストアンサー

0

とりあえず、

def diffusion(T, time_stride):
    ang = diffusion_motion(T, time_stride)
    ani = [[diffusion_anime_ball(ang)]]
    return ani

の部分を、

def diffusion(T, time_stride):
    ang = diffusion_motion(T, time_stride)
    ani = diffusion_anime_ball(ang) # [[ ]] を削除
    return ani

としたら何かが動きました。

また、他の怪しげな部分としては、

def diffusion_motion(T, time_stride):
    g = 9.8 #重力加速度
    l = 0.1 #棒の長さ
    steps = round(T / time_stride) #繰り返し回数
    result = ita.array.make1d(steps) #結果格納用の配列
    result[0] = math.pi/ 3 #初期条件
    for i in range(1, steps):
        if i ==1:
            result[i] = - g/l*time_stride**2*math.sin(result[i-1])
            + result[i-1]
        else:
            result[i] = - g/l*time_stride**2*math.sin(result[i-1])
            + 2*result[i-1] - result[i-2]
    return result

の + result[i-1] や + 2*result[i-1] - result[i-2] の部分はおそらく継続行だと思われるので、前の行の最後に \ が必要な気がします。
参考: 1つの文が複数行に渡る場合の書き方 - いしだ日記

def diffusion_anime_ball(ang):
    images = ita.array.make1d(len(ang))
    #アニメーション用の配列を準備
    for i in range(0, len(ang)):
        image = ita.array.make3d(100,200, 3)
        cur_y = 0 + 30*math.cos(ang[i]) #物体のy座標
        cur_x = 50 + 30*math.sin(ang[i]) #物体のx座標
        draw_circle(5, round(cur_y), round(cur_x), [0, 0, 0], image)
        #その時刻の物体の座標に半径5の白い円を描く
        draw_stick(0, 50, round(cur_y), round(cur_x), [1,1, 0], image)
        #その時刻の物体と天井を結ぶ棒を描く
        images[i] = image
    return images

の draw_circle の引数 [0, 0, 0] ですが、これは黒で背景色と同じなので何も表示されません。
試しに [0, 0, 1] に変更したら青いものが出現しました。

以上の変更でも動きはかなり怪しいのですが、とりあえず何かが動くと楽しいですね。
あとは計算式を地道に見直す必要があるかと思います。頑張ってください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/10 11:24

    itaについての説明も含め、数多くの助言ほんとにありがとうございます。ご指摘いただいた個所を直してみると、とりあえずコンパイルはできるようになりました。まだ自分の思うような表示はできていないので、ここから試行錯誤してやってみようと思います。ほんとうにありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • 振り子運動のシミュレーションにおいて、わからないエラーメッセージの意味(とそのデバッグ法)を教えてほしい