Python Newbie

C

Chris Angelico

One of the things I love about Python is its ability to get out of the way
and let me work:

- no variable declarations, just use 'em
- no type declarations, just use 'em
- no need to remember what's an object and what's not -- everything is an
object
- no need to cast to bool as everything has a truthy/falsey (something vs
nothing) value

Variable declarations can go either way; Python requires you to name
all globals that you mutate, and to be careful when working with
nested functions. With declared variables, you name all locals, and
can enforce scoping and destructors without language features like
'with'. Both options are viable.

I absolutely agree with your third point. Treat 'em all as objects!
But of *course*, Java is "more object oriented" than Python. Everyone
knows that.

ChrisA
 
R

Roy Smith

no need to remember what's an object and what's not -- everything is an
object
[/QUOTE]

Well, not quite everything. If I write:

if foo:
do_this()
and_this()

the code block making up the body of the "if" statement is not an
object. In some languages, it is.
 
J

Joshua Landau

Hi. Steve, I don't know where you have been over the past couple of days
but it is widely known (if the thread title is any indication) that I am
indeed very new to Python, but not new to programming in general.

To give a bit of background where I found __str__, I am using a Python IDE
called PyScripter. Its Intellisense is full of methods starting and ending
with "__", hence the question.

Regarding Hungarian notation, I don't use it in any other language but
Python and JS. Call it poor, but it helps me to remember what type a
variable is.


If you can't remember what type a variable is, you're doing something
incorrectly.

The redundant comments serve the same purpose.


To help you remember the type of the variable?
intX = 32 # decl + init int var
How is it not obvious that "intX" is an integer *without* the comment?
How is it not obvious that X is an integer?
intX_asString = None # decl + init with NULL string var
How is it not obvious that intX_asString is an integer (it starts with
"int", duh"... oh wait)

The comment says it's the NULL string, so it's "". F*ck.

It's None. Why? No idea.
intX_asString = intX.__str__ () # convert int to string
Wait. So why'd you write the previous line?

Just write:
X_as_string = str(X)
'Cause "str" *always* returns a string. So it's a string. How is that not
obvious?


But then, what's the context?

"X" is a *useless* name. Why are you converting X to a string? I have no
idea. The problem with the code isn't that you could be overwriting "X".
The problem is that your code is contradictory, pretends it's C, has
useless names and doesn't try to be readable.

As for "pointless predeclaration", it helps me know where in the code I
first started using the variable, so I know there are no references to it
before then.

Why? Why can't you overwrite old variables? Why can't a variable change
type? If your functions are so large that you're likely to lose track of
what's defined, you have a different problem indeed.


For example:
def floatA_floatB_floatC_to_tupleR(floatA, floatB, floatC): # decl with
floatA, floatB, floatC parameters
floatD = None # decl + init with NULL float var
floatD = ((floatB ** 2) - (4 * floatA * floatC)) # set to B² - 4AC
floatD = floatD ** 0.5 # set to √floatD

floatR1 = None # decl + init with NULL float var
floatR1 = (((- floatB) + floatD) / (2 * floatA)) # set to (-B+D)/(2A)

floatR2 = None # decl + init with NULL float var
floatR2 = (((- floatB) - floatD) / (2 * floatA)) # set to (-B-D)/(2A)

return (floatR1, floatR2)

Versus

def solve_quadratic(a, b, c):
"""Solve a quadratic equation of the form ax² + bx + c = 0

The result will be a tuple of the two results; the results can be equal if
the determinant is 0.
This supports imaginary results for if the determinant is negative."""

# The method used is the quadratic equation:
# http://en.wikipedia.org/wiki/Quadratic_equation

# b² - 4ac
determinant = b**2 - 4*a*c

# ±√(b² - 4ac)
sqrt_determinant = determinant ** 0.5
squareroots = sqrt_determinant, -sqrt_determinant

# -b ± √(b² - 4ac)
fraction_tops = [(-b + d) for d in squareroots]

results = [top/(2*a) for top in fraction_tops]

return results

Which is easier to read? Reading through it you don't just suddenly forget
what the type of "determinant" is (which must be a number because it's a
determinant) or "results" (which is a container since it's plural). The
names tell you.

The useful comments such as "The method used is..." and "±√(b² - 4ac)" give
you context, too, which is a lot more than can be said of
"floatA_floatB_floatC_to_tupleR". For that, I tried to emulate what I saw
in your code.

I'm not a good programmer. But because of that the code I write makes
sense, so I can understand it. Tell the reader what they want to know, not
what they see.
 
C

Chris Angelico

[/QUOTE]

Careful on the citations - Ethan Furman said that, I just quoted him.
Well, not quite everything. If I write:

if foo:
do_this()
and_this()

the code block making up the body of the "if" statement is not an
object. In some languages, it is.

Maybe, but the code of an entire function *is*. Granted, it's not an
object that can be built up manually (at least, not that I know of),
and it offers only limited functionality (dis.dis, but not a lot
else), so really it could be seen as just an implementation detail of
the function object itself. But it's still an object.

ChrisA
 
J

Joshua Landau

Chris Angelico said:
That could also be written:

if condition1 \
and condition2 \
and condition3:

but as a practical matter, I would write it in the parens style, if for
no other reason than because emacs does a better job of auto-indenting
it that way :)

Pah,

condition1 = long_condition_expression_1
condition2 = long_condition_expression_2
condition3 = long_condition_expression_3

if condition1 and condition2 and condition3:
STUFF

No multiline needed. If you have *many* conditions, then:

supercondition = all(
condition1,
condition2,
condition3,
condition4,
condition5,
condition6,
condition7,
condition8,
condition9
) # or equiv.

if supercondition:
STUFF


Reason:
Indentation should be *really simple*.
 
C

Chris Angelico

def solve_quadratic(a, b, c):
"""Solve a quadratic equation of the form ax² + bx + c = 0

The result will be a tuple of the two results; the results can be equal if
the determinant is 0.
This supports imaginary results for if the determinant is negative."""
...
results = [top/(2*a) for top in fraction_tops]

Yeah, I think we know which one is the more readable... Just to
nit-pick a little though, that returns a list when its docstring says
it'll return a tuple :)

Other than that (which is probably better solved by changing the docs
than the code), the only change I'd make would be to ditch the
fraction_tops temporary (and to throw out some of the comments that
serve only to reexpress the code that immediately follows them, though
for a demo they're entirely appropriate). Even in a language with
mandatory declarations, the code would look pretty similar:

# Assume that the declaration 'complex' permits a float - otherwise
you need a Pike-style piped declaration eg "float|complex"
# Details elided for brevity, keep the docstring and comments from the
above version
list(complex) solve_quadratic(float a, float b, float c):
float determinant = b**2 - 4*a*c
complex sqrt_determinant = determinant ** 0.5
tuple(complex) squareroots = sqrt_determinant, -sqrt_determinant
return [(-b + d)/(2*a) for top in squareroots]

Variable names seldom if ever need to identify their types, if by
"type" you mean what the language sees as a type. There are times when
it's useful to adorn a variable name with a unit, perhaps (length_ft
and height_m shouldn't be multiplied together), or some other special
marker (a "tainted" flag on all data that's come from user input, and
which therefore must not be executed or interpolated into SQL or
anything), but this is a much higher level of abstraction.

ChrisA
 
M

Mitya Sirenef

Careful on the citations - Ethan Furman said that, I just quoted him.


Maybe, but the code of an entire function *is*. Granted, it's not an
object that can be built up manually (at least, not that I know of),
and it offers only limited functionality (dis.dis, but not a lot
else), so really it could be seen as just an implementation detail of
the function object itself. But it's still an object.

ChrisA


But if block doesn't have to be inside a function, right? It needs
to be inside a module, but then again everything is inside a module, but
it wouldn't be very object-oriented if the module was the only object in
Python :).

-m
 
P

piterrr.dolinski

Josh,

Not thank you for your malicious post.
I think you are missing the point here.

My source code was just a dummy to offer context for the question I wanted to ask. Further down the line, if I ever feel I don't need to pseudo-declare variables I will stop doing it. But for the moment I am trying to imitate familiar ground.

My code as written has no syntax errors, so what's the problem? It is highly unlikely you will ever read any of my Python code - no need to get excited over a few of my lines.

And you don't need to answer questions which were not posed, thank you.

I wanted Python to register what type of variable I'm after. So I init my vars accordingly, int might be 0, float 0.0 and string with null, err... None.

In practice, I wouldn't define an intX_asString var, I would do "str (num)" every time a string representation is needed, provided it isn't a loop, as in that context the expression would probably negatively impact performance in an interpreted language.

Peter
 
P

piterrr.dolinski

Josh,

Not thank you for your malicious post.
I think you are missing the point here.

My source code was just a dummy to offer context for the question I wanted to ask. Further down the line, if I ever feel I don't need to pseudo-declare variables I will stop doing it. But for the moment I am trying to imitate familiar ground.

My code as written has no syntax errors, so what's the problem? It is highly unlikely you will ever read any of my Python code - no need to get excited over a few of my lines.

And you don't need to answer questions which were not posed, thank you.

I wanted Python to register what type of variable I'm after. So I init my vars accordingly, int might be 0, float 0.0 and string with null, err... None.

In practice, I wouldn't define an intX_asString var, I would do "str (num)" every time a string representation is needed, provided it isn't a loop, as in that context the expression would probably negatively impact performance in an interpreted language.

Peter
 
D

Dave Angel

Hi guys,

Question. Have this code

intX = 32 # decl + init int var
intX_asString = None # decl + init with NULL string var

None is not a str, and it's not a "NULL string var" Perhaps what you
want is intX_asString = ""
I am using a Python IDE called PyScripter. Its Intellisense is full
of methods starting and ending with "__", hence the question.

I'm surprised; I'd expect the Intellisense to filter those out by
default, since people seldom should call them.
 
J

Joshua Landau

def solve_quadratic(a, b, c):
"""Solve a quadratic equation of the form ax² + bx + c = 0

The result will be a tuple of the two results; the results can be equal if
the determinant is 0.
This supports imaginary results for if the determinant is negative."""
...
results = [top/(2*a) for top in fraction_tops]

Yeah, I think we know which one is the more readable... Just to
nit-pick a little though, that returns a list when its docstring says
it'll return a tuple :)

Good catch.

Other than that (which is probably better solved by changing the docs
than the code), the only change I'd make would be to ditch the
fraction_tops temporary (and to throw out some of the comments that
serve only to reexpress the code that immediately follows them, though
for a demo they're entirely appropriate).

I knew someone would critique it. It's an exaggerated demo for foo's sake.
Heck, who even uses a function like that (or uses unicode in comments :p)?
 
J

Joel Goldstick

Josh,

Not thank you for your malicious post.
I think you are missing the point here.

My source code was just a dummy to offer context for the question I wanted
to ask. Further down the line, if I ever feel I don't need to
pseudo-declare variables I will stop doing it. But for the moment I am
trying to imitate familiar ground.

My code as written has no syntax errors, so what's the problem? It is
highly unlikely you will ever read any of my Python code - no need to get
excited over a few of my lines.

And you don't need to answer questions which were not posed, thank you.

I wanted Python to register what type of variable I'm after. So I init my
vars accordingly, int might be 0, float 0.0 and string with null, err...
None.

In a language that defines Names that are bound to objects, there can't be
a 'type' inferred. In C or similar, when you delcair the variable you are
setting aside the memory to hold something of that type. This is compile
time typing. That isn't how python works, so naming something an int will
never make it an int. intMe = 'Joel' is totally valid in python.

Sticking to ideas like this will hinder understanding of how python works.
I suggest taking two hours to study the python documentation at python.org.
I don't speak Chinese, but I know that I can't just use a dictionary of
English to Chinese and use the same syntax. It won't be Chinese.

Get over your prejudice and learn the new language.... or don't, but trying
to shoe horn python into the concepts of another language won't help you
understand python, it will produce ugly, messy, unsupportable code.
 
J

Joshua Landau

Josh,

Not thank you for your malicious post.

Be careful, us programmers do *eventually* catch on to who is a troll, and
if you say things like that we may eventually mark you off as just to
hostile.
I *honestly* meant no malice or insult. If you can't take my word, you can
point out what I said that was otherwise.

(Then again, you'll have about a week before we really start to notice :p)

I think you are missing the point here.

My source code was just a dummy to offer context for the question I wanted
to ask. Further down the line, if I ever feel I don't need to
pseudo-declare variables I will stop doing it. But for the moment I am
trying to imitate familiar ground.

My code as written has no syntax errors, so what's the problem? It is
highly unlikely you will ever read any of my Python code - no need to get
excited over a few of my lines.

You said "Any comments on this before I quit my job?".

I commented on how I think you should approach Python in order to
appreciate its virtues rather than get stuck in its differences. Again, I
am no good programmer, but I think these methods will help you.

And you don't need to answer questions which were not posed, thank you.

Nor do I need to answer questions which were posed.

I wanted Python to register what type of variable I'm after. So I init my
vars accordingly, int might be 0, float 0.0 and string with null, err...
None.

You seem to think that a "null" version of a type is the falsy version.
Then:
int -> 0
float -> 0.
tuple -> ()
list -> []

And then (*dun dun duuun!*):

str -> "" (NOT None, which is a different type)

Other people have commented on whether this is a good idea (it's not), so
I'll suggest you read those, too.

In practice, I wouldn't define an intX_asString var, I would do "str (num)"
every time a string representation is needed, provided it isn't a loop, as
in that context the expression would probably negatively impact performance
in an interpreted language.


PS: Guess what str(None) is.
 
P

piterrr.dolinski

How is it not obvious that "intX" is an integer *without* the comment?

Indeed the assignment is enough to deduce "intX" is an int. The comment is there to let me know it is unlikely intX appears earlier in the code. Please, let me do things my way until I find reasons to the contrary.

Regarding my use of None to mean NULL, point taken to use "" instead.

Peter
 
P

piterrr.dolinski

How is it not obvious that "intX" is an integer *without* the comment?

Indeed the assignment is enough to deduce "intX" is an int. The comment is there to let me know it is unlikely intX appears earlier in the code. Please, let me do things my way until I find reasons to the contrary.

Regarding my use of None to mean NULL, point taken to use "" instead.

Peter
 
C

Chris Angelico

Indeed the assignment is enough to deduce "intX" is an int. The comment is there to let me know it is unlikely intX appears earlier in the code. Please, let me do things my way until I find reasons to the contrary.

Regarding my use of None to mean NULL, point taken to use "" instead.

It's worth noting that None does make a good rendition of
"null-as-opposed-to-blank", for instance when you're fetching data
from an VARCHAR field in an SQL database. You'd use a string for
anything that isn't NULL, and None for the others.

ChrisA
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top