合計 昨日 今日

Pythonのファイルのバイト単位でのランダムアクセスについて

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

Name: asd
[URL]
熟練のプログラマー(66,839 ポイント)
Date: 2017年8月01日(火) 21:08
No: 31
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

複数の指摘を書くと1か所にしか反応されなさそうで不安ではありますが、
keito94さんの決心を信じて指摘します。

keito94 さんが書きました:分かりました、書きますね。
コード[C++]: 全て選択
1
2
3
4
5
6
    def load(self,val,byte = 1):
        self.fn.seek(val)
        data = self.fn.read(byte)
        # ここでエラーが出る。
        self.fn.seek(-val)
        return data

のうち、self.fn.seek(-val)が悪さをすることに気づき、
なんとかself.fn.seek(-val)を取り除きました。


えーと、load関数は廃止されたと以下のレスで書いてありましたが、廃止前にやったことの説明でしょうか?
そうであればここは特に触れずに行きますね。

viewtopic.php?f=3&t=19442#p147101

keito94 さんが書きました:あと、get_layerに違和感があることに気づき、


get_layerについては今初めて本文中に登場した気がしますが、
本題とはあまり関係ないものの、ここも直してみたという説明でしょうか?
違和感があることに気づき…どうしたのかはわかりませんが何かしら奮闘されたと理解しておきます。

keito94 さんが書きました:そして、頭を悩ませた以下のエラーの原因もわかりました。
コード[C++]: 全て選択
1
2
3
4
5
6
7
  File "C:/Users/keito940/PycharmProjects/quoyletest/test.py", line 53, in <module>
    main()
  File "C:/Users/keito940/PycharmProjects/quoyletest/test.py", line 41, in main
    map_data = map.data_load()
  File "C:/Users/keito940/PycharmProjects/quoyletest\quoyle\map.py", line 80, in data_load
    map_data[i].append(self.get_pos(1, j, i))
IndexError: list index out of range

マップデータを表す配列が一列しかない上に、存在しない二列目に書き込もうとして以上のエラーが発生している模様です。
解決方法は、新たに二列目の配列を作る必要がある模様です。


というかこちらが本題ですよね?
ようやく本題に戻ってきて安心しました。

keito94 さんが書きました:
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
    def data_load(self):
        map_data = [[]]
        # 開始時の位置を決める。
        for i in range(self.MAP_H):
            for j in range(self.MAP_W):
                if i < 0 and j == 0:
                    map_data.append([self.get_pos(1, j, i)])
                else:
                    map_data[i].append(self.get_pos(1, j, i))
 
        return map_data

ですが、二列目の配列が生成されず、無効な配列を参照しているというエラーが出てしまいます。
どうやって、二列目の配列を生成されるのでしょうか?


その質問に答える前に原因と対応方針が正しいかを確認させてもらうため、いくつか質問しますね。

・「二列目の配列が生成されず…」ということは一列目はきちんと配列が生成されているということでしょうか?
 →実際に一列目だけ読み込まれたことはどうやって確認したのでしょうか?
・上記コードのif文の条件式 i < 0 and j ==0ですがこれは何を期待しての条件式でしょうか?
 →どういう場合にTrueになるつもりで書いていますかを教えてください
・例えばマップチップデータ側が横幅5マス、縦幅2マスだったとして以下のようなデータを読み取った場合、
 生成されることを期待するmap_dataは以下で正しいでしょうか?

マップデータ(5*2マス):0123456789
期待するmap_data:[ [0,1,2,3,4] , [5,6,7,8,9] ]
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: shira211
[URL]
かけだし(1,370 ポイント)
Date: 2017年8月03日(木) 14:25
No: 32
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

いろいろいじってたらこんな出力が得られましたけど、これが今回の目標でいいんですよね?
Offtopic :
MAPファイルはQuoyleで開けない、QMPファイルは画像ファイルへの絶対パスが含まれてUPするのを躊躇う・・・
相対パスで指定出来たら便利そうですけどね
添付ファイル
Quoyle.png
Quoyle.png (20.77 KiB) 表示数: 1021 回

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月04日(金) 19:00
No: 33
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

asd さんが書きました:えーと、load関数は廃止されたと以下のレスで書いてありましたが、廃止前にやったことの説明でしょうか?

正確にはソースコードを廃止前に戻して、
廃止前のエラーを修正したという感じですね。

get_layerについては今初めて本文中に登場した気がしますが、
本題とはあまり関係ないものの、ここも直してみたという説明でしょうか?
違和感があることに気づき…どうしたのかはわかりませんが何かしら奮闘されたと理解しておきます。

はい。その通りです。
違和感に気づく前のコードは、以下のとおりです。
ファイルのアドレスは0から始まるとばかり思っていたのですが、
1から始まることに気づいて修正しました。
コード[C++]: 全て選択
1
2
3
4
5
6
7
    def get_layer(self, index):
        print("レイヤーを読み取ります。")
        # メモリと範囲をチェック
        if self.LAYER_C > index:
            return None
 
        return 15 + self.MAP_W * self.MAP_H * self.bysize * (index-1)

・「二列目の配列が生成されず…」ということは一列目はきちんと配列が生成されているということでしょうか?

はい。

実際に一列目だけ読み込まれたことはどうやって確認したのでしょうか?

Pycharmについているブレークポイントによるデバッグ機能で、調べました。
添付している画像を見てください。
ちなみに画像は1列目の7行目まで来たところです。

・上記コードのif文の条件式 i < 0 and j ==0ですがこれは何を期待しての条件式でしょうか?
 →どういう場合にTrueになるつもりで書いていますかを教えてください

これは、参照するマップが新しい列に来たときに、新しく配列を生成することを期待しての条件式です。
すでに生成されている最初の列でない、なおかつ新しく読み込まれる列のときにTrueになります。

・例えばマップチップデータ側が横幅5マス、縦幅2マスだったとして以下のようなデータを読み取った場合、
 生成されることを期待するmap_dataは以下で正しいでしょうか?

マップデータ(5*2マス):0123456789
期待するmap_data:[ [0,1,2,3,4] , [5,6,7,8,9] ]

はい。その通りです。

shira211 さんが書きました:いろいろいじってたらこんな出力が得られましたけど、これが今回の目標でいいんですよね?

そうです!!それです!!
この一件が解決したらGithubにも上げておきますね!!

MAPファイルはQuoyleで開けない、QMPファイルは画像ファイルへの絶対パスが含まれてUPするのを躊躇う・・・
相対パスで指定出来たら便利そうですけどね


だったら、HSPDecoで、Quoyleを逆コンパイルして、mapファイルを読み込めるようにしてはいかがでしょうか?
調べてみたところ、HSP製のソフトらしいので。Elona(HSP製なことで有名なゲームです。)の解析にも、使われているソフトですよ。

Offtopic :
self.fn.write()とstruct.pack()で、マップファイルの書き込みが実現できるらしいけど、
エラーが出てしまうかもしれない不安があったので却下した(><)
誰か、マップファイルの書き込み機能作って…。
(と言うか、読み込むので精一杯…。)
添付ファイル
Pycharmのスクショ.png
Pycharmのスクショ.png (34.12 KiB) 表示数: 977 回
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: 沖 滉均
[URL]
熟練のプログラマー(50,788 ポイント)
Date: 2017年8月04日(金) 20:10
No: 34
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

ようやく返信がついたようなのでひとつずつ進めていきましょうか
keito94 さんが書きました:
asd さんが書きました:・上記コードのif文の条件式 i < 0 and j ==0ですがこれは何を期待しての条件式でしょうか?
 →どういう場合にTrueになるつもりで書いていますかを教えてください

これは、参照するマップが新しい列に来たときに、新しく配列を生成することを期待しての条件式です。
すでに生成されている最初の列でない、なおかつ新しく読み込まれる列のときにTrueになります。

本当でしょうか?
この部分だけを抜き出して動かしてみるとあなたが期待していない動作をしていることがわかるはずです。

何度言ってもデバッグのやり方がわからないようなので今回は単純な確認用のコードを提示しましょう
マップは例として5x5で設定しています。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
print("data_load関数の条件確認")
map_data = [[]]
print("map_data:{}".format(map_data))
for i in range(5):
    print("i:{}".format(i))
    for j in range(5):
        print("  j:{}".format(j))
        print("    i < 0 and j == 0:{}".format(i < 0 and j == 0))
        if i < 0 and j == 0:
            print("      map_data.append([self.get_pos(1, {}, {}))]".format(j, i))
        else:
            print("      map_data[{}].append([self.get_pos(1, {}, {}))]".format(i, j, i))


コード[Text]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
data_load関数の条件確認
map_data:[[]]
i:0
  j:0
    i < 0 and j == 0:False
      map_data[0].append([self.get_pos(1, 0, 0))]
  j:1
    i < 0 and j == 0:False
      map_data[0].append([self.get_pos(1, 1, 0))]
  j:2
    i < 0 and j == 0:False
      map_data[0].append([self.get_pos(1, 2, 0))]
  j:3
    i < 0 and j == 0:False
      map_data[0].append([self.get_pos(1, 3, 0))]
  j:4
    i < 0 and j == 0:False
      map_data[0].append([self.get_pos(1, 4, 0))]
i:1
  j:0
    i < 0 and j == 0:False
      map_data[1].append([self.get_pos(1, 0, 1))]
  j:1
    i < 0 and j == 0:False
      map_data[1].append([self.get_pos(1, 1, 1))]
  j:2
    i < 0 and j == 0:False
      map_data[1].append([self.get_pos(1, 2, 1))]
  j:3
    i < 0 and j == 0:False
      map_data[1].append([self.get_pos(1, 3, 1))]
  j:4
    i < 0 and j == 0:False
      map_data[1].append([self.get_pos(1, 4, 1))]
i:2
  j:0
    i < 0 and j == 0:False
      map_data[2].append([self.get_pos(1, 0, 2))]
  j:1
    i < 0 and j == 0:False
      map_data[2].append([self.get_pos(1, 1, 2))]
  j:2
    i < 0 and j == 0:False
      map_data[2].append([self.get_pos(1, 2, 2))]
  j:3
    i < 0 and j == 0:False
      map_data[2].append([self.get_pos(1, 3, 2))]
  j:4
    i < 0 and j == 0:False
      map_data[2].append([self.get_pos(1, 4, 2))]
i:3
  j:0
    i < 0 and j == 0:False
      map_data[3].append([self.get_pos(1, 0, 3))]
  j:1
    i < 0 and j == 0:False
      map_data[3].append([self.get_pos(1, 1, 3))]
  j:2
    i < 0 and j == 0:False
      map_data[3].append([self.get_pos(1, 2, 3))]
  j:3
    i < 0 and j == 0:False
      map_data[3].append([self.get_pos(1, 3, 3))]
  j:4
    i < 0 and j == 0:False
      map_data[3].append([self.get_pos(1, 4, 3))]
i:4
  j:0
    i < 0 and j == 0:False
      map_data[4].append([self.get_pos(1, 0, 4))]
  j:1
    i < 0 and j == 0:False
      map_data[4].append([self.get_pos(1, 1, 4))]
  j:2
    i < 0 and j == 0:False
      map_data[4].append([self.get_pos(1, 2, 4))]
  j:3
    i < 0 and j == 0:False
      map_data[4].append([self.get_pos(1, 3, 4))]
  j:4
    i < 0 and j == 0:False
      map_data[4].append([self.get_pos(1, 4, 4))]

いかがですか?あなたの期待通りの動作になっていますか?
さて、この続きはあなたがどう考えるか次第です。
There is no royal road to learning.
[code]タグで指定できる言語
沖の雑記帳

Name: asd
[URL]
熟練のプログラマー(66,839 ポイント)
Date: 2017年8月05日(土) 01:24
No: 35
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

本題は沖さんが回答している通りなので、私はそれ以外を主としてレスします。
(私のレスだけに反応して本題がおろそかにならないよう注意!)

keito94 さんが書きました:
asd さんが書きました:えーと、load関数は廃止されたと以下のレスで書いてありましたが、廃止前にやったことの説明でしょうか?

正確にはソースコードを廃止前に戻して、
廃止前のエラーを修正したという感じですね。


なるほど。そういうことであれば廃止はやめて、load関数方式で行くことにしたと明示してくださいね。
書かれていないことは分からないので、私のように「廃止前の説明かな?」と誤解を招いてしまいます。

keito94 さんが書きました:
asd さんが書きました:get_layerについては今初めて本文中に登場した気がしますが、
本題とはあまり関係ないものの、ここも直してみたという説明でしょうか?
違和感があることに気づき…どうしたのかはわかりませんが何かしら奮闘されたと理解しておきます。

はい。その通りです。
違和感に気づく前のコードは、以下のとおりです。
ファイルのアドレスは0から始まるとばかり思っていたのですが、
1から始まることに気づいて修正しました。


なるほどなるほど。
であれば、何を直したのかを今回のように明示してもらえると助かります。
修正後のソースだけをはるのであれば「○○を△△に直しました」のように説明を付与してもらわないと
何を直したのか分からないままになることがありますので。

keito94 さんが書きました:
asd さんが書きました:実際に一列目だけ読み込まれたことはどうやって確認したのでしょうか?

Pycharmについているブレークポイントによるデバッグ機能で、調べました。
添付している画像を見てください。
ちなみに画像は1列目の7行目まで来たところです。


この図を見るにブレイクポイントを置きながらステップ実行された感じでしょうか?
であれば、その過程でif文の実行順がおかしいと気が付きませんでしたか?

keito94 さんが書きました:
asd さんが書きました:・上記コードのif文の条件式 i < 0 and j ==0ですがこれは何を期待しての条件式でしょうか?
 →どういう場合にTrueになるつもりで書いていますかを教えてください

これは、参照するマップが新しい列に来たときに、新しく配列を生成することを期待しての条件式です。
すでに生成されている最初の列でない、なおかつ新しく読み込まれる列のときにTrueになります。


上記で少し書きましたが、現在のソースでステップ実行してみてその条件でTrueになり期待した通りに動いたでしょうか?
これは沖さんのデバッグのやり方も参考にしておかしな部分を見つけてみましょう。

keito94 さんが書きました:
asd さんが書きました:・例えばマップチップデータ側が横幅5マス、縦幅2マスだったとして以下のようなデータを読み取った場合、
 生成されることを期待するmap_dataは以下で正しいでしょうか?

マップデータ(5*2マス):0123456789
期待するmap_data:[ [0,1,2,3,4] , [5,6,7,8,9] ]

はい。その通りです。


確認ありがとうございます。
ということは上記の例示データでkeito94さんの期待した動きだと以下のようになる感じですね。
(行初めで行全体の配列を追加するイメージ)

map_data:[]
map_data:[[0]] ※行初めなので行全体の配列を追加(if文がTrue時の処理)
map_data:[[0,1]]
~(省略)~
map_data:[[0,1,2,3,4]]
map_data:[[0,1,2,3,4],[5]] ※行初めなので行全体の配列を追加(if文がTrue時の処理)
map_data:[[0,1,2,3,4],[5,6]]
~(省略)~
map_data:[[0,1,2,3,4],[5,6,7,8,9]]

ということでまずは沖さん指摘のif文が自分の期待した通りに判定されているかを確認してみましょう。

Offtopic :
ちなみに私だったらif文を使わずにつくると思います。
混乱させてしまうと思うので、そのやり方は本題が解決した後に余力があれば提示しますね。
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: shira211
[URL]
かけだし(1,370 ポイント)
Date: 2017年8月05日(土) 01:33
No: 36
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

Offtopic :
keito94 さんが書きました:だったら、HSPDecoで、Quoyleを逆コンパイルして、mapファイルを読み込めるようにしてはいかがでしょうか?
調べてみたところ、HSP製のソフトらしいので。Elona(HSP製なことで有名なゲームです。)の解析にも、使われているソフトですよ。

実行例が「目に見える形で」示されていないのが問題だと思って投稿しただけで、Quoyleの仕様に不満があるわけではありませんよ。まあ、Quoyleに同封されているhello.qmpを.mapにコンバートしたものだという予想は付きますし、手元でコンバートしてみてバイナリエディタとかで比べればわかる話ですが、、、それって回答者の仕事じゃないですよね。
(そもそも、読み込みたいのが.qmpなのか.mapなのかも示されてませんね。コードを見ればわかりますし、.qmpを読み込んだってうれしくないので.mapなのだろうとは思いますが、プログラムと、テストデータが投稿されるまでは確証がありませんでした。)

ちなみにNo:32の結果はif文を使わないやり方でやりました。(asdさんと同じなのかな?)
asdさんと同じ理由ですぐには書かないことにしました。

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月07日(月) 13:35
No: 37
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

>>沖さん
たしかに条件満たしているはずなのにTrueなってない!!
でも、デバッグの仕方がようやくわかり始めたから、テスト用のコードの提供はありがたいです!!

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
data_load関数の条件確認
map_data:[[]]
i:0
  j:0
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 0, 0))]
  j:1
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 1, 0))]
  j:2
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 2, 0))]
  j:3
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 3, 0))]
  j:4
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 4, 0))]
i:1
  j:0
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 0, 1))]
  j:1
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 1, 1))]
  j:2
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 2, 1))]
  j:3
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 3, 1))]
  j:4
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 4, 1))]
i:2
  j:0
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 0, 2))]
  j:1
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 1, 2))]
  j:2
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 2, 2))]
  j:3
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 3, 2))]
  j:4
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 4, 2))]
i:3
  j:0
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 0, 3))]
  j:1
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 1, 3))]
  j:2
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 2, 3))]
  j:3
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 3, 3))]
  j:4
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 4, 3))]
i:4
  j:0
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 0, 4))]
  j:1
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 1, 4))]
  j:2
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 2, 4))]
  j:3
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 3, 4))]
  j:4
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 4, 4))]
 
Process finished with exit code 0


shira211 さんが書きました:ちなみにNo:32の結果はif文を使わないやり方でやりました。(asdさんと同じなのかな?)

えっ、if文は使わなくてもできるのですか!?初めて知りました。

>>asdさん
ボクはprintデバッグよりも、GUIのブレークポイント派ではあるのですが、そこまでは気づきませんでした…。
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: 沖 滉均
[URL]
熟練のプログラマー(50,788 ポイント)
Date: 2017年8月07日(月) 14:40
No: 38
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

keito94 さんが書きました:>>沖さん
たしかに条件満たしているはずなのにTrueなってない!!
でも、デバッグの仕方がようやくわかり始めたから、テスト用のコードの提供はありがたいです!!

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
data_load関数の条件確認
map_data:[[]]
i:0
  j:0
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 0, 0))]
  j:1
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 1, 0))]
  j:2
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 2, 0))]
  j:3
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 3, 0))]
  j:4
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 4, 0))]
i:1
  j:0
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 0, 1))]
  j:1
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 1, 1))]
  j:2
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 2, 1))]
  j:3
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 3, 1))]
  j:4
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 4, 1))]
以下略…


表示と実行結果が一致していないですね。
表示されている条件に変えたのであれば下記のようになっているはずです。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
print("data_load関数の条件確認")
map_data = [[]]
print("map_data:{}".format(map_data))
for i in range(5):
    print("i:{}".format(i))
    for j in range(5):
        print("  j:{}".format(j))
        print("    i <= 1 and j == 0:{}".format(i <= 1 and j == 0))
        if i <= 1 and j == 0:
            print("      map_data.append([self.get_pos(1, {}, {}))]".format(j, i))
        else:
            print("      map_data[{}].append([self.get_pos(1, {}, {}))]".format(i, j, i))


コード[Text]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
data_load関数の条件確認
map_data:[[]]
i:0
  j:0
    i <= 1 and j == 0:True
      map_data.append([self.get_pos(1, 0, 0))]
  j:1
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 1, 0))]
  j:2
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 2, 0))]
  j:3
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 3, 0))]
  j:4
    i <= 1 and j == 0:False
      map_data[0].append([self.get_pos(1, 4, 0))]
i:1
  j:0
    i <= 1 and j == 0:True
      map_data.append([self.get_pos(1, 0, 1))]
  j:1
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 1, 1))]
  j:2
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 2, 1))]
  j:3
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 3, 1))]
  j:4
    i <= 1 and j == 0:False
      map_data[1].append([self.get_pos(1, 4, 1))]
i:2
  j:0
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 0, 2))]
  j:1
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 1, 2))]
  j:2
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 2, 2))]
  j:3
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 3, 2))]
  j:4
    i <= 1 and j == 0:False
      map_data[2].append([self.get_pos(1, 4, 2))]
i:3
  j:0
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 0, 3))]
  j:1
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 1, 3))]
  j:2
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 2, 3))]
  j:3
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 3, 3))]
  j:4
    i <= 1 and j == 0:False
      map_data[3].append([self.get_pos(1, 4, 3))]
i:4
  j:0
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 0, 4))]
  j:1
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 1, 4))]
  j:2
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 2, 4))]
  j:3
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 3, 4))]
  j:4
    i <= 1 and j == 0:False
      map_data[4].append([self.get_pos(1, 4, 4))]

まず、rangeの引数については3つの方法があります。
①range(stop)
②range(start, stop)
③range(start, stop, step)
今回は①の指定なので、この場合、startは0(デフォルト値)となるため、iは0~(stop - 1)までの値を取ります。
そう考えると条件がおかしいことに気づくんじゃないでしょうか?

また、今後の話をする上で確認です。
keito94 さんが書きました:
shira211 さんが書きました:ちなみにNo:32の結果はif文を使わないやり方でやりました。(asdさんと同じなのかな?)

えっ、if文は使わなくてもできるのですか!?初めて知りました。

>>asdさん
ボクはprintデバッグよりも、GUIのブレークポイント派ではあるのですが、そこまでは気づきませんでした…。

上記のように、asdさん、shira211さんともにif文を使用しない方法で行なっています。
私も基本的にはif文を使用しない方法がスマートで良い方法だと考えています。(もちろんif文を使ってはいけないということではありません)
そこで、keito94さんはこのままif文を使用した方法で正しい条件を見つける方向ですすめていくのか
if文を使わない方法で進めていくのかを答えてください。

ただし、range関数が取り得る値については必ずドキュメントを読み理解してから先に進むようにしてください
https://docs.python.jp/3/library/stdtypes.html#range

Offtopic :
なお、asdさん、shira211さんへの返答について指摘事項がありますが、一度に色々書くと全部読まないのでこの件が終了後に改めて指摘します
There is no royal road to learning.
[code]タグで指定できる言語
沖の雑記帳

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月07日(月) 15:00
No: 39
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

沖 滉均 さんが書きました:上記のように、asdさん、shira211さんともにif文を使用しない方法で行なっています
私も基本的にはif文を使用しない方法がスマートで良い方法だと考えています。(もちろんif文を使ってはいけないということではありません)
そこで、keito94さんはこのままif文を使用した方法で正しい条件を見つける方向ですすめていくのか
if文を使わない方法で進めていくのかを答えてください。


思えば、if文は面倒なものですね…。自分で条件を探さないといけないですし…。
なのでボクはif文を使わない方法で進めたいと思います。

まず、rangeの引数については3つの方法があります。
①range(stop)
②range(start, stop)
③range(start, stop, step)
今回は①の指定なので、この場合、startは0(デフォルト値)となるため、iは0~(stop - 1)までの値を取ります。
そう考えると条件がおかしいことに気づくんじゃないでしょうか?


ああっ、たしかに!!

Offtopic :
あっちのほうが楽だというのなら、私は迷わずその道を進むわ。
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: 沖 滉均
[URL]
熟練のプログラマー(50,788 ポイント)
Date: 2017年8月07日(月) 16:04
No: 40
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

keito94 さんが書きました:思えば、if文は面倒なものですね…。自分で条件を探さないといけないですし…。
なのでボクはif文を使わない方法で進めたいと思います。

自分で条件を探さないといけないから面倒なのでif文を使用しない方法を取るのは間違いです。
今回は、if文を使用しないでもできるというだけで正しい条件を考えるのは必要なことです。
なにより、今回はrange関数の出力を理解していれば期待動作になっているはずですので
keito94 さんが書きました:ああっ、たしかに!!

と、返答されているからには理解されたんですよね?
このまま先に進めてしまうと、また理解したつもりになってしまうかもしれないので正しい条件の返答を求めます。
その後、if文を使わない方法で進めていきましょう
There is no royal road to learning.
[code]タグで指定できる言語
沖の雑記帳

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月07日(月) 16:43
No: 41
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

>>沖さん
もしかすると、こうではないのでしょうか?
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
    # 以上のライブラリを利用してマップデータをリストに変換するサンプル。
    def data_load(self):
        map_data = []
        # 開始時の位置を決める。
        for i in range(0,self.MAP_H):
            map_data.append([self.get_pos(1, 0, i)])
            for j in range(1,self.MAP_W):
                map_data[i].append(self.get_pos(1, j, i))
 
        return map_data


コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
    print("data_load関数の条件確認")
    map_data = []
    print("map_data:{}".format(map_data))
    for i in range(0,5):
        print("i:{}".format(i))
        print("map_data.append([self.get_pos(1, 0, {}))]".format(i))
        for j in range(1,5):
            print("j:{}".format(j))
            print("map_data[{}].append([self.get_pos(1, {}, {}))]".format(i, j, i))

結果:
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
data_load関数の条件確認
map_data:[]
i:0
map_data.append([self.get_pos(1, 0, 0))]
j:1
map_data[0].append([self.get_pos(1, 1, 0))]
j:2
map_data[0].append([self.get_pos(1, 2, 0))]
j:3
map_data[0].append([self.get_pos(1, 3, 0))]
j:4
map_data[0].append([self.get_pos(1, 4, 0))]
i:1
map_data.append([self.get_pos(1, 0, 1))]
j:1
map_data[1].append([self.get_pos(1, 1, 1))]
j:2
map_data[1].append([self.get_pos(1, 2, 1))]
j:3
map_data[1].append([self.get_pos(1, 3, 1))]
j:4
map_data[1].append([self.get_pos(1, 4, 1))]
i:2
map_data.append([self.get_pos(1, 0, 2))]
j:1
map_data[2].append([self.get_pos(1, 1, 2))]
j:2
map_data[2].append([self.get_pos(1, 2, 2))]
j:3
map_data[2].append([self.get_pos(1, 3, 2))]
j:4
map_data[2].append([self.get_pos(1, 4, 2))]
i:3
map_data.append([self.get_pos(1, 0, 3))]
j:1
map_data[3].append([self.get_pos(1, 1, 3))]
j:2
map_data[3].append([self.get_pos(1, 2, 3))]
j:3
map_data[3].append([self.get_pos(1, 3, 3))]
j:4
map_data[3].append([self.get_pos(1, 4, 3))]
i:4
map_data.append([self.get_pos(1, 0, 4))]
j:1
map_data[4].append([self.get_pos(1, 1, 4))]
j:2
map_data[4].append([self.get_pos(1, 2, 4))]
j:3
map_data[4].append([self.get_pos(1, 3, 4))]
j:4
map_data[4].append([self.get_pos(1, 4, 4))]
 
Process finished with exit code 0


では、今度こそ、ありがとうございました。
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: かずま
[URL]
Date: 2017年8月07日(月) 16:47
No: 42
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

配列の要素の和を求める C のプログラムを、
keito94さんは次のように書くのでしょうか。
普通の人は if文を使わずに書きます。
コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int a[5] = { 1, 2, 3, 4, 5 };
 
int main(void)
{
    int s;
    for (int i = 0; i < 5; i++)
        if (i == 0)
            s = a[0];
        else
            s += a[i];
    printf("和は %d です。\n", s);
    return 0;
}

Name: かずま
[URL]
Date: 2017年8月07日(月) 17:00
No: 43
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

配列の要素の和を求める C のプログラムを、
keito94さんは次のように書くように方針を変えたのでしょうか
コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
 
int a[5] = { 1, 2, 3, 4, 5 };
 
int main(void)
{
    int s = a[0];
    for (int i = 1; i < 5; i++)
        s += a[i];
    printf("和は %d です。\n", s);
    return 0;
}

普通の人は、そうんな風に書かないと思います。

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月07日(月) 19:50
No: 44
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

かずま さんが書きました:普通の人は、そうんな風に書かないと思います。


Pythonだからです。
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: かずま
[URL]
Date: 2017年8月07日(月) 20:53
No: 45
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

keito94 さんが書きました:Pythonだからです。

言語のことを言っているのではありません。
普通は、a[0] を特別扱いしない、ということを言っているのが
分からないようですね。

python で、リストの和なら、sum でしょう。
コード[C++]: 全て選択
1
2
a = [1, 2, 3, 4, 5]
sum(a)

python で、リストのリストを作るなら、
次のように書くのではないでしょうか?
コード[C++]: 全て選択
1
2
3
4
5
6
map_data = []
for i in range(3):
    map_data.append([])
    for j in range(4):
        map_data[i].append(i*10+j)
print(map_data)

実行結果
コード[Text]: 全て選択
1
[[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]

返事をお待ちしております。

Name: asd
[URL]
熟練のプログラマー(66,839 ポイント)
Date: 2017年8月08日(火) 00:08
No: 46
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

すごく一部にしか返信ないのが残念なのと、出遅れた感満載ですが返信してみます。

Offtopic :
shira211 さんが書きました:ちなみにNo:32の結果はif文を使わないやり方でやりました。(asdさんと同じなのかな?)
asdさんと同じ理由ですぐには書かないことにしました。

ご配慮ありがとうございます(*´ヮ`)
同じやり方かなぁ?と気になるところですが、本題解決までお披露目は我慢します(笑)


keito94 さんが書きました:えっ、if文は使わなくてもできるのですか!?初めて知りました。

はい、実際に私の手元ではifは使わない方法で作成したQuoyleMap読み込みクラスがあります。
ちなみに沖さんも書いていますが、if文を使った書き方をまずしてみて、そのうえで

・このif文があるとどういう動きになるのか?
・その動きを実現する上でif文を省略した書き換えができないか?

を考えて書き換えを行います。
慣れている人はこの動きを頭で整理した上でコードに落とし込めるのでif文を使っていないだけで、
脳内では一度if文を使った処理も考えています。

この考え方はサンプルを流し見したり、人のプログラムを写すだけでは身につきません。
きちんと処理を考える必要があるのです。

そういった考え方を身につけてもらえたらなと個人的には思っています。

keito94 さんが書きました:>>asdさん
ボクはprintデバッグよりも、GUIのブレークポイント派ではあるのですが、そこまでは気づきませんでした…。

えぇぇ…。であれば、エラーが出た際にすぐにデバッグできるではないですか…。
以前はそんなこと一言も言ってなかったですよね?

keito94 さんが書きました:>>沖さん
もしかすると、こうではないのでしょうか?

では、今度こそ、ありがとうございました。

ちゃんと動いたのかどうかを確認するのもデバッグですよ。
「こうですか?」ではなくそれで正しく動いたことをきちんと示してください。
そうしないと早合点で解決にしてしまうことになりますよ?

添付した画像は実行例ですが、私はPyGameを使っていなかったのでCUI出力で検証してます。
配置ウィンドウにあるのがpack.qmpで、コマンドプロンプトにそれを読み込んだ結果をマップチップのコードを出力してみました。
(0が何もないところ、1が壁のつもりで作ってみました。混乱させるといけないのでレイヤーはまだ考慮していません)

ここまできっちり提示しましょうとは言いませんが、何をもって正しくできたと判断したのかは提示してくださいね。
実はたまたま動いているだけで問題があるみたいなこともあり得るので。
添付ファイル
無題3.png
QuoyleMapクラス動作確認例
無題3.png (20.96 KiB) 表示数: 557 回
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月08日(火) 13:42
No: 47
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

かずま さんが書きました:言語のことを言っているのではありません。
普通は、a[0] を特別扱いしない、ということを言っているのが
分からないようですね。


ごめんなさい、a[0]は特別扱いしないんですね…。

>> asdさん
ちょっと暴論を吐いてしまった…。

ここまできっちり提示しましょうとは言いませんが、何をもって正しくできたと判断したのかは提示してくださいね。
実はたまたま動いているだけで問題があるみたいなこともあり得るので。


そうでした。デバッグ画面を見ればわかると思いますが、QuoyleMapは正しく動いてますが、
Pygameの画面に画像が表示されてません。
簡単なミスかもしれませんが…。
添付ファイル
QuoyleMapクラスは正しく動いたが….PNG
QuoyleMapクラスは正しく動いたが….PNG (39.79 KiB) 表示数: 464 回
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: asd
[URL]
熟練のプログラマー(66,839 ポイント)
Date: 2017年8月08日(火) 15:33
No: 48
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

keito94 さんが書きました:>> asdさん
ちょっと暴論を吐いてしまった…。


暴論というより説明不足というか、早合点というか…。
結局if文は使わない形で行くようですが、先の回答にも書いた通りif文を使った場合の正しい書き方(処理)を考えることは有用です。
if文を使った場合はどのように書くのが正解だったのかは考えるようにしてくださいね。

keito94 さんが書きました:そうでした。デバッグ画面を見ればわかると思いますが、QuoyleMapは正しく動いてますが、
Pygameの画面に画像が表示されてません。
簡単なミスかもしれませんが…。


ですから、その「QuoyleMapは正しく動いていることを確認し、Pygameの画面に画像が表示されない原因を見つけ修正すること」がデバッグですよ。
読み込まれたmap_dataが正しいかどうかは元のマップデータを私は知らないので確認しようがありません。keito94さん自身で確認してみてください。

その上で読み込まれているmap_dataは正しいものとして考えると調べるべき箇所は、

・imageList[40]、imageList[34]には正しいデータが格納されているか
・screen.blit行の部分の処理は正しいか
 →imageList[40]やimageList[34]を指定した場合は描画されるか
  imageList[chip]の代わりに別の画像を指定した場合は描画されるか

などが考えられます。
その上でどういう場合に成功してどういう場合に失敗するかを絞り込み、意図せず失敗するパターンを修正するのがデバッグです。

少なくとも原因箇所の特定と不具合発生の条件の絞り込みはそろそろ自力でできるようになりましょう。
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: 沖 滉均
[URL]
熟練のプログラマー(50,788 ポイント)
Date: 2017年8月08日(火) 17:07
No: 49
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

もう答え書かれてしまっていますし、表示されない原因だけ言いますよ
QuoyleMapが正しく動いていることが前提として
画面を更新していないので表示されないのは当たり前です
マップのサンプルではなく、以前のコードでは画面を更新していましたよ
画面の更新方法は自分の過去のコードから探せばいいんじゃないですかね
There is no royal road to learning.
[code]タグで指定できる言語
沖の雑記帳

Name: keito94
[URL]
プログラマー(30,585 ポイント)
Date: 2017年8月08日(火) 18:54
No: 50
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

沖 滉均 さんが書きました:もう答え書かれてしまっていますし、表示されない原因だけ言いますよ
QuoyleMapが正しく動いていることが前提として
画面を更新していないので表示されないのは当たり前です
マップのサンプルではなく、以前のコードでは画面を更新していましたよ
画面の更新方法は自分の過去のコードから探せばいいんじゃないですかね


しまった、簡単なことにも気づかなかった!!
つい最近までここにたくさんの言い訳を書いていたもんだよ…。
でも、今は自分の傲慢すぎる態度に(ようやく)気づいて改めようと決心しました。
プログラマーの心得:
①困ったら誰かに報連相。(ここはリアルでも重要)
②エラーが出たらすぐ質問せずに調べよう。
③原因が特定できない時はブレークポイントなり、printデバッグなりしよう。
④よく検討してから質問しよう。
⑤返事してくれたみんなにはお礼を言おう。
⑥上の5つを心に留めておこう。

Name: asd
[URL]
熟練のプログラマー(66,839 ポイント)
Date: 2017年8月09日(水) 19:42
No: 51
(OFFLINE)

 Re: Pythonのファイルのバイト単位でのランダムアクセスについて

Offtopic :
asd さんが書きました:ちなみに私だったらif文を使わずにつくると思います。
混乱させてしまうと思うので、そのやり方は本題が解決した後に余力があれば提示しますね。

本題については解決したようなので、棚上げしていた私の実装方法を提示して書き込みを終えたいと思います。
マップ読み込み部分だけ抜粋していますが、1行分のリスト_tmprowをまず作りそれをマップ全体のリスト__MAP_DATAに追加することでリストのリストを作成していました。
質問者のコードでは途中で方針転換して空のリストを追加してからそこに1行分のデータを追加するようになっていましたが、いずれの方法でもif文は不要ですね。
コード[C++]: 全て選択
1
2
3
4
5
6
7
            # マップ読み込み
            self.__MAP_DATA = []
            for row in range(self.__MAP_H):
                _tmprow = [] # 1行分のリスト
                for col in range(self.__MAP_W):
                    _tmprow.append(unpack('b', f.read(1))[0])
                self.__MAP_DATA.append(_tmprow)

作成したクラス全体をあげようか迷いましたがやめておきます。
Advanced Supporting Developer
無理やりこじつけ(ぉ

1つ前へ

Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[7人]