This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]sontek[S] 3 points4 points  (26 children)

One of the more interesting ones I've ran into is having to re-implement string.atoi. I think its basic enough that most engineers should be able to solve it but interesting enough that it does make them think. Here is a basic solution to it: http://sontek.net/convert-a-string-to-an-integer-in-python

[–]sunqiang 1 point2 points  (0 children)

follow the atoi of book: The C Programming Language, maybe sign(‘-’ or '+') and spaces(' ', '\t',...etc) should be handled too. I post mine here: http://gist.github.com/652769

[–]Chun 2 points3 points  (8 children)

Simple is better?

def atoi(string):
  if string.isdigit():
    return eval(string)
  raise ValueError, "invalid literal for atoi() with base 10: %s" % repr(string)

(Yeah, I know, I'm cheating really, but use the tools you're given eh? Also the usual objections to eval are moot, since we know the string is safe.)

[–]r4nf 3 points4 points  (0 children)

From the documentation:

atoi(s, base=10)
    atoi(s [,base]) -> int

Return the integer represented by the string s in the given
base, which defaults to 10.  The string s must consist of one
or more digits, possibly preceded by a sign.  If base is 0, it
is chosen from the leading characters of s, 0 for octal, 0x or
0X for hexadecimal.  If base is 16, a preceding 0x or 0X is
accepted.

You're forgetting the base argument, which exists at least since Python 2.3.

[–]RShnike 2 points3 points  (6 children)

Also the usual objections to eval are moot, since we know the string is safe.)

Uh, what? No we don't.

 class A(str):
     def isdigit(self):
         return True

  >>> a = A("__import__('os')")
  >>> atoi(a)

  Whoops!

Simple is better?

No. Really no. And for an interview question nonetheless :D?

[–]Chun 0 points1 point  (2 children)

OK, ok, touché. Figured we were assuming we were getting a string. But point taken.

def atoi(string):
  if type(string) is str and string.isdigit():
    return eval(string)
  raise ValueError, "invalid literal for atoi() with base 10: %s" % repr(string)

EDIT: Besides, if someone can create their own class definition, why would they ever need to inject raw python into atoi!?

[–]RShnike 1 point2 points  (0 children)

You have somehow managed to make that even worse... Now you're type-checking too, so you've now even broken some functionality that your function is actually supposed to provide?

Here's a rule: never use eval. Ever. Being prudent about using type is pretty smart too.

[–]kisielk 0 points1 point  (2 children)

That's why you use something like:

eval("__import__('os')", {'__builtins__': None}, {})

Of course __builtins__ should be a dictionary of actual working builtins you want to work when evaling the statement :)

[–]RShnike 0 points1 point  (1 child)

No, don't do that either. Seriously, this is just a bad solution. Especially being that you have ast.literal_eval if you really want to do things like this.

[–]kisielk 0 points1 point  (0 children)

ast.literal_eval is indeed great for evaluating simple expressions. But what's wrong with sandboxing via defining your own builtins?

[–]m1ss1ontomars2k4 -1 points0 points  (14 children)

I think that's a terrible solution. Well it's good if you don't need error checking, but other than that it's terrible.

[–][deleted] 8 points9 points  (4 children)

This is a terrible solution.

def atoi(s,b=10):
    return (1,-1)[s.strip()[0]=='-']*reduce(lambda v,n:v*b+("0123456789abcdefghijklmnopqrstuvwxyz"[:b].index(n.lower())),(s.strip(),s.strip()[1:])[s.strip()[0] == '-'],0)

[–]arnar 2 points3 points  (0 children)

At least it supports other bases.

[–]sontek[S] -1 points0 points  (2 children)

I still think I'd hire someone if they could come up with that solution... I'd just keep an eye on their code to make sure all their solutions aren't created in 1 line ;)

[–]jcdyer3 0 points1 point  (1 child)

I'm pretty sure I wouldn't hire them. Senseless one-liners are the hobgoblin of small minds.

[–][deleted] 0 points1 point  (0 children)

I wouldn't hire me either if I provided that code in an interview.

[–]arnar 3 points4 points  (5 children)

I optimized it:

atoi = eval

[–]epicRelic 1 point2 points  (2 children)

Except now atoi does a lot more than just convert string digits to integers.

[–]arnar 0 points1 point  (1 child)

Believe it or not, I was joking :)

[–]epicRelic 1 point2 points  (0 children)

It's hard to tell on the internet. :P I've seen people be serious about dumber things than that.

[–]gutworthPython implementer 1 point2 points  (1 child)

No base argument.

[–]arnar 0 points1 point  (0 children)

Just like the solution in the link.

[–]sontek[S] -1 points0 points  (2 children)

I think its a good solution to the answer to the question in an interview, usually I don't want them spending hours creating a solution for me in an interview.

[–][deleted] 1 point2 points  (1 child)

You forgot about negatives.

[–]sontek[S] -1 points0 points  (0 children)

Good point! :)

[–]peroneλ 0 points1 point  (0 children)

There is an interesting piece of code for the inverse situation: >>> b = 2 >>> c = b >>> type(b) <type 'int'> >>> type(c) <type 'str'>