I'm in the situation where the enduser can define a variable name by himself.
For instance: a variable called "tbm_al" is correct.
In order to pprint variable as latex, I'm using sympy.latex and expecting to have something like "tbm" with "al" as indice, but bm is translated in boldsymbol.
Is there a way to have both "tbm" with indice "al" and neither t (bold) with indice al nor tbm_al as string ?
like:
\begin{equation*}\begin{equation}{tbm}_{al}\end{equation}\end{equation*}
This autotranslation of bm is performed by the Sympy latex printer (sympy.printing.latex), specifically as bm is an entry in the variable modifiers dictionary modifier_dict declared in sympy.printing.latex. I see no way in the source to disable the use of the modifier dict upon call latex(expr, **settings); from what I can see, not settings are not used anywhere in the same context as the modifier_dict dictionary.
Have a look at e.g. the function translate(s) in the source:
def translate(s):
Check for a modifier ending the string. If present, convert the
modifier to latex and translate the rest recursively.
...
From the source of this function, it's quite clear that the modifier dictionary will be checked (recursively) for all entries in the argument expression.
The remaining option would then be to manually modify the name modifiers (modifier_dict) in your own custom source copy of sympy.printing.latex (or, alternatively, in the original), by simply removing the dictionary entry for key bm. This is, of course, unless you want to make use of bm elsewhere.
See also:
http://docs.sympy.org/dev/modules/printing.html#sympy.printing.latex.latex
Thx to #dfri. I decided to clear modifier_dict during latex translate.
from sympy.printing.latex import modifier_dict
from sympy import latex
def cancel_sympy_translate(f):
def wrapper(*args, **kwargs):
saved_dict = dict(modifier_dict)
modifier_dict.clear()
result = f(*args, **kwargs)
modifier_dict.update(saved_dict)
return result
return wrapper
latex = cancel_sympy_translate(latex)
t = Symbol("tbm_al")
print latex(t, mode="equation")
\begin{equation}tbm_{al}\end{equation}
with the "keep_translate_keys". (suggested by #dfri)
def cancel_sympy_translate(f, keep_translate_keys=None):
keep_translate_keys = keep_translate_keys or []
def remove_unwanted_keys(modif_dict):
for k in modif_dict.keys():
if k in keep_translate_keys:
continue
del modif_dict[k]
def wrapper(*args, **kwargs):
saved_dict = dict(modifier_dict)
remove_unwanted_keys(modifier_dict)
result = f(*args, **kwargs)
modifier_dict.update(saved_dict)
return result
return wrapper
latex = cancel_sympy_translate(latex, keep_translate_keys=["bar"])
t = Symbol("tbm_abar")
print latex(t, mode="equation")
\begin{equation}tbm_{\bar{a}}\end{equation}
Related
What's the cleanest way (from user's side) to memoize an entire block of computation (a multi-line lambda, if those were possible to create) in Python?
With memoize I intend a generic "If the result was already computed, just load it from somewhere. Otherwise compute it and save it somewhere."
My current solution (for writing something that caches to disk the result of arbitrary computations) is:
Have one decorator that does the caching (it takes the file name where to save/load as parameter):
from functools import wraps
def disk_cache(filename):
def decorator(compute_result_func):
#wraps(compute_result_func) # don't shadow function's docstring
def wrapped(*args, **kwargs):
if not os.path.exists(filename):
# compute and save
print "compute"
result = compute_result_func()
print "save"
pickle.dump(result, open(filename, 'wb'))
else:
# load
print "load"
result = pickle.load(open(filename, 'rb'))
return result
return wrapped
return decorator
Whenever I have a block of computations I would like to memoize, I wrap it into a function with a generic name (I would use a multi-line lambda if I could) that takes nothing (just captures variables that are in the larger scope) and returns a single result. I decorate this function with my decorator, and I immediately call the function.
#disk_cache(filename='/path/to/dump.pkl')
def multi_line_lambda():
# do some stuff
x = 2 ** 2
y = 7
return x + y
multi_line_lambda()
Is it possible to use a pattern which is syntactically cleaner? Something like
with cache(filename):
do x
do y
return result # which is actually just loaded if already existing
I explored this exact question in the past (shameless plug: here is my result) and found it's better to use your existing approach. However, if you are willing to abuse Python syntax, here is how you can do it:
def disk_cache(filename):
def decorator(compute_result_func):
if not os.path.exists(filename):
result = compute_result_func()
pickle.dump(result, open(filename, 'wb'))
else:
result = pickle.load(open(filename, 'rb'))
return result
return decorator
Now,
#disk_cache(filename='/path/to/dump.pkl')
def calculated_stuff():
# do some stuff
x = 2 ** 2
y = 7
return x + y
# at this point, calculated_stuff() already contains the result (11)
Please, remember it is a dirty practice. Don't do it in code somebody else can read
I have a project in which I run multiple data through a specific function that "cleans" them.
The cleaning function looks like this:
Misc.py
def clean(my_data)
sys.stdout.write("Cleaning genes...\n")
synonyms = FileIO("raw_data/input_data", 3, header=False).openSynonyms()
clean_genes = {}
for g in data:
if g in synonyms:
# Found a data point which appears in the synonym list.
#print synonyms[g]
for synonym in synonyms[g]:
if synonym in data:
del data[synonym]
clean_data[g] = synonym
sys.stdout.write("\t%s is also known as %s\n" % (g, clean_data[g]))
return data
FileIO is a custom class I made to open files.
My question is, this function will be called many times throughout the program's life cycle. What I want to achieve is don't have to read the input_data every time since it's gonna be the same every time. I know that I can just return it, and pass it as an argument in this way:
def clean(my_data, synonyms = None)
if synonyms == None:
...
else
...
But is there another, better looking way of doing this?
My file structure is the following:
lib
Misc.py
FileIO.py
__init__.py
...
raw_data
runme.py
From runme.py, I do this from lib import * and call all the functions I made.
Is there a pythonic way to go around this? Like a 'memory' for the function
Edit:
this line: synonyms = FileIO("raw_data/input_data", 3, header=False).openSynonyms() returns a collections.OrderedDict() from input_data and using the 3rd column as the key of the dictionary.
The dictionary for the following dataset:
column1 column2 key data
... ... A B|E|Z
... ... B F|W
... ... C G|P
...
Will look like this:
OrderedDict([('A',['B','E','Z']), ('B',['F','W']), ('C',['G','P'])])
This tells my script that A is also known as B,E,Z. B as F,W. etc...
So these are the synonyms. Since, The synonyms list will never change throughout the life of the code. I want to just read it once, and re-use it.
Use a class with a __call__ operator. You can call objects of this class and store data between calls in the object. Some data probably can best be saved by the constructor. What you've made this way is known as a 'functor' or 'callable object'.
Example:
class Incrementer:
def __init__ (self, increment):
self.increment = increment
def __call__ (self, number):
return self.increment + number
incrementerBy1 = Incrementer (1)
incrementerBy2 = Incrementer (2)
print (incrementerBy1 (3))
print (incrementerBy2 (3))
Output:
4
5
[EDIT]
Note that you can combine the answer of #Tagc with my answer to create exactly what you're looking for: a 'function' with built-in memory.
Name your class Clean rather than DataCleaner and the name the instance clean. Name the method __call__ rather than clean.
Like a 'memory' for the function
Half-way to rediscovering object-oriented programming.
Encapsulate the data cleaning logic in a class, such as DataCleaner. Make it so that instances read synonym data once when instantiated and then retain that information as part of their state. Have the class expose a clean method that operates on the data:
class FileIO(object):
def __init__(self, file_path, some_num, header):
pass
def openSynonyms(self):
return []
class DataCleaner(object):
def __init__(self, synonym_file):
self.synonyms = FileIO(synonym_file, 3, header=False).openSynonyms()
def clean(self, data):
for g in data:
if g in self.synonyms:
# ...
pass
if __name__ == '__main__':
dataCleaner = DataCleaner('raw_data/input_file')
dataCleaner.clean('some data here')
dataCleaner.clean('some more data here')
As a possible future optimisation, you can expand on this approach to use a factory method to create instances of DataCleaner which can cache instances based on the synonym file provided (so you don't need to do expensive recomputation every time for the same file).
I think the cleanest way to do this would be to decorate your "clean" (pun intended) function with another function that provides the synonyms local for the function. this is iamo cleaner and more concise than creating another custom class, yet still allows you to easily change the "input_data" file if you need to (factory function):
def defineSynonyms(datafile):
def wrap(func):
def wrapped(*args, **kwargs):
kwargs['synonyms'] = FileIO(datafile, 3, header=False).openSynonyms()
return func(*args, **kwargs)
return wrapped
return wrap
#defineSynonyms("raw_data/input_data")
def clean(my_data, synonyms={}):
# do stuff with synonyms and my_data...
pass
In Matlab, nargout is a variable that tells you if the output is assigned, so
x = f(2);
and
f(2);
can behave differently.
Is it possible to do similar in Python?
I have a function that plots to screen and returns a matplotlib figure object. I want that if output is assigned to a variable then do not plot to screen.
Here's a way you can do it (not that i'd advise it), but it has many cases where it won't work - to make it work you'd essentially need to parse the python code in the line and see what it is doing, which would be possible down to some level, but there are likely always going to be ways to get around it.
import inspect, re
def func(x, noCheck=False):
if not noCheck:
#Get the line the function was called on.
_, _, _, _, lines, _ = inspect.getouterframes(inspect.currentframe())[1]
#Now we need to search through `line` to see how the function is called.
line = lines[0].split("#")[0] #Get rid of any comments at the end of the line.
match = re.search(r"[a-zA-Z0-9]+ *= *func\(.*\)", line) #Search for instances of `func` being called after an equals sign
try:
variable, functioncall = match.group(0).split("=")
print variable, "=", functioncall, "=", eval(functioncall.strip()[:-1] + ", noCheck=True)")
except:
pass #print "not assigned to a variable"
#Actually make the function do something
return 3*x**2 + 2*x + 1
func(1) # x = func(1)
x = func(1)
Another way to do it would be to examine all of the set local variables when you call the code, and check if any of them have been set to the result of your function, then use that information to help parse the python.
Or you could look at object IDs, and try and do things that way, but that's not goign to be straightforward, as not all objects work the same way (i.e. do a=10 and c=10 and then have a look at each object's IDs, they're the same ven though a and c are seperate. The same happens with short strings too)
If you can think up a way to do this that would work universally, i'd be interested to know how you do it, I'd pressume it will need to be done by digging around in inspect though, rather than through parsing the actual code.
Others have mentioned that this is complex, but can be done with inspect. You may want a simple approach by having a separate function to plot it, or pass an extra variable that says to plot.
def create_plot(x):
return plot
def display(plot):
# show the plot
x = create_plot(2)
display(x)
Plot variable
def plot(x, show=False)
# create the plot
if show:
# show the plot
plot(2, True)
x = plot(2)
It is probably not worth the time and easier to just create the two functions.
Personally, I think this is ugly, nasty, and I do not believe that functionality should be based on something catching the return value. However, I was curious, and I found a way. You could probably turn this into a decorator if you want to use it in the future, but I still suggest that you use two separate methods instead of checking for an output.
import inspect
def f(val):
has_output = False
frame = inspect.currentframe()
name = frame.f_code.co_name
outer = inspect.getouterframes(frame)[1] # may want to loop through available frames.
for i in range(len(outer)):
item = str(outer[i]).replace(" ", "")
check = "="+name+"("
if check in item and "="+check not in item: # also check assignment vs equality
# Your method has an output
has_output = True
break
if has_output:
print("Something catches the output")
return val*val
# end f
In many cases this will not work either. You will have to make really good regex for the check if you always want it to work.
import my_lib
x = my_lib.f(2)
[I am using python 2.7]
I wanted to make a little wrapper function that add one output to a function. Something like:
def add_output(fct, value):
return lambda *args, **kargs: (fct(*args,**kargs),value)
Example of use:
def f(a): return a+1
g = add_output(f,42)
print g(12) # print: (13,42)
This is the expected results, but it does not work if the function given to add_ouput return more than one output (nor if it returns no output). In this case, the wrapped function will return two outputs, one contains all the output of the initial function (or None if it returns no output), and one with the added output:
def f1(a): return a,a+1
def f2(a): pass
g1 = add_output(f1,42)
g2 = add_output(f2,42)
print g1(12) # print: ((12,13),42) instead of (12,13,42)
print g2(12) # print: (None,42) instead of 42
I can see this is related to the impossibility to distinguish between one output of type tuple and several output. But this is disappointing not to be able to do something so simple with a dynamic language like python...
Does anyone have an idea on a way to achieve this automatically and nicely enough, or am I in a dead-end ?
Note:
In case this change anything, my real purpose is doing some wrapping of class (instance) method, to looks like function (for workflow stuff). However it is require to add self in the output (in case its content is changed):
class C(object):
def f(self): return 'foo','bar'
def wrap(method):
return lambda self, *args, **kargs: (self,method(self,*args,**kargs))
f = wrap(C.f)
c = C()
f(c) # returns (c,('foo','bar')) instead of (c,'foo','bar')
I am working with python 2.7, so I a want solution with this version or else I abandon the idea. I am still interested (and maybe futur readers) by comments about this issue for python 3 though.
Your add_output() function is what is called a decorator in Python. Regardless, you can use one of the collections module's ABCs (Abstract Base Classes) to distinguish between different results from the function being wrapped. For example:
import collections
def add_output(fct, value):
def wrapped(*args, **kwargs):
result = fct(*args, **kwargs)
if isinstance(result, collections.Sequence):
return tuple(result) + (value,)
elif result is None:
return value
else: # non-None and non-sequence
return (result, value)
return wrapped
def f1(a): return a,a+1
def f2(a): pass
g1 = add_output(f1, 42)
g2 = add_output(f2, 42)
print g1(12) # -> (12,13,42)
print g2(12) # -> 42
Depending of what sort of functions you plan on decorating, you might need to use the collections.Iterable ABC instead of, or in addition to, collections.Sequence.
In Python, I'm trying to implement a pseudo-ternary operator within a template string. A value is inserted into a string if kwargs has a specific key.
re module has a way do exactly what I need in re.sub(), you can pass a function to be called on matches. What I can't do is to pass **kwargs to it. Code follows
import re
template_string = "some text (pseudo_test?val_if_true:val_if_false) some text"
def process_pseudo_ternary(match, **kwargs):
if match.groups()[0] in kwargs:
return match.groups()[1]
else:
return match.groups()[2]
def process_template(ts, **kwargs):
m = re.compile('\((.*)\?(.*):(.*)\)')
return m.sub(process_pseudo_ternary, ts)
print process_template(template_string, **{'pseudo_test':'yes-whatever', 'other_value':42})
line if match.groups()[0] in kwargs: is the problem of course, as process_pseudo_ternary's kwargs are empty.
Any ideas on how to pass these? m.sub(function, string) doesn't take arguments.
The final string is to be: some text val_if_true some text (because the dictionary has the key named 'pseudo_test').
Feel free to redirect me to a different implementation of ternary operator in a string. I'm aware of Python conditional string formatting . I need the ternary to be in the string, not in the string's formatting tuple/dict.
If i understand it correctly, you could use something like http://docs.python.org/library/functools.html#functools.partial
return m.sub(partial(process_pseudo_ternary, custom_1=True, custom_2=True), ts)
EDIT: Changed a little, to match your code better.