Reputation: 51
I have a weird problem when trying create a string when using a dictionary value. Basically, I have a function that opens a file, reads a line, and stores the values it finds in that line in a dictionary. Then, it sends those values to an external program. Here is the code:
def createLandscapes(file):
landscapeParameters = {'FILE': "NULL",
'N': "NULL",
'K': "NULL",
'NUM': "100"}
for line in file:
if line == "END LANDSCAPES\n":
break
else:
parameters = line.replace(" ", '').split(",")
for parameter in parameters:
parameter = parameter.split("=")
if parameter[0] not in landscapeParameters:
malformedFile()
landscapeParameters[parameter[0]] = parameter[1]
for key in landscapeParameters:
if landscapeParameters[key] == "NULL":
malformedFile()
# This print statment is for diagnostic purposes
print("./generateScoreTables {} {} {} {}".format(landscapeParameters['FILE'],
landscapeParameters['N'],
landscapeParameters['K'],
landscapeParameters['NUM']))
os.system("./generateScoreTables {} {} {} {}".format(landscapeParameters['FILE'],
landscapeParameters['N'],
landscapeParameters['K'],
landscapeParameters['NUM']))
To make this very clear, the function looks for a series of parameter inputs on a single, comma separated line, in the form of
FILE=example, N=20, K=5, NUM=100
It takes those inputs and overrides the default inputs (if specified) in landscapeParameters
, and uses the values in landscapeParameters
to call an external program.
The strange this is that the string formatting doesn't seem to work correctly when I use the default parameters in landscapeParameters
. What I mean by this is that if the function reads the line:
FILE=example, N=20, K=5, NUM=100
Everything works correctly, and the print statement prints:
./generateScoreTables example 20 5 100
However, if the function reads the line:
FILE=example, N=20, K=5
Where I've left NUM
out to use the default parameter, I get the following output instead:
./generateScoreTables testland1 15
0 100
Segmentation fault
sh: 2: 0: not found
It appears that format is not formatting this string correctly, but I don't understand why. Does anyone have any insight into this?
Upvotes: 1
Views: 204
Reputation: 866
The problem has already been pointed out to you, but I'm still unable to comment so I'll leave this separate. This would involve reworking your code a little bit.
Once you get to this stage:
parameters = ['FILE=example', 'N=20', 'K=5', 'NUM=100']
# make a list of tuples with [(FILE, default), ('N', 20)...]
pars = [x.split("=") for x in parameters]
Now convert each twople into a Key, value pair in a dictionary dict_of_pars
dict_of_pars = {k: v for k, v in pars}
#dictionary with values for a single line
# {'FILE': 'example', 'N': '20', 'K': '5', 'NUM': '100'}
At this point you will have a dictionary containing all defined parameters for any particular line. If you make a function (that outputs) that holds default values you can send the available arguments for a line using **dict_of_pars in the call
# define output function with default parameters
def output(FILE='example, N='n', K='k', NUM='num'):
os.system(FILE, N, K, NUM)
Now you can call the function using
output(**dict_of_pars) #will unpack the arguments into output function
Made one of these temporary dictionaries for each line in the file, pass it to the output. Hope this helps.
Upvotes: 2
Reputation: 184
You're updating the same variable on every loop, so if it reads one line that doesn't have a particular field it will use the value from the last time it read it.
Instead declare an empty dictionary inside the loop and use the .get
function to have a default value if the key doesn't exist in the dictionary.
def createLandscapes(file):
params = ['FILE','N','K','NUM']
for line in file:
if line == "END LANDSCAPES\n":
break
else:
landscapeParameters = {}
parameters = line.replace(" ", '').split(",")
for parameter in parameters:
parameter = parameter.split("=")
if parameter[0] not in params:
malformedFile()
landscapeParameters[parameter[0]] = parameter[1]
for key in landscapeParameters:
if landscapeParameters[key] == "NULL":
malformedFile()
os.system("./generateScoreTables {} {} {} {}".format(landscapeParameters.get('FILE',''),
landscapeParameters.get('N',''),
landscapeParameters.get('K',''),
landscapeParameters.get('NUM',100)))
You'll probably need to tweak this a little bit, but it should give you more predictable results.
Upvotes: -1