Description
I have a script → report_creator.py which will need some variables from another python script → extracted_data.py.
The number of variables from extracted_data.py will always be based on the system it extracts data from (if the system has 1 server, we will have 1 variable, if the system has 2 servers, we will have 2 variables and so on). You can never know the exact number of variables the extracted_data.py will have.
Let's say we have extracted data from a system with 2 servers and the extracted_data.py file looks something like:
parameterx_server1 = "value"
parameterx_server2 = "another value"
What I have: → report_creator.py:
import os
import extracted_data
#Extract all variables names starting with parameterx from extracted_data.py and store them into a list
variables = os.popen("""cat extracted_data.py | grep '^parameterx_*' | awk '{print $1}'""").read().strip()
variables = variables.split("\n")
#After the execution of the command, the list looks like this:
# variables = ['parameterx_server1', 'parameterx_server2']
Problem
The script now has a list containing all the parameterx variables from extracted_data.py:
variables = ['parameterx_server1', 'parameterx_server2']
The only thing remaining is to get the corresponding value of each variable from the variables list from the extracted_data.py, something like:
print extracted_data.parameterx_server1
I tried something like:
for variable in variables:
print extracted_data.variable
But for some reason I get an AttributeError: 'module' object has no attribute 'variable'.
You can extract the variables and their value defined in the extracted_data.py file like this:
import extracted_data
extract_vars = {name: getattr(extracted_data, name)
for name in dir(extracted_data) if not name.startswith('_')}
print(extract_vars) # -> {'parameterx_server2': 'another value', 'parameterx_server1': 'value'}
As shown, afterwards extract_vars is a dictionary containing both the variable names and associated values.
Related
If I pass the string ${varName} to the built in keyword Log to Console, the console outputs the literal string ${varName}. If there is a variable named varName with a value of test123, how do I get the keyword Log to Console to output the variable value of test123 when I pass in ${varName}?
I'm making a data-driven script from an Excel spreadsheet. In the string values I'm passing in, there are variables names within it that I want replaced with the variable's value.
I've tried to run the string through the Evaluate keyword, but it just changes all of the variable names like ${varName} to RF_VAR_varName, so it's recognizing something here?
Open Excel ${ExcelFile}
${varName} Read Cell Data By Coordinates ${Sheet_Name} 0 ${RowNum}
set global variable ${varName}
log varName: ${varName} console=yes
Would output to the console:
'38773461|${TMS_ConfNo}|substr:RDSJUMHV FIRSTNAME|${globalLastName} FIRSTNAME|fullline:JEYCTINY, FIRSTNAME|${globalLastName1}, FIRSTNAME|fullline:RDSJUMHV, FIRSTNAME|${globalLastName}, FIRSTNAME|fullline'
I would like this string:
'38773461|${TMS_ConfNo}|substr:RDSJUMHV FIRSTNAME|${globalLastName} FIRSTNAME|fullline:JEYCTINY, FIRSTNAME|${globalLastName1}, FIRSTNAME|fullline:RDSJUMHV, FIRSTNAME|${globalLastName}, FIRSTNAME|fullline'
To evaluate into this:
'38773461|12345678|substr:RDSJUMHV FIRSTNAME|LASTNAME FIRSTNAME|fullline:JEYCTINY, FIRSTNAME|LASTNAME1, FIRSTNAME|fullline:RDSJUMHV, FIRSTNAME|LASTNAME, FIRSTNAME|fullline'
I would like all variables in the string to translate to their respective value.
Robot has a built-in keyword named Replace variables which will replace variables with their values in a string.
I have a jinja template that I want to pass a value into (an identifier for a country). The format of the data is a two letter country code (for example "PL" for Poland).
Through the template, I need to pass the corresponding flag as an output, but the flag is saved in the app folder structure, so i need to get the path to the image.
My problem: I could not figure out a way to use os.path in jinja, so now im trying to solve it by creating a dictionary that matches country string and relative path like this:
countries = {"PL" : "countries/flags/poland.png"}
where the system path to the app folder gets added afterwards in Python through os.path.
My question: How can i use the country string I am getting to automate transformation into the path format of the country? Something like:
for data in countries:
if data in countries.keys:
return countries.value
Thanks in advance!
Assuming data is a country code (like "PL" for example):
def get_path(data):
return countries.get(data)
The get() method checks if the dictionary has the key, and if so returns the corresponding value, otherwise it returns None.
If you want a default value other than None when the key is not present you can specify it as second argument, like this:
def get_path(data):
return countries.get(data, "default/path/x/y/z")
I have latex document in which there are various fields and there values are to be generated dynamically. So, what i am planning is to have python script which will generate values related to field and then insert it inside the latex document. The document looks as follows:
Project = ABC
Version = 1.0.0
Date = xyz
Now the values of project , version and date are to be filled by using python script. So, please help me how can i have the values inside latex document. I searched and have got generating the whole latex document from python but i want the two processes to be seperate. So, please help. I have with me the latex document code so, i realy don't want to play around with the code as its completly new to me, i just want to feed values inside the various fields using python.
If I understand your intention, I would just replace the values within the LaTeX source by named variables, such as $project instead of ABC, $version instead of 1.0.0 etc. Then you can run the following Python script to substitute these named variables by their actual values. This assumes that the LaTeX source doesn't contain other occurrences of text conflicting with the variable syntax $xy. If it is not the case, other syntax can be chosen.
You didn't specify how you get the values into the python program. Here I assume you can define them statically within the python code.
The program will fail when an undefined variable name (not present in the dictionary) is found within the source file. It could also be changed to leave such text unchanged or replace it by empty string depending on your needs.
#!/usr/bin/env python
import sys
import re
variables = {
'project': 'ABC',
'version': '1.0.0',
'date': 'xyz',
}
def run(args):
if len(args) == 1:
filename = args[0]
else:
sys.stderr.write("Filename must be passed as argument.\n")
sys.exit(1)
regex = re.compile(r"\$([a-zA-Z][a-zA-Z_]*)")
with open(filename) as f:
for line in f:
sys.stdout.write(regex.sub(lambda m: variables[m.group(1)], line))
if __name__ == '__main__':
run(sys.argv[1:])
I have written some code in Python and I would like to save some of the variables into files having the name of the variable.
The following code:
variableName1 = 3.14
variableName2 = 1.09
save_variable_to_file(variableName1) # function to be defined
save_variable_to_file(variableName1)
should create 2 files, one named variableName1.txt and the other one variableName2.txt and each should contain the value of the corresponding variable at the time the function was called.
This variable name is supposed to be unique in the code.
Thanks!
HM
It is possible to find the name of a variable, a called function can get its caller's variables using:
import sys
def save_variable_to_file(var):
names = sys._getframe(1).f_globals
names.update(sys._getframe(1).f_locals)
for key in names.keys():
if names[key] == var:
break
if key:
open(key+".txt","w").write(str(var))
else:
print(key,"not found")
thing = 42
save_variable_to_file(thing)
But it is probably a really bad idea. Note that I have converted the value to a string, how would you want dictionaries and lists to be saved? How are you going to reconstruct the variable later?
import glob
for fname in glob.iglob("*.txt"):
vname = fname.rstrip(".txt")
value = open(fname).read()
exec(vname + "=" + value)
print(locals())
Using something like exec can be a security risk, it is probably better to use something like a pickle, JSON, or YAML.
No, this won't work. When you write the variable name there, it gives the value of the variable, 3.14 and so on, to save_variable_to_file(). Try one of these variants:
d = dict(my_variable_name=3.14)
save_variable_to_file('my_variable_name', d['my_variable_name'])
or:
var_name = 'my_variable_name'
d = {var_name: 3.14}
save_variable_to_file(var_name, d[var_name])
Here is a good tutorial, that you should definitely go through, if you're serious about learning Python.
Unfortunately it is not possible to find out the name of a variable. Either you extend your function to also allow a string as a parameter, or you have to use another solution:
save_variable_to_file("variableName1", variableName1)
Another solution would be to store your variables within a dict which allows the retrieval of the keys as well:
myVariables = {}
myVariables["variableName1"] = 3.14
for key, value in myVariables.items():
save_variable_to_file(key, value)
How about using a dict:
var_dict = {'variable1': 3.14, 'variable2':1.09}
for key, value in var_dict.items():
with open('path\%s'%key, "w") as file:
file.write(value)
for key, value in locals().items():
with open(key + '.txt', 'w') as f:
f.write(value)
should do your trick - as long as all locally defined variables are to be considered.
A far better solution, however, would be to put all you need into a dict and act as the others already proposed.
You could even do this:
def save_files(**files):
for key, value in files.items():
with open(key + '.txt', 'w') as f:
f.write(value)
and then
save_files(**my_previously_defined_dict)
save_files(**locals()) # as example above
save_files(filename='content')
Variables don't have names. When your script runs it creates one or more identifiers for some of the objects it interacts with commonly called variables, but these are temporary and cease to exist when the program ends. Even if you save them, you will then be faced with the reverse problem of how to turn them back into an identifier with saved name associated with the saved value.
If you want to get the name of your variable as string, use python-varname package (python3):
from varname import nameof
s = 'Hey!'
print (nameof(s))
Output:
s
Get the package here:
https://github.com/pwwang/python-varname
I've inherited a python script that is pulling some variables from a default.conf file which I believe is a Machine configuration file.
One of the parts of the script is pulling a configuration key from the .conf file and expecting there to be a list of possible options however right now there is just one option and I'm unsure of how to make it so there are multiple options.
[syndication]
name = Test Name
title = Test Title
categories = Category 1
So in the above example the config key is syndication and the variable I'm trying to add multiple options to is category.
Thanks!
If there are too few values that fit on one line, I would choose to separate them by commas as exemplified by other fellows, otherwise per RFC822 standard you can split values by lines started by tabs:
settings.conf:
[syndication]
name = Test Name
title = Test Title
categories =
Category 1
Category 2
Category 3
settings.py:
#!/usr/bin/python
import ConfigParser
config = ConfigParser.ConfigParser()
# Reading
config.readfp(open('settings.conf'))
categories = config.get('syndication', 'categories').strip().split('\n')
# Appending
categories.append('Category 4')
# Changing
config.set('syndication', 'categories', '\n' + '\n'.join(categories))
# Storing
config.write(open('settings.conf', 'w'))
Your new settings.conf:
[syndication]
name = Test Name
title = Test Title
categories =
Category 1
Category 2
Category 3
Category 4
Note: You can put a value in the first line after the : or =, but being a list of values, I think starting from the second line is more "readable" when you've to manually edit the file.
I don't think you have a list type in configuration files. However you can do something like comma delimited values:
[syndication]
name = Test Name
title = Test Title
categories = Category 1, Category 2
Then in your code split the values by ,
values = [value.strip() for value in cfg.get('syndication', 'categories').split(',')]
You haven't mentioned how you're reading the .conf file, so I'll assume you're using ConfigParser.
I tried setting categories to a tuple and using ConfigParser.write, and ended up with a string representation of the tuple in the resulting file. This implies to me that ConfigParser doesn't support multiple options.
You can always break up an option manually:
categories = [option.strip() for option in config.get('syndication', 'categories').split(',')]
It is perhaps working the same way as python's logging configuration file format? In this case categories would be a comma separated list (In case of logging configuration files, every item is referring to a specific section in the config file)