代码在遍历 for 循环与 运行 一次时产生不同的结果
Code yields different results when iterating through for loops versus running once
我编写了一个脚本来编辑模拟程序 (LTspice) 的 .txt 文件,然后使用修改后的 .txt 文件运行模拟。
有八个值(具有三种可能的状态)我想在每次迭代中独立更改。因此,我使用八个 for 循环通过搜索和替换 .txt 文件中的字符串来遍历所有组合。这看起来像这样:
Txt_original = 'SIM_COM_Automated_Copy.txt' #LTSpice output file has to be copied manually first
rawDataFile = 'SIM_COM_Automated_Copy.raw'
list1 =[]
list2 = []
with open(Txt_original, 'rb') as file:
Data_backup = file.read()
resistorValues = [['Res1=1980', 'Res1=2000', 'Res1=2020'],['Res2=1980', 'Res2=2000', 'Res2=2020'], ['Res3=1980', 'Res3=2000', 'Res3=2020'], ['Res4=1980', 'Res4=2000', 'Res4=2020'], ['Res7=19800', 'Res7=20000', 'Res7=20200'], ['Res8=9900', 'Res8=10000', 'Res8=10100'], ['Res16=19800', 'Res16=20000', 'Res16=20200'], ['Res17=9900', 'Res17=10000', 'Res17=10100']]
count = 0
for a in range(1,3):
editSimParameters(Txt_original, resistorValues[0][0], resistorValues[0][a] ) #Res1
for b in range(1,3):
editSimParameters(Txt_original, resistorValues[1][0], resistorValues[1][b] ) #Res2
for c in range(1,3):
editSimParameters(Txt_original, resistorValues[2][0], resistorValues[2][c] ) #Res3
for d in range(1,3):
editSimParameters(Txt_original, resistorValues[3][0], resistorValues[3][d] ) #Res4
for e in range(1,2):
editSimParameters(Txt_original, resistorValues[4][0], resistorValues[4][e] ) #Res7
for f in range(1,2):
editSimParameters(Txt_original, resistorValues[5][0], resistorValues[5][f] ) #Res8
for g in range(1,2):
editSimParameters(Txt_original, resistorValues[6][0], resistorValues[6][g] ) #Res16
for h in range(1,2):
editSimParameters(Txt_original, resistorValues[7][0], resistorValues[7][h] ) #Res17
runSimulation(Txt_original)
#time.sleep(10)
result = evaluateResults(rawDataFile)
valueSet = [a, b, c, d, e, f, g, h]
if valueSet == [2,2,2,2,1,1,1,1]:
print('Res1= '+resistorValues[0][a])
print('Res2= '+resistorValues[1][b])
print('Res3= '+resistorValues[2][c])
print('Res4= '+resistorValues[3][d])
print('Res7= '+resistorValues[4][e])
print('Res8= '+resistorValues[5][f])
print('Res16= '+resistorValues[6][g])
print('Res17= '+resistorValues[7][h])
print('The result of the combination ' + str(valueSet) + ' is ' + str(result))
list1.append(result)
list2.append(valueSet)
with open(Txt_original, 'wb') as file: #Reset the working file
file.write(Data_backup)
#Progress Tracking
count = count +1
if count%25 == 0:
print(count)
editSimParameters() 函数如下所示:
def editSimParameters(workingFile, oldParam, newParam):
with open(workingFile, 'rb') as file:
Data_original = file.read()
Data_temp = Data_original.replace(oldParam.encode('utf-8'), newParam.encode('utf-8'))
with open(workingFile, 'wb') as file:
file.write(Data_temp)
我在这个例子中减少了循环迭代的次数,因此代码终止得更快。尽管如此,当 运行 此代码组合 [2,2,2,2,1,1,1,1] 的结果与我通过更改 for 循环获得的相同组合的结果不同,所以只有这个组合被执行:
迭代后的结果(共模拟16次):组合[2, 2, 2, 2, 1, 1, 1, 1]的结果为16.347881
更改 for 循环的结果(1 次模拟):组合 [2, 2, 2, 2, 1, 1, 1, 1] 的结果是 16.327114
只有一次模拟的结果是正确的,我通过手动模拟验证了这一点。
我是在迭代和更改 .txt 文件时监督了一个问题还是有其他问题?
这是您似乎正在尝试做的事情的简化(且更强大)版本,使用 itertools.product
和正则表达式来替换电阻值。
我们的想法是
- 阅读您的原始 LTSpice 文件(我手边没有,因此源代码中有一个字符串常量)
- 设置一个字典,将电阻器名称匹配到这些电阻器应该尝试使用的值
- 使用一些温和的
zip
魔法将字典按摩成 itertools.product
接受的形式
- 使用
itertools.product
生成值的笛卡尔积,然后 zip
使用键返回它们以获得 combo
dict
- 循环组合并使用
re.sub
将这些值替换到模板(的副本)中。
- 而不是像我们在这里做的那样
print()
ing data
,你会把它写到你提供给模拟器的文件中,然后在那里做你必须做的事情。 我建议不要覆盖原始模板文件。
您可以根据需要向 resistor_combos
字典添加任意数量的键和值,它们都会被彻底检查。
import itertools
import re
# Would be read from the original SIM_COM_Automated_Copy file
template = """
Res1=100
Res2=100
Res8=1000
""".strip()
resistor_combos = {
"Res1": [123, 456],
"Res2": [789, 126],
}
resistor_keys, resistor_values = zip(*resistor_combos.items())
for value_combo in itertools.product(*resistor_values):
combo = dict(zip(resistor_keys, value_combo))
data = template # "Copy" the template for modification
for key, value in combo.items():
data = re.sub(f"^{key}=(\d+)", f"{key}={value}", data, flags=re.MULTILINE)
print(combo)
print(data)
print("====")
这会打印出来
{'Res1': 123, 'Res2': 789}
Res1=123
Res2=789
Res8=1000
====
{'Res1': 123, 'Res2': 126}
Res1=123
Res2=126
Res8=1000
====
{'Res1': 456, 'Res2': 789}
Res1=456
Res2=789
Res8=1000
====
{'Res1': 456, 'Res2': 126}
Res1=456
Res2=126
Res8=1000
====
我编写了一个脚本来编辑模拟程序 (LTspice) 的 .txt 文件,然后使用修改后的 .txt 文件运行模拟。
有八个值(具有三种可能的状态)我想在每次迭代中独立更改。因此,我使用八个 for 循环通过搜索和替换 .txt 文件中的字符串来遍历所有组合。这看起来像这样:
Txt_original = 'SIM_COM_Automated_Copy.txt' #LTSpice output file has to be copied manually first
rawDataFile = 'SIM_COM_Automated_Copy.raw'
list1 =[]
list2 = []
with open(Txt_original, 'rb') as file:
Data_backup = file.read()
resistorValues = [['Res1=1980', 'Res1=2000', 'Res1=2020'],['Res2=1980', 'Res2=2000', 'Res2=2020'], ['Res3=1980', 'Res3=2000', 'Res3=2020'], ['Res4=1980', 'Res4=2000', 'Res4=2020'], ['Res7=19800', 'Res7=20000', 'Res7=20200'], ['Res8=9900', 'Res8=10000', 'Res8=10100'], ['Res16=19800', 'Res16=20000', 'Res16=20200'], ['Res17=9900', 'Res17=10000', 'Res17=10100']]
count = 0
for a in range(1,3):
editSimParameters(Txt_original, resistorValues[0][0], resistorValues[0][a] ) #Res1
for b in range(1,3):
editSimParameters(Txt_original, resistorValues[1][0], resistorValues[1][b] ) #Res2
for c in range(1,3):
editSimParameters(Txt_original, resistorValues[2][0], resistorValues[2][c] ) #Res3
for d in range(1,3):
editSimParameters(Txt_original, resistorValues[3][0], resistorValues[3][d] ) #Res4
for e in range(1,2):
editSimParameters(Txt_original, resistorValues[4][0], resistorValues[4][e] ) #Res7
for f in range(1,2):
editSimParameters(Txt_original, resistorValues[5][0], resistorValues[5][f] ) #Res8
for g in range(1,2):
editSimParameters(Txt_original, resistorValues[6][0], resistorValues[6][g] ) #Res16
for h in range(1,2):
editSimParameters(Txt_original, resistorValues[7][0], resistorValues[7][h] ) #Res17
runSimulation(Txt_original)
#time.sleep(10)
result = evaluateResults(rawDataFile)
valueSet = [a, b, c, d, e, f, g, h]
if valueSet == [2,2,2,2,1,1,1,1]:
print('Res1= '+resistorValues[0][a])
print('Res2= '+resistorValues[1][b])
print('Res3= '+resistorValues[2][c])
print('Res4= '+resistorValues[3][d])
print('Res7= '+resistorValues[4][e])
print('Res8= '+resistorValues[5][f])
print('Res16= '+resistorValues[6][g])
print('Res17= '+resistorValues[7][h])
print('The result of the combination ' + str(valueSet) + ' is ' + str(result))
list1.append(result)
list2.append(valueSet)
with open(Txt_original, 'wb') as file: #Reset the working file
file.write(Data_backup)
#Progress Tracking
count = count +1
if count%25 == 0:
print(count)
editSimParameters() 函数如下所示:
def editSimParameters(workingFile, oldParam, newParam):
with open(workingFile, 'rb') as file:
Data_original = file.read()
Data_temp = Data_original.replace(oldParam.encode('utf-8'), newParam.encode('utf-8'))
with open(workingFile, 'wb') as file:
file.write(Data_temp)
我在这个例子中减少了循环迭代的次数,因此代码终止得更快。尽管如此,当 运行 此代码组合 [2,2,2,2,1,1,1,1] 的结果与我通过更改 for 循环获得的相同组合的结果不同,所以只有这个组合被执行:
迭代后的结果(共模拟16次):组合[2, 2, 2, 2, 1, 1, 1, 1]的结果为16.347881
更改 for 循环的结果(1 次模拟):组合 [2, 2, 2, 2, 1, 1, 1, 1] 的结果是 16.327114
只有一次模拟的结果是正确的,我通过手动模拟验证了这一点。
我是在迭代和更改 .txt 文件时监督了一个问题还是有其他问题?
这是您似乎正在尝试做的事情的简化(且更强大)版本,使用 itertools.product
和正则表达式来替换电阻值。
我们的想法是
- 阅读您的原始 LTSpice 文件(我手边没有,因此源代码中有一个字符串常量)
- 设置一个字典,将电阻器名称匹配到这些电阻器应该尝试使用的值
- 使用一些温和的
zip
魔法将字典按摩成itertools.product
接受的形式 - 使用
itertools.product
生成值的笛卡尔积,然后zip
使用键返回它们以获得combo
dict - 循环组合并使用
re.sub
将这些值替换到模板(的副本)中。 - 而不是像我们在这里做的那样
print()
ingdata
,你会把它写到你提供给模拟器的文件中,然后在那里做你必须做的事情。 我建议不要覆盖原始模板文件。
您可以根据需要向 resistor_combos
字典添加任意数量的键和值,它们都会被彻底检查。
import itertools
import re
# Would be read from the original SIM_COM_Automated_Copy file
template = """
Res1=100
Res2=100
Res8=1000
""".strip()
resistor_combos = {
"Res1": [123, 456],
"Res2": [789, 126],
}
resistor_keys, resistor_values = zip(*resistor_combos.items())
for value_combo in itertools.product(*resistor_values):
combo = dict(zip(resistor_keys, value_combo))
data = template # "Copy" the template for modification
for key, value in combo.items():
data = re.sub(f"^{key}=(\d+)", f"{key}={value}", data, flags=re.MULTILINE)
print(combo)
print(data)
print("====")
这会打印出来
{'Res1': 123, 'Res2': 789}
Res1=123
Res2=789
Res8=1000
====
{'Res1': 123, 'Res2': 126}
Res1=123
Res2=126
Res8=1000
====
{'Res1': 456, 'Res2': 789}
Res1=456
Res2=789
Res8=1000
====
{'Res1': 456, 'Res2': 126}
Res1=456
Res2=126
Res8=1000
====