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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

386閲覧

AttributeErrorがでてしまう

takatoyo

総合スコア13

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/01/17 16:38

前提・実現したいこと

麻雀の初心者支援を行うアプリケーションを作成しています。
点数計算を行うプログラムを作成中にエラーが発生しました。
点数計算を行う部分は一度テストプログラムとして作成し問題なく動作したので本プログラムに合体させたところ、エラーが発生しました。
どうかご教授お願い致します。

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

アプリ起動→点数計算器
で手牌とアガリ牌を入力すると以下のエラー文が表示されてしまいます。

all_tiles_136 = tile.TilesConverter.one_line_string_to_136_array(all_tiles) AttributeError: 'str' object has no attribute 'TilesConverter'

該当のソースコード

Python

1import numpy as np 2import cv2 3import PIL.Image,PIL.ImageTk 4import tkinter as tk 5from pickle import TRUE 6from mahjong import agari, constants, shanten, tile 7from mahjong.hand_calculating import hand, hand_config 8import fire 9import copy 10 11 12##### PATH設定 13MAHJONG_TILES_PATH = 'C:\\university\\guraduation research\\pai_images\\' # 麻雀牌画像パス 14PATH_DELIMITER = '\\' 15 16### 定数定義 17Mahjong_tiles_types = ['ji1','ji2','ji3','ji4','ji5','ji6','ji7','ji1y','ji2y','ji3y','ji4y','ji5y','ji6y','ji7y', 18 'man1','man2','man3','man4','man5','man6','man7','man8','man9','man1y','man2y','man3y','man4y','man5y','man6y','man7y','man8y','man9y', 19 'pin1','pin2','pin3','pin4','pin5','pin6','pin7','pin8','pin9','pin1y','pin2y','pin3y','pin4y','pin5y','pin6y','pin7y','pin8y','pin9y', 20 'sou1','sou2','sou3','sou4','sou5','sou6','sou7','sou8','sou9','sou1y','sou2y','sou3y','sou4y','sou5y','sou6y','sou7y','sou8y','sou9y','yohaku'] 21tile_images = {} 22for tile in Mahjong_tiles_types: 23 tile_images[tile] = cv2.imread(MAHJONG_TILES_PATH + tile + '.png', cv2.IMREAD_COLOR) 24tehai = cv2.hconcat([tile_images['man1'],tile_images['man2'],tile_images['man3'],tile_images['pin4'],tile_images['pin5'],tile_images['pin6'],tile_images['sou1'],tile_images['sou1'],tile_images['sou7'],tile_images['sou8'],tile_images['sou9'],tile_images['ji1'],tile_images['ji1'],tile_images['ji1'],]) 25ji_tiles = cv2.hconcat([tile_images['ji1'],tile_images['ji2'],tile_images['ji3'],tile_images['ji4'],tile_images['ji5'],tile_images['ji6'],tile_images['ji7'],tile_images['yohaku'],tile_images['yohaku']]) 26man_tiles = cv2.hconcat([tile_images['man1'],tile_images['man2'],tile_images['man3'],tile_images['man4'],tile_images['man5'],tile_images['man6'],tile_images['man7'],tile_images['man8'],tile_images['man9']]) 27pin_tiles = cv2.hconcat([tile_images['pin1'],tile_images['pin2'],tile_images['pin3'],tile_images['pin4'],tile_images['pin5'],tile_images['pin6'],tile_images['pin7'],tile_images['pin8'],tile_images['pin9']]) 28sou_tiles = cv2.hconcat([tile_images['sou1'],tile_images['sou2'],tile_images['sou3'],tile_images['sou4'],tile_images['sou5'],tile_images['sou6'],tile_images['sou7'],tile_images['sou8'],tile_images['sou9']]) 29suuhai = cv2.vconcat([man_tiles,pin_tiles,sou_tiles]) 30mahjong_tiles = cv2.vconcat([ji_tiles,man_tiles,pin_tiles,sou_tiles]) 31ji_tiles = cv2.hconcat([tile_images['ji1'],tile_images['ji2'],tile_images['ji3'],tile_images['ji4'],tile_images['ji5'],tile_images['ji6'],tile_images['ji7']]) 32chunchanpai_man = cv2.hconcat([tile_images["man2"],tile_images["man3"],tile_images["man4"],tile_images["man5"],tile_images["man6"],tile_images["man7"],tile_images["man8"]]) 33chunchanpai_pin = cv2.hconcat([tile_images["pin2"],tile_images["pin3"],tile_images["pin4"],tile_images["pin5"],tile_images["pin6"],tile_images["pin7"],tile_images["pin8"]]) 34chunchanpai_sou = cv2.hconcat([tile_images["sou2"],tile_images["sou3"],tile_images["sou4"],tile_images["sou5"],tile_images["sou6"],tile_images["sou7"],tile_images["sou8"]]) 35chunchanpai = cv2.vconcat([chunchanpai_man,chunchanpai_pin,chunchanpai_sou]) 36 37OPT_RULES = hand_config.OptionalRules(has_open_tanyao=True) 38WIND_STR2CONST = {"EAST": constants.EAST, 39 "SOUTH": constants.SOUTH, 40 "WEST": constants.WEST, 41 "NORTH": constants.NORTH} 42WIND_STR2CHARA = {"EAST": "東", 43 "SOUTH": "南", 44 "WEST": "西", 45 "NORTH": "北"} 46 47def agari_analyzer_btn_click(): #点数計算器 48 global frame 49 main_frame.destroy() 50 frame = tk.Frame(root) 51 root.title("点数計算器") 52 frame.grid(column=0, row=0, sticky=tk.NSEW, padx=5, pady=10) 53 global entry_all_tiles 54 global entry_win_tile 55 entry_all_tiles = tk.Entry(frame) 56 entry_win_tile = tk.Entry(frame) 57 button_execute = tk.Button(frame, text="点数を計算する", command=analyze) 58 59 label = tk.Label(frame, text="アガリ形") 60 label.grid(row=0, column=0) 61 entry_all_tiles.grid(row=0, column=1) 62 entry_win_tile.grid(row=1, column=1) 63 button_execute.grid(row=2, column=1) 64 65 entry_all_tiles.insert(tk.END,"アガリ形") 66 entry_win_tile.insert(tk.END,"アガリ牌") 67 68def __analyze(all_tiles, win_tile, player_wind, round_wind, **hand_confs): 69 all_tiles_136 = tile.TilesConverter.one_line_string_to_136_array(all_tiles) 70 all_tiles_34 = tile.TilesConverter.one_line_string_to_34_array(all_tiles) 71 win_tile_136 = tile.TilesConverter.one_line_string_to_136_array(win_tile)[0] 72 player_wind = player_wind.upper() 73 round_wind = round_wind.upper() 74 player_wind_136 = WIND_STR2CONST[player_wind] 75 round_wind_136 = WIND_STR2CONST[round_wind] 76 all_hand_confs = copy.copy(hand_confs) 77 all_hand_confs["player_wind"] = player_wind_136 78 all_hand_confs["round_wind"] = round_wind_136 79 config = hand_config.HandConfig(options=OPT_RULES, **all_hand_confs) 80 sh_obj = shanten.Shanten() 81 sh_res = sh_obj.calculate_shanten(all_tiles_34) 82 ag = agari.Agari() 83 if not ag.is_agari(all_tiles_34): 84 return (sh_res, None) 85 else: 86 calc = hand.HandCalculator() 87 hand_res = calc.estimate_hand_value(tiles=all_tiles_136, 88 win_tile=win_tile_136, 89 config=config) 90 wind = "{}場{}".format(WIND_STR2CHARA[round_wind], WIND_STR2CHARA[player_wind]) 91 han_fu = "{} 飜 {} 符".format(hand_res.han, hand_res.fu) 92 if hand_res.han <= 5: 93 basic_score = hand_res.fu * 2 ** (hand_res.han + 2) 94 if basic_score > 2000: 95 gan = "満貫" 96 else: 97 gan = "" 98 elif hand_res.han <= 7: 99 gan = "跳満" 100 elif hand_res.han <= 10: 101 gan = "倍満" 102 elif hand_res.han <= 12: 103 gan = "三倍満" 104 else: 105 n = hand_res.han // 13 106 if n == 1: 107 gan = "役満" 108 else: 109 gan = "{} 倍役満".format(n) 110 111 is_tsumo = hand_confs.get("is_tsumo", False) 112 is_dealer = player_wind == "EAST" 113 if hand_res.han < 1: 114 all_cost = "1 飜縛りを満たしていません" 115 elif is_tsumo: 116 if is_dealer: 117 all_cost = "{} 点 オール".format(hand_res.cost["additional"]) 118 else: 119 all_cost = "{} 点 / {} 点".format(hand_res.cost["additional"], 120 hand_res.cost["main"]) 121 else: 122 all_cost = "{} 点".format(hand_res.cost["main"]) 123 hand_report = {"hand_res": hand_res, "wind": wind, 124 "han_fu": han_fu, "gan": gan, "all_cost": all_cost, "yakus": hand_res.yaku} 125 return (sh_res, hand_report) 126 127def analyze(player_wind="SOUTH", round_wind="EAST", **hand_confs): 128 global entry_all_tiles, entry_win_tile 129 all_tiles = entry_all_tiles.get() 130 win_tile = entry_win_tile.get() 131 analyze_res = __analyze(all_tiles, win_tile, player_wind, round_wind, **hand_confs) 132 sh_res, hand_report = analyze_res 133 if hand_report is None: 134 if sh_res != 0: 135 print("{} 向聴".format(sh_res)) 136 else: 137 print("聴牌") 138 else: 139 print(hand_report["wind"]) 140 print(hand_report["han_fu"], end=" ") 141 print(hand_report["gan"]) 142 print(hand_report["all_cost"]) 143 if hand_report["yakus"] is not None: 144 for yaku in hand_report["yakus"]: 145 print(yaku.japanese) 146 147def main(): 148 fire.Fire(analyze) 149 150 151 152 153 154def home(): 155 global root 156 root = tk.Tk() 157 root.title('麻雀初心者支援ツール') 158 root.geometry('1200x700') #*ではなく小文字のxで記述 159 global main_frame 160 main_frame = tk.Frame(root) 161 main_frame.pack(fill = tk.BOTH, pady=20) 162 global title_btn1 163 title_btn1 = tk.Button(main_frame, width=80,height=10,font=('MSゴシック','15','bold'),text = 'ルールがわからない人向け',anchor=tk.CENTER,command=title_btn1_click) 164 title_btn1.pack(fill = 'x', padx=100) 165 global title_btn2 166 title_btn2 = tk.Button(main_frame, width=80,height=10,font=('MSゴシック','15','bold'),text='ルールを覚えた人向け',anchor=tk.CENTER,command=title_btn2_click) 167 title_btn2.pack(fill='x', padx=100) 168 global agari_analyzer_btn 169 agari_analyzer_btn = tk.Button(main_frame, width=80,height=10,font=('MSゴシック','15','bold'),text='点数計算器',command=agari_analyzer_btn_click) 170 agari_analyzer_btn.pack(fill='x',padx=100) 171 root.mainloop() 172 173home() 174 175

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

python

1from mahjong import agari, constants, shanten, tile

としていますので、tile はモジュールのはずなのですが、以下の for ループで tile という名前を使ってしまっています(シャドウイングが起こっています)。

python

1for tile in Mahjong_tiles_types: 2 tile_images[tile] = cv2.imread(MAHJONG_TILES_PATH + tile + '.png', cv2.IMREAD_COLOR)

なので、 この tile という変数名を変更します(以下では mj_tile としています)。

python

1for mj_tile in Mahjong_tiles_types: 2 tile_images[mj_tile] = cv2.imread(MAHJONG_TILES_PATH + mj_tile + '.png', cv2.IMREAD_COLOR)

投稿2022/01/17 18:17

melian

総合スコア19771

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takatoyo

2022/01/18 02:45

二重で使ってしまっていたんですね、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問