I am a total iPython newbie, but I was wondering if there is a way to get the value of the last assigned variable:
In [1]: long_variable_name = 333
In [2]: <some command/shortcut that returns 333>
In R we have .Last.value:
> long_variable_name = 333
> .Last.value
[1] 333
There's a shortcut for the last returned object, _.
In [1]: 1 + 3
Out[1]: 4
In [2]: _
Out[2]: 4
You can use IPython's In and Out variables which contain the commands/statements entered and the the corresponding output (if any) of those statements.
So, a naive approach would be to use those variables as the basis of defining a %last magic method.
However, since not all statements necessarily generate output, In and Out are not synchronous.
So, the approach I came up with was to parse In, and look for the occurrences of = and parse those lines for the output:
def last_assignment_value(self, parameter_s=''):
ops = set('()')
has_assign = [i for i,inpt in enumerate(In) if '=' in inpt] #find all line indices that have `=`
has_assign.sort(reverse=True) #reverse sort, because the most recent assign will be at the end
for idx in has_assign:
inpt_line_tokens = [token for token in In[idx].split(' ') if token.strip() != ''] #
indices = [inpt_line_tokens.index(token) for token in inpt_line_tokens if '=' in token and not any((c in ops) for c in token)]
#Since assignment is an operator that occurs in the middle of two terms
#a valid assignment occurs at index 1 (the 2nd term)
if 1 in indices:
return ' '.join(inpt_line_tokens[2:]) #this simply returns on the first match with the above criteria
And, lastly to make that your own custom command in IPython:
get_ipython().define_magic('last', last_assignment_value)
And, now you can call:
%last
And this will output the term assigned as a string (which may not be what you want).
However, there is a caveat to this: in that if you had entered incorrect input that involved assignment; e.g.: (a = 2), this method will pick it up. And, if your assignment involved variables: e.g. a = name, this method will return name and the not the value of name.
Given that limitation, you can then use the parser module to try and evaluate the expression like this (which can be appended to last_assignment_value in the last if statement):
import parser
def eval_expression(src):
try:
st = parser.expr(src)
code = st.compile('obj.py')
return eval(code)
except SyntaxError:
print 'Warning: there is a Syntax Error with the RHS of the last assignment! "%s"' % src
return None
However, given the possible evils of eval, I've left that inclusion up to you.
But, to be perfectly honest, a truly wholesome method would involve a parsing of the statement to verify the validity of the found input, as well as the input before it and more.
REFERENCES:
https://gist.github.com/fperez/2396341
Related
I have some troubles understanding the way the format() method of string works.
Suppose that I set a string variable with keywords arguments:
s = '{hello} {person_name}'
I could either assign this value to another variable or print it. In the latter case, the result would be {hello} {person_name}.
I could also use the format() method while printing s and assign some values to the keywords:
print(s.format(hello='hello', person_name='Alice'))
In this case, the result is hello Alice. Of course, I could also assign it to a new variable.
My problem arises when I want to use format only on one keyword:
print(s.format(hello='hello'))
or
a = s.format(hello='hello')
Both of them throw an error:
KeyError: 'person_name'
I want to be able to run something like :
s = '{hello} {person_name}'
a = s.format(hello='hello')
if something:
b = a.format(person_name='Alice')
else:
b = a.format(person_name='Bob')
print(b)
Is something like this possible or should I set all keywords when I use format()?
In your use case, you might consider escaping the {person} in the string:
# double brace the person_name to escape it for the first format
s = '{hello} {{person_name}}'
a = s.format(hello='hello')
# a = 'hello {person_name}'
if something:
b = a.format(person_name='Alice')
# b = 'hello Alice'
else:
b = a.format(person_name='Bob')
# b = 'hello Bob'
print(b)
With this method however you will need to follow the explicit order in which you escaped your variables. i.e. you must assign hello first and then person_name. If you need to be flexible about the order of things, I would suggest using a dict to construct the variables before passing it altogether:
# dict approach
s = '{hello} {person_name}'
# determine the first variable
d = {'hello':'hello'}
... do something
d.update({'person': 'Alice'})
# unpack the dictionary as kwargs into your format method
b = s.format(**d)
# b = 'hello Alice'
This gives you a bit more flexibility on the order of things. But you must only call .format() once all the variables are provided in your dict (at least it must have a default value), otherwise it'll still raise an error.
If you want to be more fancy and want the ability to print the field names at the absence of the variable, you can make your own wrapper function as well:
# wrapper approach
# We'll make use of regex to keep things simple and versatile
import re
def my_format(message, **kwargs):
# build a regex pattern to catch words+digits within the braces {}
pat = re.compile('{[\w\d]+}')
# build a dictionary based on the identified variables within the message provided
msg_args = {v.strip('{}'): v for v in pat.findall(message)}
# update the dictionary with provided keyword args
msg_args.update(kwargs)
# ... and of course, print it
print(message.format(**msg_args))
s = 'Why {hello} there {person}'
my_format(s, hello='hey')
# Why hey there {person}
my_format(s, person='Alice')
# Why {hello} there Alice
You can determine the default display (at the absence of a variable) you want by modifying the v in dictionary comprehension.
As per PEP 3101 If the index or keyword refers to an item that does not exist, then an IndexError/KeyError should be raised.
But you can create your own custom formatter class like this.
from string import Formatter
class MyStringFormatter(Formatter):
def get_value(self, key, args, kwds):
try:
return super().get_value(key, args, kwds)
except KeyError:
return "{%s}" % key
fmt = MyStringFormatter()
DEMO
s = "{hello} {person_name}"
keywords = {'hello': 'hello'}
a = fmt.format(s, **keywords)
print(a)
# This will print hello {person_name}
something = False
if something:
person_name = {'person_name': 'Alice'}
else:
person_name = {'person_name': 'Bob'}
b = fmt.format(a, **person_name)
print(b)
# This will print `hello Bob` if `something` is False, 'hello Alice' otherwise.
Is something like this possible or should I set all keywords when I use format()?
PEP-3101 says:
If the index or keyword refers to an item that does not exist, then an IndexError/KeyError should be raised.
So yes, if you are going to use keywords you would have to specify them all.
I think you have to define all the keywords while using format().
I would suggest a different approach using *args:
def printHello(*args):
print(' '.join([arg for arg in args]))
printHello('hello', 'Alice')
# hello Alice
printHello('hello')
# hello
You can send any number of words into this function.
I am having a problem like
In [5]: x = "this string takes two like {one} and {two}"
In [6]: y = x.format(one="one")
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-6-b3c89fbea4d3> in <module>()
----> 1 y = x.format(one="one")
KeyError: 'two'
I have a compound string with many keys that gets kept in a config file. For 8 different queries, they all use the same string, except 1 key is a different setting. I need to be able to substitute a key in that file to save the strings for later like:
"this string takes two like one and {two}"
How do I substitute one key at a time using format?
I think string.Template does what you want:
from string import Template
s = "this string takes two like $one and $two"
s = Template(s).safe_substitute(one=1)
print(s)
# this string takes two like 1 and $two
s = Template(s).safe_substitute(two=2)
print(s)
# this string takes two like 1 and 2
If placeholders in your string don't have any format specifications, in Python 3 you can use str.format_map and provide a mapping, returning the field name for missing fields:
class Default(dict):
def __missing__(self, key):
return '{' + key + '}'
In [6]: x = "this string takes two like {one} and {two}"
In [7]: x.format_map(Default(one=1))
Out[7]: 'this string takes two like 1 and {two}'
If you do have format specifications, you'll have to subclass string.Formatter and override some methods, or switch to a different formatting method, like string.Template.
you can escape the interpolation of {two} by doubling the curly brackets:
x = "this string takes two like {one} and {{two}}"
y = x.format(one=1)
z = y.format(two=2)
print(z) # this string takes two like 1 and 2
a different way to go are template strings:
from string import Template
t = Template('this string takes two like $one and $two')
y = t.safe_substitute(one=1)
print(y) # this string takes two like 1 and $two
z = Template(y).safe_substitute(two=2)
print(z) # this string takes two like 1 and 2
(this answer was before mine for the template strings....)
You can replace {two} by {two} to enable further replacement later:
y = x.format(one="one", two="{two}")
This easily extends in multiple replacement passages, but it requires that you give all keys, in each iteration.
All great answers, I will start using this Template package soon. Very disappointed in the default behavior here, not understanding why a string template requires passing all the keys each time, if there are 3 keys I can't see a logical reason you can't pass 1 or 2 (but I also don't know how compilers work)
Solved by using %s for the items I'm immediately substituting in the config file, and {key} for the keys I replace later upon execution of the flask server
In [1]: issue = "Python3 string {item} are somewhat defective: %s"
In [2]: preformatted_issue = issue % 'true'
In [3]: preformatted_issue
Out[3]: 'Python3 string {item} are somewhat defective: true'
In [4]: result = preformatted_issue.format(item='templates')
In [5]: result
Out[5]: 'Python3 string templates are somewhat defective: true'
I am brushing up a bit of good old algorithms, and doing it with python, since I use it more often nowadays.
I am facing an issue when running a recursive function; where the variable get reset every time that the recursive function call itself:
def recursive_me(mystring):
chars = len(mystring)
if chars is 0:
print("Done")
else:
first = int(str[0])
total = + first
print(total)
recursive_me(mystring[1:])
recursive_me("4567")
What I am doing here is to get a string made of digits; take the first, convert it to an int; and run recursively the function again, so I can take one digit at time from the string and sum all the values.
Ideally the output should show the total, while it add all the digits (4+5+6+7), although when the recursive function is called the first time, the function reset the total value.
Is common habit to use global variables when running operations with recursive functions or am I doing something wrong?
You can code as simply as this:
def recursive_me(mystring):
if mystring: # recursive case
return int(mystring[0]) + recursive_me(mystring[1:])
else: # base case
return 0
or
def recursive_me(mystring, total = 0):
if mystring: # recursive case
return recursive_me(mystring[1:], total + int(mystring[0]))
else: # base case
return total
although this won't help much in Python since it doesn't implement tail-call optimisation.
If you want to see the intermediate values, change the second version like so:
def recursive_me(mystring, total = 0):
if mystring: # recursive case
newtotal = total + int(mystring[0])
print(newtotal)
return recursive_me(mystring[1:], newtotal)
else: # base case
return total
then
4
9
15
22
22 # this is the return value; previous output is from `print()`
as a foreword: a lot of answers received meaningful edits in the meantime I was writing this answer. Don't hold it against me.
I'm throwing my two cents in here just because there's a lot of over-complicated answers.
This is a corrected copy-paste of the OP's effort.
def recursive_me(mystring, total=0):
chars = len(mystring)
if chars is 0:
print("Done")
return total
else:
first = int(mystring[0])
total += first
print(total)
recursive_me(mystring[1:], total)
first what happens is that we check the base case, if there's no left chars in the string. If the string length is 0 we return the total calculated ammount.
Otherwise, we turn the first of the chars into an int, and add it to total. The first error you have is that you wrote str[0]. str is a python built in type and the produced error would be something like "str is not subscriptable".
This error means that the str can't be operated on by "[]" operator. The same would happen if you tried doing 1[0] because 1 is a integer. The "[]" operator can only operate on lists, tuples and strings (I might've forgot some built-in type).
The second error you had was with the addition part. You had written total = + first but the operator you are looking for is the += which in fact is just a shortened way to write a = a+b.
Additionally, your original question was concerning about "python" forgetting the value of "total". This is because you have to either pass that value forward, or write your recursive function in a way that "forces" it to, what's called, evaluate your next call to your function on the spot.
In my example I'm sending the next call of the function recursive_me, the current total value. In the example given by #uselpa; above he's making python evaluate the next call to the function by putting it after operator +:
return int(mystring[0]) + recursive_me(mystring[1:])
this then gets to be (for recursive_me("4567"))
return int(4)+recursive_me("567")
return int(4)+int(5)+recursive_me("67")
....
return int(4)+int(5)+int(6)+int(7)+0
because python needs to return a value here, but the expression keeps calling new functions and python can't return until it evaluates all of them to a final number (in this case at least).
The common practice is to save these variables as parameters, and pass them along the chain. It seems in your case, you would want to pass total as an additional parameter, and update it as needed.
There's also a neat functional way to do it in python
t=raw_input()
print reduce(lambda a, b: a+b, map(int,t))
This is recursive in nature.
Some pointers:
Your default case should return an actual number (0 in your case) and not just print done.
total = + first is setting total to first, not adding first to total. You would need total += first to do the latter.
The trick with "retaining" the value of your current total is to "save" it in the recursive call-chain itself by passing it along with each call. You won't need a global variable or a default parameter to do this.
Here's a solution:
def recursive_me(mystring):
if not mystring: # True if mystring is empty
return 0
return int(mystring[0]) + recursive_me(mystring[1:])
print(recursive_me("4567")) # 22
Here is a solution that uses the LEGB scope rule to avoid creating a new string instance on every recursive call
def sum_str(mystring):
def recursive_me(pos):
cur_char = int(mystring[pos])
if pos:
return cur_char + recursive_me(pos-1)
else:
return cur_char
return recursive_me(len(mystring)-1)
s = '4567'
print('summing', s)
print(sum_str(s))
However, indexing can be avoided as well by iterating on the string
def sum_str(mystring):
def recursive_me(itx):
try:
cur_char = int(next(itx))
return cur_char + recursive_me(itx)
except StopIteration:
return 0
return recursive_me(iter(mystring))
Obviously, both solutions produce
summing 4567
22
I need some help understanding a function that i want to use but I'm not entirely sure what some parts of it do. I understand that the function is creating dictionaries from reads out of a Fasta-file. From what I understand this is supposed to generate pre- and suffix dictionaries for ultimately extending contigs (overlapping dna-sequences).
The code:
def makeSuffixDict(reads, lenSuffix = 20, verbose = True):
lenKeys = len(reads[0]) - lenSuffix
dict = {}
multipleKeys = []
i = 1
for read in reads:
if read[0:lenKeys] in dict:
multipleKeys.append(read[0:lenKeys])
else:
dict[read[0:lenKeys]] = read[lenKeys:]
if verbose:
print("\rChecking suffix", i, "of", len(reads), end = "", flush = True)
i += 1
for key in set(multipleKeys):
del(dict[key])
if verbose:
print("\nCreated", len(dict), "suffixes with length", lenSuffix, \
"from", len(reads), "Reads. (", len(reads) - len(dict), \
"unambigous)")
return(dict)
Additional Information: reads = readFasta("smallReads.fna", verbose = True)
This is how the function is called:
if __name__ == "__main__":
reads = readFasta("smallReads.fna", verbose = True)
suffixDicts = makeSuffixDicts(reads, 10)
The smallReads.fna file contains strings of bases (Dna):
"> read 1
TTATGAATATTACGCAATGGACGTCCAAGGTACAGCGTATTTGTACGCTA
"> read 2
AACTGCTATCTTTCTTGTCCACTCGAAAATCCATAACGTAGCCCATAACG
"> read 3
TCAGTTATCCTATATACTGGATCCCGACTTTAATCGGCGTCGGAATTACT
Here are the parts I don't understand:
lenKeys = len(reads[0]) - lenSuffix
What does the value [0] mean? From what I understand "len" returns the number of elements in a list.
Why is "reads" automatically a list? edit: It seems a Fasta-file can be declared as a List. Can anybody confirm that?
if read[0:lenKeys] in dict:
Does this mean "from 0 to 'lenKeys'"? Still confused about the value.
In another function there is a similar line: if read[-lenKeys:] in dict:
What does the "-" do?
def makeSuffixDict(reads, lenSuffix = 20, verbose = True):
Here I don't understand the parameters: How can reads be a parameter? What is lenSuffix = 20 in the context of this function other than a value subtracted from len(reads[0])?
What is verbose? I have read about a "verbose-mode" ignoring whitespaces but i have never seen it used as a parameter and later as a variable.
The tone of your question makes me feel like you're confusing things like program features (len, functions, etc) with things that were defined by the original programmer (the type of reads, verbose, etc).
def some_function(these, are, arbitrary, parameters):
pass
This function defines a bunch of parameters. They don't mean anything at all, other than the value I give to them implicitly. For example if I do:
def reverse_string(s):
pass
s is probably a string, right? In your example we have:
def makeSuffixDict(reads, lenSuffix = 20, verbose = True):
lenKeys = len(reads[0]) - lenSuffix
...
From these two lines we can infer a few things:
the function will probably return a dictionary (from its name)
lenSuffix is an int, and verbose is a bool (from their default parameters)
reads can be indexed (string? list? tuple?)
the items inside reads have length (string? list? tuple?)
Since Python is dynamically typed, this is ALL WE CAN KNOW about the function so far. The rest would be explained by its documentation or the way it's called.
That said: let me cover all your questions in order:
What does the value [0] mean?
some_object[0] is grabbing the first item in a container. [1,2,3][0] == 1, "Hello, World!"[0] == "H". This is called indexing, and is governed by the __getitem__ magic method
From what I understand "len" returns the number of elements in a list.
len is a built-in function that returns the length of an object. It is governed by the __len__ magic method. len('abc') == 3, also len([1, 2, 3]) == 3. Note that len(['abc']) == 1, since it is measuring the length of the list, not the string inside it.
Why is "reads" automatically a list?
reads is a parameter. It is whatever the calling scope passes to it. It does appear that it expects a list, but that's not a hard and fast rule!
(various questions about slicing)
Slicing is doing some_container[start_idx : end_idx [ : step_size]]. It does pretty much what you'd expect: "0123456"[0:3] == "012". Slice indexes are considered to be zero-indexed and lay between the elements, so [0:1] is identical to [0], except that slices return lists, not individual objects (so 'abc'[0] == 'a' but 'abc'[0:1] == ['a']). If you omit either start or end index, it is treated as the beginning or end of the string respectively. I won't go into step size here.
Negative indexes count from the back, so '0123456'[-3:] == '456'. Note that [-0]is not the last value,[-1]is. This is contrasted with[0]` being the first value.
How can reads be a parameter?
Because the function is defined as makeSuffixDict(reads, ...). That's what a parameter is.
What is lenSuffix = 20 in the context of this function
Looks like it's the length of the expected suffix!
What is verbose?
verbose has no meaning on its own. It's just another parameter. Looks like the author included the verbose flag so you could get output while the function ran. Notice all the if verbose blocks seem to do nothing, just provide feedback to the user.
I have a class Flight, and I'm trying initialize it, but I have a syntax error in
print x=Flight(flightFromInput='nebrasca')
This is a content of my example file
class Flight:
flightFrom = None
flightTo = None
departureDate = None
arrivalDate=None
airline=None
serviceClass=None
departureAirport = None
arrivalAirport=None
#----------------------------------------------------------------------
def __init__(self,flightFromInput):
self.flightFrom = flightFromInput
print x=Flight(flightFromInput='nebrasca')
What is wrong with this code?
You should write
x = Flight(flightFromInput='nebrasca')
print x
In python an assignment statement doesn't return the assigned value. So you cannot use it within another statement. As the other answers suggested, you can work around this by printing x in a separate line.
Note, that there are exceptions though:
a = b = 0 # works
a = (b = 0) # does not work
The first case is a special case allowed for convenience when you want to assign the same value to multiple variables. In the second case you clearly tell the compiler that b=0 is a separate statement, but as it doesn't return a value the outer assignment to a leads to the resulting SyntaxError.
Hope this explains it a bit more clearly, why you should do print x after assigning it.
Contrary to C, in Python assignments are statements only and not expressions. Therefore they do not have their own value. Try this:
x = Flight(flightFromInput='nebrasca')
print x