Is it possible to run a function that is specified by using the magic %paste% function in IPython?
In [1]: %paste%
def add_to_index(index,keyword,url):
for e in index:
if e[0] == keyword:
if url not in e[1]:
e[1].append(url)
return
index.append([keyword,[url]])
## -- End pasted text --
Block assigned to '%'
In [2]: %whos
Variable Type Data/Info
-----------------------------
% SList ['def add_to_index(index,<...>append([keyword,[url]])']
In [3]: add_to_index
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-e3075a18cb0c> in <module>()
----> 1 add_to_index
NameError: name 'add_to_index' is not defined
In [4]: add_to_index(index, 'test', 'http://test.com')
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-4-580237464b17> in <module>()
----> 1 add_to_index(index, 'test', 'http://test.com')
NameError: name 'add_to_index' is not defined
In [5]:
The paste magic is %paste (no trailing %):
In [3]: %paste
def add_to_index(index,keyword,url):
for e in index:
if e[0] == keyword:
if url not in e[1]:
e[1].append(url)
return
index.append([keyword,[url]])
## -- End pasted text --
In [4]: add_to_index
Out[4]: <function __main__.add_to_index>
What happens in your case is that you are using the optional argument for %paste:
In [5]: %paste?
Type: Magic function
...(text omitted)
You can also pass a variable name as an argument, e.g. '%paste foo'.
This assigns the pasted block to variable 'foo' as string, without
dedenting or executing it (preceding >>> and + is still stripped)
When you do that the pasted code does not get executed, it is just assigned to the variable you gave as an argument (% in your case).
Related
Why this works :
In [1]: def new_class(klass):
...: globals()[klass] = type(klass, (object,), {})
...:
In [2]: new_class('AA')
In [3]: AA()
Out[3]: <__main__.AA at 0x7f5629c5ddc0>
But when it is from module it doesnt ??
In [4]: from maker import *
In [5]: new_class2??
Signature: new_class2(klass)
Docstring: <no docstring>
Source:
def new_class2(klass):
globals()[klass] = type(klass, (object,), {})
File: /my/py38/seq2struct/lib/maker.py
Type: function
In [6]: new_class2('AB')
In [7]: AB()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [7], in <cell line: 1>()
----> 1 AB()
NameError: name 'AB' is not defined
The problems is that globals() returns the dictionary implementing the current module namespace. (see here)
new_class2 is defined in a different module, therefore it is modifying the globals of that module.
I see, so the solution is
In [10]: import maker
In [11]: maker.AB()
Out[11]: <maker.AB at 0x7f5629bbe370>
x = Symbol ("x")
f = log(x)
dif1 = diff(f,x)
dif2 = diff(dif1,x)
dif3 = diff(dif2,x)
dif4 = diff(dif3,x)
dif5 = diff(dif4,x)
def D11(a,h):
return (f.evalf(subs={x:a+h})-f.evalf(subs={x:a}))/h + (h/2)*dif2.evalf(subs={x:a+h/2})
def D12(a,h):
return ((f.evalf(subs={x:(a+h)}) - f(a-h)))/(2*h) - h**2/6*dif3.evalf(subs={x:(a)})
def D13(a,h):
return (f.evalf(subs={x:(a-2*h)})- 8*f.evalf(subs={x:(a-h)}) + 8*f.evalf(a+h) - f(a+2*h))/(12*h) - h**4/30*ftuletis5(a)
def D22(a,h):
return (f.evalf(subs={x:(a+h)}) - 2*f.evalf(subs={x:(a)}) + f.evalf(subs={x:(a-h)}))/h**2 - h**2/12*(dif4.evalf(subs={x:(a)}))
vigaD11 = []
vigaD12 = []
vigaD13 = []
vigaD22 = []
h=[]
for i in range(20):
h+=h+[(10**(-i))]
vigaD11+= vigaD11 + [(D11(2,h[i])-(dif1.evalf(subs={x:2})))]
vigaD12+= vigaD12+[(D12(2,h[i])-(dif1.evalf(subs={x:2})))]
vigaD13+= vigaD13 + [(D13(2,h[i])-(dif1.evalf(subs={x:2})))]
vigaD22+= vigaD22 [(D22(2,h[i])-(dif2.evalf(subs={x:2})))]
I get an error message saying that log object is not callable. Currently I'm using the math package and Sympy package to get the program to do what I want.
The error message I get:
Traceback (most recent call last):
File "C:\Users\arman\Desktop\Numbrilised meetodid\praktikum12\praktikum12.py", line 64, in <module>
vigaD12+= vigaD12+[(D12(2,h[i])-(dif1.evalf(subs={x:2})))]
File "C:\Users\arman\Desktop\Numbrilised meetodid\praktikum12\praktikum12.py", line 37, in D12
return ((f.evalf(subs={x:(a+h)}) - f(a-h)))/(2*h) - h**2/6*dif3.evalf(subs={x:(a)})
TypeError: 'log' object is not callable
It still does not work when I specifically call out the sympy version of log. Please help.
You could try f = math.log(x) or whichever log function you want to use. Maybe python just doesn't find the right function to call.
In an isympy session with * import ofsympyandxsymbol,log` a sympy object
In [1]: log
Out[1]: log
In [2]: x
Out[2]: x
In [3]: f = log(x)
In [4]: f(23)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-a73e6f7d2549> in <module>
----> 1 f(23)
TypeError: 'log' object is not callable
You can't call log again; it's already been "called". You can evaluate it at specific number with:
In [13]: f.evalf(subs={x:1.23})
Out[13]: 0.207014169384326
You do that once in the problem expression, but not the second time. Why not?
f.evalf(subs={x:(a+h)}) - f(a-h)
i'm getting NameError: for the following code...
d = [('1','as'),('2','sd')]
for i in d:
RD = ReleaseDeal(int(i[0]))
print(RD)
def ReleaseDeal(a):
RD = '''<ReleaseDeal><DealReleaseReference>R'''+ no +'''</DealReleaseReference><Deal><DealTerms><CommercialModelType>AsPerContract</CommercialModelType>
<Usage><UseType UserDefinedValue="GoogleMusicBasic">UserDefined</UseType> <UseType UserDefinedValue="SscSnmLocker">UserDefined</UseType>
<UseType UserDefinedValue="GoogleMusicSubscription">UserDefined</UseType></Usage><TerritoryCode>Worldwide</TerritoryCode><PriceInformation>
<PriceType Namespace="DPID:"">13</PriceType></PriceInformation><ValidityPeriod><StartDate>2018-10-04</StartDate></ValidityPeriod>
</DealTerms></Deal></ReleaseDeal>'''
return RD
i'm getting following errors...
Traceback (most recent call last):
File "example.py", line 3, in <module>
RD = ReleaseDeal(int(i[0]))
NameError: name 'ReleaseDeal' is not defined
please help me on this , Thanks in advance..
You got several errors:
Define something before you reference to it
The parameter does not apply to the used one in ReleaseDeal
Concatenation of int to string fails.
def ReleaseDeal(no): # this was a, is has to be no and string
RD = '''<ReleaseDeal><DealReleaseReference>R'''+ no +'''</DealReleaseReference><Deal><DealTerms><CommercialModelType>AsPerContract</CommercialModelType>
<Usage><UseType UserDefinedValue="GoogleMusicBasic">UserDefined</UseType> <UseType UserDefinedValue="SscSnmLocker">UserDefined</UseType>
<UseType UserDefinedValue="GoogleMusicSubscription">UserDefined</UseType></Usage><TerritoryCode>Worldwide</TerritoryCode><PriceInformation>
<PriceType Namespace="DPID:"">13</PriceType></PriceInformation><ValidityPeriod><StartDate>2018-10-04</StartDate></ValidityPeriod>
</DealTerms></Deal></ReleaseDeal>'''
return RD
d = [('1','as'),('2','sd')]
for i in d:
RD = ReleaseDeal(i[0])
print(RD)
Maybe type hints are useful for you ;-) https://docs.python.org/3/library/typing.html#typing.ClassVar Then you can say something like
ReleaseDeal(no: str) -> str:
So you want to get no of type string and return string.
I want to check a string - is it an import command? I have tried
# Helper - analyses a string - is it an import string?
"""
fromlike - from foo import bar
classic - import foo
classic_as - import foo as baz
"""
def check_is_import(string):
importname = ''
fromlike = False
classic = False
classic_as = False
if string[0:4] is 'from':
fromlike = True
importname = ''
if not fromlike and (string[0:6] is 'import'):
classic = True
importname = string.split(' ')[1]
if classic:
commandlist = string.split(' ')
if commandlist[2] is 'as':
classic_as = True
importname = commandlist[3]
del commandlist
if fromlike:
return ('fromlike', importname)
elif classic and (not classic_as):
return ('classic', importname)
elif classic_as:
return ('classic_as', importname)
else:
return ('no_import', importname)
but it worked for "fromlike" imports. (Note: I'm not asking "why does this code don't work?", I'm just searching a solution) What code will sure detect all imports? Basically my code takes a slice of the string. If the [0:4] slice equals 'from', the string is a "fromlike import". Else: if the [0:6] slice equals 'import', the string is a "classic import". If it detects 'as', it will find the pseudo-name. This function must return a tuple which contains the import type under index 0 and imported module-name under index 1.
If you want to be sure to handle all Python import forms, have Python do the parsing. Use the ast.parse() function and use the resulting parse tree; you'll either get Import or ImportFrom objects:
| Import(alias* names)
| ImportFrom(identifier? module, alias* names, int? level)
Each alias consists of a name and optional identifier used to import the name as:
-- import name with optional 'as' alias.
alias = (identifier name, identifier? asname)
Note that there can be multiple imports! You either have classic or fromlike imports, and both can import multiple names. Your function needs to return a list of (type, name) tuples. For invalid inputs, raise an exception (ValueError is a good fit here):
import ast
def check_is_import(string):
try:
body = ast.parse(string).body
except SyntaxError:
# not valid Python
raise ValueError('No import found')
if len(body) > 1:
# not a single statement
raise ValueError('Multiple statements found')
if not isinstance(body[0], (ast.Import, ast.ImportFrom)):
raise ValueError('No import found')
type_ = 'classic' if isinstance(body[0], ast.Import) else 'fromlike'
results = []
for alias in body[0].names:
alias_type = type_
if alias.asname:
alias_type += '_as'
results.append((alias_type, alias.asname or alias.name))
return results
The method should probably be renamed to extract_import_names(), as that reflects what it does much better.
Demo:
>>> check_is_import('from foo import bar')
[('fromlike', 'bar')]
>>> check_is_import('import foo')
[('classic', 'foo')]
>>> check_is_import('import foo as baz')
[('classic_as', 'baz')]
>>> check_is_import('from foo import bar, baz as spam, monty as python')
[('fromlike', 'bar'), ('fromlike_as', 'spam'), ('fromlike_as', 'python')]
>>> check_is_import('import foo as baz, baz, spam as ham')
[('classic_as', 'baz'), ('classic', 'baz'), ('classic_as', 'ham')]
>>> check_is_import('invalid python')
Traceback (most recent call last):
File "<stdin>", line 3, in check_is_import
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/ast.py", line 35, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File "<unknown>", line 1
invalid python
^
SyntaxError: invalid syntax
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in check_is_import
ValueError: No import found
>>> check_is_import('import foo; import bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in check_is_import
ValueError: Multiple statements found
>>> check_is_import('1 + 1 == 2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in check_is_import
ValueError: No import found
I'm using BeautifulSoup to do some crawling, and want to chain find calls, for example:
soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
Of course, this breaks whenever one of the divs cannot be found, throwing an
AttributeError: 'NoneType' object has no attribute 'find'
Is there a way to modify NoneType to add a find method such as
class NoneType:
def find(*args):
return None
so that I can do something like
thing = soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
if thing:
do more stuff
instead of
thing1 = soup.find('div', class_="class1")
if thing1:
thing2 = thing1.find('div', class_="class2")
if thing2:
thing3 = thing2.find('div', class_="class3")
etc.
I think I might be able to do something similar by using a parser with XPath capabilities, but the question is not specific to this use case and is more about modifying/overriding built in classes.
Why not use a try/except statement instead (since you cannot modify NoneType)?
try:
thing = soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
do more stuff
except AttributeError:
thing = None # if you need to do more with thing
You can't modify builtin class such as NoneType or str:
>>> nt = type(None)
>>> nt.bla = 23
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'NoneType'
For some of them (eg str), you can inherit from:
>>> class bla(str):
... def toto(self): return 1
>>> bla('2123').toto()
1
It's not possible with NoneType. And it won't help you either:
>>> class myNoneType(nt):
... def find(self): return 1
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
type 'NoneType' is not an acceptable base type
You cannot modify the class and the real question is why you would try? NoneType means there is no data there so when you attempt a .find() on that type even if it did exist you would only get null or no values from it. I would reccomend something like this.
try:
var = soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
except AttributeError:
do something else instead or message saying there was no div
You can't inherit from None:
>>> class Noneish(type(None)):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type 'NoneType' is not an acceptable base type
An approach might be to have a
class FindCaller(object):
def __init__(self, *a, **k):
self.a = a
self.k = k
def __call__(self, obj):
return obj.find(*self.a, **self.k)
def callchain(root, *fcs):
for fc in fcs:
root = fc(root)
if root is None: return
return root
and then do
thing = callchain(soup,
FindCaller('div', class_="class1"),
FindCaller('div', class_="class2"),
FindCaller('div', class_="class3"),
)
You can't. For good reasons...
In fact, NoneType is even less accessible than other built-in types:
type(None).foo = lambda x: x
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-12-61bbde54e51b> in <module>()
# ----> 1 type(None).foo = lambda x: x
# TypeError: can't set attributes of built-in/extension type 'NoneType'
NoneType.foo = lambda x: x
# ---------------------------------------------------------------------------
# NameError Traceback (most recent call last)
# <ipython-input-13-22af1ed98023> in <module>()
# ----> 1 NoneType.foo = lambda x: x
# NameError: name 'NoneType' is not defined
int.foo = lambda x: x
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-14-c46c4e33b8cc> in <module>()
# ----> 1 int.foo = lambda x: x
# TypeError: can't set attributes of built-in/extension type 'int'
As suggested above, use try: ... except AttributeError: clause.