Re: Zen of Python “obvious way to do it” (was: [TSBOAPOOOWTDI]using names from modules)
On Sun, 5 Nov 2017 12:49 pm, Ben Finney wrote: > Steve D'Aprano writes: > >> On Sun, 5 Nov 2017 06:42 am, Stefan Ram wrote: >> >> > What is the one way to do it? >> >> There is no philosophy of "one way to do it" in Python, that is a >> misunderstanding (possibly deliberate...) spread about by Perl users, >> to contrast Python from Perl's "more than one way to do it". [...] > I think the confusion is quite understandable, and that the Zen was > written quite consciously referencing the (at the time quite well-known) > Perl princple “There's more than one way to do it”. I daresay you are right about the second part, but I'm not so sure about the first. Python supports both while and for loops, and recursion, and it is well known than anything written recursively can be re-written using iteration (and vice versa), and anything using a for-loop can be re-written using while (but not vice versa). I don't think it is reasonable to give any credence to the idea that Python allows "only one way" to solve problems. Sure, it's easy to toss the phrase out without thinking, and I'm sure that in my early years as a Python user I probably did exactly that. I suppose that "people say things without thinking about them first" is a kind of understanding, so I guess I'll have to admit that technically you are right :-) > So, I have given up trying to assign *blame* for that confusion. But > from what I can tell it's a canard to say that the confusion is “spread > about by Perl users”. Perhaps I should have said "*was*. I hardly see this "Only One Way" business these days. A decade or two ago, it was much more common, and mostly (in my experience) coming from Perl users as a put-down, that Python needlessly limits what the programmer can do. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Aw: Try: Except: evaluates to True every time
On Sun, Nov 05, 2017 at 11:28:44AM +1100, Steve D'Aprano wrote: > > Try in an interactive interpreter: > > > >python> "a string" is True > > Did you try that yourself? Yes, eventually, which is why I corrected myself publicly. However, while it doesn't return True (as I mistakenly suggested) it does return False, always, which is the very same reason for OP's problem, namely returning a string, doing a logic test on that, and assuming that would tell whether the check succeeded or failed. Unless I am totally mistaken :-) Karsten -- GPG key ID E4071346 @ eu.pool.sks-keyservers.net E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346 -- https://mail.python.org/mailman/listinfo/python-list
Re: [TSBOAPOOOWTDI]using names from modules
On 5 November 2017 at 01:19, Steve D'Aprano wrote: > On Sun, 5 Nov 2017 06:42 am, Stefan Ram wrote: > >> What is the one way to do it? > > There is no philosophy of "one way to do it" in Python, that is a > misunderstanding (possibly deliberate...) spread about by Perl users, to > contrast Python from Perl's "more than one way to do it". > > The Zen of Python says: > > There should be one-- and preferably only one --obvious way to do it. > > > The emphasis is on "obvious", not "one". There should be *at least* one, but > preferably only one, OBVIOUS way to solve any problem. > > As for the question of importing names, the obvious way is to use a regular > import: > > > import math > y = math.cos(x) > > > which has the advantage of making it obvious where the name comes from, but > the disadvantage that it is more to type and involves an extra name lookup at > runtime, which is not free. > > But: > > - when performance matters > > - or the name is very well known > > - or you're only using a single name from the module (or at most a few) > > - especially if it repeats the module name (e.g. fractions.Fraction) > > it is acceptable to use the "from module import name" version: > > from math import cos > y = cos(x) > > > Which you use depends on the situation and personal taste. Also, if what you are trying to "do" is different (for example, you're trying to write code that looks familiar to mathematicians) the obvious way may be different too (so "from math import cos" may be the obvious approach in that situation). But regardless, the Zen isn't intended to be taken quite as literally as the OP was trying to do. It's a statement of principles, not a set of rules. Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Read Firefox sqlite files with Python
On 5 November 2017 at 01:22, Steve D'Aprano wrote:
> On Sun, 5 Nov 2017 04:32 am, Steve D'Aprano wrote:
>
>> I'm trying to dump a Firefox IndexDB sqlite file to text using Python 3.5.
>>
>>
>> import sqlite3
>> con = sqlite3.connect('foo.sqlite')
>> with open('dump.sql', 'w') as f:
>> for line in con.iterdump():
>> f.write(line + '\n')
>
>
> Never mind. I dumped the file using the sqlite3 command line tool. Thank you
> to all those who answered.
>
> The file contains three INSERT statements, the first two don't have anything
> of interest, and the third (which presumably contains all the data I'm trying
> to recover) is an opaque 600+ KB blob.
>
> Naturally. Why would you use a database as a database, when instead you could
> just dump a big ball of mud into it?
Hmm, *.sql files normally contain SQL source code (as this one does).
SQLIte databases in my experiences typically use either ".sqlite" or
".db" for the extension. Are you sure you're looking at the right
file? Alternatively I guess it's possible that Firefox creates an
in-memory database, then executes the dump.sql file to populate it,
for performance reasons.
Paul
--
https://mail.python.org/mailman/listinfo/python-list
Re: Aw: Try: Except: evaluates to True every time
On Sun, 5 Nov 2017 09:53 pm, Karsten Hilbert wrote: > On Sun, Nov 05, 2017 at 11:28:44AM +1100, Steve D'Aprano wrote: > >> > Try in an interactive interpreter: >> > >> >python> "a string" is True >> >> Did you try that yourself? > > Yes, eventually, which is why I corrected myself publicly. Oops, didn't see that. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: [TSBOAPOOOWTDI]using names from modules
On Mon, 6 Nov 2017 12:54 am, Stefan Ram wrote: > Paul Moore writes: >>But regardless, the Zen isn't intended to be taken quite as literally >>as the OP was trying to do. It's a statement of principles, not a set >>of rules. > > What I am looking for is a default notation to use in my > beginner's tutorial and also to recommand for beginners. When I first started learning Python, I had a bit of difficulty with the two import forms. For about an hour, until I experimented in the interactive interpreter until I got it. Part of the problem at the time was that I had no concept of "namespaces" or modules. If your students are experienced in other languages, don't treat them like dummies. They'll probably understand about namespaces and variable scopes. Teach them that math.cos is the syntax for accessing a name "cos" inside the "math" namespace, and they'll get it. Teach them that the from...import version brings the name into the current scope, and they'll get that too. You might have to give them analogous examples from whatever languages they're used to. If your students are completely new to this, like I was, then it might help to start them with just the "import math" form, and then later introduce "from...import" as syntactic sugar for: import math cos = math.cos del math Although I wouldn't literally teach `del` at this point, I'd just leave it out and and "except that the name 'math' isn't actually made available". > Learners have a limited capacity for learning and storing > information. People don't learn isolated facts too well. But they learn *models* which they can then infer behaviour from VERY well. This is why the Principle of Least Surprise is so important for usable interfaces and APIs. If you try to teach things as isolated facts, students will struggle. But: - teach import math first; - then show how `from math import cos` is syntactic sugar for making a local alias for math.cos; - then you can show that there's no particular reason why the names have to be the same: from math import cos as mycos is just sugar for import math mycos = math.cos But don't teach them this: > |from math import * There's no reason for beginners to use wildcard imports until they've mastered *not* using wildcard imports. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
On 2017-11-05, Steve D'Aprano wrote: > On Sat, 4 Nov 2017 04:44 am, Jon Ribbens wrote: >> That conforms to my model. It's searching for the condition >> 'count > MAX_OBJECTS'. > > That's sounds to me that you are willing to call just about any test of a > condition inside a loop a "search". I don't think that's helpful. I think it > is mangling the word to the point it is meaningless. You're entitled to your opinion, of course. I've provided you with a way of thinking about 'for...else' that makes its purpose and meaning intuitively obvious. You'd apparently prefer to think about it a different way that makes it counter-intuitive, and would like to change the language to match your thinking instead. I'd regretfully suggest that that is not going to happen. > How about a loop that exits at some random time? Is that a search? > > for i in range(100, 0, -1): > if flip_coin() == 'Heads': Of course, that's searching for the condition "flip_coin() == 'Heads'". > What you actually wrote, in various posts: > > You have a 'for...else' with no 'break'. Like I said, that should > probably be a syntax error. > > if what the 'for' clause is doing doesn't match the concept > of 'searching for a match' then it's obvious that you shouldn't > be using 'for...else' in the first place. > > the language doesn't currently strictly enforce the requirement > for a 'break', but nevertheless if you don't have one you almost > certainly have a bug. > > I stand by my comment as an accurate description of your response. You're conflating two completely different points: * whether to allow 'for...else' with no 'break' * how to think about 'for...else' with a 'break' My comment about syntax errors only has any relevance at all to the former point. > I find the code useful. I shouldn't have to justify why it is useful to me, > but for the record it especially comes in handy when I've already typed out a > multi-line loop in the REPL, and only then realised that I'll need some way > to add an extra line at the end. Just press up arrow to go back and edit the first line of your current input and insert an 'if 1:' as someone else suggested. > And yes, a better REPL would also solve that problem. But I have to use the > REPL that exists, not the imaginary one that I'd like. If you want to call > this a hackish work around for a limitation of the REPL, I'll say... okay. > What's your point? It is still useful. The question isn't whether it's useful, but whether it's *more* useful than preventing bugs in peoples' code. You're entitled to your opinion on that, and I'm entitled to mine, and neither opinion is 'arrogant'. We're all just making guesses in the dark, unless anybody has any statistics about how much time is wasted each year by bugs caused by 'for...else' with no 'break' and how much time would be wasted each year by people being unable to use your REPL trick. -- https://mail.python.org/mailman/listinfo/python-list
Re: [TSBOAPOOOWTDI]using names from modules
On 5 November 2017 at 13:54, Stefan Ram wrote: > Paul Moore writes: >>But regardless, the Zen isn't intended to be taken quite as literally >>as the OP was trying to do. It's a statement of principles, not a set >>of rules. > > What I am looking for is a default notation to use in my > beginner's tutorial and also to recommand for beginners. Then "import math" at the top of the file, and refer to module functions as "math.sin". That's the normal approach you'd see in pretty much every Python project on the web, so "follow normal practice" applies. By the time your students know enough to ask if there's a way to avoid needing to repeat "math" (and understand the answer) they are likely to be experienced enough to judge which option is better in a given situation. Paul -- https://mail.python.org/mailman/listinfo/python-list
Python Mailing list moderators
Folks, More and more nonsense are coming in and I find it really difficult to follow any new post that may come and I have to either search for specific content or scroll down until I hit it by accident. Can we do something about it? It's getting really frustrating :/ Cheers. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Mailing list moderators
On 05Nov2017 13:09, Στέφανος Σωφρονίου wrote: Folks, More and more nonsense are coming in and I find it really difficult to follow any new post that may come and I have to either search for specific content or scroll down until I hit it by accident. Can we do something about it? It's getting really frustrating :/ It seems from the headers on your message that you're actually using the comp.lang.python newsgroup and not the mailing list. The newsgroup is completed unmoderated. The mailing list is far less noisy. Go here: https://mail.python.org/mailman/listinfo/python-list and subscribe, and see if things seem better than the newsgroup. Cheers, Cameron Simpson (formerly [email protected]) -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Mailing list moderators
On 11/5/2017 4:14 PM, Cameron Simpson wrote: On 05Nov2017 13:09, Στέφανος Σωφρονίου wrote: Folks, More and more nonsense are coming in and I find it really difficult to follow any new post that may come and I have to either search for specific content or scroll down until I hit it by accident. Can we do something about it? It's getting really frustrating :/ It seems from the headers on your message that you're actually using the comp.lang.python newsgroup and not the mailing list. The newsgroup is completed unmoderated. The mailing list is far less noisy. Go here: https://mail.python.org/mailman/listinfo/python-list and subscribe, and see if things seem better than the newsgroup. Or point your newsreader to news.gmane.org group gmane.comp.python.general, which mirrors python-list. Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
Jon Ribbens writes: > I've provided you with a way of thinking about 'for...else' that makes > its purpose and meaning intuitively obvious. I've read that sentence several times, and I still can't make it anything but a contradiction in terms. Something that is “intuitively obvious” surely has the property that it *does not need* a special “way of thinking about” it. So I can't see that it could be “intuitively obvious” if that special way of thinking about it is needed. Did you mean something else? -- \ “Don't worry about what anybody else is going to do. The best | `\ way to predict the future is to invent it.” —Alan Kay | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
On 2017-11-05, Ben Finney wrote: > Jon Ribbens writes: >> I've provided you with a way of thinking about 'for...else' that makes >> its purpose and meaning intuitively obvious. > > I've read that sentence several times, and I still can't make it > anything but a contradiction in terms. Well, keep at it and I'm sure you'll work it out eventually. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
Jon Ribbens writes: > On 2017-11-05, Ben Finney wrote: > > Jon Ribbens writes: > >> I've provided you with a way of thinking about 'for...else' that makes > >> its purpose and meaning intuitively obvious. > > > > I've read that sentence several times, and I still can't make it > > anything but a contradiction in terms. > > Well, keep at it and I'm sure you'll work it out eventually. You don't want to provide me with a way of thinking about it that makes it mean something non-contradictory? :-) -- \ “Capitalism has destroyed our belief in any effective power but | `\ that of self interest backed by force.” —George Bernard Shaw | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
On Mon, 6 Nov 2017 10:06 am, Jon Ribbens wrote: > On 2017-11-05, Ben Finney wrote: >> Jon Ribbens writes: >>> I've provided you with a way of thinking about 'for...else' that makes >>> its purpose and meaning intuitively obvious. >> >> I've read that sentence several times, and I still can't make it >> anything but a contradiction in terms. > > Well, keep at it and I'm sure you'll work it out eventually. Alice laughed. 'There's no use trying,' she said. 'One can't believe impossible things.' 'I daresay you haven't had much practice,' said the Queen. 'When I was your age, I always did it for half-an-hour a day. Why, sometimes I've believed as many as six impossible things before breakfast.' -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
On Mon, Nov 6, 2017 at 11:06 AM, Steve D'Aprano wrote: > On Mon, 6 Nov 2017 10:06 am, Jon Ribbens wrote: > >> On 2017-11-05, Ben Finney wrote: >>> Jon Ribbens writes: I've provided you with a way of thinking about 'for...else' that makes its purpose and meaning intuitively obvious. >>> >>> I've read that sentence several times, and I still can't make it >>> anything but a contradiction in terms. >> >> Well, keep at it and I'm sure you'll work it out eventually. > > > Alice laughed. 'There's no use trying,' she said. 'One can't > believe impossible things.' > > 'I daresay you haven't had much practice,' said the Queen. > 'When I was your age, I always did it for half-an-hour a day. > Why, sometimes I've believed as many as six impossible things > before breakfast.' Yes, that. Although I was more thinking of the word "intuitively": `When _I_ use a word,' Humpty Dumpty said in rather a scornful tone, `it means just what I choose it to mean -- neither more nor less.' `The question is,' said Alice, `whether you CAN make words mean so many different things.' `The question is,' said Humpty Dumpty, `which is to be master - - that's all.' ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
On Mon, 6 Nov 2017 01:39 am, Jon Ribbens wrote: > On 2017-11-05, Steve D'Aprano wrote: >> On Sat, 4 Nov 2017 04:44 am, Jon Ribbens wrote: >>> That conforms to my model. It's searching for the condition >>> 'count > MAX_OBJECTS'. >> >> That's sounds to me that you are willing to call just about any test of a >> condition inside a loop a "search". I don't think that's helpful. I think >> it is mangling the word to the point it is meaningless. > > You're entitled to your opinion, of course. I've provided you with a > way of thinking about 'for...else' that makes its purpose and meaning > intuitively obvious. By definition, if people have to learn the "right mental model" (as opposed to the one which just comes to them naturally) then there is nothing intuitive about it. [...] >> I find the code useful. I shouldn't have to justify why it is useful to me, >> but for the record it especially comes in handy when I've already typed out >> a multi-line loop in the REPL, and only then realised that I'll need some >> way to add an extra line at the end. > > Just press up arrow to go back and edit the first line of your > current input and insert an 'if 1:' as someone else suggested. "Just press up arrow" -- and that will magically fill in the other 10 lines I typed, will it? Don't be so condescending. I know how to use up-arrow, and I even described using it, which you cut out of your reply. That's a pretty dishonest trick. You saw that I had already discussed the limitations of using up-arrow to retrieve lines from command line history, but rather than acknowledge that, you deleted my comment and added condescending and useless "advice" to make me seem like I don't even know something as simple as up-arrow. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: replacing `else` with `then` in `for` and `try`
On Sat, 4 Nov 2017 03:57 pm, Michael Torrie wrote: > On 11/03/2017 09:06 PM, Chris Angelico wrote: >> On Sat, Nov 4, 2017 at 1:57 PM, Michael Torrie wrote: >>> On 11/03/2017 07:09 PM, Steve D'Aprano wrote: On Sat, 4 Nov 2017 06:15 am, Michael Torrie wrote: > In fact if you have no break you may as well drop the > else entirely, because the block will always execute. That's incorrect. There are multiple ways to exit a loop that will prevent the `else` block from executing, `break` is only one. >>> >>> Such as? >> >> There are many. But other than break, I don't know of any that WOULD >> execute the next line of code immediately _after_ the loop. > > Can you be more specific? What are some of these "many" ways of aborting > a loop? Help a guy out here. Aside from more exotic methods such as os.abort, os._exit and signal handlers, the common ways of breaking out of a loop are: - raise - return - break Am I being pedantic? Of course I am. But we're programmers -- if we don't have an accurate and complete understanding of code, who will? Given how many people find it difficult to understand the semanics of for...else, I think we need to be pedantic about it. I raise these because such commonplace ways of exiting a loop rules out suggestions that we think of or rename `else` as "else no break" or "finally": (1) `else no break` is misleading as it implies that `break` is the only way to avoid running the block; (2) `finally` is misleading as it suggests that the block runs even when you raise or return out of the loop, like a try...finally block. > I know, for example, that we have exceptions. But those hardly matter in > this discussion because they wouldn't execute the else clause either. That contradicts what you said earlier: "if you have no break the [else] block will always execute." Of course you are right -- an exception will also prevent the `else` clause from running. But that's not what you said earlier. Hence my correction. The fact that `raise` and `return` avoid running the `else` block is not a given. We cannot afford to say "that's so obvious it doesn't need to be said". It isn't obvious. There are at least two other code blocks that make guarantees about code "always"[1] running, even if you raise or return: - in a try...except...else block, the `finally` block will still run; - in a `with` block, the context manager's `__exit__` method will usually run (it depends on the context manager). [1] For reasonable values of "always". Obviously if you drop a 1000 tonne weight on the computer, the `finally` clause will not get a chance to run before the CPU is crushed into powder :-) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Read Firefox sqlite files with Python
On Mon, 6 Nov 2017 12:39 am, Paul Moore wrote:
> On 5 November 2017 at 01:22, Steve D'Aprano
> wrote:
>> On Sun, 5 Nov 2017 04:32 am, Steve D'Aprano wrote:
>>
>>> I'm trying to dump a Firefox IndexDB sqlite file to text using Python 3.5.
>>>
>>>
>>> import sqlite3
>>> con = sqlite3.connect('foo.sqlite')
>>> with open('dump.sql', 'w') as f:
>>> for line in con.iterdump():
>>> f.write(line + '\n')
>>
>>
>> Never mind. I dumped the file using the sqlite3 command line tool. Thank
>> you to all those who answered.
>>
>> The file contains three INSERT statements, the first two don't have
>> anything of interest, and the third (which presumably contains all the data
>> I'm trying to recover) is an opaque 600+ KB blob.
>>
>> Naturally. Why would you use a database as a database, when instead you
>> could just dump a big ball of mud into it?
>
> Hmm, *.sql files normally contain SQL source code (as this one does).
The .sql file is the result of running .dump from the sqlite command line
tool. The original source database is 'foo.sqlite'. To be precise, it is the
database used by the Firefox Add-On "One Tab".
/home/steve/.mozilla/firefox/2z5po7dx.default/storage/permanent/indexeddb+++extension-at-one-tab-dot-com/idb/1832832054obnaet.sqlite
One Tab provides an alternative bookmark-like function, allowing you to record
URLs in groups for later use -- a bit like bookmarks. So I've been using this
for some months, until the add-on stopped working. (Yet again an automatic
update has screwed me and broken functionality.) So now I'm trying to
retrieve the bookmarks.
The database itself (the .sqlite file) is not corrupt. The sqlite CLI
processes it fine, and gives me a dump file containing a valid looking
transaction:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE file (id INTEGER PRIMARY KEY, refcount INTEGER NOT NULL);
CREATE TABLE "database" ( name TEXT PRIMARY KEY, origin TEXT NOT NULL, version
INTEGER NOT NULL DEFAULT 0, last_vacuum_time INTEGER NOT NULL DEFAULT 0,
last_analyze_time INTEGER NOT NULL DEFAULT 0, last_vacuum_size INTEGER NOT
NULL DEFAULT 0) WITHOUT ROWID;
...
COMMIT;
But the *interesting* part, the actual data which I hoped would be something
useful like a table of URLs, is a binary blob:
CREATE TABLE "object_data"( object_store_id INTEGER NOT NULL, key BLOB NOT
NULL, index_data_values BLOB DEFAULT NULL, file_ids TEXT, data BLOB NOT NULL,
PRIMARY KEY (object_store_id, key), FOREIGN KEY (object_store_id) REFERENCES
object_store(id) ) WITHOUT ROWID;
which then has three insertions, all of which look something like:
INSERT INTO "object_data" VALUES(1,X'307475627566',NULL,NULL,X'B8F32BA8...');
where the last argument is anything up to 11000+ hex digits. So it looks like
it might be just dumping its in-memory data structure into the database as a
blob.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
--
https://mail.python.org/mailman/listinfo/python-list
