Pyton - How to find out if a key exists in a dictionary

9. April 2013 08:00

 

Another simple python example which is how to find out if a key exists in python

 

Just use "if" and "in" like in the following example

 

 

>>> x['item1'] = 0
>>> if 'item1' in x:
...  print "True"
...
True

 

 

Some of the mistakes that I have seen is this will "appear" to work correctly but in fact it does not. Have a look at these examples. You can see here that it will fail because it is testing the value rather than the key.

 

 

>>> x['item1'] = 1
>>> if x['item1']:
...  print "True"
...
True
>>>

>>> x['item1'] = 0
>>> if x['item1']:
...  print "True"
...
>>>
E-mail Kick it! DZone it! del.icio.us Permalink


Python - json encode / decode

4. April 2013 08:00

 

This is a short example to be able to encode / decode json inside python. Its actually really easy to do.

You will first need to import the json library using

import json

 

Encoding to json

 

>>> x = {}
>>> x['1'] = 0
>>> x['2'] = 0
>>> x['3'] = 0
>>> x['4'] = 0
>>> json.dumps(x)

 

Deocoding from json

 

>>> x = json.loads('{"1": 0, "2": 0, "3": 0, "4": 0}')
>>> print x
{u'1': 0, u'3': 0, u'2': 0, u'4': 0}
>>>

 

It really is as simple as that!

E-mail Kick it! DZone it! del.icio.us Permalink


Python - while else statement

14. August 2012 07:56

 

In python most people are familure with a combination of if / else or a while loop. Did you know you can combine a while with an else statement. the obvious main advantage here is to prevent using extra variables and nested statement which makes the code shorter and clearer to understand.

 

This short example demonstrates this functionality.

 

 

lst = []
while lst:
    print "There is a list"
    break
else:
    print "Empty List"

 

 

In the case above because the contents of the while loop are no executed because the list is empty it will print "Empty List" instead. This can also work with for loops like in the following example.

 

 

for x in lst:
    if x == "Something":
        DoSomething()
        break
else:
    print "Not Found"

 

You should probably take notice of the break statements in the above code as the else statements runs on the last evaluation of the loop condition so when a loop terminates because its condition is false the else will always run. The break statement changes this so that the loop conditition is true and the else will be skipped.

E-mail Kick it! DZone it! del.icio.us Permalink


boost python and custom exception

6. July 2012 08:00

 

One of the problems faced with creating boost python wrappers is that sooner or later you can run into the situation where you need to support extra exception messages which are being thrown from C++ code but are not understood by python or the python wrapper. So this is a guide to support these extra exceptions.

 

You will know that you have come across this issue when you see the following being produced in python. In this case the Example function in C++ throws a MyException class which provides an error message which in its current state just isn't really useful to try to trace the problem.

 

 

>>> import MyClass_py
>>> obj = MyClass_py.MyClass()
>>> obj.Example()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: unidentifiable C++ exception
>>>

 

 

In previous posts about creating python wrappers and supporting operator overloading. I have been using much the same example code. In this case it has been changed to add the extra exception. So the C++ code now looks like this.

 

 

class MyException {
	public:
		MyException(const std::string str) {
			m_str = str;
		}
		
		~MyException() {
		
		}
		
		std::string GetMessage() const {
			return m_str;
		}
		
	private:
		std::string m_str;
};

class MyClass {
	public:
		MyClass() { }
		~MyClass() { }
		
		std::string Example() {
			throw(MyException("Hello World"));
		}
		
};

 

 

To get the exception method supported we need to add an exception converter to our python module using a boost python macro register_exception_translator and an extra C/C++ function in our wrapper. Note that the C++ function should not be in the BOOST_PYTHON_MODULE section but the register_exception_translator is. This is how it should look to handle the exception.

Also take note that because the MyExceptionTranslator requires the argument to be a const the functions that you call must also be marked as const or it will not compile. In this case the function for "MyException::GetMessage" must be declared as "std::string MyException::GetMessage() const" to say that it does not modify the contents of the MyException this is because it is meant to be constant.

 

static void MyExceptionTranslator(const MyException &err) {
        PyErr_SetString(PyExc_UserWarning, err.GetMessage().c_str());
}


BOOST_PYTHON_MODULE(MyClass_py)
{
	register_exception_translator<MyException>(&MyExceptionTranslator);

	class_<MyClass>( "MyClass", init<>() )
	
		.def("Example", static_cast< std::string (MyClass::*)() > (&MyClass::Example) )
		
	;
	
}

 

When compiled and run from python we now get the following instead of the useless error message above

 

 

>>> import MyClass_py
>>> obj = MyClass_py.MyClass()
>>> obj.Example()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UserWarning: Hello World

 

I have included a full working example.

 

#include <string>

#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/init.hpp>
#include <boost/python/operators.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/return_by_value.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/overloads.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>

using namespace boost::python;


class MyException {
	public:
		MyException(const std::string str) {
			m_str = str;
		}
		
		~MyException() {
		
		}
		
		std::string GetMessage() const {
			return m_str;
		}
		
	private:
		std::string m_str;
};

class MyClass {
	public:
		MyClass() { }
		~MyClass() { }
		
		std::string Example() {
			throw(MyException("Hello World"));
		}
		
};

static void MyExceptionTranslator(const MyException &err) {
        PyErr_SetString(PyExc_UserWarning, err.GetMessage().c_str());
}


BOOST_PYTHON_MODULE(MyClass_py)
{
	register_exception_translator<MyException>(&MyExceptionTranslator);

	class_<MyClass>( "MyClass", init<>() )
	
		.def("Example", static_cast< std::string (MyClass::*)() > (&MyClass::Example) )
		
	;
	
}

The above example can be compiled with

 

g++ -shared -Wall MyClass_py.cpp -o MyClass_py.so -I/usr/include/python2.6/ -lboost_python -lpython2.6

 

E-mail Kick it! DZone it! del.icio.us Permalink


boost python operator overloading for calling C++ classes

3. July 2012 08:00

 

In a previous post about creating basic python wrappers. I mentioned that there can be an issue with trying to call C++ from the python wrapper which are operator overloaded. Taking the following C++ code the python wrapper cannot tell the different between the two functions when being compile or which one should be used.

 

class MyClass {
	public:
		MyClass() { }
		~MyClass() { }
		
		std::string Example() {
			return "Hello World";
		}
		
		std::string Example(std::string str) {
			return str;
		}
};

BOOST_PYTHON_MODULE(MyClass_py)
{

	class_( "MyClass", init<>() )
	
		.def("Example", &MyClass::Example)
		
	;
	
}

When compiling you will get en error of this.

 

MyClass_py.cpp: In function 'void init_module_MyClass_py()':
MyClass_py.cpp:44: error: no matching function for call to 'boost::python::class_<MyClass, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::def(const char [8], <unresolved overloaded function type>)'

 

You can work around it using the static cast to get the correct function to be called and rename the python function to something else. Effectivly this removes the operating overload from the python end of things when it is not supported. The example of the wrapper code is below.

 

BOOST_PYTHON_MODULE(MyClass_py)
{

	class_<MyClass>( "MyClass", init<>() )
	
		.def("Example", static_cast< std::string (MyClass::*)() > (&MyClass::Example) )
		.def("ExampleStr", static_cast< std::string (MyClass::*)(std::string ) > (&MyClass::Example) )
		
	;
	
}

Our python code is then forced to use the aliased function name.

 

>>> import MyClass_py
>>> obj = MyClass_py.MyClass()
>>> obj.Example()
'Hello World'
>>> obj.ExampleStr('Foo')
'Foo'
>>>

I have included an complete example for you to play with.

 

#include <string>

#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/init.hpp>
#include <boost/python/operators.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/return_by_value.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/overloads.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>

using namespace boost::python;

class MyClass {
	public:
		MyClass() { }
		~MyClass() { }
		
		std::string Example() {
			return "Hello World";
		}
		
		std::string Example(std::string str) {
			return str;
		}
};


BOOST_PYTHON_MODULE(MyClass_py)
{

	class_<MyClass>( "MyClass", init<>() )
	
		.def("Example", static_cast< std::string (MyClass::*)() > (&MyClass::Example) )
		.def("ExampleStr", static_cast< std::string (MyClass::*)(std::string ) > (&MyClass::Example) )
		
	;
	
}

 

You can compile the above with

 

g++ -shared -Wall MyClass_py.cpp -o MyClass_py.so -I/usr/include/python2.6/ -lboost_python -lpython2.6

E-mail Kick it! DZone it! del.icio.us Permalink