473,813 Members | 4,122 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Limits of Metaprogramming

Hi all,

I have an interesting problem that I'm hoping can be solved with
metaprogramming , but I don't know how far Python supports code
generation (and I don't know if I'm taking the correct approach
either... hence why I'm asking on this group):

I'd like to write a program that writes/manipulates a statemachine. My
idea was that I would define states in a .py file along with their
transitions and other metadata. I could then write a suite of programs
that would manipulate these states in interesting ways, such as
generate diagrams and documentation, test suites, do verifications and
also edit them. These programs would import the .py file and use
introspection upon the module's classes (states would be modelled as
classes). For example, a documentation tool could use graphviz to draw
the statediagram with the transition table and docstring...

My problem is that I don't know if it's possible to edit these states
and then write them back to .py. Firstly, if my editing tool was to
create a new state, I would want to create the class (using type) and
attach it to the imported state module somehow. I can't find
information on whether this is possible. Secondly, I'd like to
manipulate the class and then use the inspect module to get the source
and write it back to file. Now I'm pretty sure the inspect module will
only write the source code as found in the original .py file. Is there
a way to generate the code for a class or other python objects in a
generic way? Or will I have to bite the bullet and write to custom
file and generate code from that (like glade with XML)? Or is there
another solution with templates that I'm over looking?

Having the classes in memory, editing their attributes, adding methods
and then serialising them to code has an elegance to it in my mind and
would hopefully simplify things. The result would be directly
executable by the interpreter itself and editable by python
developers. But I fear that I may need an intermediary notation/format
for storage. Any advice/hints would be very useful.

Thanks,
Paul
Aug 4 '08 #1
16 1624
You could write a class composed of states and then use the pickle
module to serialize it to disk.
Aug 4 '08 #2
On 4 Aug, 12:55, Jeff <jeffo...@gmail .comwrote:
You could write a class composed of states and then use the pickle
module to serialize it to disk.
Thanks Jeff.

I guess this is my intermediary format!
Aug 4 '08 #3
On Mon, 4 Aug 2008, Wilson wrote:
Hi all,
Howdy,

I am not sure if my remarks will be of any use for you, but here it goes.
I have an interesting problem that I'm hoping can be solved with
metaprogramming , but I don't know how far Python supports code
generation (and I don't know if I'm taking the correct approach
either... hence why I'm asking on this group):

I'd like to write a program that writes/manipulates a statemachine. My
idea was that I would define states in a .py file along with their
transitions and other metadata. I could then write a suite of programs
that would manipulate these states in interesting ways, such as
generate diagrams and documentation, test suites, do verifications and
also edit them. These programs would import the .py file and use
introspection upon the module's classes (states would be modelled as
classes). For example, a documentation tool could use graphviz to draw
the statediagram with the transition table and docstring...
Maybe you have actually two problems.

One problem is processing source code into something useful, but
not executable. So it does not necessarily need metaprogramming to be
solved, just some "code comprehension" (like get a python grammar,
lex/yacc and read a lot of docs how to use them).
My problem is that I don't know if it's possible to edit these states
and then write them back to .py. Firstly, if my editing tool was to
create a new state, I would want to create the class (using type) and
attach it to the imported state module somehow. I can't find
information on whether this is possible. Secondly, I'd like to
manipulate the class and then use the inspect module to get the source
and write it back to file. Now I'm pretty sure the inspect module will
only write the source code as found in the original .py file. Is there
a way to generate the code for a class or other python objects in a
generic way? Or will I have to bite the bullet and write to custom
file and generate code from that (like glade with XML)? Or is there
another solution with templates that I'm over looking?
Well, "everything " is doable in a Turing-complete language :-). However,
this one problem - code generation and using it on the fly - may be better
solved with some other language, perhaps?

Not that I want to dissuade you (or anyone else) from using Python, but
last time I checked the state of things (was a good couple of years ago, I
wanted to solve some math-related problem with metaprogramming in Python)
I decided I would do better if I learned Scheme. At least in Scheme,
program structure is so simple, it is just a list (or a sequence of them),
so manipulating code is IMHO much easier.

I mean, even if in theory every language in Turing-complete class is equal
to each other (one can do the same kind of stuff in one as in the other),
in practice they are not equal at all. So doing everything in one ultimate
language of choice is not very wise from my point of view.

It does not mean you should immediately go to

http://en.wikipedia.org/wiki/Scheme_...mming_language)

but you may do so, and then make an informed choice by yourself. To be
better informed, you may also google for more material - introductions,
opinions, comparisons and some first-hand experience.

On the other hand, writing "metafiles" and interpreters for them - ugh...
:-). I have read somewhere, that some programmers resist using Scheme
(or some other Lisp) for solving their problem and end up with writing
their own Lisp-like (language|file format) and interpreter(s) for it. So
you better watch yourself. If this effort is going to be something more
permament than "done and go", then you will probably find yourself in the
situation of reinventing the wheel, as your project goes more and more
complex. If this is going to happen, you might use existing wheels and
save some time for thinking on something better.
Having the classes in memory, editing their attributes, adding methods
and then serialising them to code has an elegance to it in my mind and
would hopefully simplify things. The result would be directly
executable by the interpreter itself and editable by python
developers. But I fear that I may need an intermediary notation/format
for storage. Any advice/hints would be very useful.
Yes, there is something elegant in this way of thinking, at least for me.

As I (indirectly) said above, I am not up to date with recent Python
abilities (I still use Python for a lot of things, I just do not overuse
it for things, that it seems to be not so good at). I hope someone knows
better and steps in to prove me wrong - it is always good to learn
something new. Also, if you have just one problem, then learning a new
language because of it is a bit too much (or maybe not, if you enjoy it
:-) ). But if you plan doing similar or more difficult things in the
future, then knowing Scheme may be good for you. Even if you choose to not
use it, you will be aware of what can be done with it so this knowledge
can provide some ready to use templates.

And yes, there are also some other languages in Lisp family, but I think
Scheme is best choice if you don't know any of them already. It is quite
small, it is well defined (I mean, it has some real specification,
instead of being "specified by its implementation" ) and there is a lot of
info about it on the net that could be easily understood. And, last but
not least, it has metaprogramming included with nice bunch of additional
stuff. For a start, PLT's DrScheme looks nice (IMHO - yes, there are
other nice looking Scheme implementations but this one is probably best
fitted for a beginner):

http://www.plt-scheme.org/

Regards,
Tomasz Rola

--
** A C programmer asked whether computer had Buddha's nature. **
** As the answer, master did "rm -rif" on the programmer's home **
** directory. And then the C programmer became enlightened... **
** **
** Tomasz Rola mailto:to****** ***@bigfoot.com **
Aug 4 '08 #4
On 4 Aug, 14:47, Tomasz Rola <rto...@ceti.co m.plwrote:
On Mon, 4 Aug 2008, Wilson wrote:
Hi all,

Howdy,

I am not sure if my remarks will be of any use for you, but here it goes.
I have an interesting problem that I'm hoping can be solved with
metaprogramming , but I don't know how far Python supports code
generation (and I don't know if I'm taking the correct approach
either... hence why I'm asking on this group):
I'd like to write a program that writes/manipulates a statemachine. My
idea was that I would define states in a .py file along with their
transitions and other metadata. I could then write a suite of programs
that would manipulate these states in interesting ways, such as
generate diagrams and documentation, test suites, do verifications and
also edit them. These programs would import the .py file and use
introspection upon the module's classes (states would be modelled as
classes). For example, a documentation tool could use graphviz to draw
the statediagram with the transition table and docstring...

Maybe you have actually two problems.

One problem is processing source code into something useful, but
not executable. So it does not necessarily need metaprogramming to be
solved, just some "code comprehension" (like get a python grammar,
lex/yacc and read a lot of docs how to use them).
I do want my resultant code to be executable; I want to be able to use
"import" to get programmatical access to the classes and structures it
contains, such that they can be manipulated, added to, exercised and
drawn (using graphviz) via introspection.. . After any manipulation,
i'd like to be able to flatten them back into a .py file (as source
such that they are readable as Python code).
My problem is that I don't know if it's possible to edit these states
and then write them back to .py. Firstly, if my editing tool was to
create a new state, I would want to create the class (using type) and
attach it to the imported state module somehow. I can't find
information on whether this is possible. Secondly, I'd like to
manipulate the class and then use the inspect module to get the source
and write it back to file. Now I'm pretty sure the inspect module will
only write the source code as found in the original .py file. Is there
a way to generate the code for a class or other python objects in a
generic way? Or will I have to bite the bullet and write to custom
file and generate code from that (like glade with XML)? Or is there
another solution with templates that I'm over looking?

Well, "everything " is doable in a Turing-complete language :-). However,
this one problem - code generation and using it on the fly - may be better
solved with some other language, perhaps?

Not that I want to dissuade you (or anyone else) from using Python, but
last time I checked the state of things (was a good couple of years ago, I
wanted to solve some math-related problem with metaprogramming in Python)
I decided I would do better if I learned Scheme. At least in Scheme,
program structure is so simple, it is just a list (or a sequence of them),
so manipulating code is IMHO much easier.

I mean, even if in theory every language in Turing-complete class is equal
to each other (one can do the same kind of stuff in one as in the other),
in practice they are not equal at all. So doing everything in one ultimate
language of choice is not very wise from my point of view.

It does not mean you should immediately go to

http://en.wikipedia.org/wiki/Scheme_...mming_language)

but you may do so, and then make an informed choice by yourself. To be
better informed, you may also google for more material - introductions,
opinions, comparisons and some first-hand experience.

On the other hand, writing "metafiles" and interpreters for them - ugh...
:-). I have read somewhere, that some programmers resist using Scheme
(or some other Lisp) for solving their problem and end up with writing
their own Lisp-like (language|file format) and interpreter(s) for it. So
you better watch yourself. If this effort is going to be something more
permament than "done and go", then you will probably find yourself in the
situation of reinventing the wheel, as your project goes more and more
complex. If this is going to happen, you might use existing wheels and
save some time for thinking on something better.
I appreciate these comments, and I know the quote that you are
refering to although I can't find it now... Something like:
" Every sufficiently large application has a poor/incomplete
implementation of LISP embedded within it ". I've looked at LISP
before and do appreciate its elegance, but Python has a beauty of its
own in its pragmatism, standard libraries and community. So I'll
choose to stick with it.
Having the classes in memory, editing their attributes, adding methods
and then serialising them to code has an elegance to it in my mind and
would hopefully simplify things. The result would be directly
executable by the interpreter itself and editable by python
developers. But I fear that I may need an intermediary notation/format
for storage. Any advice/hints would be very useful.

Yes, there is something elegant in this way of thinking, at least for me.

As I (indirectly) said above, I am not up to date with recent Python
abilities (I still use Python for a lot of things, I just do not overuse
it for things, that it seems to be not so good at). I hope someone knows
better and steps in to prove me wrong - it is always good to learn
something new. Also, if you have just one problem, then learning a new
language because of it is a bit too much (or maybe not, if you enjoy it
:-) ). But if you plan doing similar or more difficult things in the
future, then knowing Scheme may be good for you. Even if you choose to not
use it, you will be aware of what can be done with it so this knowledge
can provide some ready to use templates.
I've been through quite a few of the SICP lectures and again, do
appreciate its elegance and they have changed the way I program.
And yes, there are also some other languages in Lisp family, but I think
Scheme is best choice if you don't know any of them already. It is quite
small, it is well defined (I mean, it has some real specification,
instead of being "specified by its implementation" ) and there is a lot of
info about it on the net that could be easily understood. And, last but
not least, it has metaprogramming included with nice bunch of additional
stuff. For a start, PLT's DrScheme looks nice (IMHO - yes, there are
other nice looking Scheme implementations but this one is probably best
fitted for a beginner):
http://www.plt-scheme.org/

Regards,
Tomasz Rola
Thanks for your comments. But I believe my solution may lie in using a
template language such as cheetah. Too much is already invested in
Python!

Best Regards,
Paul
Aug 4 '08 #5
Wilson wrote:
Hi all,

I have an interesting problem that I'm hoping can be solved with
metaprogramming , but I don't know how far Python supports code
generation (and I don't know if I'm taking the correct approach
either... hence why I'm asking on this group):

I'd like to write a program that writes/manipulates a statemachine. My
idea was that I would define states in a .py file along with their
transitions and other metadata.
You're probably better off coming up with a representation for a
state machine (which might be a pickled collection of Python objects)
then providing a "compile" operation which cranks out a .py file
with code to implement the state machine.

John Nagle
Aug 4 '08 #6
On Mon, 4 Aug 2008, Wilson wrote:
" Every sufficiently large application has a poor/incomplete
implementation of LISP embedded within it ".
Yep, this is either exact or very close copy of what I have read.
I've looked at LISP
before and do appreciate its elegance, but Python has a beauty of its
own in its pragmatism, standard libraries and community. So I'll
choose to stick with it.
[...]
I've been through quite a few of the SICP lectures and again, do
appreciate its elegance and they have changed the way I program.
[...]
Thanks for your comments. But I believe my solution may lie in using a
template language such as cheetah. Too much is already invested in
Python!

Best Regards,
Paul
Ok, so you do know something about Lisp - that is good :-). Of course,
since you have already existing Python code, converting is not for you.
Just to make sure you stay informed, there is CLPython:

http://common-lisp.net/project/clpython/

I did not try this thing, but I am very pleased it exists. I have some
Python code myself and knowing there is a way to reuse it if I choose some
other way makes me feel better. Or rather, knowing I can easily merge the
two (or more) ways.

Regards,
Tomasz Rola

--
** A C programmer asked whether computer had Buddha's nature. **
** As the answer, master did "rm -rif" on the programmer's home **
** directory. And then the C programmer became enlightened... **
** **
** Tomasz Rola mailto:to****** ***@bigfoot.com **
Aug 4 '08 #7
On 4 Aug, 16:50, John Nagle <na...@animats. comwrote:
Wilson wrote:
Hi all,
I have an interesting problem that I'm hoping can be solved with
metaprogramming , but I don't know how far Python supports code
generation (and I don't know if I'm taking the correct approach
either... hence why I'm asking on this group):
I'd like to write a program that writes/manipulates a statemachine. My
idea was that I would define states in a .py file along with their
transitions and other metadata.

* * You're probably better off coming up with a representation for a
state machine (which might be a pickled collection of Python objects)
then providing a "compile" operation which cranks out a .py file
with code to implement the state machine.

* * * * * * * * * * * * * * * * John Nagle
I agree. I guess my 'representation ' is the big question!

Thanks!
Aug 4 '08 #8
On Aug 4, 4:48*am, Wilson <PaulAlexWil... @gmail.comwrote :
Hi all,

My problem is that I don't know if it's possible to edit these states
and then write them back to .py. Firstly, if my editing tool was to
create a new state, I would want to create the class (using type) and
attach it to the imported state module somehow. I can't find

Thanks,
Paul
Yes it's possible, using type, but you can't attach it to the module
in any persistent way. The next time you load the module, it's back
to the way it was.

I think this may be the hang-up in your design: if you think about
generating lines of code directly from the user's actions, you might
stay on the right track. At that point, you can place them in the .py
file. Then you can reimport it, or just execute the new lines
directly.

If this is your class,

class Auto54701:
def next( self, input ):
if( something ):
return value1
return value2

Here's how to work with it at the interactive prompt:
>>s= """class Auto54701:
... def next( self, input ):
... if( something ):
... return value1
... return value2
... """
>>s
'class Auto54701:\n def next( self, input ):\n if( something ):
\n ret
urn value1\n return value2\n'
>>exec( s )
Auto54701
<class __main__.Auto54 701 at 0x00A80C60>
>>>
And by the way, you can't use pickle to store types. There needs to
be some fleshed-out code to back them up.

Two more alternatives, which I can discuss more later, one where you
implement code as data, but it ends up being a lot like Python
anyway. It only works if your classes' methods are going to be
simple, probably sequential if-s and assignments at most.

class Auto54701:
def next( self, input ):
if( something1 ):
return value1
elif( something2 ):
return value2
elif( something3 ):
return value3
elif( something4 ):
return value4
return value5

can be stored in data as

[ ( something1, value1 ), ( something2, value2 ), ... ]

, and just checked in a loop, that you only have in code once, rather
than many times.

class GenericAuto:
def next( self, input ):
for something, value in conditionpairs:
if( something ):
return value
return valuen

Two, if all your methods will have uniform signatures and closures,
you can store class methods as only their co_code objects:
>>C.g.im_func.f unc_code.co_cod e
'd\x00\x00S'

And fabricate them dynamically into full live types as needed.
Aug 4 '08 #9
On Aug 4, 6:49*pm, castironpi <castiro...@gma il.comwrote:
On Aug 4, 4:48*am, Wilson <PaulAlexWil... @gmail.comwrote :
Hi all,
My problem is that I don't know if it's possible to edit these states
and then write them back to .py. Firstly, if my editing tool was to
create a new state, I would want to create the class (using type) and
attach it to the imported state module somehow. I can't find
Thanks,
Paul

Yes it's possible, using type, but you can't attach it to the module
in any persistent way. *The next time you load the module, it's back
to the way it was.

I think this may be the hang-up in your design: if you think about
generating lines of code directly from the user's actions, you might
stay on the right track. *At that point, you can place them in the .py
file. *Then you can reimport it, or just execute the new lines
directly.

If this is your class,

class Auto54701:
* def next( self, input ):
* * *if( something ):
* * * *return value1
* * *return value2

Here's how to work with it at the interactive prompt:
>s= """class Auto54701:

... * def next( self, input ):
... * * *if( something ):
... * * * *return value1
... * * *return value2
... """>>s

'class Auto54701:\n *def next( self, input ):\n * * if( something ):
\n * * * ret
urn value1\n * * return value2\n'>>exec ( s )
>Auto54701

<class __main__.Auto54 701 at 0x00A80C60>

And by the way, you can't use pickle to store types. *There needs to
be some fleshed-out code to back them up.

Two more alternatives, which I can discuss more later, one where you
implement code as data, but it ends up being a lot like Python
anyway. *It only works if your classes' methods are going to be
simple, probably sequential if-s and assignments at most.

class Auto54701:
* def next( self, input ):
* * *if( something1 ):
* * * *return value1
* * *elif( something2 ):
* * * *return value2
* * *elif( something3 ):
* * * *return value3
* * *elif( something4 ):
* * * *return value4
* * return value5

can be stored in data as

* [ ( something1, value1 ), ( something2, value2 ), ... ]

, and just checked in a loop, that you only have in code once, rather
than many times.

class GenericAuto:
* def next( self, input ):
* * for something, value in conditionpairs:
* * * if( something ):
* * * * return value
* * return valuen

Two, if all your methods will have uniform signatures and closures,
you can store class methods as only their co_code objects:
>C.g.im_func.fu nc_code.co_code

'd\x00\x00S'

And fabricate them dynamically into full live types as needed.
Thanks for your comments and advice. This second option intrigues me;
could you elaborate further, I don't follow you...

Thanks Paul
Aug 4 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2165
by: Dave | last post by:
Would people agree with the statement that to a large degree, using template metaprogramming techniques turns a C++ compiler into a C++ interpreter (but just for the metaprogrammed portions of the code)? It's not a perfect analogy, but it seems to be a reasonable statement...
9
1578
by: Rock Johnson | last post by:
I understand that template metaprogramming is a technique that allows for calcualations to occur at compile-time rather than run-time. Can someone explain what is the benefit of this, and when it is good to employ Template Metaprogramming?
21
2106
by: Protoman | last post by:
I've been looking at template metaprogramming. It seems really cool, make the compiler do most of the work. I have very simple program that uses TMP,it calculates the square of a number, but it doesn't seem to work. Here it is: #include <iostream> #include <cstdlib> using namespace std; template<int n>
3
1427
by: wakun | last post by:
Hi there, I am working a project in numerical computation in which iterative method is applied for solving equation. The problem is so big and slow. Few days ago, I found a paper on metaprogramming , it seems that such technique has good performance for some case. For ordinary case, my code for implementing iterative method like for (int i=1; i<N; i++) { x = f(x, x);
9
3425
by: PengYu.UT | last post by:
Hi, I have the code below this email. I want to replace the last 4 lines with a Metaprogramming loop to get something like the following (I don't know the syntax). Is it possible? for type in {left_tag, right_tag, down_tag, up_tag) { fun(type()); }
7
3566
by: Joe | last post by:
Hi, I found a concept named template metaprogramming that can be used in C+ + code at compile-time. I am a beginner at C++. But I am a programmer on the .NET platform. Do you know if template metaprogramming is supported in C# (.NET)? For reference I found it: http://en.wikipedia.org/wiki/Template_metaprogramming. Thanks to all.
5
3623
by: iapx86 | last post by:
My parser project calls for a computed goto (see code below). The C preprocessor delivers the desired result, but is ugly. Template metaprogramming delivers results I do not understand. Can anyone explain why loop unrolling doesn't play well with templates? Or better, can someone submit a code fragment to get desired results? Here are the command-lines I use to generate code: "g++ -DTEMPLATE=0 -o gotofun0 gotofun.cpp" works exactly as...
9
1639
by: andrew cooke | last post by:
Hi, Thanks for the help a couple of days ago. I completed what I was doing and wrote a summary which I've posted at http://acooke.org/cute/PythonMeta0.html (it's kind of long to post here). I hope it might be useful to someone else - it's complete code for a simple metaprogramming task that uses metaclasses and descriptors. I'd also appreciate further feedback if I've done anything stupid or if there's some interesting approach I've...
12
3375
by: nooneinparticular314159 | last post by:
Hello. If I declare the following: template<int a, int b, int SomeArray> class DoSomething{ public: .. .. ..
0
9734
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9607
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10665
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10406
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9221
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5568
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5704
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4358
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3029
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.