• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Pythonのプログラムが狙い通りに動きません)

Pythonプログラムが狙い通りに動かない

このQ&Aのポイント
  • 学習目的で組んだPythonプログラムが予想とは異なる結果を出力し、メモリーエラーが発生しています。
  • プログラムは入力フォームを表示し、指定範囲の数の中に含まれる素数の数を確率的に予測するものです。
  • しかし、試行錯誤を重ねても想定外の結果が出力されたり、メモリ不足のエラーが発生しています。

質問者が選んだベストアンサー

  • ベストアンサー
  • _kappe_
  • ベストアンサー率68% (1524/2218)
回答No.6

回答No.3、4で間違った指摘をしてしまったので、プログラムを書き直してみました。全角空白を使って字下げをしているので、適宜置き換えてから実行してください。 def sosuu_kuzi(trials):  total = 0  for cnt in range(trials):   from random import randint   a_num = randint(2,search_range)   for num in range(2,a_num):    if a_num % num == 0:     break   else:    total += 1  print((total * 100 / trials), "%") sosuu_kuzi(10000) このプログラムでsearch_rangeの値を1000とすると、17.35 %のような出力が得られました。乱数のために毎回結果は変わります。 sosuu_kuziの引数は試行回数です。 while True:による無限ループは消しています。 a_numが素数だったときにリストにappendする必要を感じなかったので、単純にtotalでカウントするようにしました。

hf-sbf5
質問者

お礼

親切な回答をありがとうございます。 早速修正してみます!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

  • _kappe_
  • ベストアンサー率68% (1524/2218)
回答No.5

回答No.3、4の者です。 私が字下げを勘違いしていたようです。質問文で意図していたのは for num in range(2,a_num):  if a_num % num == 0:   break  else:   list_num.append(1%1000) ではなくて for num in range(2,a_num):  if a_num % num == 0:   break else:  list_num.append(1%1000) (else:はifではなくてforに対応する) だったんですね。 これがあるからこのサイトでPythonは扱いづらい。

hf-sbf5
質問者

お礼

ありがとうございます。 質問するときは、インデント部にアンダーバーを入れた方が良さそうですね。

全文を見る
すると、全ての回答が全文表示されます。
  • _kappe_
  • ベストアンサー率68% (1524/2218)
回答No.4

回答No.3について一つ訂正です。 ・num=5のとき、a_num%5=0なので... と書きましたが、a_numが5のときnumの値は4で終わりで、5になることはありませんでした。失礼しました。

hf-sbf5
質問者

お礼

お礼が遅れた申し訳ありません。 回答ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • _kappe_
  • ベストアンサー率68% (1524/2218)
回答No.3

>いくら調べても試行錯誤しても間違った結果が >出力される原因が見つからなかったんです。 おかしな点は多々ありそうですが、ひとまずこの部分だけ。 for num in range(2,a_num):  if a_num % num == 0:   break  else:   list_num.append(1%1000) a_numが素数のときにlist_numに追加したいのかなと想像しますが、具体的な数字で順番に考えてみてましょう。 たとえばa_numが5だとすると ・num=2のとき、a_num%2=1なのでlist_numに追加 ・num=3のとき、a_num%3=2なのでlist_numに追加 ・num=4のとき、a_num%4=1なのでlist_numに追加 ・num=5のとき、a_num%5=0なのでbreakでfor num in range(2,a_num)のループを抜ける となって、list_numに3回も追加されてしまいました。a_numが17なら15回追加されます。 一方で、a_numが2のときにはlist_numに1回も追加しないままループを抜けてしまいます。 この動きは意図通りですか?

hf-sbf5
質問者

お礼

お礼が遅れた申し訳ありません。 回答ありがとうございました。

hf-sbf5
質問者

補足

回答ありがとうございます!早速修正してみます。 そういえば、このプログラムは「みんなのPython」 という参考書の第4版のサンプルコード(144ページ) を元に書いたんですが、そこの説明文には 「このプログラムにある else 以下のブロックは、  break 文が実行されずにループを抜けたとき  にのみ実行されます。」と書いてありました。 (以下にサンプルコードの内容を示しました。) a_num = 59 for num in range(2, a_num):  if a_num % num == 0: print(a_num,”は素数ではありません”)   break else:  print(a_num,”は素数です”) では、以下のサンプルコードで、a_num = 25 と書き換えて実行した場合、 "25は素数です" (2で割った余りが1なので) "25は素数です" (3で割った余りが1なので) "25は素数です" (4で割った余りが1なので) "25は素数ではありません" (5で割った余りが0なので、              ここで初めて break 文が実行) という結果にならないのはなぜですか?

全文を見る
すると、全ての回答が全文表示されます。
  • asciiz
  • ベストアンサー率70% (6650/9426)
回答No.2

いろいろ問題があります。 while True で開始しているなら、どこかに break でもないとループを抜けられませんが、このプログラムに一つだけある break は for を抜けるのみなので、whileループは永遠に終了しません。 > list_num.append(1%1000) %演算子は、剰余です。なので 1%1000 は常に1です。 なので、あなたの >そうでなければ(1/1000 ) を加える この考えとは食い違っています。 そして再度こちら、 > list_num.append(1%1000) 永遠に脱出しないループ内で、list_num リストを増やし続けているので、最後にはメモリを食い尽くします。 それが「メモリ不足」というエラーとなって表示されました。 ---- まあ本質的には、while True でなく、いつかは必ず終了する条件でループするのが良いと思います。

hf-sbf5
質問者

お礼

親切な回答をありがとうございます。 勉強になりました。

hf-sbf5
質問者

補足

皆さんのおかげで、ループ文に関する理解は深まったんですが、 僕が本当に困っていたのは絶対におかしい結果が出力される事だったんです。 (質問文にしっかり書いておくべきでしたね…) 質問分が分かりにくくて申し訳ないんですが、 絶対ありえない結果が表示されるというのは、例えば 1~100までの数の中から素数を探したのに、45.112 といった風に出力される事を言っていました。 1~100 までの数の中には25個の素数があるので、25.355 といった結果が返ってこないと狙い通りに動いたとは言えないのです。 なお、何もエラーが出ないプログラム自体は前回僕が質問した時に 回答者様のおかげで作れたんですが、あの時から いくら調べても試行錯誤しても間違った結果が 出力される原因が見つからなかったんです。 前回の質問のページのURL:https://okwave.jp/qa/q9745091.html

全文を見る
すると、全ての回答が全文表示されます。
  • okwavey4
  • ベストアンサー率18% (99/546)
回答No.1

ろくに見てはいないけど、無限ループの処理があるから、どんなケースでも必ずループを抜けるのか確認すべきだと思いました。 >絶対おかしいと思うんですが… そんなことないですよ。 質問内容が技術者とは思えませんが、カテゴリー名見落としてますし、エラーメッセージの方が信頼できます。

hf-sbf5
質問者

お礼

回答ありがとうございます。 質問のカテゴリは 学問→応用科学→情報工学 にすればいいですか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VB2005で、Structureの配列を返すプログラムを以下のように書きたい

    VB2005で、Structureの配列を返すプログラムを以下のように書きたいのですが、そもそもVB6しか使ったことが無いもので、以下のような素数の結果を返すこのプログラムの書き方はVB2005らしいでしょうか? Module Module1 Public Structure SosuuStatus Public num As Integer Public status As String End Structure Class Sosuu Function SosuuCheck(ByVal st As Integer, ByVal ed As Integer) As SosuuStatus() Dim i As Integer, j As Integer Dim sosuu(0 To ed - st) As SosuuStatus Dim cnt As Integer = 0 For i = st To ed sosuu(cnt).num = i sosuu(cnt).status = "" '初期化 If 1 = i Then sosuu(cnt).status = "素数ではない" ElseIf 0 = (i Mod 2) Then sosuu(cnt).status = "素数ではない" Else For j = 3 To Math.Sqrt(ed) If 0 = (i / j) Then sosuu(cnt).status = "素数ではない" End If Next j End If If sosuu(cnt).status = "" Then sosuu(cnt).status = "素数である" End If cnt = cnt + 1 Next i SosuuCheck = sosuu End Function End Class End Module

  • python リストのプログラムがうまくいかない

    閲覧ありがとうございます。 学校の講義にてgoogle colaboでpythonを使っています。 課題 複数の記事を読み込んで、行を記事、単語を列とした単語数カウントの行列を作成せよ (ファイルは 単語:単語数 単語:単語数... で、行末尾にnegativeとなっていて、1行に1記事ずつ入っている) import numpy as np import matplotlib.pyplot as plt with open('/content/drive/MyDrive/train.processed') as f: articles = f.readlines() # 記事を読み込む list_articles = [] # 記事単位のリスト list_words = [] # 単語単位のリスト list_count = [] # 単語数カウントの行列 x = len(articles) for article in articles: list_articles.append(article.split()) # 記事ごとに[単語:単語数]で配列に入れる(二次元) for i in range(x): # x=記事数 for j in range(len(list_articles[i])-1): # negativeを除いた1記事当たりの単語数 if not '::' in list_articles[i][j]: # 単語として[:]があるとバグるのでない場合のみ処理を行う(::3みたいになってる) col = list_articles[i][j].find(':') # 単語と単語数の間の:の位置を求める word = list_articles[i][j][:col] # コロン未満(単語部分)をwordに代入する if not word in list_words: # list_wordsにない場合、追加する list_words.append(word) list_count.append([0 for k in range(x)]) # 記事数分のリストを追加する(行列に1行追加) list_count[i][list_words.index(word)] = int(list_articles[i][j][col+1:]) # 何記事目かを行、何の単語かを列として単語数を代入 print(word) list_count[i][list_words.index(word)] = int(list_articles[i][j][col+1:]) ここでIndex out of rangeが出ます。print(word)で途中まで出力されるので、エラーが起きながら動いていたのか、途中でエラーが起きて止まったのかもわかりません。 色付きのプログラムを写真に添付します。 かなり時間をかけて考えたのですが、理解できなかったので質問させていただきました。 よろしくお願いします。

  • python ですが下記のプログラムがエラーになり

    python ですが下記のプログラムがエラーになります。どうしてでしょうか。よろしくお願い致します。 def revers(data): for index in range(len (data)-1,-1,-1): yield data[index] some_list = [‘a’, ‘b’, ‘c’, ‘d’] for e in revers(some_list): print(e) 実行結果をd      c      b      a にしたいのですがエラーがでます。

  • Pythonの機械学習のコードでエラーが消えません

    https://www.youtube.com/watch?v=L4f6KGgX4xI 上の動画を元にプログラムを書き、 部分ごとに分割して動作させてみたりして エラーを消していったんですが、最後に残った ---> 60 elif total_list[odd]-total_list[even] < 0: 61 delta_gosa = total_list[odd]-total_list[even]#誤差の合計の変化量を出すため、total_list を使う。 62 h += 0.001 * abs(delta_gosa) IndexError: list index out of range というエラーがどうしても消えません。 h = 0 n = 1 total_list = [] という部分より上の部分はエラーが出ずに動く事を確認し、 次にこの部分以下と同じ構造のループを持つ文を書いた時に上手くいったのに、 これらをつなげて動かすとエラーメッセージが出てきます。 (インデントは全角スペースで表現しています) def random_leaner():  gari_highth_list = []  gari_mass_list = []  gari_num = len(gari_mass_list)  debu_highth_list = []  debu_mass_list = []  debu_num = len(debu_mass_list)  for i in range(90):   from random import randint   highth = randint(130,190)   mass = randint(30,90)   if highth/mass > 17/5 :    gari_highth_list.append(highth)    gari_mass_list.append(mass)   else:    debu_highth_list.append(highth)    debu_mass_list.append(mass)  gari_highth_max = max(gari_highth_list)#ガリの高さ最大値と体重最大値が同じになるよう補正  gari_mass_max = max(gari_mass_list)  k_for_gari = gari_highth_max / gari_mass_max  debu_highth_max = max(debu_highth_list)#デブの高さ最大値と体重最大値が同じになるよう補正  debu_mass_max = max(debu_mass_list)  k_for_debu = debu_highth_max / debu_mass_max  h = 0  n = 1  total_list = []  big_num = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000  for tnt in range(1,big_num): # while True にしたかったんですが、繰り返し変数を利用したかったので big_num で代用します。   odd = 2*tnt-3   even = 2*tnt-4   gari_GOSA_total = 0   for num in range(0,gari_num+1):    #(190ー背の高さ)+(90-体重の重さ)を出し、nを掛けて h”を”引いている    gari_GOSA = (280 - gari_highth_list[num] - gari_mass_list[num]*k_for_gari)*n - h    gari_GOSA_total += gari_GOSA   debu_GOSA_total = 0   for num in range(0,debu_num+1):    #(190ー背の高さ)+(90-体重の重さ)を出し、nを掛けて h”から”引いている    debu_GOSA = h - (280 - debu_highth_list[num] - debu_highth_list[num]*k_for_debu)*n    debu_GOSA_total += debu_GOSA   total_list.append(gari_GOSA_total + debu_GOSA_total)   if tnt == 1:# hを少し変化させ、誤差の合計が減ったかどうか調べる。    h += 0.001    n += 0.001   elif total_list[odd]-total_list[even] < 0:    delta_gosa = total_list[odd]-total_list[even]#誤差の合計の変化量を出すため、total_list を使う。    h += 0.001 * abs(delta_gosa)    n += 0.001 * abs(delta_gosa)   elif total_list[odd]-total_list[even] > 0:    delta_gosa = total_list[odd]-total_list[even]    h -= 0.001 * abs(delta_gosa)    n -= 0.001 * abs(delta_gosa)   else:    print(h,n)    print(gari_highth_list)    print(total_list)    break random_leaner()

  • あるプログラムの結果がうまく表示されません

    以下のプログラムを書いたのですが、結果が正確に表示されません。 どこが間違っているのでしょうか? プログラムの内容は10個の整数を入力し、更に入力した数字で割れる個数を表示するものです。 #include <stdio.h> void input_i(int *in, int num); int div_enable(int *in, int num, int divisor); int main(void) { int array[10]; int i, s_num; input_i(array, 10); scanf("%d", &s_num); i = div_enable(array, 10, s_num); printf("%d\n", i); return 0; } void input_i(int *in, int num) { int i; for(i=0; i<num; i++){ scanf("%d", in+1); } } int div_enable(int *in, int num, int divisor) { int cnt, i; cnt = 0; for(i=0; i<num; i++) { if(in[i]%divisor == 0){ cnt++; } } return cnt; }

  • Javaのプログラムで・・・

    Javaのプログラムで1~20までの整数乱数を実行後に指定回数だけ発生させ、そのうち何%が奇数であったかを表示するプログラムを作成中です。 乱数を発生させるところまでは行ったのですがここからどのように計算していくのかわかりません。 以下が作成したものですがアドバイスお願いします。 import java.io.*; public class Rand { public static void main(String args[]) throws IOException { System.out.print("発生させる乱数の回数は?"); BufferedReader br= new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); int num= Integer.parseInt(str); for(int i=1;i<=num;i++){ int a=(int)(20*Math.random()+1); System.out.println(a); } for(int a=1; a<=;a++){ if(a%2==1); System.out.println("発生した乱数の"++"%が奇数です。"); } } }

  • pythonのリスト代入が分かりません。

    pythonの独学をしていまして、 参考書の練習問題を解こうとした際に、 下記のようにプログラムを書いた際に、Temp_new=Temp とリストにリストを代入させた後に、片方だけリストの一部を変更させた際に、両方ともに変更が適応されてしまい、なぜそうなるの分かりません。どなたかどうしてこうなるのかご存じでしょうか? temp=[] temp_new=[] d_time=[8,9,10] cnt=0 for n in d_time: d_add=int(input('Please type temparation data >>')) temp.append(d_add) print('{} o\'clock temparation is {}'.format(d_time[cnt],d_add)) cnt+=1 temp_new=temp temp_new[1]='N/A' print('temp={}'.format(temp)) print('temp_new={}'.format(temp_new)) ※添付ファイルの黄色部分を変えた気が無いのですが、 なぜか変わってしまいます。

  • プログラムの改良

    文章を単語毎に分割するプログラムを作っています。 下記のプログラムだと I□am□a□boy. の場合、Iとamとaとboyと.に分割され、ここまではいいのですが。 さらにI□am□□a□□□boy□.とスペースが余計に入ってしまってる文章の場合に、Iとamと□aと□□boyと□. と表示させたいのですがどう改良したらいいのか分かりません。 下記のプログラムだとI□am□□a□□□boy□.はIとamとaとboyと.になってしまいます。 どなたかプログラムの追加を教えていただけないでしょうか。□はスペース一個を表しております。 #include <stdio.h> int main() { int i,key,len,num ; char str[256],*ptr[128] ; num = 0 ; len = 0 ; ptr[0] = str ; do { key = getchar(); str[len] = (char)key ; if ( key == ' ' || key == '.' || key == ',' || key == '!' || key == '?' || key == '"' || key == 0x0a || key == 0x0d ){ str[len] = '\0' ; if ( str+len-ptr[num] ){ num ++ ; } ptr[num] = str+len+1 ; if( key=='.' || key== '!' || key=='?' || key=='"'){ str[++len]=(char)key; str[++len]='\0'; ptr[++num]=&str[len+1]; } } len ++ ; } while ( key != 0x0a && key != 0x0d && len < 255 ); str[255] = '\0' ; for (i=0 ;i<num ;i++){ printf("%d. %s\n",i+1,ptr[i]); } return i ; }

  • このプログラムを改良したい

    この単語分割プログラムを区切り文字である( . ? ! " )等も一つの単語として表示させたいのですが、どう改良したらいいかわかりません。 どなたかプログラムの追加削除を教えていたたけないでしょうか。 #include <stdio.h> int main() { int i,key,len,num ; char str[256],*ptr[128] ; num = 0 ; len = 0 ; ptr[0] = str ; do { key = getchar(); str[len] = (char)key ; if ( key == ' ' || key == '.' || key == ',' || key == '!' || key == '?' || key == '"' || key == 0x0a || key == 0x0d ){ str[len] = '\0' ; if ( str+len-ptr[num] ){ num ++ ; } ptr[num] = str+len+1 ; } len ++ ; } while ( key != 0x0a && key != 0x0d && len < 255 ); str[255] = '\0' ; for (i=0 ;i<num ;i++){ printf("%d. %s\n",i+1,ptr[i]); } return i ; } *教えてgoo 質 問 No.919881 arukamunさんのプログラムを引用しました。

  • python超初心者です(3時間目)。pythonで以下のようなランダ

    python超初心者です(3時間目)。pythonで以下のようなランダム数列を生成させるにはどうしたらいいのでしょうか? 最終結果のイメージ(16進数8桁の数列x20行): 0 : c39a29eb 1 : b26cc9bb 2 : 4c494e47 ... 19: 93c85836 以下のようにコードを組んでみたのですが、 > tmp = ws.join(list) > TypeError: sequence item 0: expected string, int found のようなエラーが出てしまいます。どうやら数字を連結しようとしてるのでダメなのかな?と思っています。 ======================================== #! /usr/bin/python import random list = [] ws = "" for i in range (20): print i, ":", for j in range(8): list.append(random.randint(0,15)) tmp = ws.join(list) print tmp list = [] tmp = "" ======================================== ※ printでは必ずスペースが入ってしまうので、それを嫌う場合配列に入れて、要素を連結させなくてはならない、とwebにあったので、その方向で試してみました。 ※ また、ここではあくまでrandom を使用し、一文字(0,1,2,...E,F)づつ出力させたいと思っています。 なお、perlでは以下のように書くことができたのですが... ======================================== #! /usr/bin/perl for($i=0; $i<20; $i++){ printf ("%-02s: ", $i); for($j=0; $j<8; $j++){ printf("%x", int(rand(15)) ); } print "\n"; } ======================================== ※ んー第二言語としてpythonを学習してみていますが道のり険しそうです(やっぱrubyにしようか)... 宜しくお願い致します。