👋
構造一貫解析ソフトSS7をPythonで実行する #2 ループ処理例(コマンド実行)
フォルダ構成
src
├─ss7_make_command.py :: 入力csv -> 解析のループを行う。
├─ss7_make_command_GUI.py
├─ module/
│ ├─ ss7_SB1.py :: ss7出力csvの読書きを行う。
│ └─ ss7_scmd.py :: scmdファイルを作成する
└─ data/
├─ csv/
│ ├─ exp.csv :: ss7.iknから生成。順次書替え。
│ └─ inp.csv :: ss7.iknから生成。順次書替え。
└─ scmd/
├─ ss01_0001.scmd :: 1回目解析用テンプレート
├─ ss01_0002.scmd :: 2回目解析用テンプレート
└─ ss03.scmd :: 順次更新。
プログラムの流れ
① 解析済ss7.iknファイル -> exp.csv, inp.csv出力
② exp.csvとinp.csvを読取る。
exp.csvより小梁の断面算定情報を取得し、設定クライテリアと比較する。
NGの場合の小梁配置情報をリスト化する。
③ NGの小梁を書換してinp.csvを作成する。
④ imp.csvから.iknを生成し、解析実行。-> exp.csv, inp.csv出力。
以降②~④のループをNGがなくなるまで繰返し。
ss7_make_command.py
import module.ss7_SB1 as sb
import module.ss7_scmd as sc
import subprocess
import sys
import os
#メインファイルTkinter追加必要あり。
print(sys.getdefaultencoding()) #文字コードの確認
path = os.getcwd() #カレントディレクトリの取得
print("カレントディレクトリ ::", path)
path_ikn = "C:\\UsrData\\Ss7Data\\物件A_Auto2023.ikn"
path_ikn1 = "C:\\UsrData\\Ss7Data\\物件A_Auto2023_1.ikn"
base_scmd = ".\data\scmd\ss01_0001.scmd" #1回目に実行するscmdファイル
base_scmd1 = '.\data\scmd\ss01_0002.scmd' #csvからss7に変換する部分が追加されたベースファイル
newfile = ".\data\scmd\ss03.scmd" #実行ファイル
inpath = "data\csv\inp.csv"
expath = "data\csv\exp.csv"
nwinpath = "data\csv\inp0.csv"
inpath = os.path.join(path, inpath)
expath = os.path.join(path, expath)
nwinpath = os.path.join(path, nwinpath)
def main(crit0, crit1):
count = 1
print("\n計算回数 = %i"%count)
#scmdファイル実行(SS7コマンド実行)
#第1回目の実行(結果1に実行済ファイルが存在する前提)
sc.go_scmd(path_ikn, base_scmd, newfile, inpath, expath, nwinpath)
subprocess.run(newfile, shell=True)
#csv読み書きとエラー個数取得
n1 = sb.csvmaker(inpath, expath, nwinpath, crit0, crit1)
print("エラー個数 = ", n1)
#whileループになるか判断(n1=0の時、ループには入らない)
if n1 == 0:
n = 0 #下記のwhileループに入らない。
else:
n = 100 #初期値>1 ならなんでもOK whileループに入る。
count += 1
while n >= 1: #エラーがある場合ループ入り
print("\n計算回数 = %i"%count)
#scmdファイル実行(SS7コマンド実行)
sc.go_scmd(path_ikn1, base_scmd1, newfile, inpath, expath, nwinpath)
subprocess.run(newfile, shell=True)
#csvの読み書きとエラー個数
n1 = sb.csvmaker(inpath, expath, nwinpath, crit0, crit1)
print("エラー個数 = ", n1)
n = n1
count += 1
crit0 = 0.9 # 検定比
crit1 = 300 # 変形
main(crit0, crit1)
ss7_make_command_GUI.py
import module.ss7_SB1 as sb
import module.ss7_scmd as sc
import subprocess
import sys
import os
#GUI用
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
import datetime
now = datetime.datetime.now()
now = now.strftime("%y%m%d_%H%M")
# フォルダ指定の関数
def dirdialog_clicked():
iDir = 'C:\\UsrData\\Ss7Data'
iDirPath = filedialog.askdirectory(initialdir = iDir)
entry1.set(iDirPath)
def conductMain(): # 実行ボタン押下時の実行関数
filePath1 = entry1.get() #INPUT FILE
crit0 = float(text4.get(1.0, END+"-1c"))
crit1 = float(text5.get(1.0, END+"-1c"))
print(filePath1)
print(crit0, crit1)
main(crit0, crit1)
#メインファイルTkinter追加必要あり。
print(sys.getdefaultencoding()) #文字コードの確認
path = os.getcwd() #カレントディレクトリの取得
print("カレントディレクトリ ::", path)
path_ikn = "C:\\UsrData\\Ss7Data\\物件A_Auto2023.ikn"
path_ikn1 = "C:\\UsrData\\Ss7Data\\物件A_Auto2023_1.ikn"
base_scmd = ".\data\scmd\ss01_0001.scmd" #1回目に実行するscmdファイル
base_scmd1 = '.\data\scmd\ss01_0002.scmd' #csvからss7に変換する部分が追加されたベースファイル
newfile = ".\data\scmd\ss03.scmd" #実行ファイル
inpath = "data\csv\inp.csv"
expath = "data\csv\exp.csv"
nwinpath = "data\csv\inp0.csv"
inpath = os.path.join(path, inpath)
expath = os.path.join(path, expath)
nwinpath = os.path.join(path, nwinpath)
def main(crit0, crit1):
count = 1
print("\n計算回数 = %i"%count)
#scmdファイル実行(SS7コマンド実行)
#第1回目の実行(結果1に実行済ファイルが存在する前提)
sc.go_scmd(path_ikn, base_scmd, newfile, inpath, expath, nwinpath)
subprocess.run(newfile, shell=True)
#csv読み書きとエラー個数取得
n1 = sb.csvmaker(inpath, expath, nwinpath, crit0, crit1)
print("エラー個数 = ", n1)
#whileループになるか判断(n1=0の時、ループには入らない)
if n1 == 0:
n = 0 #下記のwhileループに入らない。
else:
n = 100 #初期値>1 ならなんでもOK whileループに入る。
count += 1
while n >= 1: #エラーがある場合ループ入り
print("\n計算回数 = %i"%count)
#scmdファイル実行(SS7コマンド実行)
sc.go_scmd(path_ikn1, base_scmd1, newfile, inpath, expath, nwinpath)
subprocess.run(newfile, shell=True)
#csvの読み書きとエラー個数
n1 = sb.csvmaker(inpath, expath, nwinpath, crit0, crit1)
print("エラー個数 = ", n1)
n = n1
count += 1
# rootの作成
root = Tk()
root.title("小梁順次変更 by_kitagawa")
# Frame1の作成
frame1 = ttk.Frame(root, padding=10)
frame1.grid(row=1, column=1, sticky=E)
# 「ファイル参照」ラベルの作成
IFileLabel = ttk.Label(frame1, text="ファイル参照(.ikn)>>", padding=(5, 2))
IFileLabel.pack(side=LEFT)
# 「ファイル参照」エントリーの作成
entry1 = StringVar()
IFileEntry = ttk.Entry(frame1, textvariable=entry1, width=30)
IFileEntry.pack(side=LEFT)
# 「ファイル参照」ボタンの作成
IFileButton = ttk.Button(frame1, text="参照", command=dirdialog_clicked)
IFileButton.pack(side=LEFT)
# Frame4の作成
frame4 = ttk.Frame(root, padding=10)
frame4.grid(row=2, column=1, sticky=E)
IFileLabel = ttk.Label(frame4, text="目標検定比 >>", padding=(5, 2))
IFileLabel.pack(side=LEFT)
text4=Text(frame4, height=1)
text4.pack()
text4.insert(END, 0.9)
# Frame5の作成
frame5 = ttk.Frame(root, padding=10)
frame5.grid(row=3, column=1, sticky=E)
IFileLabel = ttk.Label(frame5, text="変形クライテリア1/ >>", padding=(5, 2))
IFileLabel.pack(side=LEFT)
text5=Text(frame5, height=1)
text5.pack()
text5.insert(END, 300)
# Frame7の作成
frame7 = ttk.Frame(root, padding=10)
frame7.grid(row=4,column=1,sticky=W)
# 実行ボタンの設置
button1 = ttk.Button(frame7, text="実行", command=conductMain)
button1.pack(fill = "x", padx=30, side = "left")
# キャンセルボタンの設置
button2 = ttk.Button(frame7, text=("閉じる"), command=quit)
button2.pack(fill = "x", padx=30, side = "left")
root.mainloop()
ss7_SB1.py
import csv
class sbdata:
def __init__(self, inpath, expath):
s = self
#入力csvファイルを読み込んでリストに格納
s.l = []
with open(inpath, 'r') as f:
reader = csv.reader(f)
for row in reader:
s.l.append(row)
s.lxp = []
with open(expath, 'r') as f:
reader = csv.reader(f)
for row in reader:
s.lxp.append(row)
def get_data_range(self, name, in_out): #name= name, l
#データの範囲とデータリストを返す関数。
s = self
if in_out == 0:
l = s.l
else:
l = s.lxp
st = 0 #nameを見つけたフラグ
count = 0 #デバッグ用
for i in range(len(l)):
li = l[i]
if "name="+name in li:
st = 1
no0 = i
else:
None
if st == 1:
count += 1
if "<data>" in li:
no1 = i
elif not li: #リストのから判定
no2 = i
break
else:
None
#if count > 25:
# break
dl = l[no1+1:no2]
return(no0, no1, no2, dl) #[nameのある行i, <data>のある行i, deta終了行i, 範囲のテキストデータ]
def get_unique(names): #重複削除関数(登場の順番を守るもの)
unique = []
for name in names:
if name not in unique:
unique.append(name)
return(unique)
def get_jrow(dl,j): #2次元配列の特定列を取得
BL = []
for i in range(len(dl)):
BL.append(dl[i][j])
return(BL)
def dls(dl, kai, iti, first, fugo): #小梁の位置と符号があっているものを返す。
#print(kai, iti, first, fugo)
ilis = []
p = " "
#print(dls)
for i in range(len(dl)):
li = dl[i] #一行取出し(S小梁断面の値)
kai0 = li[0] #階
iti0 = li[1] #位置
first0 = li[3] #小梁ナンバー
fugo0 = li[9] #符号名
#以下判定用文字列
han0 = str(kai) +p+str(iti) +p+str(first) +p+str(fugo)
han1 = str(kai0)+p+str(iti0)+p+str(first0)+p+str(fugo0)
#判定用文字列の確認
if han0 == han1:
ilis.append(i)
print("ilis", ilis)
return(ilis[0])
def list_no(li_in,search): #リストで何番目に指定文字があるのか
for i in range(len(li_in)):
li = li_in[i]
if li == search:
return(i)
else:
None
def killdata(sbd):
#input = './inp.csv'
#sbd = sbdata(input)
no0,no1,no2,dl = sbd.get_data_range("小梁配置",0) #nameとリストを渡す。#[nameのある行i, <data>のある行i, deta終了行i, 範囲のテキストデータ]
#小梁リストを抜き出す
BL = get_jrow(dl,9) #9列目だけのデータ取得
ul = (get_unique(BL)) #ユニークなリストのみ残す
#配置されていない小梁断面を削除する予定(行リストを作成する、まだ削除しない)
no0,no1,no2,dl = sbd.get_data_range("S小梁断面",0) #nameとリストを渡す #nameとリストを渡す。#[nameのある行i, <data>のある行i, deta終了行i, 範囲のテキストデータ]
BL = get_jrow(dl,0)
nox = no1 + 1 #dataのある行のナンバー
kill = [] #最後に削除する行のリスト(このタイミングでは変えない)
for i in range(len(BL)):
li = BL[i]
x = nox + i
if li in ul:
None
else:
kill.append(x)
def killer_kome(s):
s = s.replace("*", "")
return(s)
def check_export(sbd, crit0, crit1):
#input = './inp.csv'
#標準S小梁リスト(北川作成)を呼び出す。(作成予定)
#EXPファイルから"S小梁断面算定表"の項目を見て
#小梁の断面算定結果を見て 設計を整える。
#入力csvファイルを読み込んでリストに格納
lxp = sbd.lxp
no0,no1,no2,dl = sbd.get_data_range("S小梁断面算定表",1) #nameとリストを渡す。
ITI = []
ITIc = []
for i in range(len(dl)):
if "[" in dl[i][0] and "B" in dl[i][0]: #Bのついている小梁しか検討できないことになる。あとで直したい。
hantei = "OK"
bname = dl[i][0].replace(" ","")
bname = bname.replace("[","")
bname = bname.replace("]","")
first = int(dl[i+1][1].split("=")[1]) #"一次="
itii = [bname, dl[i][1].replace("[",""), dl[i][2], dl[i][3], dl[i][4], dl[i][5].replace("]",""),first]
os = 2 #下方向のオフセット
crit0org = float(killer_kome(dl[i+os][15]))
crit1org = int(killer_kome(dl[i+os][21].split("/")[1].replace(" ","")))
if crit0org <= crit0:
print(crit0org,"<=",crit0,"...OK",itii)
else:
print(crit0org,">",crit0,"...NG",itii)
hantei = "NG"
if crit1org >= crit1:
print(crit1org,">=",crit1,"...OK",itii)
else:
print(crit1org,"<",crit1,"...NG",itii)
hantei = "NG"
itii.append(hantei)
ITI.append(itii)
if hantei == "NG":
ITIc.append(itii) #NGの位置のリスト
else:
None
return(ITIc)
def change_inport(sbd, ITIc, nwpath):
#inport のファイルで小梁の符号を書き変える。
#小梁断面リスト
l = sbd.l
#nameとリストを渡す。#[nameのある行i, <data>のある行i, deta終了行i, 範囲のテキストデータ] = sbd.get_data_range()
no0,no1,no2,dl = sbd.get_data_range("S小梁断面", 0) #nameとリストを渡す
BLn = get_jrow(dl,0) #小梁断面の符号リスト
no0,no1,no2,dl = sbd.get_data_range("小梁配置", 0) #nameとリストを渡す。
ci = []
for li in ITIc:
sp = " - "
print(li[1], li[3] + sp +li[5] + sp + li[2] + sp + li[4], li[6], li[0])
iii = dls(dl, li[1], li[3] + sp +li[5] + sp + li[2] + sp + li[4], li[6], li[0])
ci.append(iii)
for li in ci: #ciは小梁配置の下方向番号
ind = li+no1+1 #書き換える行ナンバー
#print(ind)
no = list_no(BLn, l[ind][9]) # 小梁の位置
l[ind][9] = BLn[no+1] #小梁符号を書き換える
#リストを新たなcsvファイルに保存
with open(nwpath, 'w', newline = "") as f:
writer = csv.writer(f)
writer.writerows(l)
###################################################################################
# 同じディレクトリのinp.csv, exp.csvのファイルを読み込んで、
# S小梁断面を編集したinp2.csvを作成する。
#
#
###################################################################################
#def main():
def csvmaker(inpath, expath, nwpath, crit0, crit1):
#inpath = "./data/csv/inp.csv"
#expath = "./data/csv/exp.csv"
#nwpath = "./data/cev/inp0.csv"
sbd = sbdata(inpath, expath)
l = sbd.l #入力のcsvリスト
#lxp = sbd.lexp #出力のcsvリスト
ITIc = check_export(sbd, crit0, crit1) #出力でクライリアを確認
#ITIc :: S小梁断面算定表でNGとなる小梁のリスト
print("NGlist=", ITIc)
change_inport(sbd, ITIc, nwpath) #inportファイルの書き換え
return(len(ITIc)) #小梁のエラー個数を返却
if __name__ == "__main__":
main()
ss7_scmd.py
import codecs
def shift(s):
s = s.encode("shift_jis")
return(s)
def rename_ikn(PATH_IKN):
a = PATH_IKN.find(".")
s = PATH_IKN[0:a] + "_Auto" + PATH_IKN[a:]
return(s)
#def main(PATH_IKN,base_scmd, openfile):
def go_scmd(PATH_IKN, base_scmd, openfile, inpath, expath, nwinpath):
inpcsv0 = nwinpath
inpcsv = inpath
outcsv = expath
fout = codecs.open(openfile, "w", "shift_jis") #実行ファイルはss03.scmd
s = ""
for line in codecs.open(base_scmd, "r", "shift_jis"): #データを読み込んですべて一つの文字列とする。
s += line
s.encode("utf-8")
s = s.replace("PATH_IKN", PATH_IKN) #文字列のPATH_IKNをssデータの絶対パスに変更
s = s.replace("PATH_CSV_0_inp", inpcsv0) #文字列の書き換え
s = s.replace("PATH_CSVinp", inpcsv) #文字列の書き換え
s = s.replace("PATH_CSVexp", outcsv) #文字列の書き換え
fout.write(s)
fout.close()
Discussion