How do I use a variable that is built from other variables? - python

I am trying to build a dynamic URL with some of the information stored in a list. I have loaded the list with some values and then iterate through the list concatenating the value from the list with a prefix. I then want to reference that concatenated value which matches a preloaded variable.
In the below code url_var just returns the name of the variable but not the value of the variable.
base_url_asia = "https://www.location1.com/"
base_url_americas = "https://www.location2.com/"
regions = [asia, americas]
for i in range(len(regions)):
url_var = 'base_url_' + regions[i]
print(url_var)
I expect the output to be the full URL however all I get is base_url_asia or base_url_americas and not the actual url.

You are defining variables that you are not using. 'base_url_' is a string and not a variable. If you want to store different locations using the same variable but with different names, you should use a dictionary.
base_url=dict()
base_url['asia'] = 'www.location1.com'
base_url['americas'] = 'www.location2.com'
continent = ['asia','americas']
for cont in continent:
print(base_url[cont])
Note that cont is not an integer, but is the name of the continents.
I hope you find it useful. Good luck!

Related

How can I make it so that a value becomes "NULL" if there's an Exception?

I'm storing data from an API (that I then store as a pickle) and sometimes there are errors due to missing fields. I'm wondering how I can make it so that it only targets the problematic variable and logs its value as "NULL".
The issue is that I'm storing 6 different variables, so if a single one of them has an issue, all other 5 variables will be skipped. Instead, I want that (or those) problematic variables get replaced by the value "NULL" (or None).
meta = loaded_from_pickle('myData.pickle')
def getAllData():
data = []
for i in range(len(meta)):
try:
name = meta[i]['base']['name']
weight = meta[i]['base']['weight']
height = meta[i]['base']['height']
age = meta[i]['secondary']['age']
eye_color = meta[i]['secondary']['eye_color']
birthday = meta[i]['secondary']['birthday']
data.append((name, weight, height, age, eye_color, birthday))
except:
pass
return data
print(getAllData())
So what happens is that I end up losing a lot of data points because some data doesn't have "eye_color" or whatnot. So what I should do when there's an "except" should be "make problematic variable = "NULL" ", rather than just passing the entire loop.
Instead of accessing the keys directly using square brackets try using get() it returns a default value of None if the key is not found.
See this answer for more info https://stackoverflow.com/a/11041421/3125312
You could use it in your code:
name = meta[i]['base'].get('name')
weight = meta[i]['base'].get('weight')
height = meta[i]['base'].get('height')
...
You could also rewrite your for loop using enumerate assuming meta is a list
for index, value in enumerate(meta):
name = value['base'].get('name')
...

How to define variables dynamically in python?

I need to create variables dynamically based on the data that is coming from my UI.
Sample JSON:
Some of the sample JSON I'll get from UI to hit the python code.
data_json = {'key1':'value1','key2':'value2','key3':['abc','def']}
data_json = {'key1':'value2','key2':'value8','key3':['abc','def','ghi','jklmn']}
data_json = {'key1':'value3','key2':'value9','key3':['abc']}
data_json = {'key1':'value4','key2':'value2','key3':['abc','def','xyz']}
data_json = {'key1':'value6','key2':'value2','key3':['abc','def']}
I have data in JSON format in which the length of the "key3" value will keep changing each time.
I have to capture those values in separate variables and have to use them later in other functions.
If I pass the first data_json first block of if condition will work and assign it to variables. And if I pass the second data_json second block will define the variables.
Python:
secret = data_json['key1']
if secret in ['value1','value6']: ​
​first_value = data_json['key3'][0]
​ second_value = data_json['key3'][1]
if secret in ['value2']:
​ first_value = data_json['key3'][0]
​​ second_value = data_json['key3'][1]
third_value = data_json['key3'][2]
fourth_value = data_json]'key3'][3]
if secret in ['value3']:
first_value = data_json['key3'][0]
if secret in ['value4']:
​ first_value = data_json['key3'][0]
​​ second_value = data_json['key3'][1]
third_value = data_json['key3'][2]
print("Value in first:%s",first_value)
print("Value in second :%s",second_value)
print("Value in third:%s",third_value)
I'm using conditions to capture those variables.The above code is working fine. But I have to avoid using if conditions. Is there any way to define the variables dynamically on the fly and so that i can use it later in same functions?
I don't think you are approaching it the right way. For such cases - where we have unknown number of variables - we use lists! Lists in python are of dynamic size. So, you don't need to know the exact size before creating a list.
Therefore, you can store your numbers in a list and then access them using the indices like this:
all_values = data_json['key3']
print("Value in first:%s", all_-values[0])
print("Value in second :%s", all_values[1])
print("Value in third:%s", all_values[2])
Note that here you don't need conditional statements to make sure you are reading the exact number of values (not more or less) from the JSON.
What you are calling dynamic variables are not needed! Wherever you need first_value, you can use all_values[0]. For, second_value, you can use all_values[1] and so on...
The best way to solve your problem is to save the values in an array and access then via indices, rather than creating separate variables for each element in the array.
data_json = {'key1':'value2','key2':'value8','key3':['abc','def','ghi','jklmn']}
key3_vars = data_json['key3']
for var in key3_vars:
print(var)
But if you have to create separate variables, then you can use the built-in function exec.
data_json = {'key1':'value2','key2':'value8','key3':['abc','def','ghi','jklmn']}
key3_vars = data_json['key3']
for i, var in enumerate(key3_vars):
exec(f"key3_var{i} = '{var}'")
print(key3_var0)
print(key3_var1)
print(key3_var2)
print(key3_var3)

How to iterate to create variables in a list

Suppose I have the following code:
classifiers_name_all = [('AdaBoostClassifier', AdaBoostClassifier(), 'AdaBoost'),
('BernoulliNB', BernoulliNB(), 'Bernoulli Naive Bayes'),
('DummyClassifier', DummyClassifier(), 'Dummy Classifier')]
clf_values = []
for clf_na in classifiers_name_all:
clf_values.append((locals()['score_'+clf_na[0]+'_mean'], locals()['score_'+clf_na[0]+'_stddev']))
clf_values
The code above doesn't quite work.
I want to get a list which contains the variables:
clf_values = [(score_AdaBoostClassifier_mean, score_AdaBoostClassifier_stddev),
(score_BernoulliNB_mean, score_BernoulliNB_stddev)
(score_DummyClassifier_mean, score_DummyClassifier_stddev)]
How do I do this? Many thanks.
From whatever info you have given so far, I infer that there are no key errors and the resultant list is a list containing nones.
This can only mean, that your code works fine but the variables u are trying to access have 'None' values assigned to them. Check why your values are having None values and once that is fixed, this list will get desired values.

Parsing and arranging text in python

I'm having some trouble figuring out the best implementation
I have data in file in this format:
|serial #|machine_name|machine_owner|
If a machine_owner has multiple machines, I'd like the machines displayed in a comma separated list in the field. so that.
|1234|Fred Flinstone|mach1|
|5678|Barney Rubble|mach2|
|1313|Barney Rubble|mach3|
|3838|Barney Rubble|mach4|
|1212|Betty Rubble|mach5|
Looks like this:
|Fred Flinstone|mach1|
|Barney Rubble|mach2,mach3,mach4|
|Betty Rubble|mach5|
Any hints on how to approach this would be appreciated.
You can use dict as temporary container to group by name and then print it in desired format:
import re
s = """|1234|Fred Flinstone|mach1|
|5678|Barney Rubble|mach2|
|1313|Barney Rubble||mach3|
|3838|Barney Rubble||mach4|
|1212|Betty Rubble|mach5|"""
results = {}
for line in s.splitlines():
_, name, mach = re.split(r"\|+", line.strip("|"))
if name in results:
results[name].append(mach)
else:
results[name] = [mach]
for name, mach in results.items():
print(f"|{name}|{','.join(mach)}|")
You need to store all the machines names in a list. And every time you want to append a machine name, you run a function to make sure that the name is not already in the list, so that it will not put it again in the list.
After storing them in an array called data. Iterate over the names. And use this function:
data[i] .append( [ ] )
To add a list after each machine name stored in the i'th place.
Once your done, iterate over the names and find them in in the file, then append the owner.
All of this can be done in 2 steps.

use slice in for loop to build a list

I would like to build up a list using a for loop and am trying to use a slice notation. My desired output would be a list with the structure:
known_result[i] = (record.query_id, (align.title, align.title,align.title....))
However I am having trouble getting the slice operator to work:
knowns = "output.xml"
i=0
for record in NCBIXML.parse(open(knowns)):
known_results[i] = record.query_id
known_results[i][1] = (align.title for align in record.alignment)
i+=1
which results in:
list assignment index out of range.
I am iterating through a series of sequences using BioPython's NCBIXML module but the problem is adding to the list. Does anyone have an idea on how to build up the desired list either by changing the use of the slice or through another method?
thanks zach cp
(crossposted at [Biostar])1
You cannot assign a value to a list at an index that doesn't exist. The way to add an element (at the end of the list, which is the common use case) is to use the .append method of the list.
In your case, the lines
known_results[i] = record.query_id
known_results[i][1] = (align.title for align in record.alignment)
Should probably be changed to
element=(record.query_id, tuple(align.title for align in record.alignment))
known_results.append(element)
Warning: The code above is untested, so might contain bugs. But the idea behind it should work.
Use:
for record in NCBIXML.parse(open(knowns)):
known_results[i] = (record.query_id, None)
known_results[i][1] = (align.title for align in record.alignment)
i+=1
If i get you right you want to assign every record.query_id one or more matching align.title. So i guess your query_ids are unique and those unique ids are related to some titles. If so, i would suggest a dictionary instead of a list.
A dictionary consists of a key (e.g. record.quer_id) and value(s) (e.g. a list of align.title)
catalog = {}
for record in NCBIXML.parse(open(knowns)):
catalog[record.query_id] = [align.title for align in record.alignment]
To access this catalog you could either iterate through:
for query_id in catalog:
print catalog[query_id] # returns the title-list for the actual key
or you could access them directly if you know what your looking for.
query_id = XYZ_Whatever
print catalog[query_id]

Categories

Resources