+++++++++++++++++++++++++++++++++++++++++++
 Building Hybrid Systems with Boost.Python
+++++++++++++++++++++++++++++++++++++++++++

:Author: David Abrahams
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: 2003-05-14

:Author: Ralf W. Grosse-Kunstleve

:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved

.. contents:: Table of Contents

.. _`Boost Consulting`: http://www.boost-consulting.com

==========
 Abstract
==========

Boost.Python is an open source C++ library which provides a concise
IDL-like interface for binding C++ classes and functions to
Python. Leveraging the full power of C++ compile-time introspection
and of recently developed metaprogramming techniques, this is achieved
entirely in pure C++, without introducing a new syntax.
Boost.Python's rich set of features and high-level interface make it
possible to engineer packages from the ground up as hybrid systems,
giving programmers easy and coherent access to both the efficient
compile-time polymorphism of C++ and the extremely convenient run-time
polymorphism of Python.

==============
 Introduction
==============

Python and C++ are in many ways as different as two languages could
be: while C++ is usually compiled to machine-code, Python is
interpreted.  Python's dynamic type system is often cited as the
foundation of its flexibility, while in C++ static typing is the
cornerstone of its efficiency. C++ has an intricate and difficult
compile-time meta-language, while in Python, practically everything
happens at runtime.

Yet for many programmers, these very differences mean that Python and
C++ complement one another perfectly.  Performance bottlenecks in
Python programs can be rewritten in C++ for maximal speed, and
authors of powerful C++ libraries choose Python as a middleware
language for its flexible system integration capabilities.
Furthermore, the surface differences mask some strong similarities:

* 'C'-family control structures (if, while, for...)

* Support for object-orientation, functional programming, and generic
  programming (these are both *multi-paradigm* programming languages.)

* Comprehensive operator overloading facilities, recognizing the
  importance of syntactic variability for readability and
  expressivity.

* High-level concepts such as collections and iterators.

* High-level encapsulation facilities (C++: namespaces, Python: modules)
  to support the design of re-usable libraries.

* Exception-handling for effective management of error conditions.

* C++ idioms in common use, such as handle/body classes and
  reference-counted smart pointers mirror Python reference semantics.

Given Python's rich 'C' interoperability API, it should in principle
be possible to expose C++ type and function interfaces to Python with
an analogous interface to their C++ counterparts.  However, the
facilities provided by Python alone for integration with C++ are
relatively meager.  Compared to C++ and Python, 'C' has only very
rudimentary abstraction facilities, and support for exception-handling
is completely missing.  'C' extension module writers are required to
manually manage Python reference counts, which is both annoyingly
tedious and extremely error-prone. Traditional extension modules also
tend to contain a great deal of boilerplate code repetition which
makes them difficult to maintain, especially when wrapping an evolving
API.

These limitations have lead to the development of a variety of wrapping
systems.  SWIG_ is probably the most popular package for the
integration of C/C++ and Python. A more recent development is SIP_,
which was specifically designed for interfacing Python with the Qt_
graphical user interface library.  Both SWIG and SIP introduce their
own specialized languages for customizing inter-language bindings.
This has certain advantages, but having to deal with three different
languages (Python, C/C++ and the interface language) also introduces
practical and mental difficulties.  The CXX_ package demonstrates an
interesting alternative.  It shows that at least some parts of
Python's 'C' API can be wrapped and presented through a much more
user-friendly C++ interface. However, unlike SWIG and SIP, CXX does
not include support for wrapping C++ classes as new Python types.

The features and goals of Boost.Python_ overlap significantly with
many of these other systems.  That said, Boost.Python attempts to
maximize convenience and flexibility without introducing a separate
wrapping language.  Instead, it presents the user with a high-level
C++ interface for wrapping C++ classes and functions, managing much of
the complexity behind-the-scenes with static metaprogramming.
Boost.Python also goes beyond the scope of earlier systems by
providing:

* Support for C++ virtual functions that can be overridden in Python.

* Comprehensive lifetime management facilities for low-level C++
  pointers and references.

* Support for organizing extensions as Python packages,
  with a central registry for inter-language type conversions.

* A safe and convenient mechanism for tying into Python's powerful
  serialization engine (pickle).

* Coherence with the rules for handling C++ lvalues and rvalues that
  can only come from a deep understanding of both the Python and C++
  type systems.

The key insight that sparked the development of Boost.Python is that
much of the boilerplate code in traditional extension modules could be
eliminated using C++ compile-time introspection.  Each argument of a
wrapped C++ function must be extracted from a Python object using a
procedure that depends on the argument type.  Similarly the function's
return type determines how the return value will be converted from C++
to Python.  Of course argument and return types are part of each
function's type, and this is exactly the source from which
Boost.Python deduces most of the information required.

This approach leads to *user guided wrapping*: as much information is
extracted directly from the source code to be wrapped as is possible
within the framework of pure C++, and some additional information is
supplied explicitly by the user.  Mostly the guidance is mechanical
and little real intervention is required.  Because the interface
specification is written in the same full-featured language as the
code being exposed, the user has unprecedented power available when
she does need to take control.

.. _Python: http://www.python.org/
.. _SWIG: http://www.swig.org/
.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php
.. _Qt: http://www.trolltech.com/
.. _CXX: http://cxx.sourceforge.net/
.. _Boost.Python: http://www.boost.org/libs/python/doc

===========================
 Boost.Python Design Goals
===========================

The primary goal of Boost.Python is to allow users to expose C++
classes and functions to Python using nothing more than a C++
compiler.  In broad strokes, the user experience should be one of
directly manipulating C++ objects from Python.

However, it's also important not to translate all interfaces *too*
literally: the idioms of each language must be respected.  For
example, though C++ and Python both have an iterator concept, they are
expressed very differently.  Boost.Python has to be able to bridge the
interface gap.

It must be possible to insulate Python users from crashes resulting
from trivial misuses of C++ interfaces, such as accessing
already-deleted objects.  By the same token the library should
insulate C++ users from low-level Python 'C' API, replacing
error-prone 'C' interfaces like manual reference-count management and
raw ``PyObject`` pointers with more-robust alternatives.

Support for component-based development is crucial, so that C++ types
exposed in one extension module can be passed to functions exposed in
another without loss of crucial information like C++ inheritance
relationships.

Finally, all wrapping must be *non-intrusive*, without modifying or
even seeing the original C++ source code.  Existing C++ libraries have
to be wrappable by third parties who only have access to header files
and binaries.

==========================
 Hello Boost.Python World
==========================

And now for a preview of Boost.Python, and how it improves on the raw
facilities offered by Python. Here's a function we might want to
expose::

    char const* greet(unsigned x)
    {
       static char const* const msgs[] = { "hello", "Boost.Python", "world!" };

       if (x > 2)
           throw std::range_error("greet: index out of range");

       return msgs[x];
    }

To wrap this function in standard C++ using the Python 'C' API, we'd
need something like this::

    extern "C" // all Python interactions use 'C' linkage and calling convention
    {
        // Wrapper to handle argument/result conversion and checking
        PyObject* greet_wrap(PyObject* args, PyObject * keywords)
        {
             int x;
             if (PyArg_ParseTuple(args, "i", &x))    // extract/check arguments
             {
                 char const* result = greet(x);      // invoke wrapped function
                 return PyString_FromString(result); // convert result to Python
             }
             return 0;                               // error occurred
        }

        // Table of wrapped functions to be exposed by the module
        static PyMethodDef methods[] = {
            { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" }
            , { NULL, NULL, 0, NULL } // sentinel
        };

        // module initialization function
        DL_EXPORT init_hello()
        {
            (void) Py_InitModule("hello", methods); // add the methods to the module
        }
    }

Now here's the wrapping code we'd use to expose it with Boost.Python::

    #include <boost/python.hpp>
    using namespace boost::python;
    BOOST_PYTHON_MODULE(hello)
    {
        def("greet", greet, "return one of 3 parts of a greeting");
    }

and here it is in action::

    >>> import hello
    >>> for x in range(3):
    ...     print hello.greet(x)
    ...
    hello
    Boost.Python
    world!

Aside from the fact that the 'C' API version is much more verbose,
it's worth noting a few things that it doesn't handle correctly:

* The original function accepts an unsigned integer, and the Python
  'C' API only gives us a way of extracting signed integers. The
  Boost.Python version will raise a Python exception if we try to pass
  a negative number to ``hello.greet``, but the other one will proceed
  to do whatever the C++ implementation does when converting an
  negative integer to unsigned (usually wrapping to some very large
  number), and pass the incorrect translation on to the wrapped
  function.

* That brings us to the second problem: if the C++ ``greet()``
  function is called with a number greater than 2, it will throw an
  exception.  Typically, if a C++ exception propagates across the
  boundary with code generated by a 'C' compiler, it will cause a
  crash.  As you can see in the first version, there's no C++
  scaffolding there to prevent this from happening.  Functions wrapped
  by Boost.Python automatically include an exception-handling layer
  which protects Python users by translating unhandled C++ exceptions
  into a corresponding Python exception.

* A slightly more-subtle limitation is that the argument conversion
  used in the Python 'C' API case can only get that integer ``x`` in
  *one way*.  PyArg_ParseTuple can't convert Python ``long`` objects
  (arbitrary-precision integers) which happen to fit in an ``unsigned
  int`` but not in a ``signed long``, nor will it ever handle a
  wrapped C++ class with a user-defined implicit ``operator unsigned
  int()`` conversion. Boost.Python's dynamic type conversion
  registry allows users to add arbitrary conversion methods.

==================
 Library Overview
==================

This section outlines some of the library's major features.  Except as
neccessary to avoid confusion, details of library implementation are
omitted.

------------------
 Exposing Classes
------------------

C++ classes and structs are exposed with a similarly-terse interface.
Given::

    struct World
    {
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

The following code will expose it in our extension module::

    #include <boost/python.hpp>
    BOOST_PYTHON_MODULE(hello)
    {
        class_<World>("World")
            .def("greet", &World::greet)
            .def("set", &World::set)
        ;
    }

Although this code has a certain pythonic familiarity, people
sometimes find the syntax bit confusing because it doesn't look like
most of the C++ code they're used to. All the same, this is just
standard C++.  Because of their flexible syntax and operator
overloading, C++ and Python are great for defining domain-specific
(sub)languages
(DSLs), and that's what we've done in Boost.Python. To break it down::

    class_<World>("World")

constructs an unnamed object of type ``class_<World>`` and passes
``"World"`` to its constructor.  This creates a new-style Python class
called ``World`` in the extension module, and associates it with the
C++ type ``World`` in the Boost.Python type conversion registry.  We
might have also written::

    class_<World> w("World");

but that would've been more verbose, since we'd have to name ``w``
again to invoke its ``def()`` member function::

        w.def("greet", &World::greet)

There's nothing special about the location of the dot for member
access in the original example: C++ allows any amount of whitespace on
either side of a token, and placing the dot at the beginning of each
line allows us to chain as many successive calls to member functions
as we like with a uniform syntax.  The other key fact that allows
chaining is that ``class_<>`` member functions all return a reference
to ``*this``.

So the example is equivalent to::

    class_<World> w("World");
    w.def("greet", &World::greet);
    w.def("set", &World::set);

It's occasionally useful to be able to break down the components of a
Boost.Python class wrapper in this way, but the rest of this article
will stick to the terse syntax.

For completeness, here's the wrapped class in use: ::

    >>> import hello
    >>> planet = hello.World()
    >>> planet.set('howdy')
    >>> planet.greet()
    'howdy'

Constructors
============

Since our ``World`` class is just a plain ``struct``, it has an
implicit no-argument (nullary) constructor.  Boost.Python exposes the
nullary constructor by default, which is why we were able to write: ::

  >>> planet = hello.World()

However, well-designed classes in any language may require constructor
arguments in order to establish their invariants.  Unlike Python,
where ``__init__`` is just a specially-named method, In C++
constructors cannot be handled like ordinary member functions.  In
particular, we can't take their address: ``&World::World`` is an
error.  The library provides a different interface for specifying
constructors.  Given::

    struct World
    {
        World(std::string msg); // added constructor
        ...

we can modify our wrapping code as follows::

    class_<World>("World", init<std::string>())
        ...

of course, a C++ class may have additional constructors, and we can
expose those as well by passing more instances of ``init<...>`` to
``def()``::

    class_<World>("World", init<std::string>())
        .def(init<double, double>())
        ...

Boost.Python allows wrapped functions, member functions, and
constructors to be overloaded to mirror C++ overloading.

Data Members and Properties
===========================

Any publicly-accessible data members in a C++ class can be easily
exposed as either ``readonly`` or ``readwrite`` attributes::

    class_<World>("World", init<std::string>())
        .def_readonly("msg", &World::msg)
        ...

and can be used directly in Python: ::

    >>> planet = hello.World('howdy')
    >>> planet.msg
    'howdy'

This does *not* result in adding attributes to the ``World`` instance
``__dict__``, which can result in substantial memory savings when
wrapping large data structures.  In fact, no instance ``__dict__``
will be created at all unless attributes are explicitly added from
Python. Boost.Python owes this capability to the new Python 2.2 type
system, in particular the descriptor interface and ``property`` type.

In C++, publicly-accessible data members are considered a sign of poor
design because they break encapsulation, and style guides usually
dictate the use of "getter" and "setter" functions instead.  In
Python, however, ``__getattr__``, ``__setattr__``, and since 2.2,
``property`` mean that attribute access is just one more
well-encapsulated syntactic tool at the programmer's disposal.
Boost.Python bridges this idiomatic gap by making Python ``property``
creation directly available to users.  If ``msg`` were private, we
could still expose it as attribute in Python as follows::

    class_<World>("World", init<std::string>())
        .add_property("msg", &World::greet, &World::set)
        ...

The example above mirrors the familiar usage of properties in Python
2.2+: ::

    >>> class World(object):
    ...     __init__(self, msg):
    ...         self.__msg = msg
    ...     def greet(self):
    ...         return self.__msg
    ...     def set(self, msg):
    ...         self.__msg = msg
    ...     msg = property(greet, set)

Operator Overloading
====================

The ability to write arithmetic operators for user-defined types has
been a major factor in the success of both languages for numerical
computation, and the success of packages like NumPy_ attests to the
power of exposing operators in extension modules.  Boost.Python
provides a concise mechanism for wrapping operator overloads. The
example below shows a fragment from a wrapper for the Boost rational
number library::

    class_<rational<int> >("rational_int")
      .def(init<int, int>()) // constructor, e.g. rational_int(3,4)
      .def("numerator", &rational<int>::numerator)
      .def("denominator", &rational<int>::denominator)
      .def(-self)        // __neg__ (unary minus)
      .def(self + self)  // __add__ (homogeneous)
      .def(self * self)  // __mul__
      .def(self + int()) // __add__ (heterogenous)
      .def(int() + self) // __radd__
      ...

The magic is performed using a simplified application of "expression
templates" [VELD1995]_, a technique originally developed for
optimization of high-performance matrix algebra expressions.  The
essence is that instead of performing the computation immediately,
operators are overloaded to construct a type *representing* the
computation.  In matrix algebra, dramatic optimizations are often
available when the structure of an entire expression can be taken into
account, rather than evaluating each operation "greedily".
Boost.Python uses the same technique to build an appropriate Python
method object based on expressions involving ``self``.

.. _NumPy: http://www.pfdubois.com/numpy/

Inheritance
===========

C++ inheritance relationships can be represented to Boost.Python by adding
an optional ``bases<...>`` argument to the ``class_<...>`` template
parameter list as follows::

     class_<Derived, bases<Base1,Base2> >("Derived")
          ...

This has two effects:

1. When the ``class_<...>`` is created, Python type objects
   corresponding to ``Base1`` and ``Base2`` are looked up in
   Boost.Python's registry, and are used as bases for the new Python
   ``Derived`` type object, so methods exposed for the Python ``Base1``
   and ``Base2`` types are automatically members of the ``Derived``
   type.  Because the registry is global, this works correctly even if
   ``Derived`` is exposed in a different module from either of its
   bases.

2. C++ conversions from ``Derived`` to its bases are added to the
   Boost.Python registry.  Thus wrapped C++ methods expecting (a
   pointer or reference to) an object of either base type can be
   called with an object wrapping a ``Derived`` instance.  Wrapped
   member functions of class ``T`` are treated as though they have an
   implicit first argument of ``T&``, so these conversions are
   neccessary to allow the base class methods to be called for derived
   objects.

Of course it's possible to derive new Python classes from wrapped C++
class instances.  Because Boost.Python uses the new-style class
system, that works very much as for the Python built-in types.  There
is one significant detail in which it differs: the built-in types
generally establish their invariants in their ``__new__`` function, so
that derived classes do not need to call ``__init__`` on the base
class before invoking its methods : ::

    >>> class L(list):
    ...      def __init__(self):
    ...          pass
    ...
    >>> L().reverse()
    >>>

Because C++ object construction is a one-step operation, C++ instance
data cannot be constructed until the arguments are available, in the
``__init__`` function: ::

    >>> class D(SomeBoostPythonClass):
    ...      def __init__(self):
    ...          pass
    ...
    >>> D().some_boost_python_method()
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: bad argument type for built-in operation

This happened because Boost.Python couldn't find instance data of type
``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__``
function masked construction of the base class.  It could be corrected
by either removing ``D``'s ``__init__`` function or having it call
``SomeBoostPythonClass.__init__(...)`` explicitly.

Virtual Functions
=================

Deriving new types in Python from extension classes is not very
interesting unless they can be used polymorphically from C++.  In
other words, Python method implementations should appear to override
the implementation of C++ virtual functions when called *through base
class pointers/references from C++*.  Since the only way to alter the
behavior of a virtual function is to override it in a derived class,
the user must build a special derived class to dispatch a polymorphic
class' virtual functions::

    //
    // interface to wrap:
    //
    class Base
    {
     public:
        virtual int f(std::string x) { return 42; }
        virtual ~Base();
    };

    int calls_f(Base const& b, std::string x) { return b.f(x); }

    //
    // Wrapping Code
    //

    // Dispatcher class
    struct BaseWrap : Base
    {
        // Store a pointer to the Python object
        BaseWrap(PyObject* self_) : self(self_) {}
        PyObject* self;

        // Default implementation, for when f is not overridden
        int f_default(std::string x) { return this->Base::f(x); }
        // Dispatch implementation
        int f(std::string x) { return call_method<int>(self, "f", x); }
    };

    ...
        def("calls_f", calls_f);
        class_<Base, BaseWrap>("Base")
            .def("f", &Base::f, &BaseWrap::f_default)
            ;

Now here's some Python code which demonstrates: ::

    >>> class Derived(Base):
    ...     def f(self, s):
    ...          return len(s)
    ...
    >>> calls_f(Base(), 'foo')
    42
    >>> calls_f(Derived(), 'forty-two')
    9

Things to notice about the dispatcher class:

* The key element which allows overriding in Python is the
  ``call_method`` invocation, which uses the same global type
  conversion registry as the C++ function wrapping does to convert its
  arguments from C++ to Python and its return type from Python to C++.

* Any constructor signatures you wish to wrap must be replicated with
  an initial ``PyObject*`` argument

* The dispatcher must store this argument so that it can be used to
  invoke ``call_method``

* The ``f_default`` member function is needed when the function being
  exposed is not pure virtual; there's no other way ``Base::f`` can be
  called on an object of type ``BaseWrap``, since it overrides ``f``.

Deeper Reflection on the Horizon?
=================================

Admittedly, this formula is tedious to repeat, especially on a project
with many polymorphic classes.  That it is neccessary reflects some
limitations in C++'s compile-time introspection capabilities: there's
no way to enumerate the members of a class and find out which are
virtual functions.  At least one very promising project has been
started to write a front-end which can generate these dispatchers (and
other wrapping code) automatically from C++ headers.

Pyste_ is being developed by Bruno da Silva de Oliveira.  It builds on
GCC_XML_, which generates an XML version of GCC's internal program
representation.  Since GCC is a highly-conformant C++ compiler, this
ensures correct handling of the most-sophisticated template code and
full access to the underlying type system.  In keeping with the
Boost.Python philosophy, a Pyste interface description is neither
intrusive on the code being wrapped, nor expressed in some unfamiliar
language: instead it is a 100% pure Python script.  If Pyste is
successful it will mark a move away from wrapping everything directly
in C++ for many of our users.  It will also allow us the choice to
shift some of the metaprogram code from C++ to Python.  We expect that
soon, not only our users but the Boost.Python developers themselves
will be "thinking hybrid" about their own code.

.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html
.. _`Pyste`: http://www.boost.org/libs/python/pyste

---------------
 Serialization
---------------

*Serialization* is the process of converting objects in memory to a
form that can be stored on disk or sent over a network connection. The
serialized object (most often a plain string) can be retrieved and
converted back to the original object. A good serialization system will
automatically convert entire object hierarchies. Python's standard
``pickle`` module is just such a system.  It leverages the language's strong
runtime introspection facilities for serializing practically arbitrary
user-defined objects. With a few simple and unintrusive provisions this
powerful machinery can be extended to also work for wrapped C++ objects.
Here is an example::

    #include <string>

    struct World
    {
        World(std::string a_msg) : msg(a_msg) {}
        std::string greet() const { return msg; }
        std::string msg;
    };

    #include <boost/python.hpp>
    using namespace boost::python;

    struct World_picklers : pickle_suite
    {
      static tuple
      getinitargs(World const& w) { return make_tuple(w.greet()); }
    };

    BOOST_PYTHON_MODULE(hello)
    {
        class_<World>("World", init<std::string>())
            .def("greet", &World::greet)
            .def_pickle(World_picklers())
        ;
    }

Now let's create a ``World`` object and put it to rest on disk::

    >>> import hello
    >>> import pickle
    >>> a_world = hello.World("howdy")
    >>> pickle.dump(a_world, open("my_world", "w"))

In a potentially *different script* on a potentially *different
computer* with a potentially *different operating system*::

    >>> import pickle
    >>> resurrected_world = pickle.load(open("my_world", "r"))
    >>> resurrected_world.greet()
    'howdy'

Of course the ``cPickle`` module can also be used for faster
processing.

Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol
defined in the standard Python documentation. Like a __getinitargs__
function in Python, the pickle_suite's getinitargs() is responsible for
creating the argument tuple that will be use to reconstruct the pickled
object.  The other elements of the Python pickling protocol,
__getstate__ and __setstate__ can be optionally provided via C++
getstate and setstate functions.  C++'s static type system allows the
library to ensure at compile-time that nonsensical combinations of
functions (e.g. getstate without setstate) are not used.

Enabling serialization of more complex C++ objects requires a little
more work than is shown in the example above. Fortunately the
``object`` interface (see next section) greatly helps in keeping the
code manageable.

------------------
 Object interface
------------------

Experienced 'C' language extension module authors will be familiar
with the ubiquitous ``PyObject*``, manual reference-counting, and the
need to remember which API calls return "new" (owned) references or
"borrowed" (raw) references.  These constraints are not just
cumbersome but also a major source of errors, especially in the
presence of exceptions.

Boost.Python provides a class ``object`` which automates reference
counting and provides conversion to Python from C++ objects of
arbitrary type.  This significantly reduces the learning effort for
prospective extension module writers.

Creating an ``object`` from any other type is extremely simple::

    object s("hello, world");  // s manages a Python string

``object`` has templated interactions with all other types, with
automatic to-python conversions. It happens so naturally that it's
easily overlooked::

   object ten_Os = 10 * s[4]; // -> "oooooooooo"

In the example above, ``4`` and ``10`` are converted to Python objects
before the indexing and multiplication operations are invoked.

The ``extract<T>`` class template can be used to convert Python objects
to C++ types::

    double x = extract<double>(o);

If a conversion in either direction cannot be performed, an
appropriate exception is thrown at runtime.

The ``object`` type is accompanied by a set of derived types
that mirror the Python built-in types such as ``list``, ``dict``,
``tuple``, etc. as much as possible. This enables convenient
manipulation of these high-level types from C++::

    dict d;
    d["some"] = "thing";
    d["lucky_number"] = 13;
    list l = d.keys();

This almost looks and works like regular Python code, but it is pure
C++.  Of course we can wrap C++ functions which accept or return
``object`` instances.

=================
 Thinking hybrid
=================

Because of the practical and mental difficulties of combining
programming languages, it is common to settle a single language at the
outset of any development effort.  For many applications, performance
considerations dictate the use of a compiled language for the core
algorithms.  Unfortunately, due to the complexity of the static type
system, the price we pay for runtime performance is often a
significant increase in development time.  Experience shows that
writing maintainable C++ code usually takes longer and requires *far*
more hard-earned working experience than developing comparable Python
code.  Even when developers are comfortable working exclusively in
compiled languages, they often augment their systems by some type of
ad hoc scripting layer for the benefit of their users without ever
availing themselves of the same advantages.

Boost.Python enables us to *think hybrid*.  Python can be used for
rapidly prototyping a new application; its ease of use and the large
pool of standard libraries give us a head start on the way to a
working system.  If necessary, the working code can be used to
discover rate-limiting hotspots.  To maximize performance these can
be reimplemented in C++, together with the Boost.Python bindings
needed to tie them back into the existing higher-level procedure.

Of course, this *top-down* approach is less attractive if it is clear
from the start that many algorithms will eventually have to be
implemented in C++.  Fortunately Boost.Python also enables us to
pursue a *bottom-up* approach.  We have used this approach very
successfully in the development of a toolbox for scientific
applications.  The toolbox started out mainly as a library of C++
classes with Boost.Python bindings, and for a while the growth was
mainly concentrated on the C++ parts.  However, as the toolbox is
becoming more complete, more and more newly added functionality can be
implemented in Python.

.. image:: images/python_cpp_mix.png

This figure shows the estimated ratio of newly added C++ and Python
code over time as new algorithms are implemented.  We expect this
ratio to level out near 70% Python.  Being able to solve new problems
mostly in Python rather than a more difficult statically typed
language is the return on our investment in Boost.Python.  The ability
to access all of our code from Python allows a broader group of
developers to use it in the rapid development of new applications.

=====================
 Development history
=====================

The first version of Boost.Python was developed in 2000 by Dave
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
as a guide to "The Zen of Python".  One of Dave's jobs was to develop
a Python-based natural language processing system.  Since it was
eventually going to be targeting embedded hardware, it was always
assumed that the compute-intensive core would be rewritten in C++ to
optimize speed and memory footprint [#proto]_.  The project also wanted to
test all of its C++ code using Python test scripts [#test]_.  The only
tool we knew of for binding C++ and Python was SWIG_, and at the time
its handling of C++ was weak.  It would be false to claim any deep
insight into the possible advantages of Boost.Python's approach at
this point.  Dave's interest and expertise in fancy C++ template
tricks had just reached the point where he could do some real damage,
and Boost.Python emerged as it did because it filled a need and
because it seemed like a cool thing to try.

This early version was aimed at many of the same basic goals we've
described in this paper, differing most-noticeably by having a
slightly more cumbersome syntax and by lack of special support for
operator overloading, pickling, and component-based development.
These last three features were quickly added by Ullrich Koethe and
Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived
on the scene to contribute enhancements like support for nested
modules and static member functions.

By early 2001 development had stabilized and few new features were
being added, however a disturbing new fact came to light: Ralf had
begun testing Boost.Python on pre-release versions of a compiler using
the EDG_ front-end, and the mechanism at the core of Boost.Python
responsible for handling conversions between Python and C++ types was
failing to compile.  As it turned out, we had been exploiting a very
common bug in the implementation of all the C++ compilers we had
tested.  We knew that as C++ compilers rapidly became more
standards-compliant, the library would begin failing on more
platforms.  Unfortunately, because the mechanism was so central to the
functioning of the library, fixing the problem looked very difficult.

Fortunately, later that year Lawrence Berkeley and later Lawrence
Livermore National labs contracted with `Boost Consulting`_ for support
and development of Boost.Python, and there was a new opportunity to
address fundamental issues and ensure a future for the library.  A
redesign effort began with the low level type conversion architecture,
building in standards-compliance and support for component-based
development (in contrast to version 1 where conversions had to be
explicitly imported and exported across module boundaries).  A new
analysis of the relationship between the Python and C++ objects was
done, resulting in more intuitive handling for C++ lvalues and
rvalues.

The emergence of a powerful new type system in Python 2.2 made the
choice of whether to maintain compatibility with Python 1.5.2 easy:
the opportunity to throw away a great deal of elaborate code for
emulating classic Python classes alone was too good to pass up.  In
addition, Python iterators and descriptors provided crucial and
elegant tools for representing similar C++ constructs.  The
development of the generalized ``object`` interface allowed us to
further shield C++ programmers from the dangers and syntactic burdens
of the Python 'C' API.  A great number of other features including C++
exception translation, improved support for overloaded functions, and
most significantly, CallPolicies for handling pointers and
references, were added during this period.

In October 2002, version 2 of Boost.Python was released.  Development
since then has concentrated on improved support for C++ runtime
polymorphism and smart pointers.  Peter Dimov's ingenious
``boost::shared_ptr`` design in particular has allowed us to give the
hybrid developer a consistent interface for moving objects back and
forth across the language barrier without loss of information.  At
first, we were concerned that the sophistication and complexity of the
Boost.Python v2 implementation might discourage contributors, but the
emergence of Pyste_ and several other significant feature
contributions have laid those fears to rest.  Daily questions on the
Python C++-sig and a backlog of desired improvements show that the
library is getting used.  To us, the future looks bright.

.. _`EDG`: http://www.edg.com

=============
 Conclusions
=============

Boost.Python achieves seamless interoperability between two rich and
complimentary language environments.  Because it leverages template
metaprogramming to introspect about types and functions, the user
never has to learn a third syntax: the interface definitions are
written in concise and maintainable C++.  Also, the wrapping system
doesn't have to parse C++ headers or represent the type system: the
compiler does that work for us.

Computationally intensive tasks play to the strengths of C++ and are
often impossible to implement efficiently in pure Python, while jobs
like serialization that are trivial in Python can be very difficult in
pure C++.  Given the luxury of building a hybrid software system from
the ground up, we can approach design with new confidence and power.

===========
 Citations
===========

.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
   Vol. 7 No. 5 June 1995, pp. 26-31.
   http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html

===========
 Footnotes
===========

.. [#proto] In retrospect, it seems that "thinking hybrid" from the
        ground up might have been better for the NLP system: the
        natural component boundaries defined by the pure python
        prototype turned out to be inappropriate for getting the
        desired performance and memory footprint out of the C++ core,
        which eventually caused some redesign overhead on the Python
        side when the core was moved to C++.

.. [#test] We also have some reservations about driving all C++
        testing through a Python interface, unless that's the only way
        it will be ultimately used.  Any transition across language
        boundaries with such different object models can inevitably
        mask bugs.

.. [#feature] These features were expressed very differently in v1 of
        Boost.Python


Q:

Finish two activities on receive the same broadcast

I have a BroadcastReceiver which handles System Broadcasts like AC Connected and disconnected. The BroadcastReceiver receives POWER_CONNECTED and starts an Activity "MainActivity", which unlocks KeyGuard and acquires WakeLock. In the onCreate and in onResume I register dynamically a BroadcastReceiver to listen on POWER_DISCONNECTED.
The "MainActivity" starts a second "VideoPlayer Activity", which also register a BroadcastReceiver listening on POWER_DISCONNECTED.
When I send the ACTION_POWER_DISCONNECT over adb I see through LogCat that the "MainActivity" stops first. Why?
How can I handle that the "VideoPlayerActivity" finishes first?
Thanks

A:

Look here (http://developer.android.com/reference/android/content/BroadcastReceiver.html):

Normal broadcasts (sent with Context.sendBroadcast) are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time. This is more efficient, but means that receivers cannot use the result or abort APIs included here.

You can't guarantee that VideoPlayerActivity will receive.
I would recommend to create a separate BroadcastReceiver (which isn't part of activities). And in this broadcast receiver do something like this:
videoPlayerActivity.finish();
mainActivity.finish();

Sure, you need to initialize both of these variables in onCreate or onResume of your activities.


Q:

Is it safe to restart PostgreSQL if process terminated for some reason?

I am writing a docker-compose config with a container with PostgreSQL in it. docker-compose has a configuration options called restart. If I enable it then whenever the Postgres process stops it will restart Postgres rightaway. However it is (probably) not relevant how it is restarted.
I know that in MySQL it is not safe to start the database right after it stopped because MyISAM tables may be broken. One has to manually repair MyISAM tables first with an unrelated command-line tool and then start the db.
So I wonder if it is generally safe to just restart PostgreSQL in case something is wrong. Or maybe we should first backup, repair, read logs and only then try to start it back.
A related situation would be a power outage for instance. What do I do after that?

A:

Postgres generally handles server restarts pretty well.  Assuming that all the correct hardware is in place (battery-backed cache, etc.), bringing up Postgres after a crash will automatically cause it to enter recovery mode, where it will attempt to replay all the WAL files since the last CHECKPOINT.  Once it has finish replaying up to a consistent state, you are free to use the database and continue with your business.  Having said that, however, it's up to you as the DBA to perform consistency checks as per your business requirements to ensure there is no corruption.
Disclosure: I work for EnterpriseDB (EDB) as a Support Engineer


Boulder Creek Bridge

Boulder Creek Bridge may refer to:

 Boulder Creek Bridge (Tortilla Flat, Arizona), listed on the National Register of Historic Places in Maricopa County, Arizona
 Boulder Creek Bridge (Boulder, Colorado), listed on the National Register of Historic Places in Boulder County, Colorado


3-Nitropropionic acid neurotoxicity in hippocampal slice cultures: developmental and regional vulnerability and dependency on glucose.
We investigated whether neurotoxic effects of the mitochondrial toxin 3-nitropropionic acid (3-NP) in hippocampal slice cultures are dependent on glucose levels in the culture medium and whether such effects occur via apoptosis or necrosis. In addition, 3-NP toxicity was investigated at two developmental stages of the cultures, prepared from rat brain at postnatal day 5-7 and grown in Neurobasal medium for 1 or 3 weeks. Cultures were exposed to 3-NP in the presence of high (25 mM), normal (5 mM), or low (3 mM) glucose for 48 h, followed by 48 h incubation in medium without 3-NP. Cellular propidium iodide (PI) uptake and lactate dehydrogenase (LDH) efflux into the medium revealed time- and dose-dependent cell death by 3-NP, with EC(50) values of about 60 microM in high or normal glucose. Regional vulnerability, as assessed by PI uptake and MAP2 immunostaining, in 3-week-old cultures was as follows: CA1 > CA3 > fascia dentata. In low glucose much lower concentrations of 3-NP (25 microM) triggered neurotoxicity. One-week-old cultures were less susceptible to 3-NP toxicity than 3-week-old cultures, but the dentate granule cells were relatively more affected in the immature cultures. We found no evidence for apoptotic cell death by 3-NP in 3-week-old cultures, but in 1-week-old cultures the putative apoptotic marker c-JUN/AP1 and nuclear fragmentation (Hoechst) were significantly increased in the dentate granule cells.


module Steep
  module Errors
    class Base
      attr_reader :node

      def initialize(node:)
        @node = node
      end

      def location_to_str
        Rainbow("#{node.loc.expression.source_buffer.name}:#{node.loc.first_line}:#{node.loc.column}").red
      end

      def print_to(io)
        source = node.loc.expression.source
        io.puts "#{to_s} (#{Rainbow(source.split(/\n/).first).blue})"
      end
    end

    module ResultPrinter
      def print_result_to(io, level: 2)
        printer = Drivers::TracePrinter.new(io)
        printer.print result.trace, level: level
        io.puts "==> #{result.error.message}"
      end

      def print_to(io)
        super
        print_result_to io
      end
    end

    class IncompatibleAssignment < Base
      attr_reader :lhs_type
      attr_reader :rhs_type
      attr_reader :result

      include ResultPrinter

      def initialize(node:, lhs_type:, rhs_type:, result:)
        super(node: node)
        @lhs_type = lhs_type
        @rhs_type = rhs_type
        @result = result
      end

      def to_s
        "#{location_to_str}: IncompatibleAssignment: lhs_type=#{lhs_type}, rhs_type=#{rhs_type}"
      end
    end

    class IncompatibleArguments < Base
      attr_reader :node
      attr_reader :receiver_type
      attr_reader :method_type

      def initialize(node:, receiver_type:, method_type:)
        super(node: node)
        @receiver_type = receiver_type
        @method_type = method_type
      end

      def to_s
        "#{location_to_str}: IncompatibleArguments: receiver=#{receiver_type}, method_type=#{method_type}"
      end
    end

    class UnresolvedOverloading < Base
      attr_reader :node
      attr_reader :receiver_type
      attr_reader :method_name
      attr_reader :method_types

      def initialize(node:, receiver_type:, method_name:, method_types:)
        super node: node
        @receiver_type = receiver_type
        @method_name = method_name
        @method_types = method_types
      end

      def to_s
        "#{location_to_str}: UnresolvedOverloading: receiver=#{receiver_type}, method_name=#{method_name}, method_types=#{method_types.join(" | ")}"
      end
    end

    class ArgumentTypeMismatch < Base
      attr_reader :node
      attr_reader :expected
      attr_reader :actual
      attr_reader :receiver_type

      def initialize(node:, receiver_type:, expected:, actual:)
        super(node: node)
        @receiver_type = receiver_type
        @expected = expected
        @actual = actual
      end

      def to_s
        "#{location_to_str}: ArgumentTypeMismatch: receiver=#{receiver_type}, expected=#{expected}, actual=#{actual}"
      end
    end

    class IncompatibleBlockParameters < Base
      attr_reader :node
      attr_reader :method_type

      def initialize(node:, method_type:)
        super(node: node)
        @method_type = method_type
      end

      def to_s
        "#{location_to_str}: IncompatibleBlockParameters: method_type=#{method_type}"
      end
    end

    class BlockParameterTypeMismatch < Base
      attr_reader :expected
      attr_reader :actual

      def initialize(node:, expected:, actual:)
        super(node: node)
        @expected = expected
        @actual = actual
      end

      def to_s
        "#{location_to_str}: BlockParameterTypeMismatch: expected=#{expected}, actual=#{actual}"
      end
    end

    class NoMethod < Base
      attr_reader :type
      attr_reader :method

      def initialize(node:, type:, method:)
        super(node: node)
        @type = type
        @method = method
      end

      def to_s
        "#{location_to_str}: NoMethodError: type=#{type}, method=#{method}"
      end
    end

    class ReturnTypeMismatch < Base
      attr_reader :expected
      attr_reader :actual
      attr_reader :result

      include ResultPrinter

      def initialize(node:, expected:, actual:, result:)
        super(node: node)
        @expected = expected
        @actual = actual
        @result = result
      end

      def to_s
        "#{location_to_str}: ReturnTypeMismatch: expected=#{expected}, actual=#{actual}"
      end
    end

    class UnexpectedBlockGiven < Base
      attr_reader :method_type

      def initialize(node:, method_type:)
        super(node: node)
        @method_type = method_type
      end

      def to_s
        "#{location_to_str}: UnexpectedBlockGiven: method_type=#{method_type}"
      end
    end

    class RequiredBlockMissing < Base
      attr_reader :method_type

      def initialize(node:, method_type:)
        super(node: node)
        @method_type = method_type
      end

      def to_s
        "#{location_to_str}: RequiredBlockMissing: method_type=#{method_type.location&.source}"
      end
    end

    class BlockTypeMismatch < Base
      attr_reader :expected
      attr_reader :actual
      attr_reader :result

      include ResultPrinter

      def initialize(node:, expected:, actual:, result:)
        super(node: node)
        @expected = expected
        @actual = actual
        @result = result
      end

      def to_s
        "#{location_to_str}: BlockTypeMismatch: expected=#{expected}, actual=#{actual}"
      end
    end

    class BreakTypeMismatch < Base
      attr_reader :expected
      attr_reader :actual
      attr_reader :result

      include ResultPrinter

      def initialize(node:, expected:, actual:, result:)
        super(node: node)
        @expected = expected
        @actual = actual
        @result = result
      end

      def to_s
        "#{location_to_str}: BreakTypeMismatch: expected=#{expected}, actual=#{actual}"
      end
    end

    class UnexpectedJump < Base
      def to_s
        "#{location_to_str}: UnexpectedJump"
      end
    end

    class UnexpectedJumpValue < Base
      def to_s
        "#{location_to_str}: UnexpectedJumpValue"
      end
    end

    class MethodArityMismatch < Base
      def to_s
        "#{location_to_str}: MethodArityMismatch: method=#{node.children[0]}"
      end
    end

    class IncompatibleMethodTypeAnnotation < Base
      attr_reader :interface_method
      attr_reader :annotation_method
      attr_reader :result

      include ResultPrinter

      def initialize(node:, interface_method:, annotation_method:, result:)
        super(node: node)
        @interface_method = interface_method
        @annotation_method = annotation_method
        @result = result
      end

      def to_s
        "#{location_to_str}: IncompatibleMethodTypeAnnotation: interface_method=#{interface_method.type_name}.#{interface_method.name}, annotation_method=#{annotation_method.name}"
      end
    end

    class MethodDefinitionWithOverloading < Base
      attr_reader :method

      def initialize(node:, method:)
        super(node: node)
        @method = method
      end

      def to_s
        "#{location_to_str}: MethodDefinitionWithOverloading: method=#{method.name}, types=#{method.types.join(" | ")}"
      end
    end

    class MethodReturnTypeAnnotationMismatch < Base
      attr_reader :method_type
      attr_reader :annotation_type
      attr_reader :result

      include ResultPrinter

      def initialize(node:, method_type:, annotation_type:, result:)
        super(node: node)
        @method_type = method_type
        @annotation_type = annotation_type
        @result = result
      end

      def to_s
        "#{location_to_str}: MethodReturnTypeAnnotationMismatch: method_type=#{method_type.return_type}, annotation_type=#{annotation_type}"
      end
    end

    class MethodBodyTypeMismatch < Base
      attr_reader :expected
      attr_reader :actual
      attr_reader :result

      include ResultPrinter

      def initialize(node:, expected:, actual:, result:)
        super(node: node)
        @expected = expected
        @actual = actual
        @result = result
      end

      def to_s
        method = case node.type
                 when :def
                   node.children[0]
                 when :defs
                   prefix = node.children[0].type == :self ? "self" : "*"
                   "#{prefix}.#{node.children[1]}"
                 end
        "#{location_to_str}: MethodBodyTypeMismatch: method=#{method}, expected=#{expected}, actual=#{actual}"
      end
    end

    class UnexpectedYield < Base
      def to_s
        "#{location_to_str}: UnexpectedYield"
      end
    end

    class UnexpectedSuper < Base
      attr_reader :method

      def initialize(node:, method:)
        super(node: node)
        @method = method
      end

      def to_s
        "#{location_to_str}: UnexpectedSuper: method=#{method}"
      end
    end

    class IncompatibleZuper < Base
      attr_reader :method

      def initialize(node:, method:)
        super(node: node)
        @method = method
      end

      def to_s
        "#{location_to_str}: IncompatibleZuper: method=#{method}"
      end
    end

    class MethodDefinitionMissing < Base
      attr_reader :module_name
      attr_reader :kind
      attr_reader :missing_method

      def initialize(node:, module_name:, kind:, missing_method:)
        super(node: node)
        @module_name = module_name
        @kind = kind
        @missing_method = missing_method
      end

      def to_s
        method = case kind
                 when :instance
                   "#{missing_method}"
                 when :module
                   "self.#{missing_method}"
                 end
        "#{location_to_str}: MethodDefinitionMissing: module=#{module_name}, method=#{method}"
      end
    end

    class UnexpectedDynamicMethod < Base
      attr_reader :module_name
      attr_reader :method_name

      def initialize(node:, module_name:, method_name:)
        @node = node
        @module_name = module_name
        @method_name = method_name
      end

      def to_s
        "#{location_to_str}: UnexpectedDynamicMethod: module=#{module_name}, method=#{method_name}"
      end
    end

    class UnknownConstantAssigned < Base
      attr_reader :type

      def initialize(node:, type:)
        super(node: node)
        @type = type
      end

      def to_s
        "#{location_to_str}: UnknownConstantAssigned: type=#{type}"
      end
    end

    class FallbackAny < Base
      def initialize(node:)
        @node = node
      end

      def to_s
        "#{location_to_str}: FallbackAny"
      end
    end

    class UnsatisfiableConstraint < Base
      attr_reader :method_type
      attr_reader :var
      attr_reader :sub_type
      attr_reader :super_type
      attr_reader :result

      def initialize(node:, method_type:, var:, sub_type:, super_type:, result:)
        super(node: node)
        @method_type = method_type
        @var = var
        @sub_type = sub_type
        @super_type = super_type
        @result = result
      end

      include ResultPrinter

      def to_s
        "#{location_to_str}: UnsatisfiableConstraint: method_type=#{method_type}, constraint=#{sub_type} <: '#{var} <: #{super_type}"
      end
    end

    class IncompatibleAnnotation < Base
      attr_reader :var_name
      attr_reader :result
      attr_reader :relation

      def initialize(node:, var_name:, result:, relation:)
        super(node: node)
        @var_name = var_name
        @result = result
        @relation = relation
      end

      include ResultPrinter

      def to_s
        "#{location_to_str}: IncompatibleAnnotation: var_name=#{var_name}, #{relation}"
      end
    end

    class IncompatibleTypeCase < Base
      attr_reader :var_name
      attr_reader :result
      attr_reader :relation

      def initialize(node:, var_name:, result:, relation:)
        super(node: node)
        @var_name = var_name
        @result = result
        @relation = relation
      end

      include ResultPrinter

      def to_s
        "#{location_to_str}: IncompatibleTypeCase: var_name=#{var_name}, #{relation}"
      end
    end

    class ElseOnExhaustiveCase < Base
      attr_reader :type

      def initialize(node:, type:)
        super(node: node)
        @type = type
      end

      def to_s
        "#{location_to_str}: ElseOnExhaustiveCase: type=#{type}"
      end
    end

    class UnexpectedSplat < Base
      attr_reader :type

      def initialize(node:, type:)
        super(node: node)
        @type = type
      end

      def to_s
        "#{location_to_str}: UnexpectedSplat: type=#{type}"
      end
    end

    class IncompatibleTuple < Base
      attr_reader :expected_tuple
      include ResultPrinter

      def initialize(node:, expected_tuple:, result:)
        super(node: node)
        @result = result
        @expected_tuple = expected_tuple
      end

      def to_s
        "#{location_to_str}: IncompatibleTuple: expected_tuple=#{expected_tuple}"
      end
    end

    class UnexpectedKeyword < Base
      attr_reader :unexpected_keywords

      def initialize(node:, unexpected_keywords:)
        super(node: node)
        @unexpected_keywords = unexpected_keywords
      end

      def to_s
        "#{location_to_str}: UnexpectedKeyword: #{unexpected_keywords.to_a.join(", ")}"
      end
    end

    class MissingKeyword < Base
      attr_reader :missing_keywords

      def initialize(node:, missing_keywords:)
        super(node: node)
        @missing_keywords = missing_keywords
      end

      def to_s
        "#{location_to_str}: MissingKeyword: #{missing_keywords.to_a.join(", ")}"
      end
    end

    class UnsupportedSyntax < Base
      attr_reader :message

      def initialize(node:, message: nil)
        super(node: node)
        @message = message
      end

      def to_s
        msg = message || "#{node.type} is not supported"
        "#{location_to_str}: UnsupportedSyntax: #{msg}"
      end
    end
  end
end


VIBRANT TORONTO

Hi everybody!

It's Kathleen here from Tour America. I am currently spending my year living in & travelling North America with the fabulous city of Toronto as my home for the year.

As the ultimate New York City gal, it's hard for me to find a city that even comes close to the Big Apple & Toronto is the first city I've visited that I have liked just as much. We flew with British Airways via London to Toronto but in the summer months Air Canada do go direct from Dublin so it's a really great & accessible city.

We stayed in the Delta Chelsea Hotel for 5 nights and it was such a brilliant hotel in a brilliant location! We were steps from Dundas Square and the world famous Eaton Centre!

So, what is it that I love about this East Coast City & what is it that I think you will love as well…

Having stepped out of our hotel onto Yonge Street, we were greeted with the cool, relaxed Toronto vibe. For such a large bustling city, Toronto really has a great laid back feel to it. Dundas Square which is the heart of the city is full of laughing locals and happy tourists. Throughout the year it's home to many street festivals and similar to Times Square, it has plenty of bright lights for those perfect Kodak moments. A walk around the Square will have your heart pounding and your taste buds exploding as the square is filled with many shops & fabulous restaurants. It's also the home to the incredible Eaton Shopping Centre.

One of my favourite things about the city (other than the shopping of course) is the fantastic selection of restaurants. Toronto has something to suit everyone's taste from Asian cuisine to Italian to French. Two of my favourite places to eat are – Five Guys Burgers & Fries on Yonge Street & Big Daddy's Bourbon Street Bistro on King Street West. If you love a good burger & a great 50's style restaurant then you will love Five Guys Burger & Fries! The restaurant has a great vibe and it's a really fun place to eat after some shopping! Or, you love Southern Cuisine then a visit to Big Daddy's Bourbon Street Bistro is a must! This restaurant will take you to New Orleans while you enjoy the most amazing dishes from the Deep South. A great restaurant with a great menu & an even better atmosphere!

Sport is also huge in Toronto and this makes it a perfect city for the boys. Toronto takes pride in all of their teams and they boast very successful teams in ice hockey, baseball, basketball & soccer. We haven't been lucky enough to attend a match just yet but when we do, I will tell you guys all about it! Sporting events take place throughout the year so for couples travelling to the city â€“ the girls will get to visit the amazing shops & later in the day, the guys get to go watch a match! It's a win win!

Toronto's landmark, the CN Tower will greet you as you come in from the airport (I got so excited and started taking hundreds of photos!!) and you will be amazed by it. Each night, it changes colour so if you are out for a walk make sure to bring your camera along and get snapping! You can go up the tower as well, and the view is just amazing!

Toronto is build on Lake Ontario and in the warmer months; a trip out to the Toronto Islands is a must. Sit on the beach or go for a stroll all while you enjoy looking across at the amazing Toronto skyline. I know that's where I'll be going to get my tan this Summer!

Toronto also boasts many Broadway shows & museums so there is lots to do on a trip here. If you have seen New York & Boston and you want to do something a little different, this is a really great city to visit with so much to offer.

So what's next on my to-do list in this fabulous city!? I will shortly be off to visit the breathtaking Niagara Falls which I am so excited about! I will share my experience with you all once I get back!

I will also be doing a post soon on Toronto Shopping â€“ yes the shopping is SO good it deserves a post entirely dedicated to it so do keep an eye out for that in the coming weeks as well.

For now, it's good bye from this side of the world & I will touch base with you all again really soon!Kathleen

Sharing is Caring

0

SHARES

Enquiry Form

Name

Email Address

Phone Number

Subscribe to our Newsletter

Your EnquiryBe specific with dates and destination/hotels

Thanks for your enquiry.Please complete all the required fields above.


Q:

Using the mod operator C++

Without using any stls, boosts, and the like I have been trying to rotate the elements in my array. I've been trying to use the mod operator, to be efficient:
void stack::rotate(int r)
{
 r = ( r % maxSize + maxSize ) % maxSize;
 for ( int first_index = 0; first_index < r; ++first_index )
 {
  int mem = items[first_index].n;
  int index = ( first_index + r ) % maxSize, index_prev = first_index;
  while ( index != first_index )
  {
   items[index_prev] = items[index];
   index_prev = index;
   index = ( index + r ) % maxSize;
  }
  items[index_prev].n = mem;
 }

Where items is an allocated array to an item struct. Although it is a little weird the item struct has an integer 'n' member so that i may use it with integer type varaibles.
But its still not comming out right =( . Im losing the contents of my second element. I think its break time ;)

A:

In-place array rotation is trickier than it looks.  You might be interested in this article:
http://www.azillionmonkeys.com/qed/case8.html

A:

Tips:
Add assertions (r is positive, nonzero?, less than maxsize, maxsize is nonzero, etc.)
Write tests for this function, starting from an easy array and going up. Do not throw them away - keep them written and run all of them in a row.
Give clear names to variables.
Do not reuse r.
Your code looks a bit too obscure for me. At first sight it is crying "Off by one errors here! Come see!". Assert each and every possible boundary error.
For any more detailed answers, you should expand a bit on "its still not comming out right".


How SAP Authorizations Management Impacts SAP Licensing Compliancy

Commonly, SAP licensing is measured based upon the entitled access of named user accounts within the SAP systems. From my experiecne as a license auditor, working with some of the biggest global SAP organizations, this is the most common licensing principle I’ve come across in SAP contracts. It does however depend on the specific conditions in your SAP contract where usage based terms can exist.

What does licensing based on entitled access mean?

In general, if users are entitled to use certain SAP functionality and perform specific tasks by way of designated access controls (SAP authorizations) then those users should be licensed in a way that reflects those permissions. If your contract stipulates licensing based on the authorized access and you have been licensing users based on what users are actually doing in those systems then there is certainly a potential risk of non-compliance.

In my experience, many customers have been licensing users based on what users are doing in SAP, based on the transaction codes those users have been executing. This is done by analysing usage data also known as STAD data. My professional opinion in these cases was that these customers were non-compliant and potentially significantly underlicensed. The shortfall in license assets held typically as result of being lured into a false sense of security by the usage based assessment of their licensing requirements.

“My professional opinion in these cases was that these customers were non-compliant and potentially significantly underlicensed”

A Practical example

A user has been assigned permissions to (1) create and (2) maintain purchase requisitions (Assuming Limited Professional Activity) and, additionally (3) maintain vendor master data (Assuming Professional Activity). According to the principle of licensing by authorized access and the associated user definitions in the customers contract, the grouping of these tasks requires a Professional license. However, through the customers own methodology of licensing users based on actual usage they have determined that the user has only created purchase requisitions (Assuming Limited Professional Activity) in the past year, therefore has assigned a Limited Professional license to that user. In the case of license by authorized access contract the user would actually require a full professional license to be compliant.

The question is, is the customer compliant with their contract or not? In my opinion, it depends on the definitions within that contract. If the user license definitions read like “An individual who is entitled to perform…” or “is authorized to perform” then this tells me that the customer is not compliant as they have licensed the user based on what the user has done not what the user can do.

License Audit Risk

The major risk here is of a License Audit. License Audit Workbench (LAW) is not capable of interrogating user authorizations to determine the actual license required. USMM, the measurement transaction merely gathers the customer assigned license type from the SAP systems. LAW consolidates all systems accessed to determine the prevailing license type for each user, where the highest usage takes precedence. This means that customers who are managing licensing based on usage data and not authorizations data could be significantly non-compliant to their SAP contracts. You can quite easily submit your USMM/LAW results year upon year without this issue every being raised. Because it doesnt show up in the data that USMM collects. In fact, this is one of the single greatest causes of large value non-compliancy claims. Where the customer has tens of thousand of users this can mean a compliancy gap of seven or even eight figures, which means a potentially costly license audit.

“Where the customer has tens of thousand of users this can mean a compliancy gap of seven or even eight figures, which means a potentially costly license audit.”

Possible Workarounds

If you as a customer are licensing users based on what named users are actually doing in SAP and not what users are entitled to do then there is a solution. Performing a redundant access clean-up project. This involves removing the redundant access provisions that have most likely accumulated over the years. In turn this has likely made your access controls and Segregation of Duties (SoD) risks increase or remain, and now is potentially causing you contract compliancy issues.

If you are relying on a SAM tool for peace of mind, again (which I have covered in a previous blog) then ensure that the tool is actually measuring your SAP landscape based on your SAP contract, not some ‘out of the box’ queries that are providing you with the figures you want to see not the figures that actually count.

If you are relying on some form of tool or script for output, whatever it is make sure that the output reflects your contract. If you are allowing SAP named users to accumulate access rights they potentially no longer need then consider a clean-up project. It will be a two in one win potentially reducing your business risks associated with SAP system access and potentially become more compliant with your SAP contract.

“If you are allowing SAP named users to accumulate access rights they potentially no longer need then consider a clean-up project”

Key Takeaways

The key takeaways from this article is to read your contract! Read the definitions of the user licenses that you have purchased and don’t google them to identify any generic user license definitions that are most likely not relevant to your organization. I would advise you trying to source information on SAP License Management and User License Definitions given that fact that they differ in every contract, and what matters to your organisation is written in yours.

Related Information

SAP License Audit Simulation – Measures actual usage of the SAP software according to contractual defintions comared to licensing entitlements held to determine your SAP liensing and Compliancy position. Our Audit Simulation identifies where redundant access clean-up can be performed in order to truly your optimize SAP licensing.

James Cochlin is Principle Consultant and Head of Audit & Compliancy Services at JNC, A company which has been providing SAP License Management services since 2009. In total James possesses over 12 years’ experience in SAP License Management and Auditing with significant knowledge and experience in SAP security, Authorisations and GRC. In the past, James was an SAP License Auditor for Deloitte. As Global Technical Lead James audited clients around the world on behalf of SAP, and was involved in the development of SAP’s License Audit Methodology. Now James works with customers helping reduce their risk of non-compliance, identify cost savings and avoid the pit-falls of licensing SAP estates. Throughout his consulting career, James has worked at some of the largest clients of SAP helping them solve complex licensing problems whilst helping them regain control of SAP Licensing and Compliancy. James continues to train SAP Consultants on SAP licensing to the highest standards, he was the lead architect of a well know SAP Software Asset Management tool, and is held in high esteem internationally as a leading SME and authority on SAP License Management.

Categories

The SAP logo displayed on this website are the trademark(s) or registered trademark(s) of SAP SE in Germany and in several other countries. SAP is a registered trademark of SAP AG in Germany and in several other countries all over the world.

About JNC - The SAP & GRC Consultancy Experts

As a premium security and compliancy consulting firm we strive to deliver and execute our client’s cost effective SAP compliancy projects whilst positioning them to ensure adequate and robust cost control mechanisms.
Our company portfolio has a range of clients from a multitude of sectors from across the world where we advise and nurture our clients through a range of difficulties in a wide range of tasks.
JNC strives to deliver excellence on all levels and believes in a 360° approach when performing all activities to ensure our clients are compliant in all areas.

JNC have locations in three cities across the continent.

You can find out more about which cookies we are using or switch them off in settings.

Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

You can adjust all of your cookie settings by navigating the tabs on the left hand side.

Strictly Necessary Cookies

Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.

If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.

3rd Party Cookies

This website uses Google Analytics to collect anonymous information such as the number of visitors to the site, and the most popular pages.

Keeping this cookie enabled helps us to improve our website.

Please enable Strictly Necessary Cookies first so that we can save your preferences!


J-S02008-16

NON-PRECEDENTIAL DECISION - SEE SUPERIOR COURT I.O.P. 65.37

COMMONWEALTH OF PENNSYLVANIA,                    IN THE SUPERIOR COURT OF
                                                       PENNSYLVANIA
                        Appellee

                   v.

DEAN LASEAN BROWN,

                        Appellant                      No. 913 EDA 2015

          Appeal from the Judgment of Sentence March 2, 2015
            In the Court of Common Pleas of Delaware County
           Criminal Division at No(s): CP-23-CR-0003000-2014

BEFORE: SHOGAN, LAZARUS, and STABILE, JJ.

MEMORANDUM BY SHOGAN, J.:                        FILED FEBRUARY 19, 2016

     Appellant, Dean Lasean Brown, appeals from the judgment of sentence

entered on March 2, 2015. We affirm.

     The trial court summarized the facts of the crime as follows:

           Joseph Galiano is the owner of Suburban Armory and has
     been so employed for the past nineteen years. The store sells
     firearms and accessories. Typically, when a person comes in to
     purchase a handgun, the individual will select the gun they wish
     to purchase and then Mr. Galiano has them fill out two forms:
     the Federal ATF 4473 and the Pennsylvania State Police
     Application/Record of Sale. In addition to the forms, Mr. Galiano
     also takes a photo of everyone’s ID.

           On February 4, 2014, at approximately 2:45 p.m.,
     Appellant came in to Suburban Armory with the intention of
     purchasing a Smith and Wesson Sigma Series Pistol. Appellant
     told Mr. Galiano that he wished to purchase the gun and in turn,
     Mr. Galiano handed Appellant the requisite forms and told
     Appellant what he tells all of his customers: “I tell everyone that
     they have to fill it out and then they have to sign it and I tell
     them by signing it they’re taking an oath, they’re telling the
     truth, that it’s a felony to lie on the form.” He also tells people if
J-S02008-16

     they have any questions they are free to ask him; however, he
     does not watch the person fill out the form. It would be up to
     the individual to ask for assistance.

           Appellant filled out both forms. On the Federal ATF 4473
     question 11(b) “are you under indictment or information in any
     Court for a felony or any other crime for which the Judge could
     imprison you for more than one year,” Appellant answered “no”.
     On the Pennsylvania State Police Application/Record of Sale,
     question 32 states: “are you now charged with or have you ever
     been convicted of a crime punishable by imprisonment for a
     term exceeding one year? This is the maximum sentence that
     you could have received, not the actual sentence you did
     receive.” Appellant answered “no.” Appellant signed and dated
     the paperwork. Mr. Galiano called the Pennsylvania State [Fire]
     Arm Unit and proceeded to do a background check. As a result
     of the check, Appellant was denied purchase of the gun.
     Appellant left the store that day without incident.

           Trooper Mark Gibble, a criminal investigator employed with
     the Pennsylvania State Police at the Troop K Media Barracks had
     occasion to become involved with Appellant in April of 2014.
     Trooper Gibble was provided with the date of sale, location of
     attempted purchase, Appellant’s name, date of birth and a
     request to start an investigation into the denial of the purchase.
     Trooper Gibble was also aware that the reason Appellant was
     denied purchase was due to an open felony case. With that
     information, Trooper Gibble went to Suburban Armory, spoke
     with Mr. Galiano, and received copies of both the federal form
     and the state form that Appellant filled out. Trooper Gibble
     observed that Appellant answered “no” to 11(b) on the federal
     form and “no” on question 32 of the state form and signed both
     documents. Trooper Gibble also received the copy that Mr.
     Galiano made of Appellant’s driver’s license and confirmed
     Appellant’s identity through JNET. Trooper Gibble attempted to
     contact Appellant but his efforts proved unsuccessful.

Trial Court Opinion, 4/27/15, at 2–4 (internal citations and footnote

omitted).

     On April 29, 2014, police charged Appellant with two counts of

violating the Uniform Firearms Act by making a materially false written

                                   -2-
J-S02008-16

statement on any form promulgated by federal or state agencies during the

purchase, delivery, or transfer of a firearm, 18 Pa.C.S. § 6111(g)(4)(ii), two

counts of unsworn falsification to authorities (statements “under penalty”),

18 Pa.C.S. § 4904(b), and two counts of tampering with public records or

information, 18 Pa.C.S. § 4911(a)(1). Appellant proceeded to a bench trial

on October 24, 2014; Mr. Galiano, Trooper Gibble, and Delaware County

Detective Matthew Cresta testified on behalf of the Commonwealth, and

Appellant testified on his own behalf.

      At trial, the Commonwealth indicated it was proceeding only on one

count each of materially false written statement and statement under

penalty. N.T., 10/24/14, at 9. The trial court found Appellant guilty of both

charges   and   ordered   a   presentence   investigation    and   psychological

evaluation. Id. at 74.

      On March 2, 2015, the trial court sentenced Appellant to eleven and

one-half to twenty-three months of incarceration for the firearms conviction

and a consecutive term of one year of probation for unsworn falsification.

Appellant filed a timely notice of appeal. Both Appellant and the trial court

complied with Pa.R.A.P. 1925.

      Appellant raises the following two issues on appeal:

             Whether the Trial Court abused its discretion when it
      precluded J.R. Brockman, caseworker employed by Northwestern
      Human Services, from testifying as to Appellant’s ability to
      comprehend and understand questions posed to him and how
      Appellant’s ability to understand things was affected by his
      intellectual disabilities.

                                     -3-
J-S02008-16

            Whether the evidence was insufficient to establish beyond
      a reasonable doubt all the elements of Materially False Written
      Statement and Statement Under Penalty where the testimony
      presented at trial failed to support a showing that Appellant
      “knowingly and intentionally” made false statements on the
      Pennsylvania State Police Application/Record of Sale form
      (specifically question #32) and/or made statements Appellant
      did not believe to be true.

Appellant’s Brief at 10.

      The first issue involves the admission of evidence. In particular, when

Appellant attempted to call J.R. Brockman, Appellant’s Northwestern Human

Services caseworker from an unrelated, ongoing case involving Appellant’s

children, the Commonwealth requested an offer of proof.          Based on that

offer, the trial court precluded the witness’s testimony.     N.T., 4/24/15, at

48.

      The admission of evidence is governed by the following standards:

      “The admission of evidence is solely within the discretion of the
      trial court, and a trial court’s evidentiary rulings will be reversed
      on appeal only upon an abuse of that discretion.”
      Commonwealth v. Reid, ___ Pa.___, 99 A.3d 470, 493
      (2014). An abuse of discretion will not be found based on a
      mere error of judgment, but rather occurs where the court has
      reached a conclusion that overrides or misapplies the law, or
      where the judgment exercised is manifestly unreasonable, or the
      result of partiality, prejudice, bias or ill-will. Commonwealth v.
      Davido, ___ Pa. ___, 106 A.3d 611, 645 (2014).

Commonwealth v. Woodard, ___ A.3d ___, ___, 2015 WL 7767271 at

*10 (Pa. December 3, 2015). “[A]n erroneous ruling by a trial court on an

evidentiary issue does not necessitate relief where the error was harmless

                                      -4-
J-S02008-16

beyond a reasonable doubt.” Commonwealth v. Travaglia, 28 A.3d 868,

874 (Pa. 2011).

         Appellant’s remaining challenge is to the sufficiency of the evidence

supporting his convictions. Specifically, Appellant asserts, “even by way of

[his] own testimony,” Appellant’s Brief at 28, his acts were not knowing and

intentional when he denied ever having been charged with a crime

punishable by imprisonment for a term exceeding one year, even though at

the time he attempted to buy the firearm, he was charged with felony

insurance fraud and was awaiting trial. Commonwealth’s Brief at 12; N.T.,

10/24/14, at 33, 39.      Appellant denied understanding Question 32 on the

Pennsylvania State Police Application/Record of Sale form, which stated as

follows:

         Are you now charged with or have you ever been convicted of a
         crime punishable by imprisonment for a term exceeding one
         year? This is the maximum sentence that you could have
         received, not the actual sentence you did receive. . . .

Pennsylvania State Police Application/Record of Sale, Exh C-1; N.T.,

10/24/14, at 15. Thus, he contends the Commonwealth failed to prove that

the false statement was done knowingly and intentionally. Appellant’s Brief

at 23.

         In reviewing a sufficiency challenge, “we must decide whether the

evidence admitted at trial, and all reasonable inferences drawn therefrom in

favor of the Commonwealth, as verdict winner,” are sufficient to support all

elements of the offense.     Commonwealth v. Hitcho, 123 A.3d 731, 746

                                      -5-
J-S02008-16

(Pa. 2015).   The trial court, sitting as the finder of fact, is free to believe

some, all, or none of the evidence. Commonwealth v. Cousar, 928 A.2d

1025 (Pa. 2007); Commonwealth v. Tejada, 107 A.3d 788, 792–793 (Pa.

Super. 2015).    Moreover, the Commonwealth may sustain its burden of

proof by wholly circumstantial evidence.     Commonwealth v. Diggs, 949

A.2d 873 (Pa. 2008); Commonwealth v. Vogelsong, 90 A.3d 717 (Pa.

Super. 2014), appeal denied, 102 A.3d 985 (Pa. 2014).          As an appellate

court, we may not re-weigh the evidence and substitute our judgment for

that of the fact-finder.   Commonwealth v. Rogal, 120 A.3d 994 (Pa.

Super. 2015).

      Upon review of the parties’ briefs, the certified record, and our

standard of review, we conclude that the trial court properly disposed of

Appellant’s issues in its Pa.R.A.P. 1925(a) opinion. Therein, the trial court

determined, inter alia, that precluding the testimony of Appellant’s Human

Services caseworker was not an abuse of its discretion and that the evidence

of record was sufficient to sustain Appellant’s convictions.        Trial Court

Opinion, 4/27/15, at 7–10. Moreover, the trial court specifically found that

“Appellant’s self-serving testimony was not credible.” Id. at 9. Therefore,

we affirm the judgment of sentence on the basis of the trial court’s April 27,

2015 Pa.R.A.P. 1925(a) opinion.     In the event of future proceedings, the

parties are directed to attach a copy of the trial court’s opinion to this

memorandum.

                                     -6-
J-S02008-16

     Judgment of sentence affirmed.

Judgment Entered.

Joseph D. Seletyn, Esq.
Prothonotary

Date: 2/19/2016

                                 -7-


Q:

$x$ is an element of $\mathbb{Z}$, for all values of $x$, $x^2 - x \geq 0$

I understand why this works, the proof does not make sense to me though:

How does he get the $-\dfrac14$, and why does it prove that the statement is true?

A:

If you want a more hands on approach, let's try cases. Note $x^2-x=x(x-1)$. Now if $x\geq 2$, both $x$ and $x-1$ are positive, so their product is as well. What happens if $x<0$? What about the remaining two cases?


HTML5 vs. Flash – The Never Ending Argument [Infographic]

I’ve found a really neat way of explaining the differences between Flash and HTML5 – it’s an infographic that shows the benefits of each of them so that you can make the right choice if you’re going to build your own website. This is really useful, especially for those of us who aren’t really that tecchie – everything’s explained in simple terms so that it’s easy to understand which would be the best to use when you’re building a website.

You just need to have a clear idea of what sort of website you want and what sort of things you want the website to do. You’ll need to have thought about the type of people that will be visiting your website and what they will expect to see when they get there. Whether you’ll have games or videos on the site or whether it will be mostly text. Do you think the people accessing your website will mostly do so on their computers or on their mobile phones? How secure do you need the website to be? All of these issues need to be taken into consideration when you choose. Some of these features will work better with Flash, whereas HTML5 would be the best option for others. If you already know what sort of website you want to make, then using this infographic is the easiest way of choosing which of the platforms would be the right one for you.


On paper, Moody's decision to downgrade Ireland's credit rating is a blow for the Irish Taoiseach, who had just returned from the US where he was trying to drum up business for the battered economy.

But the story virtually disappeared from the news agenda within hours – overtaken by yet another development in Ireland's banking horrors. Austerity measures after the banking crisis have brought huge cuts in the public and private sectors, with unemployment now at a record 450,000. Negative equity is a huge issue for home owners and small businesses including factories, pubs and hotels, are being squeezed by a continuing credit squeeze and the general downturn in the economy.

So when Moody's announced its rating downgrade, the public reaction could be summed up as: so what, we're broke anyway.

"The main story here is our problems are huge, but we are doing the right things to fix them. What Ireland has done better than any other country is that it was the first out of the traps to try and fix things.

"Darling and Brown went in the completely opposite way. They thought they could spend their way out of the recession," said Simon Carswell, financial journalist and author of Something Rotten: Irish Banking Scandals.

Mark Fielding, chief executive of Irish Small and Medium Enterprises Association, a regular critic of the government, said: "While it's not nice to have it on your CV as a country, the reality is people can see what changes are being made and that the government is going in the right direction."

Their comments would be small comfort for the Taoiseach, Brian Cowen, who launched an attack on the media for what he was said was constant negative coverage of the economy.

Cowen faces a critical challenge to his efforts to get the country back on its feet. His decision to set up a "toxic bank" to handle all Celtic Tiger property loans, could be overturned in court by a property developer who argues the National Asset Management Asset Agency (Nama) is in breach of his human rights.

The case is being brought by Paddy McKillen, who has significant investments in London including a stake in the Maybourne hotel group – the company which owns the five-star Claridge's, Connaught and Berkeley hotels. He claims all his loans are "fully performing" and the transfer of loans into NAMA will have a "drastic and significantly detrimental" impact on his business reputation.

The state told the court that Paddy McKillen's case "was a very real threat to the vital work of Nama" in fostering confidence in the Irish economy on the international markets.

Mr Justice Paddy Kelly granted the state's application to have the case fast-tracked for a full hearing which will take place on 12 October. Nama has bought its second batch of loans paying less than 30 cents in the euro on loans from one of the four banks involved, exposing the true scale of the the banking crisis yet again.