Stupid ways to spell simple code

Discussion in 'Python' started by Chris Angelico, Jun 30, 2013.

  1. There's a bit of a discussion on python-ideas that includes a function
    that raises StopIteration. It inspired me to do something stupid, just
    to see how easily I could do it...

    On Sun, Jun 30, 2013 at 3:45 PM, Nick Coghlan <> wrote:
    Re: [Python-ideas] "Iteration stopping" syntax
    >>>> def stop():

    > ... raise StopIteration


    Here's a much more insane way to spell that:

    stop = (lambda: 0 and (yield 1))().__next__

    So, here's a challenge: Come up with something really simple, and
    write an insanely complicated - yet perfectly valid - way to achieve
    the same thing. Bonus points for horribly abusing Python's clean
    syntax in the process.

    Go on, do your worst!

    ChrisA
    Chris Angelico, Jun 30, 2013
    #1
    1. Advertising

  2. Chris Angelico

    Rick Johnson Guest

    On Sunday, June 30, 2013 1:06:35 AM UTC-5, Chris Angelico wrote:
    > So, here's a challenge: Come up with something really simple, and
    > write an insanely complicated - yet perfectly valid - way to achieve
    > the same thing. Bonus points for horribly abusing Python's clean
    > syntax in the process.


    Chris, i'm sorry, but your challenge is decades too late. If you seek amusement you need look no further than the Python stdlib. If you REALLY want tobe amused, peruse the "idlelib" -- not only is the code obfuscated, it also breaks PEP8 and the PYTHON ZEN many times over.
    Rick Johnson, Jun 30, 2013
    #2
    1. Advertising

  3. On 30 June 2013 15:58, Rick Johnson <> wrote:
    > Chris, i'm sorry, but your challenge is decades too late. If you seek amusement you need look no further than the Python stdlib. If you REALLY want to be amused, peruse the "idlelib" -- not only is the code obfuscated, it also breaks PEP8 and the PYTHON ZEN many times over.


    To translate: Not only is the code impossible to read, inefficient and
    unmaintainable whilst being only shallowly correct, but, *GASP* it
    sometimes *breaks* semi-arbitrary code *style* *suggestions*! How dare it!‽
    Joshua Landau, Jun 30, 2013
    #3
  4. On Mon, Jul 1, 2013 at 1:08 AM, Joshua Landau
    <> wrote:
    > On 30 June 2013 15:58, Rick Johnson <> wrote:
    >> Chris, i'm sorry, but your challenge is decades too late. If you seek amusement you need look no further than the Python stdlib. If you REALLY wantto be amused, peruse the "idlelib" -- not only is the code obfuscated, it also breaks PEP8 and the PYTHON ZEN many times over.

    >
    > To translate: Not only is the code impossible to read, inefficient and
    > unmaintainable whilst being only shallowly correct, but, *GASP* it
    > sometimes *breaks* semi-arbitrary code *style* *suggestions*! How dare it!‽


    Yeah, I cannot seriously imagine that the stdlib does anything like
    the example I gave :) Pity nobody else is offering further examples, I
    thought this might be a fun thread.

    ChrisA
    Chris Angelico, Jun 30, 2013
    #4
  5. Chris Angelico

    Ian Kelly Guest

    On Sun, Jun 30, 2013 at 9:20 AM, Chris Angelico <> wrote:
    > Yeah, I cannot seriously imagine that the stdlib does anything like
    > the example I gave :) Pity nobody else is offering further examples, I
    > thought this might be a fun thread.


    Well, there is the "this" module. But its code is not *that*
    obfuscated, and maintainability is not really an issue there since it
    is short and does nothing of actual importance.
    Ian Kelly, Jun 30, 2013
    #5
  6. On Sun, 30 Jun 2013 16:06:35 +1000, Chris Angelico wrote:

    > So, here's a challenge: Come up with something really simple, and write
    > an insanely complicated - yet perfectly valid - way to achieve the same
    > thing. Bonus points for horribly abusing Python's clean syntax in the
    > process.


    Here's a trivially stupid way to find the length of an iterable:

    sum(1 for obj in iterable)

    (except it isn't actually stupid, if the iterable is an iterator, and you
    don't mind consuming it to find out home many items it had). This leads
    to an obvious obfuscation:

    sum(('.' for obj in iterable), '').count('.')


    but sadly Python, in a rare case of protecting you from shooting your own
    foot off, doesn't allow this. Never mind, we can defeat the safety catch
    on sum() and complicate the code at the same time:

    sum(('.' for obj in iterable), type('S', (),
    {'__add__': lambda self, o: o})()).count('.')


    Obfuscated *and* quadratic performance. Do I win?

    Wait, I can beat that. Sorting is too trivial in Python:

    alist.sort()

    Pfft! Where's the challenge in that? Let's use an O(n!) algorithm for
    sorting -- yes, n factorial -- AND abuse a generator expression for its
    side effect. As a bonus, we use itertools, and just for the lulz, I
    obfuscate as many of the names as I can:


    from random import shuffle as OOO00O
    from itertools import takewhile as OO0O0O, count as O0OO0O

    OO0O00 = range(5)

    list(OO0O0O(lambda O: any(O[O0] < O[O0-1] for O0 in
    range(1, sum(('O' for O in O), type('O', (),
    {'__add__': lambda O0O, OO0: OO0})()).count('O'))),
    (OOO00O(OO0O00) or OO0O00 for O in O0OO0O())))[0]



    --
    Steven
    Steven D'Aprano, Jun 30, 2013
    #6
  7. Chris Angelico

    Roy Smith Guest

    In article <51d06cb6$0$29999$c3e8da3$>,
    Steven D'Aprano <> wrote:

    > On Sun, 30 Jun 2013 16:06:35 +1000, Chris Angelico wrote:
    >
    > > So, here's a challenge: Come up with something really simple, and write
    > > an insanely complicated - yet perfectly valid - way to achieve the same
    > > thing. Bonus points for horribly abusing Python's clean syntax in the
    > > process.

    >
    > Here's a trivially stupid way to find the length of an iterable:
    >
    > sum(1 for obj in iterable)


    That's how you would do it in a map-reduce environment :)
    Roy Smith, Jun 30, 2013
    #7
  8. On 30 June 2013 18:36, Steven D'Aprano
    <> wrote:
    > Pfft! Where's the challenge in that? Let's use an O(n!) algorithm for
    > sorting -- yes, n factorial -- AND abuse a generator expression for its
    > side effect. As a bonus, we use itertools, and just for the lulz, I
    > obfuscate as many of the names as I can:
    >
    >
    > from random import shuffle as OOO00O
    > from itertools import takewhile as OO0O0O, count as O0OO0O
    >
    > OO0O00 = range(5)
    >
    > list(OO0O0O(lambda O: any(O[O0] < O[O0-1] for O0 in
    > range(1, sum(('O' for O in O), type('O', (),
    > {'__add__': lambda O0O, OO0: OO0})()).count('O'))),
    > (OOO00O(OO0O00) or OO0O00 for O in O0OO0O())))[0]


    I've got to say -- that last line got me for quite a while, especially
    as the list of lists was returning a list of sorted lists!

    For obfuscation, though, you want unicode. It's much harder to reason
    about code that you can't read.

    from itertools import count as æ, permutations as Æ, starmap as ð
    [globals().setdefault("%c"%sum(ø.encode()),ß)for ø,ß in
    vars(__builtins__).items()if ø!="vars"]
    sorted = lambda ħ:ƿ(ƞ for ı in
    φ(ƴ(lambda:ħ,æ),ń(0,ń(ħ)**(len(ħ)*2-1)*len(ħ)))for ƞ in Æ(ħ)if
    ǂ(()).__eq__((ŕ(ð(ǂ(Ƽ(ƞ).pop()).__rpow__,φ(ŕ(œ(ƞ,ƴ(lambda:0,ħ)),()),1))),ħ),ı))[::-1]

    print(sorted([4, -3, 4, 2, -1]))

    This only works for integers (including negatives) and some things
    that seem to do nothing but slow it down are needed to cover special
    cases. This one takes about 3½ minutes on my computer -- it's got a
    runtime efficiency of something along the lines of O( (L!) * ((L)**i)
    ) for i being related to the elements in the list and L being the
    length of the list.

    That said, it's rather OK at sorting [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].


    I know this is more oriented towards obfuscation of code than
    obfuscation of technique, but --as I said-- I'm writing a library for
    that. I'll be back when it's ready.
    Joshua Landau, Jun 30, 2013
    #8
  9. Chris Angelico

    Neil Cerutti Guest

    On 2013-06-30, Chris Angelico <> wrote:
    > So, here's a challenge: Come up with something really simple,
    > and write an insanely complicated - yet perfectly valid - way
    > to achieve the same thing. Bonus points for horribly abusing
    > Python's clean syntax in the process.
    >
    > Go on, do your worst!


    I've often thought it was redundant for Python to support 'if'
    when it has dictionaries, cf the rationale for having no
    'switch'.

    valid_name = None
    while not valid_name:
    name = input("Enter your name: ")
    valid_name = {
    True: lambda: print("No name longer than 20 letters."),
    False: lambda: True,
    }[len(name) > 20]()

    Much better.

    --
    Neil Cerutti
    Neil Cerutti, Jul 1, 2013
    #9
  10. On Mon, Jul 1, 2013 at 10:59 PM, Neil Cerutti <> wrote:
    > On 2013-06-30, Chris Angelico <> wrote:
    >> So, here's a challenge: Come up with something really simple,
    >> and write an insanely complicated - yet perfectly valid - way
    >> to achieve the same thing. Bonus points for horribly abusing
    >> Python's clean syntax in the process.
    >>
    >> Go on, do your worst!

    >
    > I've often thought it was redundant for Python to support 'if'
    > when it has dictionaries, cf the rationale for having no
    > 'switch'.
    >
    > valid_name = None
    > while not valid_name:
    > name = input("Enter your name: ")
    > valid_name = {
    > True: lambda: print("No name longer than 20 letters."),
    > False: lambda: True,
    > }[len(name) > 20]()
    >
    > Much better.


    Good! Good! But, waaaah. Waaaah.

    def get_name():
    while True:
    name = input("Enter your name: ")
    yield {
    True: lambda: print("No name longer than 20 letters."),
    False: lambda: name,
    }[len(name) > 20]()
    name = next(filter(None,get_name()))

    ChrisA
    Chris Angelico, Jul 1, 2013
    #10
  11. On 1 July 2013 14:14, Chris Angelico <> wrote:
    > On Mon, Jul 1, 2013 at 10:59 PM, Neil Cerutti <> wrote:
    >> On 2013-06-30, Chris Angelico <> wrote:
    >>> So, here's a challenge: Come up with something really simple,
    >>> and write an insanely complicated - yet perfectly valid - way
    >>> to achieve the same thing. Bonus points for horribly abusing
    >>> Python's clean syntax in the process.
    >>>
    >>> Go on, do your worst!

    >>
    >> I've often thought it was redundant for Python to support 'if'
    >> when it has dictionaries, cf the rationale for having no
    >> 'switch'.
    >>
    >> valid_name = None
    >> while not valid_name:
    >> name = input("Enter your name: ")
    >> valid_name = {
    >> True: lambda: print("No name longer than 20 letters."),
    >> False: lambda: True,
    >> }[len(name) > 20]()
    >>
    >> Much better.

    >
    > Good! Good! But, waaaah. Waaaah.
    >
    > def get_name():
    > while True:
    > name = input("Enter your name: ")
    > yield {
    > True: lambda: print("No name longer than 20 letters."),
    > False: lambda: name,
    > }[len(name) > 20]()
    > name = next(filter(None,get_name()))


    Oh, cruel. But you can do worse. Who needs "while" when you have
    filter(iter(FUNCTION, object()))?

    def get_name():
    name = input("Enter your name: ")
    return [
    lambda: name,
    lambda: print("No name longer than 20 letters."),
    ][len(name) > 20]()

    name = next(filter(None, iter(get_name, object())))


    But who needs *any* of this! Defining functions is so old-hat. It's
    all already in the standard library (using only assignments and function-calls):

    from functools import partial
    from operator import getitem, ge, methodcaller
    from itertools import compress, tee
    apply = methodcaller("__call__")
    ret_true = partial(getitem, [True], 0)
    print_invalid = partial(print, "No name longer than 20 letters.")
    inputs = iter(partial(input, "Enter your name: "), ...)
    inputs, valid = tee(inputs)
    valid = map(len, valid)
    valid = map(partial(ge, 20), valid)
    side_effect_valid = map(partial(getitem, [print_invalid, ret_true]), valid)
    side_effect_valid = map(apply, side_effect_valid)
    valid_inputs = compress(inputs, side_effect_valid)
    name = next(valid_inputs)


    Which can be "neatly" expressed as two statements (I'm struggling to
    got it to one without those evil lambdas):

    from functools import partial
    from operator import getitem, ge, methodcaller
    from itertools import compress, tee

    inputs, valid = tee(iter(partial(input, "Enter your name: "), ...))

    name = next(
    compress(
    inputs,
    map(
    methodcaller("__call__"),
    map(
    partial(
    getitem,
    [
    partial(print, "No name longer than 20 letters."),
    partial(getitem, [True], 0)
    ]
    ),
    map(
    partial(ge, 20),
    map(len, valid)
    )
    )
    )
    )
    )


    Beautiful, see?


    Of course, the most powerful function deals with this much more quickly:

    exec("""
    while True:
    name = input("Enter your name: ")

    if len(name) <= 20:
    break

    else:
    print("No name longer than 20 letters.")
    """)
    Joshua Landau, Jul 1, 2013
    #11
  12. On Tue, Jul 2, 2013 at 2:30 AM, Joshua Landau
    <> wrote:
    > Beautiful, see?



    Truly a work of art! I am awed.

    ChrisA
    Chris Angelico, Jul 1, 2013
    #12
  13. On 17:30 Mon 01 Jul , Joshua Landau wrote:
    > On 1 July 2013 14:14, Chris Angelico <> wrote:
    > > On Mon, Jul 1, 2013 at 10:59 PM, Neil Cerutti <> wrote:
    > >> On 2013-06-30, Chris Angelico <> wrote:
    > >>> So, here's a challenge: Come up with something really simple,
    > >>> and write an insanely complicated - yet perfectly valid - way
    > >>> to achieve the same thing. Bonus points for horribly abusing
    > >>> Python's clean syntax in the process.
    > >>>
    > >>> Go on, do your worst!
    > >>
    > >> I've often thought it was redundant for Python to support 'if'
    > >> when it has dictionaries, cf the rationale for having no
    > >> 'switch'.
    > >>
    > >> valid_name = None
    > >> while not valid_name:
    > >> name = input("Enter your name: ")
    > >> valid_name = {
    > >> True: lambda: print("No name longer than 20 letters."),
    > >> False: lambda: True,
    > >> }[len(name) > 20]()
    > >>
    > >> Much better.

    > >
    > > Good! Good! But, waaaah. Waaaah.
    > >
    > > def get_name():
    > > while True:
    > > name = input("Enter your name: ")
    > > yield {
    > > True: lambda: print("No name longer than 20 letters."),
    > > False: lambda: name,
    > > }[len(name) > 20]()
    > > name = next(filter(None,get_name()))

    >
    > Oh, cruel. But you can do worse. Who needs "while" when you have
    > filter(iter(FUNCTION, object()))?
    >
    > def get_name():
    > name = input("Enter your name: ")
    > return [
    > lambda: name,
    > lambda: print("No name longer than 20 letters."),
    > ][len(name) > 20]()
    >
    > name = next(filter(None, iter(get_name, object())))
    >
    >
    > But who needs *any* of this! Defining functions is so old-hat. It's
    > all already in the standard library (using only assignments and function-calls):
    >
    > from functools import partial
    > from operator import getitem, ge, methodcaller
    > from itertools import compress, tee
    > apply = methodcaller("__call__")
    > ret_true = partial(getitem, [True], 0)
    > print_invalid = partial(print, "No name longer than 20 letters.")
    > inputs = iter(partial(input, "Enter your name: "), ...)
    > inputs, valid = tee(inputs)
    > valid = map(len, valid)
    > valid = map(partial(ge, 20), valid)
    > side_effect_valid = map(partial(getitem, [print_invalid, ret_true]), valid)
    > side_effect_valid = map(apply, side_effect_valid)
    > valid_inputs = compress(inputs, side_effect_valid)
    > name = next(valid_inputs)
    >
    >
    > Which can be "neatly" expressed as two statements (I'm struggling to
    > got it to one without those evil lambdas):
    >
    > from functools import partial
    > from operator import getitem, ge, methodcaller
    > from itertools import compress, tee
    >
    > inputs, valid = tee(iter(partial(input, "Enter your name: "), ...))
    >
    > name = next(
    > compress(
    > inputs,
    > map(
    > methodcaller("__call__"),
    > map(
    > partial(
    > getitem,
    > [
    > partial(print, "No name longer than 20 letters."),
    > partial(getitem, [True], 0)
    > ]
    > ),
    > map(
    > partial(ge, 20),
    > map(len, valid)
    > )
    > )
    > )
    > )
    > )
    >
    >
    > Beautiful, see?
    >
    >
    > Of course, the most powerful function deals with this much more quickly:
    >
    > exec("""
    > while True:
    > name = input("Enter your name: ")
    >
    > if len(name) <= 20:
    > break
    >
    > else:
    > print("No name longer than 20 letters.")
    > """)
    > --
    > http://mail.python.org/mailman/listinfo/python-list



    Here is another example which I came across when playing with
    generators, the first function is actually quite useful, the second
    generator is the whole fun:

    from functools import wraps
    def init(func):
    """decorator which initialises the generator
    """
    @wraps(func)
    def inner(*args, **kwargs):
    g = func(*args, **kwargs)
    g.send(None)
    return g
    return inner

    @init
    def gen(func):
    x = (yield)
    while True:
    x = (yield func(x))


    now if you have function f
    def f(arg):
    return arg**2

    then calling f(5) is the same as

    g = gen(f)
    g.send(5)


    I wrote a blog post where I did include this as a `useless` example:
    http://pycorner.herokuapp.com/blog/5

    Best regards,
    Marcin
    Marcin Szamotulski, Jul 1, 2013
    #13
  14. On Mon, 01 Jul 2013 20:36:29 +0100, Marcin Szamotulski wrote:

    > Here is another example which I came across when playing with
    > generators, the first function is actually quite useful, the second
    > generator is the whole fun:
    >
    > from functools import wraps
    > def init(func):
    > """decorator which initialises the generator """
    > @wraps(func)
    > def inner(*args, **kwargs):
    > g = func(*args, **kwargs)
    > g.send(None)
    > return g
    > return inner
    >
    > @init
    > def gen(func):
    > x = (yield)
    > while True:
    > x = (yield func(x))
    >
    >
    > now if you have function f
    > def f(arg):
    > return arg**2
    >
    > then calling f(5) is the same as
    >
    > g = gen(f)
    > g.send(5)




    I think you must be missing an important part of the trick, because
    calling f(5) returns 25. It's not:

    @gen
    def f(arg):
    return arg**2


    because that raises TypeError.




    --
    Steven
    Steven D'Aprano, Jul 1, 2013
    #14
  15. Steven D'Apranoæ–¼ 2013å¹´7月2日星期二UTC+8上åˆ6時09分18秒寫é“:
    > On Mon, 01 Jul 2013 20:36:29 +0100, Marcin Szamotulski wrote:
    >
    >
    >
    > > Here is another example which I came across when playing with

    >
    > > generators, the first function is actually quite useful, the second

    >
    > > generator is the whole fun:

    >
    > >

    >
    > > from functools import wraps

    >
    > > def init(func):

    >
    > > """decorator which initialises the generator """

    >
    > > @wraps(func)

    >
    > > def inner(*args, **kwargs):

    >
    > > g = func(*args, **kwargs)

    >
    > > g.send(None)

    >
    > > return g

    >
    > > return inner

    >
    > >

    >
    > > @init

    >
    > > def gen(func):

    >
    > > x = (yield)

    >
    > > while True:

    >
    > > x = (yield func(x))

    >
    > >

    >
    > >

    >
    > > now if you have function f

    >
    > > def f(arg):

    >
    > > return arg**2

    >
    > >

    >
    > > then calling f(5) is the same as

    >
    > >

    >
    > > g = gen(f)

    >
    > > g.send(5)

    >
    >
    >
    >
    >
    >
    >
    > I think you must be missing an important part of the trick, because
    >
    > calling f(5) returns 25. It's not:
    >
    >
    >
    > @gen
    >
    > def f(arg):
    >
    > return arg**2
    >
    >
    >
    >
    >
    > because that raises TypeError.
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > --
    >
    > Steven


    Lets be serious about generators and iterators.

    A generator can be used only once in a program
    is different from a a generator method of a class that
    can produce several instances with generators of the same kind
    but operated in each instance of the class.
    88888 Dihedral, Jul 2, 2013
    #15
  16. On 22:09 Mon 01 Jul , Steven D'Aprano wrote:
    > On Mon, 01 Jul 2013 20:36:29 +0100, Marcin Szamotulski wrote:
    >
    > > Here is another example which I came across when playing with
    > > generators, the first function is actually quite useful, the second
    > > generator is the whole fun:
    > >
    > > from functools import wraps
    > > def init(func):
    > > """decorator which initialises the generator """
    > > @wraps(func)
    > > def inner(*args, **kwargs):
    > > g = func(*args, **kwargs)
    > > g.send(None)
    > > return g
    > > return inner
    > >
    > > @init
    > > def gen(func):
    > > x = (yield)
    > > while True:
    > > x = (yield func(x))
    > >
    > >
    > > now if you have function f
    > > def f(arg):
    > > return arg**2
    > >
    > > then calling f(5) is the same as
    > >
    > > g = gen(f)
    > > g.send(5)

    >
    >
    >
    > I think you must be missing an important part of the trick, because
    > calling f(5) returns 25. It's not:
    >
    > @gen
    > def f(arg):
    > return arg**2
    >
    >
    > because that raises TypeError.
    > --
    > Steven
    > --
    > http://mail.python.org/mailman/listinfo/python-list


    Sure it does, you're now supposed to use .send method instead of
    calling it but this is just different syntax. If you want to call it
    use this :

    def identity(func):
    @init
    def gen(func):
    x = (yield)
    while True:
    x = (yield func(x))
    return gen(func).send

    Now you will get:

    >>> @identity
    >>> def f(a): a+1

    ....
    >>> f(0)

    1

    Best regards,
    Marcin
    Marcin Szamotulski, Jul 2, 2013
    #16
  17. On Sunday, June 30, 2013 8:06:35 AM UTC+2, Chris Angelico wrote:
    > There's a bit of a discussion on python-ideas that includes a function
    >
    > that raises StopIteration. It inspired me to do something stupid, just
    >
    > to see how easily I could do it...
    >
    >
    >
    > On Sun, Jun 30, 2013 at 3:45 PM, Nick Coghlan <> wrote:
    >
    > Re: [Python-ideas] "Iteration stopping" syntax
    >
    > >>>> def stop():

    >
    > > ... raise StopIteration

    >
    >
    >
    > Here's a much more insane way to spell that:
    >
    >
    >
    > stop = (lambda: 0 and (yield 1))().__next__
    >
    >
    >
    > So, here's a challenge: Come up with something really simple, and
    >
    > write an insanely complicated - yet perfectly valid - way to achieve
    >
    > the same thing. Bonus points for horribly abusing Python's clean
    >
    > syntax in the process.
    >
    >
    >
    > Go on, do your worst!
    >
    >
    >
    > ChrisA


    Here's a way to count items in a string.

    def count(string, x):
    return len(''.join(string)) - len(''.join(string).replace(x, '')) / len(x)
    Russel Walker, Jul 2, 2013
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brandon McCombs
    Replies:
    4
    Views:
    498
    Richard Wheeldon
    Aug 28, 2006
  2. rincewind

    stupid, STUPID question!

    rincewind, Apr 19, 2009, in forum: HTML
    Replies:
    25
    Views:
    1,007
  3. Joshua Landau

    Re: Stupid ways to spell simple code

    Joshua Landau, Jun 30, 2013, in forum: Python
    Replies:
    0
    Views:
    82
    Joshua Landau
    Jun 30, 2013
  4. Cameron Simpson

    Re: Stupid ways to spell simple code

    Cameron Simpson, Jun 30, 2013, in forum: Python
    Replies:
    0
    Views:
    77
    Cameron Simpson
    Jun 30, 2013
  5. Joshua Landau

    Re: Stupid ways to spell simple code

    Joshua Landau, Jul 11, 2013, in forum: Python
    Replies:
    0
    Views:
    62
    Joshua Landau
    Jul 11, 2013
Loading...

Share This Page