A certainl part of an if() structure never gets executed.

  • Thread starter Íéêüëáïò Êïýñáò
  • Start date
D

Dave Angel

Yes, that would be better.

UCS-2 is identical to UTF-16, except it doesn't support non-BMP
characters and therefore doesn't have surrogate pairs.

UCS-4 is functionally equivalent to UTF-16,

Perhaps you mean UTF-32 ?

as far as I can tell. (I'm
not really sure what the difference is.)

Now you've got me curious, by bringing up surrogate pairs. Do you know
whether a narrow build (say 3.2) really works as UTF16, so when you
encode a surrogate pair (4 bytes) to UTF-8, it encodes a single Unicode
character into a single UTF-8 sequence (prob. 4 bytes long) ?
 
S

Steven D'Aprano

Perhaps you mean UTF-32 ?


Yes, sorry for the repeated confusion.

Now you've got me curious, by bringing up surrogate pairs. Do you know
whether a narrow build (say 3.2) really works as UTF16, so when you
encode a surrogate pair (4 bytes) to UTF-8, it encodes a single Unicode
character into a single UTF-8 sequence (prob. 4 bytes long) ?

In a Python narrow build, the internal storage of strings is equivalent
to UTF-16: all characters in the Basic Multilingual Plane require two
bytes:

py> sys.maxunicode
65535
py> sys.getsizeof('Ï€') - sys.getsizeof('')
2

Outside of the BMP, characters are treated as a pair of surrogates:

py> c = chr(0x10F000) # one character...
py> len(c) # ...stored as a pair of surrogates
2

Encoding and decoding works fine:

py> c.encode('utf-8').decode('utf-8') == c
True
py> c.encode('utf-8')
b'\xf4\x8f\x80\x80'


The problem with surrogates is that it is possible to accidentally
separate the pair, which leads to broken, invalid text:

py> c[0].encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode character '\udbfc' in
position 0: surrogates not allowed


(The error message is a little misleading; surrogates are allowed, but
only if they make up a valid pair.)


Python's handling of UTF-16 is, as far as I know, correct. What isn't
correct is that the high-level Python string methods assume that two
bytes == one character, which can lead to surrogates being separated,
which gives you junk text. Wide builds don't have this problem, because
every character == four bytes, and neither does Python 3.
 
S

Steven D'Aprano

Not quite: a and b _are_ memory addresses,

Not in Python they aren't. a and b are names in a namespace.

At the same time, a and b
are references to the data (the objects) stored in those memory
locations.

Not in Python they aren't. In Python, objects are free to move around
memory. Not all implementations take advantage of this freedom, but some
like Jython, IronPython and PyPy do.

The distinction is probably more important in languages like C/C++,
where the _language_ gives you direct access to, and can manipulate,
these memory addresses (through pointers). Python handles it
differently and does not give you this sort of ability, it all occurs
"under the hood". Yes, the id() function will tell you the addresses,
but you can't do anything with them other than perhaps compare them.
It's really pretty much useless information.

The id() function does not tell you the address of the object, except by
accident. The id() function gives you an arbitrary ID number for the
object:


steve@runes:~$ ipy
IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433
Type "help", "copyright", "credits" or "license" for more information.
44


steve@runes:~$ jython
Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)
[OpenJDK Client VM (Sun Microsystems Inc.)] on java1.6.0_18
Type "help", "copyright", "credits" or "license" for more information.
2



That some implementations happen to use a fixed memory address as the ID
number is, well, a mere accident of implementation. That's not what id()
*is*, any more than "id() returns the next value in an integer sequence
starting from 43" just because that's what IronPython happens to do.
 
Î

Îίκος

Στις 18/6/2013 9:39 πμ, ο/η Larry Hudson έγÏαψε:
Not quite: a and b _are_ memory addresses, At the same time, a and b
are references to the data (the objects) stored in those memory locations.

The distinction is probably more important in languages like C/C++,
where the _language_ gives you direct access to, and can manipulate,
these memory addresses (through pointers). Python handles it
differently and does not give you this sort of ability, it all occurs
"under the hood". Yes, the id() function will tell you the addresses,
but you can't do anything with them other than perhaps compare them.
It's really pretty much useless information.

So, a and b are actual memory addresses.

Does the term of a pointer exist in Python?
I mean if print(a) or print(b) outputs the object that a and b are
linked to, then how do we access a's and b's memory locations themselves
t create links among variables, one pointing to the other and so on?

Can a variable point to another variable or variables never point to
other variables but instead are *only* linked to the objects of those
var's instead?
 
S

Steven D'Aprano

Στις 18/6/2013 9:39 πμ, ο/η Larry Hudson έγÏαψε:

So, a and b are actual memory addresses.

No, no, no, a thousand times no.

Does the term of a pointer exist in Python?
No.


I mean if print(a) or
print(b) outputs the object that a and b are linked to, then how do we
access a's and b's memory locations themselves t create links among
variables, one pointing to the other and so on?

You cannot. You can only have links between OBJECTS, not between
VARIABLES. There is no way to have a name "a" set to point to another
name "b". All you can do is have a name "a" set to refer to the same
object as "b" has *right now*. If "b" changes to another object, "a" will
not follow.

Can a variable point to another variable or variables never point to
other variables but instead are *only* linked to the objects of those
var's instead?

Names are *always* linked to objects, not to other names.

a = []
b = a # Now a and b refer to the same list
a = {} # Now a refers to a dict, and b refers to the same list as before
 
Î

Îίκος

Στις 18/6/2013 12:05 μμ, ο/η Steven D'Aprano έγÏαψε:
Names are *always* linked to objects, not to other names.

a = []
b = a # Now a and b refer to the same list
a = {} # Now a refers to a dict, and b refers to the same list as before

I see, thank you Steven.

But since this is a fact how do you create complicated data structures
that rely on various variables pointing one to another liek we did in
C++(cannot recall their names) ?
 
C

Chris Angelico

Óôéò 18/6/2013 12:05 ìì, ï/ç Steven D'Aprano Ýãñáøå:
Names are *always* linked to objects, not to other names.

a = []
b = a # Now a and b refer to the same list
a = {} # Now a refers to a dict, and b refers to the same list as before


I see, thank you Steven.

But since this is a fact how do you create complicated data structures that
rely on various variables pointing one to another liek we did in C++(cannot
recall their names) ?

Why do you need to? Linked lists, trees, and so on are just tools.
They're usually used to implement data structures like mappings,
growable arrays, lists that can have elements inserted into them, etc,
etc. Python does these sorts of things in better ways. You should not
need to worry about memory locations, pointers, etc. Now, if you want
to have one object reference another, that can be done in plenty of
ways. Check the Python tutorial.

ChrisA
 
J

Jan Riechers

if '-' not in name + month + year:
cur.execute( '''SELECT * FROM works WHERE clientsID =
(SELECT id FROM clients WHERE name = %s) and MONTH(lastvisit) = %s and
YEAR(lastvisit) = %s ORDER BY lastvisit ASC''', (name, month, year) )
elif '-' not in name + year:
cur.execute( '''SELECT * FROM works WHERE clientsID =
(SELECT id FROM clients WHERE name = %s) and YEAR(lastvisit) = %s ORDER
BY lastvisit ASC''', (name, year) )
elif '-' not in month + year:
cur.execute( '''SELECT * FROM works WHERE MONTH(lastvisit)
= %s and YEAR(lastvisit) = %s ORDER BY lastvisit ASC''', (month, year) )
elif '-' not in year:
cur.execute( '''SELECT * FROM works WHERE YEAR(lastvisit) =
%s ORDER BY lastvisit ASC''', year )


This finally worked!


I spared myself to read the whole thread cause its super long and I find
it admirable that some people took time to troubleshoot the issue and
(even) added optimizations of what can be done differently/better.. even
so it seems there was only a wrong char used in the ifs?..

And as a short note - you should add code which handles the worst-case
scenario (everthing fails, nothing valid, avoid into code which might
require variables/data which is not present and so forth..)


But generally speaking:
As a best practice in any language not just Python.
If you have the option to print out evaluations and values, use it!


As rule of thumb for debugging code:
1. Print out what values you get in (from user, in(to) a function)
2a. Test statements and logic either by setting a print (in your case
inside each if) with something like "if1", "if2", ... "else fired" or
what you prefer OR do a direct comparison if the evaluation statements
are not super long (someone mentioned that..)
2b. In case of longer statements/calculations, break them into chunks,
simplify the problem to smaller ones and try to verify the results as
possible (being "far apart" and "getting closer" after each time is
already a good hint in calculations..)
3. If you catch data from a database and you see now results -> print
out if your search/query even can return anything at all or if your
query itself has a flaw or similar.

Optional but also useful:
4. On the end of a function, print if the output of the function is as
expected

This small technique costs minimal time, but brings a brilliant ability:
1. Understand the code flow
2. Understand mistakes
3. Save yourself a big time by searching targeted for code parts which
are executed..

...and ignore not directly connected code - for example when looking at
other peoples code without documentation, comments or introduction.
This can spare loads of headaches.

And all this can be done in a couple of minutes..

Jan
 
D

Dave Angel

I think this is an excellent description of name binding with mutable
objects. I just have one clarification to insert below.

Nick the Gr33k said:
What is an arbitrary value? don even knwo what arbitrary means literally
in English.

Basically, it means "any". In Python, you can use ANY value where a
Boolean is expected. All types have a Boolean meaning. For integers, 0 is
false, anything else is true. For strings, an empty string "" is false,
anything else is true. For lists, an empty list [] is false, anything else
is true. For tuples, an empty tuple () is false, anything else is true.
For dicts, an empty dict {} is false, anything else is true.
The argument being returned in an "and" or "or" expression is the one
that *determined' the evaluation of the expression.

That's not exactly how I'd put it, but the statement is correct. The last
thing it had to evaulate is the result of the expression.
And actually what's being returned is not the argument itself but the
argument's value.

But this is no different than any other programming language. Expressions
always use the value of their operands, and they always return a value.

The name vs value thing is critical to understanding Python, in my opinion,
and it can be a stumbling block when you're coming from another language.
Here's how I think about it.

Python had two distinct spaces: there is a space for names, and there is a
space for objects (which are values). Objects live in a nameless, faceless
object cloud.

A name is always bound to some object (which might be the "None" object). A
name always knows its object, but an object never knows what names it is
bound to.

The only things that can be used in expressions and function arguments are
objects. Names are merely the way we specify which objects to be used.

Names are *one of* the ways we specify which objects are to be used.
(We can also specify objects via an container and a subscript or slice,
or via an attribute of another object. And probably another way or two.)
a = [3]

That creates a nameless list containing a single integer object with the
value 3. It then binds the name "a" to that list. Note that the list has
no clue that it is bound to any names.

b = a

That binds "b" to the same list. "b" and "a" are not related in any way,
except that they happen to be bound to the same object. Note that there is
still only one list.

a.append(4)

That modifies the list so that it now contains [3,4]. b is bound to the
same list, so if you
print(b)
you'll see [3,4]

Now, let's say I do this:

a = [5]

Here's where people get tripped up. This does not change our original
list. Instead, it creates a new nameless list containing 5, and binds the
name a to that list. a and b are no longer bound to the same object.
 
C

Chris Angelico

Names are *one of* the ways we specify which objects are to be used. (We can
also specify objects via an container and a subscript or slice, or via an
attribute of another object. And probably another way or two.)

But you always have to bootstrap it with either a name. Or a literal.
So those are the only two ways to specify which objects are to be
used.

(Anyone fanatically devoted to nice red uniforms?)

ChrisA
 
Î

Îίκος

Στις 19/6/2013 8:08 πμ, ο/η Tim Roberts έγÏαψε:
Nick the Gr33k said:
What is an arbitrary value? don even knwo what arbitrary means literally
in English.

Basically, it means "any". In Python, you can use ANY value where a
Boolean is expected. All types have a Boolean meaning. For integers, 0 is
false, anything else is true. For strings, an empty string "" is false,
anything else is true. For lists, an empty list [] is false, anything else
is true. For tuples, an empty tuple () is false, anything else is true.
For dicts, an empty dict {} is false, anything else is true.
The argument being returned in an "and" or "or" expression is the one
that *determined' the evaluation of the expression.

That's not exactly how I'd put it, but the statement is correct. The last
thing it had to evaulate is the result of the expression.
And actually what's being returned is not the argument itself but the
argument's value.

But this is no different than any other programming language. Expressions
always use the value of their operands, and they always return a value.

The name vs value thing is critical to understanding Python, in my opinion,
and it can be a stumbling block when you're coming from another language.
Here's how I think about it.

Python had two distinct spaces: there is a space for names, and there is a
space for objects (which are values). Objects live in a nameless, faceless
object cloud.

A name is always bound to some object (which might be the "None" object). A
name always knows its object, but an object never knows what names it is
bound to.

The only things that can be used in expressions and function arguments are
objects. Names are merely the way we specify which objects to be used.

a = [3]

That creates a nameless list containing a single integer object with the
value 3. It then binds the name "a" to that list. Note that the list has
no clue that it is bound to any names.

b = a

That binds "b" to the same list. "b" and "a" are not related in any way,
except that they happen to be bound to the same object. Note that there is
still only one list.

a.append(4)

That modifies the list so that it now contains [3,4]. b is bound to the
same list, so if you
print(b)
you'll see [3,4]

Now, let's say I do this:

a = [5]

Here's where people get tripped up. This does not change our original
list. Instead, it creates a new nameless list containing 5, and binds the
name a to that list. a and b are no longer bound to the same object.
Thank you very much Tim for the simply and detailed put explanation.
 
D

Dave Angel

But you always have to bootstrap it with either a name.

Whatever bootstrap really means in this context. But if you have
myname[3] + myname[5], the two objects being added are identified by a
subscript operation, not just a name.
Or a literal.

A literal is used to create an object, and acts like a temporary name
for that object, but once again the object being operated on isn't
necessarily that one. You can subscript and get attributes from a
literal as well.
So those are the only two ways to specify which objects are to be
used.

That would be a pretty weak language, and it wouldn't be python.


Now if you considered "." and "[" as operators, then I could understand
your point. But
http://docs.python.org/3/reference/lexical_analysis.html#operators
seems to say differently.

Also see
http://docs.python.org/3/reference/expressions.html#primaries
 
C

Chris Angelico

But you always have to bootstrap it with either a name.


Whatever bootstrap really means in this context. But if you have myname[3]
+ myname[5], the two objects being added are identified by a subscript
operation, not just a name.
Or a literal.


A literal is used to create an object, and acts like a temporary name for
that object, but once again the object being operated on isn't necessarily
that one. You can subscript and get attributes from a literal as well.

So those are the only two ways to specify which objects are to be
used.

That would be a pretty weak language, and it wouldn't be python.


Now if you considered "." and "[" as operators, then I could understand your
point. But
http://docs.python.org/3/reference/lexical_analysis.html#operators
seems to say differently.

Also see
http://docs.python.org/3/reference/expressions.html#primaries

They may not quite be "operators" per se, but the fact is that they're
composites built of primitives. You can't reference an object without
somewhere having either a name or a literal to start it off. Your
example starts with the object identified by the name 'myname', and
the objects referenced by the literals 3 and 5, and builds up from
there. Rebinding 'myname' would change that expression, as would
changing the meanings of 3 or 5, though I don't know of any way to do
the latter :)

ChrisA
 
S

Steven D'Aprano

You can't reference an object without
somewhere having either a name or a literal to start it off.

True, but not necessarily a name bound to the object you are thinking of:

some_function()

gives you an object, but it's not a literal, and "some_function" is not
the name of the object you end up with.

In a sense, you're making a fairly uninteresting claim:

"You cannot refer to an object without referring to something"

which is obviously correct. The ways to refer to something are more
interesting:

* you can refer to a thing directly by referring to it as a literal;

* you can refer to a thing bound to a name by referring to the name;

* you can refer to a thing in a namespace by referring to the namespace
in some fashion, followed by a dot, followed by the name in that
namespace, e.g. some_object.attribute, __import__('math').pi;

* you can refer to a thing in a sequence by referring to the sequence in
some fashion, followed by an index number in square brackets, e.g. seq[3];

* you can refer to a thing that is returned by a callable (function,
method, type, etc.) by referring in some fashion to that callable object,
followed by calling it, e.g. functions[9](arg) gives you a reference to
some object which may not be any of `functions`, `9`, or `arg`.


Have I missed any?
 
C

Chris Angelico

True, but not necessarily a name bound to the object you are thinking of:

some_function()

gives you an object, but it's not a literal, and "some_function" is not
the name of the object you end up with.

You start with the object identified by some_function, then you call
it. Same thing. Okay, so according to the Python grammar some of these
things I've been treating as operators aren't classified as them; but
there are still operations done to existing objects to derive other
objects:
The ways to refer to something are more
interesting:

* you can refer to a thing directly by referring to it as a literal;

* you can refer to a thing bound to a name by referring to the name;

The two I started with
* you can refer to a thing in a namespace by referring to the namespace
in some fashion, followed by a dot, followed by the name in that
namespace, e.g. some_object.attribute, __import__('math').pi;

Retrieving an attribute of an object, whether that object be
referenced by name or by function call.
* you can refer to a thing in a sequence by referring to the sequence in
some fashion, followed by an index number in square brackets, e.g. seq[3];

Ditto. These can call magic methods; as far as I'm concerned, they're
equivalent to operators. You can apply them to anything.
* you can refer to a thing that is returned by a callable (function,
method, type, etc.) by referring in some fashion to that callable object,
followed by calling it, e.g. functions[9](arg) gives you a reference to
some object which may not be any of `functions`, `9`, or `arg`.

And same again. You start with functions, 9, and arg, look up two of
them as names, traverse the series of operations, and get back a
result. Or maybe you throw an exception.
def __call__(self):
print("Hello, world!")

Hello, world!

Is foo a function? Kinda. Sorta. We don't care. Is the function call
notation () an operator? Ditto - we don't care. It works like one.
There's little fundamental difference between:
'asdf 5 qwer'

and
'%'

but one of them is called an operator and one's not. Would you say
that percent notation there is another way to reference an object? Is
it a different type of string literal? No. It's a string literal and
an operation done to it. Same with the subscripting, even though
that's not technically an operator. It's not a different way to get an
object. It's an operation on an object.

ChrisA
 
M

Michael Torrie

Στις 18/6/2013 12:05 μμ, ο/η Steven D'Aprano έγÏαψε:
Names are *always* linked to objects, not to other names.

a = []
b = a # Now a and b refer to the same list
a = {} # Now a refers to a dict, and b refers to the same list as before

I see, thank you Steven.

But since this is a fact how do you create complicated data structures
that rely on various variables pointing one to another liek we did in
C++(cannot recall their names) ?

As Steve said Python provides all manner of data structures and the
means to create data structures. Any data structure (trees, lists, etc)
can all be made easily in Python using Python's basic data structures,
if the built-in data structures are not sufficient. It turns out that
lists, hashes (dicts), and classes can pretty much do anything with
having to much about with C-style pointers and such.

Do yourself a favor and forget about the low-level stuff in Python for
now. You'll be more frustrated if you don't.

The real power and expressivity of Python comes from embracing the
abstractions that Python provides to your advantage. There's a certain
elegance and beauty that comes from such things, which I believe really
comes from the elegance and beauty of LISP, some of which manages to
shine forth in Python, despite its deficiencies. When I first learned
Python, I was impressed that some of the elegance that I remember from
Scheme (how to use lists as a basic type for example) was there, but in
a form that appealed to me.
 
M

Michael Torrie

It turns out that lists, hashes (dicts), and classes can pretty much
do anything with having to much about with C-style pointers and
such.

Oh wow. Parse error. should read, "pretty much do anything without
having to muck about with C-style pointers and such."
 
S

Steven D'Aprano

The real power and expressivity of Python comes from embracing the
abstractions that Python provides to your advantage. There's a certain
elegance and beauty that comes from such things, which I believe really
comes from the elegance and beauty of LISP, some of which manages to
shine forth in Python, despite its deficiencies. When I first learned
Python, I was impressed that some of the elegance that I remember from
Scheme (how to use lists as a basic type for example) was there, but in
a form that appealed to me.


Well said!
 
M

Michael Torrie

Well said!

Glad you made sense of it... the bit about LISP and Scheme came out a
wee bit muddled. In fact thinking about it, perhaps LISPers would say
about Python what a bible passage says about having the form of
Godliness but denying the power thereof! For example, Python's lambda
functions, and Python's functional programming capabilities in general.
But since the LISP never really got a form beyond S-expressions,
leaving us with lots of parenthesis everywhere, Python wins much as the
Hitchhiker's Guide to the Galaxy wins.
 
R

Roel Schroeven

Îίκος schreef:
Στις 18/6/2013 12:05 μμ, ο/η Steven D'Aprano έγÏαψε:
Names are *always* linked to objects, not to other names.

a = []
b = a # Now a and b refer to the same list
a = {} # Now a refers to a dict, and b refers to the same list as before

I see, thank you Steven.

But since this is a fact how do you create complicated data structures
that rely on various variables pointing one to another liek we did in
C++(cannot recall their names) ?

You almost never need to do that in Python. But if you really want to,
out of curiosity, you can. For example, you could create a simple singly
linked list like this:
def __init__(self, value):
self.value = value
self.next = None


You could iterate over it like this:
while node:
yield node.value
node = node.next

print v


--
"People almost invariably arrive at their beliefs not on the basis of
proof but on the basis of what they find attractive."
-- Pascal Blaise

(e-mail address removed)
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top