- The component names are automatically generated. It is always better to let the user name the components as they may correspond to PCB designs etc.
- Any change in the circuit topology, even an extension of a branch would be seen a new circuit with default values. Better to check if any of the components in the new circuit have parameters in the parameter file and start with those parameters.
So, a change in the code. The components will now be names followed by an underscore ("_") and then the name of the component. Example: Resistor_R1, voltagesource_v1. Case is not important in the component names though it is in the tags.
The unique identifier continues to be cell position. However, for a particular component type, the same tag can't be used. For example: resistor_r1 and resistor_r1 would be illegal. However, two different components could have the same tag. For example: Resistor_br and inductor_br are OK. If the user want to name the components according to function, this might be a good option.
Here is the code (click on "view raw" below the box to see the entire code):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
import sys, math | |
import network_reader as nw_rd | |
def csv_tuple(csv_elem): | |
""" Convert a cell position from spreadsheet form | |
to [row, tuple] form. """ | |
csv_elem.upper() | |
# Create a dictionary of alphabets | |
csv_col="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" | |
csv_dict={} | |
csv_col_list=csv_col.split(" ") | |
# Make the alphabets correspond to integers | |
for c1 in range(1, 27): | |
csv_dict[csv_col_list[c1-1]]=c1 | |
# The cell position starts with a number | |
flag="number" | |
c1=0 | |
while flag=="number": | |
# When conversion to int fails | |
# it means the element is an alphabet | |
try: | |
int(csv_elem[c1]) | |
except ValueError: | |
flag="alphabet" | |
else: | |
c1+=1 | |
# Split them up into numbers and alphabets | |
pol_row=int(csv_elem[0:c1]) | |
pol_col=csv_elem[c1:] | |
elem_tuple=[pol_row-1, 0] | |
# Convert the alphabets to number | |
# Similar to converting binary to decimal | |
for c1 in range(len(pol_col)-1, -1, -1): | |
if len(pol_col)-1-c1>0: | |
elem_tuple[1]+=26*(len(pol_col)-1-c1)*csv_dict[pol_col[c1]] | |
else: | |
elem_tuple[1]+=csv_dict[pol_col[c1]]-1 | |
return elem_tuple | |
def reading_params(param_file): | |
""" Read a file. Ramove additional quotes and | |
carriage returns. Remove leading spaces. """ | |
from_file=[] | |
for line in param_file: | |
from_file.append(line.split(",")) | |
for c1 in range(len(from_file)): | |
for c2 in range(len(from_file[c1])-1, -1, -1): | |
# Remove additional quotes and carriage returns | |
if from_file[c1][c2]: | |
nw_rd.scrub_elements(from_file, c1, c2) | |
# Remove blank spaces and null elements | |
if from_file[c1][c2]==" " or from_file[c1][c2]=="": | |
del from_file[c1][c2] | |
return from_file | |
class Resistor: | |
def __init__(self, res_index, res_pos, res_tag): | |
self.res_number=res_index | |
self.res_pos=res_pos | |
self.res_tag=res_tag | |
self.resistor=100.0 | |
def display(self): | |
print "Resistor is ", | |
print self.res_tag, | |
print "= %f" %self.resistor, | |
print " located at ", | |
print self.res_pos | |
def ask_values(self, x_list, ckt_mat): | |
res_params=["Resistor"] | |
res_params.append(self.res_tag) | |
res_params.append(self.res_pos) | |
res_params.append(self.resistor) | |
x_list.append(res_params) | |
def get_values(self, x_list, ckt_mat): | |
self.resistor=float(x_list[0]) | |
class Inductor: | |
def __init__(self, ind_index, ind_pos, ind_tag): | |
self.ind_number=ind_index | |
self.ind_pos=ind_pos | |
self.ind_tag=ind_tag | |
self.inductor=0.001 | |
def display(self): | |
print "Inductor is ", | |
print self.ind_tag, | |
print "=%f" %self.inductor, | |
print " located at ", | |
print self.ind_pos | |
def ask_values(self, x_list, ckt_mat): | |
ind_params=["Inductor"] | |
ind_params.append(self.ind_tag) | |
ind_params.append(self.ind_pos) | |
ind_params.append(self.inductor) | |
x_list.append(ind_params) | |
def get_values(self, x_list, ckt_mat): | |
self.inductor=float(x_list[0]) | |
class Capacitor: | |
def __init__(self, cap_index, cap_pos, cap_tag): | |
self.cap_number=cap_index | |
self.cap_pos=cap_pos | |
self.cap_tag=cap_tag | |
self.capacitor=10.0e-6 | |
def display(self): | |
print "Capacitor is ", | |
print self.cap_tag, | |
print "= %f" %self.capacitor, | |
print " located at ", | |
print self.cap_pos | |
def ask_values(self, x_list, ckt_mat): | |
cap_params=["Capacitor"] | |
cap_params.append(self.cap_tag) | |
cap_params.append(self.cap_pos) | |
cap_params.append(self.capacitor) | |
x_list.append(cap_params) | |
def get_values(self, x_list, ckt_mat): | |
self.capacitor=float(x_list[0]) | |
class Voltage_Source: | |
def __init__(self, volt_index, volt_pos, volt_tag): | |
self.volt_number=volt_index | |
self.volt_pos=volt_pos | |
self.volt_tag=volt_tag | |
self.v_peak=120.0 | |
self.v_freq=60.0 | |
self.v_phase=0.0 | |
def display(self): | |
print "Voltage Source is ", | |
print self.volt_tag, | |
print "of %f V(peak), %f Hz(frequency) and %f (degrees phase shift)" %(self.v_peak, self.v_freq, self.v_phase), | |
print " located at ", | |
print self.volt_pos, | |
print " with positive polarity towards %s %s" %(nw_rd.csv_element(self.v_polrty), self.v_polrty) | |
def ask_values(self, x_list, ckt_mat): | |
volt_params=["VoltageSource"] | |
volt_params.append(self.volt_tag) | |
volt_params.append(self.volt_pos) | |
volt_params.append("Peak (Volts) = %f" %self.v_peak) | |
volt_params.append("Frequency (Hertz) = %f" %self.v_freq) | |
volt_params.append("Phase (degrees) = %f" %self.v_phase) | |
# Looking for a default value of polarity | |
# in the neighbouring cells | |
self.volt_elem=csv_tuple(self.volt_pos) | |
if self.volt_elem[0]>0: | |
if ckt_mat[self.volt_elem[0]-1][self.volt_elem[1]]: | |
self.v_polrty=[self.volt_elem[0]-1, self.volt_elem[1]] | |
elif self.volt_elem[1]>0: | |
if ckt_mat[self.volt_elem[0]][self.volt_elem[1]-1]: | |
self.v_polrty=[self.volt_elem[0], self.volt_elem[1]-1] | |
elif self.volt_elem[0]<len(ckt_mat)-1: | |
if ckt_mat[self.volt_elem[0]+1][self.volt_elem[1]]: | |
self.v_polrty=[self.volt_elem[0]+1, self.volt_elem[1]] | |
elif self.volt_elem[1]<len(ckt_mat)-1: | |
if ckt_mat[self.volt_elem[0]][self.volt_elem[1]+1]: | |
self.v_polrty=[self.volt_elem[0], self.volt_elem[1]+1] | |
volt_params.append("Positive polarity towards (cell) = %s" %nw_rd.csv_element(self.v_polrty)) | |
x_list.append(volt_params) | |
def get_values(self, x_list, ckt_mat): | |
self.v_peak=float(x_list[0].split("=")[1]) | |
self.v_freq=float(x_list[1].split("=")[1]) | |
self.v_phase=float(x_list[2].split("=")[1]) | |
volt_polrty=x_list[3].split("=")[1] | |
# Convert the human readable form of cell | |
# to [row, column] form | |
while volt_polrty[0]==" ": | |
volt_polrty=volt_polrty[1:] | |
self.v_polrty=csv_tuple(volt_polrty) | |
if not ckt_mat[self.v_polrty[0]][self.v_polrty[1]]: | |
print "Polarity incorrect. Branch does not exist at %s" %nw_rd.csv_element(self.v_polrty) | |
component_list={"resistor":Resistor, "inductor":Inductor, "capacitor":Capacitor, "voltagesource":Voltage_Source} | |
test_ckt=open("testckt1.csv","r") | |
# Read the circuit into tst_mat | |
# Also performs a scrubbing of tst_mat | |
tst_mat=nw_rd.csv_reader(test_ckt) | |
components_found={} | |
for c1 in range(len(tst_mat)): | |
for c2 in range(len(tst_mat[0])): | |
elem=tst_mat[c1][c2] | |
if elem: | |
# wire is a zero resistance connection | |
if elem.lower()!="wire": | |
if len(elem.split("_"))==1: | |
print "Error! Component at %s does not have a unique name/tag." %nw_rd.csv_element([c1, c2]) | |
else: | |
[elem_name, elem_tag]=elem.split("_") | |
elem_type=elem_name.lower() | |
if elem_type[0]==" ": | |
elem_type=elem_type[1:] | |
if elem_tag[0]==" ": | |
elem_tag=elem_tag[1:] | |
# Check if component exists | |
if elem_type in component_list.keys(): | |
# If found for the first time | |
# Create that dictionary element with key | |
# as component type | |
if elem_type not in components_found: | |
components_found[elem_type]=[[nw_rd.csv_element([c1, c2]), elem_tag]] | |
else: | |
# If already found, append it to | |
# dictionary item with that key. | |
components_found[elem_type].append([nw_rd.csv_element([c1, c2]), elem_tag]) | |
else: | |
print "Error! Component at %s doesn't exist." %nw_rd.csv_element([c1, c2]) | |
# Check if a component of the same type has the same tag. | |
for items in components_found.keys(): | |
for c1 in range(len(components_found[items])): | |
for c2 in range(len(components_found[items])): | |
if c1!=c2: | |
if components_found[items][c1][1]==components_found[items][c2][1]: | |
print "Duplicate labels found for components of type %s at %s and %s" %(items, components_found[items][c1][0], components_found[items][c2][0]) | |
component_objects={} | |
for items in components_found.keys(): | |
# Take every type of component found | |
# item -> resistor, inductor etc | |
for c1 in range(len(components_found[items])): | |
# Each component type will be occurring | |
# multiple times. Iterate through every find. | |
# The list corresponding to each component is | |
# the unique cell position in the spreadsheet | |
component_objects[components_found[items][c1][0]] = \ | |
component_list[items](c1+1, components_found[items][c1][0], components_found[items][c1][1]) | |
# Check if the nw_params.csv file exists. | |
try: | |
csv_check_values=open("nw_params.csv","r") | |
# If not, it has to be created and filled | |
# with default values. | |
except: | |
#param_flag="no" | |
pass | |
# Check if any of the components with the same | |
# tags are present in nw_params.csv. If so, take | |
# those parameters from nw_params.csv and replace | |
# the default parameters in the component objects. | |
else: | |
params_from_file=reading_params(csv_check_values) | |
for c1 in range(len(params_from_file)): | |
# Remove leading spaces if any | |
# The first column is the type of element | |
if params_from_file[c1][0][0]==" ": | |
params_from_file[c1][0]=params_from_file[c1][0][1:] | |
name_from_file=params_from_file[c1][0].lower() | |
for c2 in range(len(components_found[name_from_file])): | |
# Remove leading spaces if any | |
if params_from_file[c1][1][0]==" ": | |
params_from_file[c1][1]=params_from_file[c1][1][1:] | |
# Check if the component tag exists in | |
# components found so far | |
if params_from_file[c1][1]==components_found[name_from_file][c2][1]: | |
# If so take the parameters and move them into the object | |
# having of that type and having the new cell position | |
component_objects[components_found[name_from_file][c2][0]].get_values(params_from_file[c1][3:], tst_mat) | |
csv_check_values.close() | |
values_to_file=[] | |
for items in component_objects.keys(): | |
# Each component object has a method | |
# ask_values that prints in the csv file | |
# default values for parameters. | |
component_objects[items].ask_values(values_to_file, tst_mat) | |
csv_ask_values=open("nw_params.csv","w") | |
for c1 in range(len(values_to_file)): | |
for c2 in range(len(values_to_file[c1])): | |
csv_ask_values.write("%s" %values_to_file[c1][c2]) | |
csv_ask_values.write(", ") | |
csv_ask_values.write("\n") | |
csv_ask_values.close() | |
# Wait for the user to enter parameters before | |
# reading the nw_params.csv file. | |
cont_ans="n" | |
while cont_ans.lower()!="y": | |
cont_ans=raw_input("Enter parameters in file nw_params.csv. When ready press y and enter to continue -> ") | |
csv_get_values=open("nw_params.csv","r") | |
params_from_file=reading_params(csv_get_values) | |
csv_get_values.close() | |
for c1 in range(len(params_from_file)): | |
# Getting rid of the beginning spaces | |
# in the component keys | |
if params_from_file[c1][2][0]==" ": | |
params_from_file[c1][2]=params_from_file[c1][2][1:] | |
component_objects[params_from_file[c1][2]].get_values(params_from_file[c1][3:], tst_mat) | |
# Just checking the objects | |
for items in component_objects.keys(): | |
component_objects[items].display() | |
No comments:
Post a Comment