By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,745 Members | 1,897 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,745 IT Pros & Developers. It's quick & easy.

Tricky Areas in Python

P: n/a
What possible tricky areas/questions could be asked in Python based
Technical Interviews?

Oct 23 '05 #1
Share this Question
Share on Google+
25 Replies


P: n/a
PyPK wrote:
What possible tricky areas/questions could be asked in Python based
Technical Interviews?


I would try to check if the applicant understands the Python data model:
http://docs.python.org/ref/objects.html Because I thinkt that's
fundamental to understanding the Python language and understanding
complexity of operations.

-- Gerhard
Oct 23 '05 #2

P: n/a
hmm Thats one thing. Also I was thinking of something like benefites of
python over other languages. Probably that coould be one ?

Oct 23 '05 #3

P: n/a
I usually start by asking how you make variables "private" within
classes. That seems to tell me if they understand something about the
design of the language and it's a quick filter to tell if they know
something about the syntax.

The other question that I use is asking about 3rd party libraries that
they have found useful. That can lead into some good questions about
what they like about those libraries and what they dislike. That
question helps me understand whether they've thought at all about how
to design in Python.

If I can't get a good conversation started with either of those, I'll
ask what they don't like about Python, to see if they've actually used
it to solve a real problem, or if they've just read the tutorial.

As always, the best interview questions are open-ended, and give the
candidate some room to really show their stuff (or give them enough
rope to hang themselves).

Oct 23 '05 #4

P: n/a
PyPK <su*******@gmail.com> wrote:
What possible tricky areas/questions could be asked in Python based
Technical Interviews?


I like to present code that seems like it should work, but has some kind
of relatively subtle problem, either of correctness in some corner case,
or of performance, etc -- and I ask them what they would say if they
were to code-review that code, or how they would help a student who came
to them with that code and complaints about it not working, &c.

This tells me whether they have real-world Python experience, and how
deep, or whether they've carefully studied the appropriate areas of
"Python in a Nutshell" and the Cookbook (and I'm biased enough to think
that the second kind of preparation is almost as good as the first
kind...;-).

Not sure whether you think this count as "tricky"... they're typically
problems that do come up in the real world, from (e.g.):
for string_piece in lots_of_pieces:
bigstring += string_piece
(a typical performance-trap) to
for item in somelist:
if isbad(item):
somelist.remove(item)
(with issues of BOTH correctness and performance), to
class Sic:
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)
to
class Base(object)
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)

class Derived(Base):
def getFoo(self): ....

and so on, and so forth. If a candidate makes short work of a couple of
these, and I've been asked to focus my part of the interview solely on
Python coding, I may branch out into more advanced stuff such as asking
for an example use case for a closure, a custom descriptor, or an import
hook, for example -- those are the cases in which I'm trying to decide
if, on a scale of 1 to 5, the candidate's Python competence is about 4
or well over 4 (I would not consider having no idea of why one might
want to code a custom descriptor to be at all "disqualifying" -- it
would just mean I'd rate the candidate 4 out of five, instead of 4.5 or
more, for Python coding competence).
Alex
Oct 24 '05 #5

P: n/a
On 10/24/05, Alex Martelli <al*****@yahoo.com> wrote:
I may branch out into more advanced stuff such as asking
for an example use case for a closure, a custom descriptor, or an import
hook, for example


Isn't that approaching things from the wrong angle? You're asking them
to synthesise a problem for a given solution, rather than analyse a
problem to determine an appropriate solution. Asking questions like
these tests memory more than competence -- for example, if you ask me
of a use case for a closure, the only answer I could give would be to
remember a problem I'd solved in the past using one.

Andrew
Oct 24 '05 #6

P: n/a
Andrew Durdin <ad*****@gmail.com> wrote:
On 10/24/05, Alex Martelli <al*****@yahoo.com> wrote:
I may branch out into more advanced stuff such as asking
for an example use case for a closure, a custom descriptor, or an import
hook, for example


Isn't that approaching things from the wrong angle? You're asking them
to synthesise a problem for a given solution, rather than analyse a
problem to determine an appropriate solution. Asking questions like
these tests memory more than competence -- for example, if you ask me
of a use case for a closure, the only answer I could give would be to
remember a problem I'd solved in the past using one.


And why do you think that would be wrong? If you've used closures, you
know what you've used them for, and (I would hope) why. If you've never
used them, you're welcome to answer "I have no idea why anybody would
wanna use THAT crazy thing for" (I always give points for honesty;-), or
else try to bluff your way through (sorry, no points for chutzpah!-).

I don't know of any issue that could be solved ONLY by a closure (we
didn't have closures in 1.5.2 yet we made out excellently well
anyhow;-), after all. The point is, does the candidate really
understand closures (ideally by practical experience)? Within the
limited confines of a less-than-an-hour interview (which is what we
normally use -- several interviewers, but no more than about 45 minutes
each, with different focus for each interviewer) I believe that asking
for use cases is a perfectly good way to gauge if a candidate fully
understands (ideally by experience) a certain language feature.

It's not just Python, btw. When I'm asked to focus on C++ skills, I
will similarly ask, e.g., what a use case would be for virtual
inheritance, say. How ELSE would you gauge, within that very limited
time-span, a candidate's grasp of some advanced language feechur?-)
Alex
Oct 24 '05 #7

P: n/a
PyPK wrote:
hmm Thats one thing. Also I was thinking of something like benefites of
python over other languages.


That's fairly context-dependant *and* subjective.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Oct 24 '05 #8

P: n/a
Alex Martelli wrote:
I like to present code that seems like it should work, but has some kind
of relatively subtle problem, either of correctness in some corner case,
or of performance, etc -- and I ask them what they would say if they
were to code-review that code, or how they would help a student who came
to them with that code and complaints about it not working, &c.
[snip]
Not sure whether you think this count as "tricky"... they're typically
problems that do come up in the real world, from (e.g.):
for string_piece in lots_of_pieces:
bigstring += string_piece
(a typical performance-trap) to
for item in somelist:
if isbad(item):
somelist.remove(item)
(with issues of BOTH correctness and performance), to
Those two are easy. However, and this is where I show
my hard-won ignorance, and admit that I don't see the
problem with the property examples:
class Sic:
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)
to
class Base(object)
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)

class Derived(Base):
def getFoo(self): ....


Unless the answer is "Why are you using setters and
getters anyway? This isn't Java you know."

Oh wait! Yes I do... the setter doesn't actually take
an argument to set the property too. Is that it, or
have a missed a cunningly hidden deeper problem?
--
Steven.

Oct 24 '05 #9

P: n/a
Steven D'Aprano wrote:
Alex Martelli wrote: Those two are easy. However, and this is where I show my hard-won
ignorance, and admit that I don't see the problem with the property
examples:
class Base(object)
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)

class Derived(Base):
def getFoo(self): ....

Unless the answer is "Why are you using setters and getters anyway? This
isn't Java you know."

Oh wait! Yes I do... the setter doesn't actually take an argument to set
the property too. Is that it, or have a missed a cunningly hidden deeper
problem?


Derived.getFoo() will not override the use of Base.getFoo() to access the attribute foo.

Kent
Oct 24 '05 #10

P: n/a
Steven D'Aprano wrote:
Those two are easy. However, and this is where I show
my hard-won ignorance, and admit that I don't see the
problem with the property examples:

class Base(object)
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)

class Derived(Base):
def getFoo(self): ....


the property call in Base binds to the Base.getFoo and Base.setFoo method
*objects*, not the names, so overriding getFoo in Derived won't affect the foo
property.

to get proper dispatching for accessors, you need to add an extra layer:

def getFoo(self): ...
def setFoo(self, ...): ...
def getFooDispatcher(self): self.getFoo() # use normal lookup
def setFooDispatcher(self, ...): self.setFoo(...) # use normal lookup
foo = property(getFooDispatcher, setFooDispatcher)

this gotcha is the motivation for this proposal:

http://article.gmane.org/gmane.comp.python.devel/72348

(see that thread for more on this topic)

</F>

Oct 24 '05 #11

P: n/a
Steven D'Aprano <st***@REMOVEMEcyber.com.au> wrote:
...
my hard-won ignorance, and admit that I don't see the
problem with the property examples:
class Sic:
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)
Sorry for skipping the 2nd argument to setFoo, that was accidental in my
post. The problem here is: class Sic is "classic" ("legacy",
"old-style") so property won't really work for it (the setter will NOT
trigger when you assign to s.foo and s is an instance of Sic).
to
class Base(object)
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)

class Derived(Base):
def getFoo(self): ....


Unless the answer is "Why are you using setters and
getters anyway? This isn't Java you know."


Nope, that's not a problem -- presumably the "..." bodies DO something
useful, and they do get nicely dressed in attribute syntax. The
problem, as others have indicated, is that overriding doesn't work as
one might expect -- the solution, in Python 2.4 and earlier, is to use
one extra level of indirection:
def __getFoo(self): return self.getFoo()
def getFoo(self): ...
foo = property(__getFoo)
so the name lookup for 'getFoo' on self happens when you access s.foo
(for s being an instance of this here-sketched class) and overriding
works just as expected. This can be seen as the simplest possible use
case for the "Template Method" Design Pattern, btw;-)
Alex
Oct 24 '05 #12

P: n/a
Alex Martelli wrote:
class Base(object)
def getFoo(self): ...
def setFoo(self): ...
foo = property(getFoo, setFoo)

class Derived(Base):
def getFoo(self): ....

[snip] the solution, in Python 2.4 and earlier, is to use
one extra level of indirection:
def __getFoo(self): return self.getFoo()
def getFoo(self): ...
foo = property(__getFoo)
so the name lookup for 'getFoo' on self happens when you access s.foo
(for s being an instance of this here-sketched class) and overriding
works just as expected.


Another solution (for those of you scoring at home) would be to use a
property-like descriptor that delays the name lookup until the time of
the method call, e.g.

http://aspn.activestate.com/ASPN/Coo.../Recipe/442418
http://aspn.activestate.com/ASPN/Coo.../Recipe/408713

STeVe
Oct 24 '05 #13

P: n/a
let me try.

1) ''.join(lots_of_pieces)

2) This doesn't even work, if something is removed, the list is too
short. So:
[x for x in somelist if not isbad(x)]
well, list comprehension is Python 2.4 and 2.3 is the standard in many
OSes, so it is possibly not the most portable solution
I had to look up the syntax, because i never use it in my code, yet.

3+4) I never used property - had to look it up. So i learned something
:)

Oct 24 '05 #14

P: n/a
beza1e1 wrote:
let me try.

1) ''.join(lots_of_pieces)

2) This doesn't even work, if something is removed, the list is too
short. So:
[x for x in somelist if not isbad(x)]
well, list comprehension is Python 2.4 and 2.3 is the standard in many
OSes, so it is possibly not the most portable solution
I had to look up the syntax, because i never use it in my code, yet.
Python 2.2.1 (#1, Aug 25 2004, 16:56:05)
[GCC 2.95.4 20011002 (Debian prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
[a.upper() for a in ['two', 'point', 'two']] ['TWO', 'POINT', 'TWO']


3+4) I never used property - had to look it up. So i learned something
:)

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Oct 24 '05 #15

P: n/a
beza1e1 wrote:
well, list comprehension is Python 2.4 and 2.3 is the standard in many
OSes, so it is possibly not the most portable solution


You're probably remembering "generator expressions", which were added in
Python 2.4 and aren't available in earlier versions. They fit in a
similar place in one's mind, anyway....

-Peter
Oct 24 '05 #16

P: n/a
beza1e1 <an*************@googlemail.com> wrote:
let me try.

1) ''.join(lots_of_pieces)
Yep.
2) This doesn't even work, if something is removed, the list is too
short. So:
[x for x in somelist if not isbad(x)]
well, list comprehension is Python 2.4 and 2.3 is the standard in many
OSes, so it is possibly not the most portable solution
No, LC goes back a long way -- I think it was in 2.0 already, 2.1 for
sure. If you have to support (say) Python 1.5.2, the simplest (not
fastest) solution is to loop on a COPY of the list, rather than the very
list you're also modifying.
I had to look up the syntax, because i never use it in my code, yet.

3+4) I never used property - had to look it up. So i learned something
:)


Good!-)
Alex
Oct 25 '05 #17

P: n/a
"PyPK" <su*******@gmail.com> wrote:

What possible tricky areas/questions could be asked in Python based
Technical Interviews?


What's the point of asking "tricky" questions? Aren't you really more
interested in what applications they have worked on and whether they were
successful?

I don't know. I'm not sure I need a job with a company that insists on
playing "Programming Jeopardy" during the interview.
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Oct 25 '05 #18

P: n/a
Tim Roberts wrote:
"PyPK" <su*******@gmail.com> wrote:
What possible tricky areas/questions could be asked in Python based
Technical Interviews?


What's the point of asking "tricky" questions? Aren't you really more
interested in what applications they have worked on and whether they were
successful?

I don't know. I'm not sure I need a job with a company that insists on
playing "Programming Jeopardy" during the interview.


That's okay. Those companies don't need you either. ;-)

Seriously though, the point of asking such questions is that with
minimal effort they _can_ (not "definitely will") quickly qualify a
candidate's level of expertise in a language. Novices, and those who
while they might have programmed in a language for several years still
don't really understand it deeply enough to be considered entirely safe
on their own, will generally trip up on all or most such questions
(where "trip up" means anything from giving wrong answers to giving you
the "deer in the headlights" look). _Anyone_ could trip up on one or
two of them, especially given the pressure of an interview situation.
(And even seeing an expert trip up under pressure tells you something
useful about the candidate.)

In short, a true senior programmer will provide good correct answers to
most such questions, while those less senior generally will not.

Asking such questions in isolation, without also delving deeply into
other background such as what applications you've worked on, is just as
dangerous as asking _only_ about such applications. I've made the
mistake of hiring people who had lengthy involvement -- apparently at a
senior level -- in significant projects, only to discover that they
clearly didn't understand some basic concepts of the languages
supposedly used. My conclusion was that they were in that class of
people who manage to interview well yet contribute little, but have
lucked out repeatedly by working for companies who were incompetent at
terminating for cause (and there are _many_ such companies). (We didn't
make the same mistake and fired them reasonably quickly.)

-Peter
Oct 25 '05 #19

P: n/a
Alex Martelli wrote:
No, LC goes back a long way -- I think it was in 2.0 already, 2.1 for
sure.


$ python1.5 -c "print [x for x in 'abc']"
File "<string>", line 1
print [x for x in 'abc']
^
SyntaxError: invalid syntax
$ python2.0 -c "print [x for x in 'abc']"
['a', 'b', 'c']

I was a bit surprised to find that 2.0 had variables, though:

$ python2.0 -c "[x for x in y]"
Traceback (most recent call last):
File "<string>", line 1, in ?
NameError: There is no variable named 'y'
$ python2.1 -c "[x for x in y]"
Traceback (most recent call last):
File "<string>", line 1, in ?
NameError: name 'y' is not defined

;-)

</F>

Oct 25 '05 #20

P: n/a
Alex Martelli wrote:
my hard-won ignorance, and admit that I don't see the
problem with the property examples:
> class Sic:
> def getFoo(self): ...
> def setFoo(self): ...
> foo = property(getFoo, setFoo)
Sorry for skipping the 2nd argument to setFoo, that was accidental in my
post. The problem here is: class Sic is "classic" ("legacy",
"old-style") so property won't really work for it (the setter will NOT
trigger when you assign to s.foo and s is an instance of Sic).


what's slightly confusing is that the getter works, at least until you attempt
to use the setter:
class Sic: .... def getFoo(self):
.... print "GET"
.... return "FOO"
.... def setFoo(self, value):
.... print "SET", value
.... foo = property(getFoo, setFoo)
.... sic = Sic()
print sic.foo GET
FOO sic.foo = 10
print sic.foo

10

(a "setter isn't part of an new-style object hierarchy" exception would have
been nice, I think...)

</F>

Oct 25 '05 #21

P: n/a
beza1e1 wrote:
let me try.

1) ''.join(lots_of_pieces)

2) This doesn't even work, if something is removed, the list is too
short. So:
[x for x in somelist if not isbad(x)]
well, list comprehension is Python 2.4
2.2.x IIRC
and 2.3 is the standard in many
OSes, so it is possibly not the most portable solution


filter(isbad, somelist)

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Oct 25 '05 #22

P: n/a
bruno modulix wrote:
beza1e1 wrote:
well, list comprehension is Python 2.4


2.2.x IIRC


List comprehensions were introduced in Python 2.0, according to the
"What's new in ..." document at
http://www.amk.ca/python/2.0/index.h...00000000000000

-- Gerhard

Oct 25 '05 #23

P: n/a
Fredrik Lundh <fr*****@pythonware.com> wrote:
Alex Martelli wrote:
> class Sic:
> def getFoo(self): ...
> def setFoo(self): ...
> foo = property(getFoo, setFoo)
Sorry for skipping the 2nd argument to setFoo, that was accidental in my
post. The problem here is: class Sic is "classic" ("legacy",
"old-style") so property won't really work for it (the setter will NOT
trigger when you assign to s.foo and s is an instance of Sic).


what's slightly confusing is that the getter works, at least until you attempt
to use the setter:


Oh yes, that IS definitely contributing to the confusion -- which is
part of why I think it makes sense to claim this is a "tricky area".
(a "setter isn't part of an new-style object hierarchy" exception would have
been nice, I think...)


Agreed. Alas, a bit too late now, I fear (until 3.0 when old-style goes
away) -- somebody might be (unwisely but "it-sort-of-works" style)
relying on this behavior. Hmmm, maybe a WARNING could be given...
Alex
Oct 25 '05 #24

P: n/a
Tim Roberts <ti**@probo.com> wrote:
"PyPK" <su*******@gmail.com> wrote:

What possible tricky areas/questions could be asked in Python based
Technical Interviews?
What's the point of asking "tricky" questions? Aren't you really more
interested in what applications they have worked on and whether they were
successful?


Understanding exactly what contribution they did, to the applications
they worked on, may be even more important. After all, we've all seen
people who worked on app "X" and made a NEGATIVE net contribution to
"X"'s success, compensated by the far better efforts of others on the
team. But it's unlikely that the candidate will actually say "I worked
on X, but my grasp of the language was so feeble that in fact I made it
_worse_ than it would have been without me in the team";-).

I don't know. I'm not sure I need a job with a company that insists on
playing "Programming Jeopardy" during the interview.


I understand how some "quiz-like" questions may rub you the wrong way.
For questions such that knowing the answers is of little or no use on
the job I might even concur -- e.g., "On what exact date was Python 1.0
released" (even if the candidate claims to have been actively part of
that release, he might perfectly well misremember the date!-).

Others are iffier, e.g., "what are all the optional arguments to
built-in function 'open'" -- some people easily memorize those even if
they use them once in a blue moon, others look them up in 2 seconds
every time they need to with a "help(open)" on the interactive
interpreter prompt, so while the knowledge sure doesn't hurt it's not
very important. That's even truer for other functions and classes with
many more, and more obscure, optional arguments.

If I asked such a question in the course of a programming task, I would
consider "hmmm, there's an optional argument for that, I don't remember
it but in real life I'd look it up in a jiffy" perfectly acceptable (if
the candidate appears to have no idea that there IS an optional argument
for a cerrtain purpose, that's slightly less good, but no disaster).

But -- being presented with a flawed solution and asked to help debug it
(by identifying the "tricky issue" on which it fails) appears to me to
be perfectly acceptable. It IS the kind of task you face all the time
IRL, and checks how well you know the language and libraries...
Alex
Oct 25 '05 #25

P: n/a
On Tue, 25 Oct 2005 10:44:07 +0200, "Fredrik Lundh" <fr*****@pythonware.com> wrote:
Alex Martelli wrote:
my hard-won ignorance, and admit that I don't see the
problem with the property examples:

> class Sic:
> def getFoo(self): ...
> def setFoo(self): ...
> foo = property(getFoo, setFoo)


Sorry for skipping the 2nd argument to setFoo, that was accidental in my
post. The problem here is: class Sic is "classic" ("legacy",
"old-style") so property won't really work for it (the setter will NOT
trigger when you assign to s.foo and s is an instance of Sic).


what's slightly confusing is that the getter works, at least until you attempt
to use the setter:
class Sic:... def getFoo(self):
... print "GET"
... return "FOO"
... def setFoo(self, value):
... print "SET", value
... foo = property(getFoo, setFoo)
... sic = Sic()
print sic.fooGET
FOO sic.foo = 10
print sic.foo10

(a "setter isn't part of an new-style object hierarchy" exception would have
been nice, I think...)

Hm, wouldn't that mean type(sic).__getattribute__ would have to look for type(sic).foo.__get__
and raise an exception (except for on foo functions that are supposed to be methods ;-)
instead of returning type(sic).foo.__get__(sic, type(sic)) without special casing to reject
non-function foos having __get__? I guess it could. Maybe it should.

BTW, I know you know, but others may not realize you can unshadow foo
back to the previous state:
sic.foo = 10
print sic.foo 10 del sic.foo
print sic.foo GET
FOO

and that applies even if __delete__ is defined in the property:
class Sic: ... def getFoo(self):
... print "GET"
... return "FOO"
... def setFoo(self, value):
... print "SET", value
... def delFoo(self):
... print "DEL"
... foo = property(getFoo, setFoo, delFoo)
... sic = Sic()
print sic.foo GET
FOO sic.foo = 10
print sic.foo 10 del sic.foo
print sic.foo GET
FOO

but it won't go beyond the instance for del foo
del sic.foo

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: Sic instance has no attribute 'foo'

Regards,
Bengt Richter
Oct 25 '05 #26

This discussion thread is closed

Replies have been disabled for this discussion.