Open Side Menu Go to the Top

03-26-2013 , 12:39 AM
here are some good places to use tuples:

Code:
tuple("o") # , Mississippi (or Oklahoma)
Code:
# Both of these are True
"wilco".parent == uncle(("o",))
"son volt".parent == uncle(("o",))
Code:
message = "Play again and "
...
elif multiplier == 5:
    message += ("quin",)
elif multiplier == 6:
    message += ("sex",)
...
message += " your winnings!"
hth!
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
03-26-2013 , 08:24 AM
Quote:
Originally Posted by clowntable
Did level8 and gave up after a bit on level9. I got as far as listing the content of .htaccess and .htpasswd but not sure what to do with it. Will think about it tomorrow, got some stuff to do.

gaming_mouse: How did you do level 4 (referer). I actually did that one via telnet and felt very proud about it :P
(easy solution is some browser plugin ldo)
Just finished natas11 ... man my php is rusty, didn't even remember how to do fairly simple stuff. Could have solved it using Python but figured it might be a good idea to actually use the language they use :P

Funny me failing at this challenge note:
Spoiler:
I had a complete brainfart and ran my sweet little program to get me my encrypted cookie. Double checked that it was converted to an array that matched the criteria etc.
Tried sending it via curl ready to fistpump...nada

Took me a walk to realize "wait a second did you just use '<censored>' as the key ... lol maybe actually finding the key is part of the exercise *doh*"


Useful tool in case anyone plays along:
http://writecodeonline.com/php/

Also someone recommended jumping directly to 10/11. I wouldn't do that because then you won't know the "magic directory" that you'll need in natas10
Unless I'm somehow mistaken you're supposed to remember that from earlier challenges.

Last edited by clowntable; 03-26-2013 at 08:29 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 10:23 AM
Quote:
Originally Posted by Xhad
I'm far from expert, but I'd say in Python it would make more sense to say that tuples should be the default and lists are guilty until proven innocent. I mean, how hard is it to change a tuple to a list (if necessary) than vice-versa? And are there any tuple gotchas on the level of the ones we just talked about upthread?

I feel like in Python, any time I could use list or X builtin type, X is always better. That isn't to say I don't use lists, I just only use them when I have a concrete reason that I can't use a tuple, a set, or a dict.
I think you hit the nail on the head here. I have this in myFile.py:

Code:
a = 3, 5
and my interpreter says a is:

Code:
>>> a
(3, 5)
>>>
and...

Code:
def myFunction(x):
    return x, x

b = myFunction(4)
Code:
>>> b
(4, 4)
Since the default from Python is the Tuple, then it stands to reason that there is no specific reason to use a Tuple, but rather, breaking the default of the language should be done so with a justifiable reason, thus, the question shouldn't be "When to use a Tuple," but "When to not use a Tuple."

Last edited by daveT; 03-26-2013 at 10:42 AM. Reason: didn't leave out anything. Whatcha talking about?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 10:28 AM
Quote:
Originally Posted by daveT

Code:
def myFunction(x):
    return x

b = myFunction(4)
Code:
>>> b
(4, 4)

This seems wrong. Or am I missing something?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 11:12 AM
Yes, an edit
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 11:29 AM
Here is one case where you definitely prefer a list over a tuple, or rather, you don't want to create a tuple thinking you created some nice immutable object:

Code:
>>> x = [i*i for i in range(5)]
>>> x
[0, 1, 4, 9, 16]
>>> x
[0, 1, 4, 9, 16]
>>> y = (i*i for i in range(5))
>>> y
<generator object <genexpr> at 0x02271580>
>>> list(y)
[0, 1, 4, 9, 16]
>>> list(y)
[]
>>>
Or maybe:

Code:
>>> y = (i*i for i in range(5))
>>> y
<generator object <genexpr> at 0x022715F8>
>>> tuple(y)
(0, 1, 4, 9, 16)
>>> tuple(y)
()
>>>
Or...

Code:
>>> y = (i*i for i in range(5))
>>> y
<generator object <genexpr> at 0x02271580>
>>> z = tuple(y)
>>> z
(0, 1, 4, 9, 16)
>>> z
(0, 1, 4, 9, 16)
>>> y
<generator object <genexpr> at 0x02271580>
>>> list(y)
[]
>>>
What is the generator object used for?

Last edited by daveT; 03-26-2013 at 11:34 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 11:55 AM
Generators are lazily evaluated so they can have performance benefits I suppose.

Downside though is since the values are generated (rather than stored in memory) you can therefore only iterate through once.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 12:45 PM
Quote:
Originally Posted by clowntable
Spoiler:

Took me a walk to realize "wait a second did you just use '<censored>' as the key ... lol maybe actually finding the key is part of the exercise *doh*"


Useful tool in case anyone plays along:
http://writecodeonline.com/php/

Also someone recommended jumping directly to 10/11. I wouldn't do that because then you won't know the "magic directory" that you'll need in natas10
Unless I'm somehow mistaken you're supposed to remember that from earlier challenges.
funny i was using the same tool. running php locally can be a pain.

forgot about that magic directory thing... good point. but the later ones are much more challenging and interesting than the earlier ones.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 04:47 PM
Yeah I haven't worked on #12 yet and I expect the fun to start about there. Had a quick look at it and have some ideas floating around already but won't get to work on it much until after easter I think.

I feel like I know very little about security despite having researched some stuff every now and then. I dunno if a career in that field (Pentest/Sec Consultant whathaveu) would be fun or get boring pretty quickly because you repeat the same more or less standard attacks over and over.

In general terms it feels like a field that could be mad fun (solve puzzles for a living, weee) but it also seems overwhelmingly complex/large and ever evolving. Kinda wish I could intern somewhere during vacation and see what it's like.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 04:54 PM
Quote:
Originally Posted by ballin4life
Generators are lazily evaluated so they can have performance benefits I suppose.

Downside though is since the values are generated (rather than stored in memory) you can therefore only iterate through once.
Right, all of this. The reason it's blank in dave's example is because the call to tuple(y) uses it up. And the reason it defaults to this behavior is that they presumably thought it was better to force "tuple" in this situation than forcing a def in the situation where you actually want the generator behavior. I'll cop to being lazy enough to occasionally use a list just because I don't feel like typing tuple(guy for guy in stuff)

jjshabado: That's a good one that I had forgotten. Generally if I have only one item, I actually do want a list because I'm going to append some stuff to it, but I dimly recall one incident where I put something like:

Code:
f(ham, toast, eggs)
where I needed:

Code:
f((ham, toast, eggs),)
And had some bizarre errors because of it.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 05:03 PM
If everyone yawned at optimizing out n-squared time, I can't imagine how a micro-benchmark would make everyone jump out of their seats.

I would totally use that generator if I wanted to cause someone a few weeks of bug-hunting. I would even put a comment next to it: "## is this what you're looking for?"
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 10:04 PM
Quote:
Originally Posted by daveT
If everyone yawned at optimizing out n-squared time, I can't imagine how a micro-benchmark would make everyone jump out of their seats.
It's a tool like any other. There are lots of times that I don't care about the performance benefit of a generator but others when I'd need it.

But yes I have seen people get all worked up that someone should be using a generator instead of a list when we're talking a really small amount of elements and the stupidness of caring in that case usually annoys me.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-26-2013 , 10:36 PM
Generators can be of arbitrarily large or even infinite size - you could have a generator that generates all the positive integers or all the primes for example
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 12:47 AM
You're not going to get an infinite generator out of a one-line comprehension though. That's really what they're talking about here.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 02:45 AM
Quote:
Originally Posted by Xhad
You're not going to get an infinite generator out of a one-line comprehension though. That's really what they're talking about here.
Yeah I get what you're saying.

Still, various ways to cheat around this:

http://stackoverflow.com/questions/5...nite-generator

My favorite is:

Code:
 (x for x in open('/dev/urandom') )
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 11:05 AM
A generator is not lazily evaluated, so the whole thing has to exist before the generator can be used, right?

How can you create and use an infinite -- or very large -- generator?

And how large does the value you'd like to output have to be before the generator becomes noticeably better than a list comprehension?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 11:21 AM
Quote:
A generator is not lazily evaluated, so the whole thing has to exist before the generator can be used, right?
I'm pretty sure that this is false (or I'm misunderstanding "lazy evalutation), and that the generator in your early post is equivalent to:

Code:
def counter():
    for i in range(5):
        yield i
Quote:
And how large does the value you'd like to output have to be before the generator becomes noticeably better than a list comprehension?
Well, the difference between python2 range and xrange/python3 range is pretty much exactly this
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 12:08 PM
If you recall the Christmas tree I created up-thread, that is (sorta) lazy evaluation. The way it works is that any element wouldn't be "realized" until you call it. Without lazy evaluation, the entire list(n -> infinity) must be computed before you can call any element of the list. Obviously, this wouldn't work, so with lazy evaluation, you could do something like getNext(list) to evaluate the next number of the infinite integers. The idea of infinity is thus implied to exist, but of course, you'd never really use it.

I just searched "python lazy evaluation" and all the articles that pop up agree that lazy evaluation isn't really possible in Python and some of them tried to do lazy with generators. One article asserts that it isn't possible in imperative languages, but I just showed one way to do it, but certainly had ugly results.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 12:28 PM
Quote:
Originally Posted by daveT
A generator is not lazily evaluated, so the whole thing has to exist before the generator can be used, right?

How can you create and use an infinite -- or very large -- generator?

And how large does the value you'd like to output have to be before the generator becomes noticeably better than a list comprehension?
Nothing has to exist in memory. I thought that's the whole point of generators?

Code:
def my_gen():
  n = 1
  while True:
    yield n
    n = n + 1


gen = my_gen()
You can now call gen.next() as many times as you want and it will continually yield the next natural number. The next value is computed, not stored anywhere in memory.

You can even do

Code:
def my_gen2():
  while True:
    yield 1
There are a bunch of infinite generators in itertools too (e.g. count(), which is a more general version of my_gen(), repeat(), a more general version of my_gen2(), and cycle() which cycles infinitely ).
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 12:36 PM
Quote:
Originally Posted by daveT
If you recall the Christmas tree I created up-thread, that is (sorta) lazy evaluation. The way it works is that any element wouldn't be "realized" until you call it. Without lazy evaluation, the entire list(n -> infinity) must be computed before you can call any element of the list. Obviously, this wouldn't work, so with lazy evaluation, you could do something like getNext(list) to evaluate the next number of the infinite integers. The idea of infinity is thus implied to exist, but of course, you'd never really use it.
OK, then I'm not getting it. It seems to me like this meets that definition just fine:

Code:
def counter():
    i = 0
    while True:
        i += 1
        yield i

c = counter()
for i in range(10):
    print(next(c))
Re the "christmas tree": Do you mean that streamofbasetwos post? I kind of thought that was intentionally ugly. Here's my generator version:

Code:
def streamOfBaseTwos():
    ans = [1]
    while True:
        yield ans[:]
        ans.append(ans[-1]*2)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 01:08 PM
Ah, coolio. Thanks guys. Definitely ought to check out the results of the query I mentioned. Some interesting articles pop up.

I guess it is basically you can kind-of-sort-of represent lazy evaluation, but apparently the language tends to be too eager in most situations unless you really force it to behave. It doesn't really matter much because at some point you end up splitting hairs.

http://www.pages.drexel.edu/~kmk592/...hon/index.html

http://swizec.com/blog/python-and-la...on/swizec/5148

http://theorangeduck.com/page/lazy-python

Essentially, they say that it appears lazy, but once you start timing things and getting down into it, they aren't exactly lazy, but idk how much the thin line matters, really. Seems like this discussion would quickly descend into over-optimization territory.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 02:00 PM
ok, that mostly makes sense. I'm not sure why this isn't an acceptable version of the second one's prime generator though:

Code:
def primes():
    known = set() 
    for n in infintecounter():
        if n > 1 and not any(n % i == 0 for i in known):
            known.add(n)
            yield n
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 02:11 PM
It may be. Perhaps send him an email with that code and see what he says about it.

I guess it depends on what infinitecounter() does, though (?).
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 02:30 PM
That was just me renaming his "generator()" so people could potentially guess what it did without clicking the link. Yields integers 1...infinity.

I may ask for a clarification. For, me the rub is this. Here's his unoptimized version:

Code:
def primes():
    for n in generator():
        if not any(i > 1 and i != n and n%i == 0
                   for i in islice(generator(), n)):
            yield n
(actually he mentions in the text changing "generator" to start from 2, so I can assume the same change and delete the "n > 1 and" from mine. Actually I'd probably name it "countfrom" and take a parameter so it would be "countfrom(2)", if I really felt the need for a counter instead of just infinite looping like my earlier posts)

From that point, he's figuring out how to optimize it by only dividing by primes, presumably while still getting cutesy with iterators, while I think it already looks obfuscated. It may be that I have no real exposure to FP and there's a massive clash in styles here, but I note that my optimized version is only one line more than his if you count not having such an unwieldy conditional that it had to take up two lines. And it's fewer characters. I mean, if there's some performance reason for desperately wanting this to be recursive, or slightly more complicated use cases where the ability to recursively define a generator in terms of itself would be useful, that's one thing, but that particular post looks more like "I tried importing __braces__ from future and it didn't work"
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
03-27-2013 , 02:52 PM
ok, I think I may have figured out the answer to my own question: For reference, here is the thing the author is "trying to write" and can't (it recurs infinitely):

Code:
def primes():
    for n in generator():
        if not any(p != n and n%p == 0
                   for p in takewhile(lambda x: n>x,
                                      primes())):
            yield n
After looking at it again, I can see why you would try to write a structure like this, and why it would work in a language that uses lazy-evaluation by default. I can also see how you could make this design "work", but only by adding enough ugly code to make the whole approach not worth it. So the answer is, if you're trying to use lazy evaluation to get something like the above, then no, you pretty much can't. You can, however, get the desired functionality if you stop trying to write Haskell in Python and just write Python (which is also the conclusion of that third link, more or less)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

      
m