teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

誤字修正

2020/10/17 05:32

投稿

bg_t
bg_t

スコア1

title CHANGED
File without changes
body CHANGED
@@ -1,7 +1,9 @@
1
1
  win10 VS2019でpython3.7(64bit)を利用してプログラムを書いているのですが、プログラム内で with を使用するとプログラム終了時にコンソールにエラーが表示されます
2
+ ```python
2
3
  # ココ
3
4
  f = open()
4
5
  f.close()
6
+ ```
5
7
  形式にするとエラーが表示されなくなるのですが、これ以上の原因が究明できないので教えて頂けると嬉しいです
6
8
 
7
9
 

1

エラーが再現できるコードを追加しました

2020/10/17 05:32

投稿

bg_t
bg_t

スコア1

title CHANGED
File without changes
body CHANGED
@@ -1,24 +1,218 @@
1
- win10 VS2019でpython3.7(64bit)を利用してプログラムを書いているのですが、プログラム内で with を使用するとプログラム終了時にコンソールにエラーが表示されます
1
+ win10 VS2019でpython3.7(64bit)を利用してプログラムを書いているのですが、プログラム内で with を使用するとプログラム終了時にコンソールにエラーが表示されます
2
- a=0はエラー位置を特定するために一時的に書いたもので、本来なら書き込みを行っています
2
+ # ココ
3
- したのプログラムはプログラムを小さく再現したものになります(これで単体ではエラーは発生しません)
3
+ f = open()
4
+ f.close()
4
- プログラム全体を貼とが出来ので、これ情報で原因が推測できる方がらっしゃいましたら教えて頂けるといです
5
+ 形式にするとエラー表示されくなるのですが、これ以上の原因が究明できので教えて頂けると嬉しいです
5
- withの行はプログラム上では通過していないのに、コメントアウトすると警告が消えるので原因がわかりません
6
6
 
7
+
7
8
  ```python
9
+ import os
10
+ import pandas as pd
11
+ from tqdm import tqdm
12
+ import re # 文字列編集
8
- TEST = False
13
+ import time
14
+ import lib
9
15
 
16
+ try:
17
+ import google.colab
18
+ IN_COLAB = True
10
- if TEST:
19
+ except:
20
+ IN_COLAB = False
21
+
22
+ if IN_COLAB: # Google Colabで実行している場合
23
+ CSV_PATH = "/content/rakuten_product_data.csv"
24
+ URL_LIST_PATH = "./image_url.lst"
25
+ IMAGE_URL_CSV_PATH = "./delete_image_name.csv"
26
+ R_CABINET_FORMAT_PATH = "./r_cabinet_delete_format.txt"
27
+ URL_INFO_TEXT_PATH = "./image_url.txt"
28
+ else: # ローカルで実行している場合
29
+ CSV_PATH = "./rakuten_product_data.csv"
30
+ URL_LIST_PATH = "./image_url.lst"
31
+ IMAGE_URL_CSV_PATH = "./delete_image_name.csv"
32
+ R_CABINET_FORMAT_PATH = "./r_cabinet_delete_format.txt"
33
+ URL_INFO_TEXT_PATH = "./image_url.txt"
34
+ VERSION = "1.0.0"
11
- # エラーが表示される
35
+ STOCK = 0 # 在庫あり
36
+ NO_STOCK = 1 # 在庫なし
37
+ LOCAL_IMG_DIR = "./image"
38
+ RAKUTEN_FORMAT_DELETE_PATH = "" # RMSフォーマット用に画像URLから削除する部分
39
+ IMAGE_URL_CSV_COLUMNS = ["file_name", "url", "deleted", "error"]
40
+
41
+
42
+
43
+ if os.path.isfile(CSV_PATH):
12
- with open(PATH, mode="w") as f:
44
+ load_csv = pd.read_csv(CSV_PATH, encoding="cp932")
45
+ else:
46
+ exit()
47
+
48
+ stock_or = [load_csv[load_csv["在庫数"] == 1], load_csv[load_csv["在庫数"] == 0]] # 在庫がある商品とない商品のリスト
49
+ all_num = len(load_csv) # 商品の数
50
+ stock_num = len(stock_or[STOCK]) # 在庫あり商品の数
51
+
52
+ img_num_no_stock = 0 # 在庫がない商品に含まれる画像の数
53
+ img_num_stock = 0 # 在庫がある商品に含まれる画像の数
54
+ not_top_img_num = 0 # サムネを含まない、在庫がない商品に含まれる画像の数
55
+ no_img_item_num = 0 # 画像が無い商品の数
13
- a = 0
56
+ i = 0
57
+
58
+ for row_stock_or in stock_or:
59
+ for row in row_stock_or["商品画像URL"]:
60
+ if type(row) == str and len(row.split()) != 0: # URL情報が格納されていれば
61
+ if i == STOCK: # 在庫がある場合
62
+ img_num_stock += len(row.split())
63
+ else: # 在庫がない場合
64
+ img_num_no_stock += len(row.split())
65
+ not_top_img_num += len(row.split()) - 1
66
+ else:
67
+ no_img_item_num += 1
68
+ i += 1
69
+
70
+
71
+ #中略
72
+
73
+
74
+ item_numbers = list(stock_or[NO_STOCK]["商品管理番号(商品URL)"])
75
+ item_names = list(stock_or[NO_STOCK]["商品名"])
76
+ img_urls = list(stock_or[NO_STOCK]["商品画像URL"])
77
+ img_urls_stock = list(stock_or[STOCK]["商品画像URL"])
78
+
79
+ #中略
80
+
81
+
82
+ print("\n削除画像一覧をテキストに出力しますか? (y/n)")
83
+ in_str = input()
84
+ if in_str == "y":
85
+ output_data = [] # CSVとして出力するためのデータ
86
+ for i in range(len(img_urls)):
87
+ if type(img_urls[i]) == str: # URLが含まれない商品をスキップする
88
+ images = img_urls[i].split(" ") # 一つの商品に含まれるURLのリスト
89
+ for j in range(1, len(images)): # サムネの画像をスキップする
90
+ output_data.append([os.path.basename(images[j]), images[j], False])
91
+
92
+ image_name_list_stock = [] # 在庫がある商品の写真のリスト
93
+ for i in range(len(img_urls_stock)):
94
+ if type(img_urls_stock[i]) == str: # URLが含まれない商品をスキップする
95
+ images = img_urls_stock[i].split(" ") # 一つの商品に含まれるURLのリスト
96
+ for j in range(1, len(images)): # サムネの画像をスキップする
97
+ image_name_list_stock.append(os.path.basename(images[j]))
98
+
99
+ print("画像情報を精査します")
100
+ exclusion_image_list = [] # 削除する画像リストから取り除く画像
101
+ image_name_list = [row[0] for row in output_data] # 在庫がない商品の写真のリスト
102
+ for row in tqdm(image_name_list):
103
+ for row2 in image_name_list_stock:
104
+ if row == row2:
105
+ exclusion_image_list.append(row)
106
+ exclusion_image_list = set(exclusion_image_list) # 万が一同じ画像があれば取り除く
107
+ if len(exclusion_image_list) == 0:
108
+ print("\n問題は見つかりませんでした")
109
+ else:
110
+ print("\n" + str(len(exclusion_image_list)) + " 件の販売中商品への再利用画像が見つかりました")
111
+ print(exclusion_image_list)
112
+
113
+ for row in output_data:
114
+ row.append(False) # 4 列目を追加する
115
+ for row2 in exclusion_image_list:
116
+ if row[0] == row2:
117
+ row[3] = True # 4 列目を書き換える
118
+
119
+ list_len = len(image_name_list) # リストの大きさ
120
+ unique_list_len = len(set(image_name_list)) # 一意に変換したリストの大きさ
121
+ if list_len != unique_list_len:
122
+ print("\n警告 : 同名の画像が存在します " + str(list_len-unique_list_len) + " / " + str(unique_list_len))
123
+ print([x for x in dict.fromkeys(image_name_list) if image_name_list.count(x) > 1])
124
+ csv_df = pd.DataFrame(output_data, columns=IMAGE_URL_CSV_COLUMNS)
125
+ csv_df.to_csv(IMAGE_URL_CSV_PATH, index=False)
126
+ print("\n削除すべき画像の情報をCSV形式で出力しました")
127
+
128
+
129
+ if os.path.isfile(IMAGE_URL_CSV_PATH):
130
+ load_img_csv = pd.read_csv(IMAGE_URL_CSV_PATH, encoding="cp932")
131
+ else:
132
+ lib.print_error_log("削除画像一覧ファイルが見つかりませんでした")
133
+ exit()
134
+
135
+ with open(R_CABINET_FORMAT_PATH, mode="w") as f: # ココ
136
+ for i in range(len(load_img_csv[IMAGE_URL_CSV_COLUMNS[0]])):
137
+ if not load_img_csv["error"][i]:
138
+ f.write(load_img_csv["url"][i].replace(RAKUTEN_FORMAT_DELETE_PATH, "") + "\n") # 指定のフォーマットに変換して出力する
139
+
140
+
141
+ lib.program_pause()
142
+ ```
143
+ lib.py↓
144
+ ```python
145
+ import os
146
+ import time
147
+ import datetime
148
+ import urllib.error # urlを扱うモジュール
149
+ import urllib.request
150
+ import inspect # 活動中のオブジェクトの情報を取得する
151
+
152
+ __version__ = "1.0.0"
153
+
154
+ # ログを出力する
155
+ def print_log(message, console_print = True, error_frame = None):
156
+ LOG_PATH = "./lib.log"
157
+ if error_frame != None: # エラーログの場合はファイルを変更する
158
+ LOG_PATH = "./error.log"
159
+ if console_print:
160
+ print(message)
14
161
 
162
+ time_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 現在時刻を取得する
163
+ if not os.path.isfile(LOG_PATH) or os.path.getsize(LOG_PATH) < 1024*1000*10: # 10MBより小さければ出力する
164
+ with open(LOG_PATH, mode="a") as f:
165
+ if error_frame != None: # エラーログ
166
+ f.write("[{}] {}({})".format(time_now, error_frame.f_code.co_name, error_frame.f_lineno).ljust(60) + message + "\n")
167
+ else: # 普通のログ
168
+ f.write("[{}] {}\n".format(time_now, message))
169
+ return True
170
+ else:
171
+ print("ログファイルの容量がいっぱいの為、出力を中止しました")
172
+ return False
15
173
 
16
- # エラーなし
174
+ # エラーログを出力する
175
+ def print_error_log(message, console_print = True):
176
+ frame = inspect.currentframe().f_back # 関数が呼ばれた場所の情報を取得する
177
+ return print_log(message, console_print, frame)
178
+
179
+ # インターネット上からファイルをダウンロードする関数
180
+ def download_file(url, dst_path):
181
+ try:
182
+ with urllib.request.urlopen(url) as web_file:
183
+ data = web_file.read()
184
+ with open(dst_path, mode='wb') as local_file:
185
+ local_file.write(data)
186
+ time.sleep(0.1)
187
+ return True
188
+ except urllib.error.URLError as e:
189
+ print_error_log(e)
190
+ return False
191
+
192
+ # ファイルをダウンロードして、失敗時に再ダウンロードを試みる関数
193
+ def download_and_check_file(url, dst_path):
194
+ TRIAL_NUM = 300 # 失敗時の試行回数
195
+ TRIAL_INTERVAL = 5 # 再ダウンロード時のクールタイム
196
+ download_file(url, dst_path)
197
+ for i in range(TRIAL_NUM):
198
+ if not os.path.isfile(dst_path):
199
+ print_error_log("ダウンロードに失敗しました、" + str(TRIAL_INTERVAL) + "秒後に再ダウンロードします ( " + str(i + 1) + " Fail )")
200
+ time.sleep(TRIAL_INTERVAL)
201
+ download_file(url, dst_path)
202
+ else: # ダウンロード成功
203
+ return True
204
+ return False
205
+
206
+ # プログラム終了時に一時停止する関数
207
+ def program_pause(program_end = True):
208
+ if not __debug__: # デバッグでなければ一時停止する
17
- f = open()
209
+ if program_end:
18
- a=0
210
+ message = "Press Enter key to exit . . ."
19
- f.close()
211
+ else:
212
+ message = "Press Enter key to continue . . ."
213
+ input(message)
214
+ return True
20
215
  ```
21
-
22
216
  Traceback (most recent call last):
23
217
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\runpy.py", line 193, in _run_module_as_main
24
218
  "__main__", mod_spec)