Re: [Tutor] How (not!) lengthy should functions be?
boB Stepp writes: > My current understanding of function length best practice is that: 1) > Each function should have preferably ONE clearly defined purpose. Yes, that's a principle to follow firmly, improving the design every time. I know of no exceptions. “Clearly defined” also entails the function signature (its name, what parameters it accepts, what return value it emits) is narrowly defined. > 2) I have seen varying recommendations as to number of lines of code > per function, but I have seem multiple recommendations that a function > generally should fit into one screen on one's monitor. A function that is clearly-designed, as above, should have no more than a handful of statements. That's intentionally vague, but it's already shorter than “a screenful”. > Of course, some people have HUGE monitors! And I assume that any > guidance applies equally well to methods. Any function with statements stretching over 20 lines is already too large, IMO. Note that the docstring can be rather lengthy, if there is a lot to say about the function's purpose or strange cases it handles. > Am I on-track or am I getting carried away? You're right to care about precision in your code. Overlong, overbroad, overcomplex, overdetermined functions happen through laziness; it takes diligence to keep the code readable through refactoring while you go. That takes more effort at each edit, but saves a lot of debugging time. Having such a principle in mind, and knowing that it's worth spending effort to uphold, will serve you well. -- \ “Outside of a dog, a book is man's best friend. Inside of a | `\dog, it's too dark to read.” —Groucho Marx | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] lists, name semantics
Bill Allen writes: > If I have a list defined as my_list = ['a','b','c'], what is the is > differnce between refering to it as my_list or my_list[:]? ‘my_list’ is a reference to the object you've already described (the existing object ‘['a', 'b', 'c']’). ‘my_list[:]’ is an operation that takes the original object and creates a new one by slicing. In this case, the new object happens to be equal to (but probably not identical to) the original, because of the slice you specified. > Is there any nuance I am missing here? Situations where one form > should be used as opposed to the other? You need to understand, when writing code, whether you are intending to refer to the original object, or to create a new one. Neither is better, they are both common but different operations. -- \ “Our products just aren't engineered for security.” —Brian | `\ Valentine, senior vice-president of Microsoft Windows | _o__)development, 2002 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] lists, name semantics
Ben Finney writes: > Bill Allen writes: > > > If I have a list defined as my_list = ['a','b','c'], what is the is > > differnce between refering to it as my_list or my_list[:]? > > ‘my_list’ is a reference to the object you've already described (the > existing object ‘['a', 'b', 'c']’). > > ‘my_list[:]’ is an operation that takes the original object and > creates a new one by slicing. In this case, the new object happens to > be equal to (but probably not identical to) the original, because of > the slice you specified. To demonstrate how identity differs from equality, use the appropriate comparison operators:: $ python3 >>> foo = ['a', 'b', 'c'] >>> bar = foo # Bind the name ‘bar’ to the same object. >>> bar # Show me the object referred to by ‘bar’. ['a', 'b', 'c'] >>> bar == foo# Is the object ‘bar’ equal to the object ‘foo’? True >>> bar is foo# Is ‘bar’ referring to the same object as ‘foo’? True >>> baz = foo[:] # Slice ‘foo’, creating a new list; bind ‘baz’ to that. >>> baz # Show me the object referred to by ‘baz’. ['a', 'b', 'c'] >>> baz == foo# Is the object ‘baz’ equal to the object ‘foo’? True >>> baz is foo# Is ‘baz’ referring to the same object as ‘foo’? False References which compare identical *are the same* object, guaranteed. Object identity almost always implies equality. (“almost always” because some object types have unusual behaviour like “the object is not equal to itself”. Don't fret about that though, these exceptions are clearly defined when you find them.) References which compare equal *may under some conditions* be identical. This is *not* ever a promise, though, and you should never rely on it, not even in the same session of a program. Some of Python's internal optimisations depend on the fact that object equality *does not* imply object identity. If you happen to notice some operations producing the same object at one point in time, but the documentation doesn't promise it, then treat that as an unpredictable implementation detail and don't rely on it in your code. -- \ “The best in us does not require the worst in us: Our love of | `\ other human beings does not need to be nurtured by delusion.” | _o__) —Sam Harris, at _Beyond Belief 2006_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sample dictionairies
Jim Mooney writes: > Where could I download Python sample dictionaries on different > subjects. I don't know what yoy mean by the “subject” of a dictionary. A Python dict is a data structure. Its values can be any collection of Python objects. Is the “subject” of a dictionary its meaning? Its meaning is entirely up to whoever wrote it and whoever reads it. So I have to guess that you mean something else. What do you mean by “dictionaries on different subjects”? -- \“Technology is neither good nor bad; nor is it neutral.” | `\ —Melvin Kranzberg's First Law of Technology | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Life Grid Implementation
niy mor writes: > Is my code completing the assignment??? Does it meet the requirements when you (and other people) run the code? > I need some *guidance* on completing my assignment. Can you be specific about what you don't understand? If you don't understand the requirements, that is best discussed with your course supervisor, not us. -- \ “Kissing a smoker is like licking an ashtray.” —anonymous | `\ | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sample dictionairies
Jim Mooney writes: > I should have known to simply try importing csv. Better: You should now know to refer to the documentation https://docs.python.org/3/library/>. -- \ “Speech is conveniently located midway between thought and | `\action, where it often substitutes for both.” —John Andrew | _o__) Holmes, _Wisdom in Small Doses_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] introspection
Alex Kleider writes: > Does python provide the introspective ability to retrieve the name to > which an object is bound? Objects aren't bound to names. So, no. The binding from a reference (a name is a reference) to objects is one-way. See this excellent presentation from PyCon US 2015 by Ned Batchelder https://www.youtube.com/watch?v=_AEJHKGk9ns>. -- \ “I must say that I find television very educational. The minute | `\ somebody turns it on, I go to the library and read a book.” | _o__)—Groucho Marx | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] bin to dec conversion puzzlement
Jim Mooney writes: > I can't seem to get my head around this 'simple' book example of > binary-to-decimal conversion, which goes from left to right: > > B = '11011101' > I = 0 > while B: > I = I * 2 + int(B[0]) > B = B[1:] > > print(I) > >>> 221 That is, IMO, a needlessly confusing way to write that code. Whoever wrote it is clearly pleased with how clever it is; but cleverness is almost always a property of *bad* code because it's difficult to understand at a glance. That's the case here. One significant problem with the code as written is that it uses a ‘while’ loop and mutates the list, where there's no point; it should just iterate over items *from* the list without changing it. Another significant problem is that it uses moronically-short, completely unexpressive names. This is Python not FORTRAN. Try this:: binary_text = '11011101' result = 0 for binary_digit in binary_text: # Accumulate powers of 2 for each digit. result = result * 2 + int(binary_digit) print(result) > Both methods work but I just can't see how the first one does. Am I > missing something obvious here? No, you were missing something needlessly obscured by the badly-written code. Which book is this? I will be sure never to recommend it. Hope that helps. -- \ “Science is a way of trying not to fool yourself. The first | `\ principle is that you must not fool yourself, and you are the | _o__) easiest person to fool.” —Richard P. Feynman, 1964 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pun panic
"Martin A. Brown" writes: > Good morning underscore underscore Peter underscore underscore, The Pythonic way to pronounce that would be “dunder Pete dunder” https://wiki.python.org/moin/DunderAlias>. -- \ “Geeks like to think that they can ignore politics. You can | `\leave politics alone, but politics won't leave you alone.” | _o__) —Richard M. Stallman, 2002-07-26 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] introspection
Alex Kleider writes: > I was hoping that it would be possible to create a function > that would do the following: > > def my_name(some_object): > return some_object.__name__ That hope is understandable. It is also easy to be confused about why such a feature doesn't exist; after all, it works for functions and classes and modules (oh my!):: >>> def foo(): pass ... >>> foo.__name__ 'foo' >>> class Bar: pass ... >>> Bar.__name__ 'Bar' >>> import sys >>> sys.__name__ 'sys' So why not arbitrary objects? >>> spam = 4 >>> spam.__name__ Traceback (most recent call last): File "", line 1, in AttributeError: 'int' object has no attribute '__name__' The answer is that functions, classes, and modules are all *defined*, and (normally) have exactly one canonical name established at definition time. Arbitrary objects are merely *instantiated*, without that definition step. Quite commonly they are used with no name bound to them; so the behaviour of most objects does not have ‘__name__’ in the API. If you would like to make a class that has that attribute on all its instances, feel free. But you need to figure out how the instance detects its own name! class LockeanThing: """ An object that knows the name by which others refer to it. """ def __init__(self): self.__name__ = ??? > But I see what I think you and others have been trying to explain to > me: that the expression some_object.__name__, if it existed, would > indeed be schizophrenic since it would be an attribute of the object, > not the name(s) to which it is bound. That's why I prefer to be clear that the binding operation is one-way only. A reference (such as a name) is bound to an object, the object is not bound to the reference — indeed, the object knows nothing about that relationship. -- \“I washed a sock. Then I put it in the dryer. When I took it | `\ out, it was gone.” —Steven Wright | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pun panic
Peter Otten <__pete...@web.de> writes: > Ben Finney wrote: > > > The Pythonic way to pronounce that would be “dunder Pete dunder” > > https://wiki.python.org/moin/DunderAlias>. > > Hm, should I campaign for a peter() builtin? You'll need a working implementation first. Put it on BullCodes https://bull.codes/> for bonus Python-based free-software repository hosting points! -- \ “I'm a born-again atheist.” —Gore Vidal | `\ | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pun panic
Albert-Jan Roskam writes: > - Original Message - > > From: Ben Finney > > You'll need a working implementation first. Put it on BullCodes > > https://bull.codes/> for bonus Python-based free-software > > repository hosting points! > > Is bull.codes better than Github or Bitbucket? Yes, because those are not free software. http://mako.cc/writing/hill-free_tools.html> Kallithea (which is what powers BullCodes) is free software, meaning anyone is free to see how it works and change it and run their own instance and share changes. http://kallithea-scm.org/> > Does it work with Travis CI and Appveyor? Not until the Kallithea community adds that support. Since it is free software that's more likely than if it were proprietary :-) -- \ “Reichel's Law: A body on vacation tends to remain on vacation | `\unless acted upon by an outside force.” —Carol Reichel | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pun panic
Alex Kleider writes: > On 2015-04-22 05:40, Ben Finney wrote: > > http://mako.cc/writing/hill-free_tools.html> > > > > Kallithea (which is what powers BullCodes) is free software, meaning > > anyone is free to see how it works and change it and run their own > > instance and share changes. > > > > http://kallithea-scm.org/> > > […] I've been unable to find anything resembling a user (i.e. someone > who wants to keep a project hosted on bull.code) 'howto' with regard > to bull.code. Any suggestions? I don't think BullCodes has a pointer to it yet, but: Kallithea's documentation contains a “General Kallithea usage” section https://docs.kallithea-scm.org/en/latest/usage/general.html>, is that what you're looking for? -- \ “I have always wished for my computer to be as easy to use as | `\ my telephone; my wish has come true because I can no longer | _o__) figure out how to use my telephone.” —Bjarne Stroustrup | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Please disable “digest mode” before participating (was: Tutor Digest, Vol 134, Issue 86)
Juanald Reagan writes: > Okay, so it doesn't look like that worked...here is the traceback. I don't > understand the second part of your request. Juanold, to keep the context and thread of the discussion, please respond to individual messages, not digests. To do that, you first need to disable “digest mode” on your subscription. Change your settings by logging in here https://mail.python.org/mailman/listinfo/python-list>. Digest mode should only ever be used if you know for certain you will never be responding to any message. -- \ “I moved into an all-electric house. I forgot and left the | `\ porch light on all day. When I got home the front door wouldn't | _o__)open.” —Steven Wright | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Please disable “digest mode” before participating
Jim Mooney writes: > On 25 April 2015 at 18:03, Ben Finney wrote: > > > Digest mode should only ever be used if you know for certain you will > > never be responding to any message. > > That brings up a great shortcut if you use gmail. If you select some > text before reply that's All that is sent. That doesn't reply to the original message. So it lacks the threading provided by the “In-Reply-To” field, since you're not replying to the original message. It also lacks the correct Subject field, the correct attribution line, etc. So, no, I still recommend strongly against responding to digest messages — the information simply isn't there to compose a correct reply message. Instead, disable digest mode, and only after individual messages start arriving at your mailbox can you participate properly, by replying to them. -- \“But it is permissible to make a judgment after you have | `\examined the evidence. In some circles it is even encouraged.” | _o__)—Carl Sagan, _The Burden of Skepticism_, 1987 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Ancient Python versions (was: Is there a way to store and later use comparison operators (<, <=, =, >=, >) ?)
boB Stepp writes: > One problem I have with searching the Python documentation is this: > https://docs.python.org/release/2.4.4/lib/lib.html If you actually need to read the documentation specifically for a Python version that has not been supported since 2008, then I agree that is a problem. The documentation has improved since then. If you want newer-looking documentation, maybe you should not expect it from a Python released nearlt a decade ago? -- \ “Not to be absolutely certain is, I think, one of the essential | `\ things in rationality.” —Bertrand Russell | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Ancient Python versions
boB Stepp writes: > On Thu, Apr 30, 2015 at 12:15 AM, Ben Finney > wrote: > > If you actually need to read the documentation specifically for a > > Python version that has not been supported since 2008, then I agree > > that is a problem. > > I'm pretty much stuck with these relics of Pythons past. Then you are, unfortunately, stuck with the documentation for that version. It will not be updated any more, because support for that ancient version has ended. > > The documentation has improved since then. If you want newer-looking > > documentation, maybe you should not expect it from a Python released > > nearlt a decade ago? > > No, I am not looking for fancy aesthetics. I am looking for > intelligent use of whitespace, so that everything does not run > together into a nearly indistinguishable blob. Bold main section > headings would be nice as well. All of this has been possible forever > and evermore. Readability counts! ~(:>) So you might like to borrow the Python time machine and complain to the people of the mid-2000s. Complaining about it today, when the currently-maintained documentation does not have these problems, is futile. -- \ “Quidquid latine dictum sit, altum viditur.” (“Whatever is | `\ said in Latin, sounds profound.”) —anonymous | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Having Unusual results
Jag Sherrington writes: > Hi Can anyone tell me where I am going wrong the end result doesn't > add up? Maybe. first, though, you'll need to turn off any “rich text” or other fancy mangling of your message content. It makes the text undecipherable. Just compose your message as plain text, and put the program text and output in the message. -- \ “Laugh and the world laughs with you; snore and you sleep | `\alone.” —anonymous | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Creating an email option in Python
Michael Lemon writes: > I'm a beginner in Python Welcome! You have chosen a great language for learning. > and I wanted to know how to create an email optional field using Python. Without knowing more about what that means, I'm not sure I would know how either :-) What is an “email optional field”? A field in what, specifically? Can you show a Short, Self-contained, Complete example http://sscce.org/> of a program which has an email field, and explain what you'd like it to do differently? -- \ “Speech is conveniently located midway between thought and | `\action, where it often substitutes for both.” —John Andrew | _o__) Holmes, _Wisdom in Small Doses_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] python dictionaries (copy by reference or copy by value?)
Alex McFerron writes: > trying to understand why this is true > > step 1: x = {} Assignment; binds a reference (the name ‘x’) to a newly-created empty dictionary. > step 2: y = x Assignment; binds a reference (the name ‘y’) to the object currently referred to by ‘x’. That's the same object as above. > step 3: x['key'] = 'value' Assignment; binds a reference (the item keyed by the string ‘'key'’ in the same dictionary as above) to the string object ‘'value'’. > # at this point if i print x or y i see {'key', 'value'} Because there's only one dictionary in all of this. > step 4: x['key'] = 'newValue' Assignment; binds a reference, the same reference as before (the item keyed by the string ‘'key'’ in the same dictionary as above) to the string object ‘'newValue'’. > #and at this point printing x or y i see {'key', 'newValue'} and this > is true if this was y['key'] Because there's only one dictionary in all of this. > because of the behavior in step 4, i'm thinking, ok the copy job from > step 2 was a pointer only and not a by value copy job. fair enough None of these operations are copies. Assignment in Python is *never* a copy operation. > step 5: x = {} Assignment; binds a reference (the name ‘x’) to a newly created empty dictionary. > step 6: print both. and what i get here is that x will be empty but y will > not (or visa verse) Because the name ‘y’ is still a reference to the original dictionary above. > question: if y=x from step 2 (the copy job) There's your error. Assignment in Python *never* copies, it only binds a reference to some value. -- \“If you continue running Windows, your system may become | `\unstable.” —Microsoft, Windows 95 bluescreen error message | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Tip (thank) your mentors
Howdy all, I just received a private message that, briefly and simply, thanked me for advice I gave in this forum, explaining specifically how it helped the recipient understand a concept better. It made my day; I have a spring in my step now. Everyone, never hesitate to thank someone – privately if you wish – for help they've given you. It is inexpensive to give, and very dear to receive. Most of us, most of the time, are engaging in these public discussions to help the community. Gratitude sincerely expressed is an important and valuable way to motivate us to keep contributing. Thank you for keeping our community welcoming and happy. -- \ “Oh, I realize it's a penny here and a penny there, but look at | `\ me: I've worked myself up from nothing to a state of extreme | _o__) poverty.” —Groucho Marx | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Terminology question
"Jim Mooney Py3.4.3winXP" writes: > I noticed that if I call a function that throws an error (Known in Python as “raise an exception”. I understood you, but it's better to use the terminology that matches what the Python docs say.) > I can catch it from the caller, instead of catching it in the > function. Is this is what is known as "errors bubbling up?" Also, is > this how you're supposed to do it? Yes, the “call stack” (the stack of function calls waiting for execution to return to them) can be thought of as a vertical stack through which an exception will “bubble up”. You should allow exceptions to bubble up to a point where they can be handled sensibly. Conversely, you should only ever catch a (type of) excption that you will be able to handle sensibly at that point, otherwise allow it to continue up the stack. -- \“It's all in the mind, you know.” —The Goon Show | `\ | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting import to use a variable name
"Jim Mooney Py3.4.3winXP" writes: > I can only use the hardcoded imported module name, shutil in this > case. If I try x = anothermodule, then import x, it doesn't work. Can you show an example of Python code that you would like to work? I am *guessing* you mean you want this to work:: >>> foo = 'barmodule' >>> import foo That doesn't work because the ‘import’ statement requires the name directly in the source, not as a string value. You will be pleased to know of the standard library ‘importlib’ library:: >>> import importlib >>> foo = 'barmodule' >>> importlib.import_module(foo) See the documentation for ‘importlib’ for more on this useful library https://docs.python.org/3/library/importlib>. -- \“The restriction of knowledge to an elite group destroys the | `\ spirit of society and leads to its intellectual | _o__)impoverishment.” —Albert Einstein | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] python 3.4 documentation
Alex Kleider writes: > >>> import csv > >>> help('csv') > ...and documentation of the modules appears in the pager! Yes. This is positive reinforcement for writing meaningful, standardised docstrings for every code object (module, class, function): the docstring is automatically available for browsing at the interactive prompt, in the context of the object itself. The flip side is: the documentation available there is only as good as the documentation that has been written as a docstring for that object. Encourage authors of libraries you use to maintain and improve their docstrings :-) -- \ “It's my belief we developed language because of our deep inner | `\ need to complain.” —Jane Wagner, via Lily Tomlin | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] __repr__ and __str__
"Marilyn Davis" writes: > Hello Python Tutors, > > A student has asked a question that has me stumped. We are using 2.7. > > Looking at this code: > > #!/usr/bin/python > > class MyList(list): > > def __str__(self): > return """Here are your data: > %s > """ % list.__str__(self) That's okay, but yo should instead use the ‘super’ method to get the superclass, instead of assuming it's known. Python allows any class to participate in multiple inheritance, and that's not determined at the point of writing your class. So you can never assume you know what class is next in the resolution order; that's what ‘super’ is for:: class MyList(list): def __str__(self): text = """Here are your data: %s """ % super().__str__() return text (I am assuming this is Python 3 code, since Python 2 is legacy-only and should not be used for teaching today. If you need Python 2, it needs a different ‘super’ invocation; see its documentation.) > But if we add the special method: > > def __repr__(self): > return "MyList(%s)" % (list.__str__(self)) That's another problem (as pointed out by others in this thread). In addition to using ‘super’ to determine the superclass, you should also be calling the equivalent method on the superclass. In other words, since you're defining ‘__repr__’, it is ‘__repr__’ you should be calling on the superclass:: def __repr__(self): text = "MyList(%s)" % super().__repr__() return text > So ? __str__ is defined and works just fine unless we also define > __repr__. > > What am I missing? The complications of inheritance and calls to the superclass. When defining special methods (the “dunder” methods, so named because they are named with a double leading and trailing underscore), it is best only to extend the same method on the superclass, and not complicate the connextions back and forth. > Thank you for any help. Hope that helps. Thank you for teaching Python 3 to more students! -- \ “DRM doesn't inconvenience [lawbreakers] — indeed, over time it | `\ trains law-abiding users to become [lawbreakers] out of sheer | _o__)frustration.” —Charles Stross, 2010-05-09 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Inheritance, superclass, ‘super’ (was: __repr__ and __str__)
Alan Gauld writes: > Whilst I agree with the general use of super I'm not sure what > the MRO resolution has to do with this case? When accessing the superclass, the MRO is always relevant. > It's explicitly single inheritance and they are explicitly calling the > superclass. They don't know that the superclass will be what is written there; that's an implication of what I said with “in Python, any class an participate in multiple inheritance”. The author of a class (e.g. the OP's example ‘MyList’) cannot know at time of writing whether the superclass is ‘list’. This is because some other class may be using ‘MyList’ in a different inheritance arrangement. Even without either party (the author of ‘MyList’, or the author of the other class) intending it to be so, the MRO can run through ‘MyList’ in a direction not specified by either author. Multiple inheitance is a fact in Python, and good practice is to not arbitrarily write classes that break it. Hence my advice to avoid hard-coding the superclass, and only use ‘super’ to discover the superclass. > There should be no MRO lookup at this class level (there may be at the > list level of course). Much as the class author might like it to be so simple, in Python it just isn't so: any other class using multiple inheitance may pull in this one, either as a parent or in some other indirect relationship. Thus the above assertion is violated. In Python code it can't be said “there should be not MRO lookup at this class level”. It's not for the class author to say whether some other class “should not” inherit, directly or indirectly, from this and some other class(es). > super makes sense (sometimes) in a multiple inheritance setup. Yes, and the class author can't know at time of writing whether that's the case. So it's prudent to never hard-code the superclass, and to only use ‘super’ to dynamically determine at run time what is the superclass. > eg. > > class A(B,C,D): >def m(self): >C.m(self) # call C's m but not B and D if they have them. > > Or am I missing something in the way Python evaluates > the C.m() call above? My understanding comes from (among other places) the Python docs:: […] dynamic ordering is necessary because all cases of multiple inheritance exhibit one or more diamond relationships (where at least one of the parent classes can be accessed through multiple paths from the bottommost class). For example, all new-style classes inherit from `object`, so any case of multiple inheritance provides more than one path to reach `object`. […] https://docs.python.org/2/tutorial/classes.html> The paths are determined at run time, and can link through the class one is writing whether on intends that or not. Any class one writes can become part of some other class's multiple-inheritance chain, and it is bad practice to assume one knows at time of writing what the superclass will be at run time. We have discused this multiple times in the past. Here is a thread from 2011, explaining why, even one isn't using multiple base classes explicitly, one should always only ever use ‘super’ to determine at run-time what the superclass is: All the smarts managing the entire inheritance hierarchy is built into `super`, so each method gets called once and exactly once, provided that every class *only* uses `super`. If you try to mix `super` calls and direct method calls like B.method(self, arg), it probably won't work correctly, and if it does, it will probably be by accident. So please use `super`, even in single inheritance. Otherwise you are restricting the usefulness of your class: it can never be used with multiple inheritance. https://mail.python.org/pipermail/tutor/2011-October/086110.html> Multiple inheritance is a counter-intuitive topic, so it's not really surprising there is still confusion about it. I try to nip the problem before it takes hold, by widely advocating use of ‘super’ to aid everyone else's Python code. Hope that helps! -- \“I took it easy today. I just pretty much layed around in my | `\ underwear all day. … Got kicked out of quite a few places, | _o__) though.” —Bug-Eyed Earl, _Red Meat_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Inheritance, superclass, ‘super’
Steven D'Aprano writes: > I mostly agree with what Ben says, comments below. > > On Wed, Jul 01, 2015 at 12:48:47PM +1000, Ben Finney wrote: > > So please use `super`, even in single inheritance. Otherwise you are > > restricting the usefulness of your class: it can never be used with > > multiple inheritance. > > I cannot disagree with Ben here. Even if you only intend to use single > inheritance, don't unnecessarily rule out the alternatives. Using > super is still usually the right thing to do. I'm glad you agree with the above, since I was quoting your words from 2011 :-) -- \“… no testimony can be admitted which is contrary to reason; | `\ reason is founded on the evidence of our senses.” —Percy Bysshe | _o__) Shelley, _The Necessity of Atheism_, 1811 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Inheritance, superclass, ‘super’
Alan Gauld writes: > On 01/07/15 03:48, Ben Finney wrote: > > Alan Gauld writes: > > > >> Whilst I agree with the general use of super I'm not sure what > >> the MRO resolution has to do with this case? > > > > When accessing the superclass, the MRO is always relevant > > Can you explain that? > If I access a class explicitly As explained on other posts: You're not getting “the superclass” if you do that. Knowing what the superclass is requires run-time determination of the MRO. > If MyList is included in a MI lattice that doesn't change the fact > that MyList inherits directly from list. Correct. The distinction being drawn here is between “the class from which MyList directly inherits” versus “the superclass of this class”. They are not the same, in multiple inheritance. To refer to the direct parent class, yes it's simple enough to hard-code that. But that's not the same thing as accessing the superclass, which must be determined at run-time. > That depends on what you mean by break it., MI should allow the > inheriting class to specify which, if any, of its direct superclasses > methods are invoked. That “should” is contrary to Python's collaborative multiple inheritance model. Instead, multiple inheritance in Python entails that any class should allow the methods of the same name, in all superclasses of this one, to execute in the sequence determined by ‘super’. So, if you want behaviour as you describe there, you want something that Python's mutliple inheritance explicitly won't give you. -- \“Intellectual property is to the 21st century what the slave | `\ trade was to the 16th.” —David Mertz | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] _ vs. _name vs. __name vs. name_ vs. __name__ usages
boB Stepp writes: > From my understandings to date: > > 1) A single underscore is used conventionally for a "throw-away" > variable, such as a loop index for which the index value is not > actually used in a subsequent calculation. That accurately describes common usage. But it's important to also know that ‘_’ has numerous conflicting common usages (including a widely-used text translation function). Less common, but IMO much more preferable for “don't actually want this value but need to bind something to it”, is the convention ‘__’ as a name:: for (__, important_value) in sequence_of_tuples: ... The name ‘__’ doesn't AFAIK have conflicting usages (therefore more strongly connoting this meaning), is pretty easy to type and much easier to spot than a single underscore. > 2) _name is used inside class methods to indicate that the > programmer's intention is that this name should only be accessed > internally by that particular class. Not so much “inside class methods”; rather, the names are on attributes of a class (or module or, sometimes, function). This is the convention for “even if you can see this attribute, it is an implementation detail, not part of the public API for this class, anything might change about this in future revisions”. With no leading underscore, the implicit promise is that the name is a published API for the code, and can be relied on to keep the same name and behaviour in future revisions of the code. > 3) __name invokes Python's name mangling mechanism. The intent of this > usage is to not allow subclasses of the class containing __name to > access this name, and to add additional emphasis to future users of my > code that this name is meant to be strictly hands-off. > > […] it seems to me that one would normally be able to use the > simpler _name construction Right. I've felt any need to use this in my Python programming career; the distinction between “public API” (‘foo’) versus “implementation detail” (‘_foo’) is plenty. > 4) name_ is used when one is "forced" to use one of Python's reserved > words as a name. Yes. It's a last resort, IMO, but a valuable one; and the only damage is to readability (difficult to distinguish when reading quickly). > it seems that normally (4) should never be needed, though I have a > feeling that I have seen something in tkinter recently that suggests > some exceptions, but I cannot (yet) bring it to mind. The Python keywords and built-in object names include some obvious, common words. This is a clear benefit, but it can also cause a clash when choosing your own names: some of the best ones are already taken. I've seen this used to name ‘assert_’, ‘file_’, and the like. > 5) __name__ is meant to be used only by the creators of Python for > their special built-in methods, such as __init__, __new__, etc. > > […] surely I should never violate this one? It seems that in > some future edition of Python they might add any particular __name__ > that I might try to use presently in their future version of Python > (however miniscule that possibility might actually be). Yes. Never name anything with this ‘__foo__’ style unless Python already will treat it specially, and your intention is to invoke that special treatment by Python. This convention is violated too often in third-party code for names that don't have any special significance to Python, leading to needless confusion about how special a newly-encoutered name really is. All the ones I've seen in third-party code would always be improved for clarity by choosing a normal ‘foo’ or ‘_foo’ name. > Are my understandings above correct or flawed? I hope that helps. -- \ “It's dangerous to be right when the government is wrong.” | `\ —Francois Marie Arouet Voltaire | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pep 8, about indentation
D Wyatt writes: > I clearly remember that the standard for Python was to use 2 spaces > for indentation of blocks. Now Pep 8 says 4. When did that change? When do you remember it being as you describe? -- \ “People's Front To Reunite Gondwanaland: Stop the Laurasian | `\ Separatist Movement!” —wiredog, http://kuro5hin.org/ | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to skip a single file when using shutil.make_archive()
Anthony Papillion writes: > I'm creating an archive of a directory using shutil.make_archive and > need to skip a single file if it is present in that directory. Is > there a way to do this or should I be looking to ZipFile to meet this > need? You can create a hierarchy of files the way you want it, and then use ‘shutil.make_archive’ once the tree is the way you want it. * Use ‘tempfile.mkdtemp’ to create a unique temporary working directory, and bind its name to ‘working_dir’. * Use ‘shutil.copytree’ to copy the entire hierarchy from its permanent location to the temporary ‘working_dir’ location. * Use other ‘shutil’ functions to manipulate the files in ‘working_dir’ the way you want. * Use ‘shutil.make_archive’ to create an archive of the files from ‘working_dir’. * Use ‘shutil.rmtree’ to remove the ‘working_dir’. -- \ “All television is educational television. The question is: | `\ what is it teaching?” —Nicholas Johnson | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to test my code's interactions with SQLite db?
boB Stepp writes: > Being committed to TDD for this project, I am not yet ready to write > code till I figure out how to write the tests. It occurs to me that > writing tests for code that interacts with the SQLite db may be > non-trivial (At least for me!). That's correct. One of the primary benefits of Test-Driven Development is to enforce good design on your code: you'll need to design your system so that it's testable with clear, narrowly-defined interfaces. SQL queries are *not* a clear, narrowly-defined interface. So, as you're discovering, it is very difficult to write unit tests for code that could execute some arbitrary query. So that points to a need for better design: Don't directly issue arbitrary SQL queries in code which implements higher-level features. Instead, define a much more specific interface between your feature code and the lower-level code that interacts with the database. Put SQL queries only in very narrowly-defined database interaction functions, where the input and output can be tested easily with unit tests. The unit tests present mock database API functions, that implement only enough to satisfy the narrow actions each low-level function will perform. If you can't set up a trivially-simple fixture to pretend to be the database API, the function is doing too much. Break it down further, possibly along the way finding duplication and refactoring those into levels of abstraction. Put feature code only in higher-level code, where the input and output doesn't have anything to do with the details of SQL and can therefore be tested easily with unit tests. The unit tests make trivially-simple collections — basic types like mappings or sequences — to fake the results from the lower-level code. If you can't make a trivially-simple sequence or mapping to pretend to be the result from the lower-level data code, the function is doing too much. Break it down further, find duplications, refactor them to abstration layers. A database is a very heavy external dependency. You should not be attempting to “mock the world” in order to make your tests run. Instead, you should be making your code well designed: small and simple and narrowly-defined functions, each one of which is easy to test with simple fixtures. -- \ “I call him Governor Bush because that's the only political | `\ office he's ever held legally.” —George Carlin, 2008 | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] variable naming conventions
Laura Creighton writes: > The Python Standard Library, for the most part, uses underscores > for variable names and CamelCase for class names. Note a sharp distinction between camelCaseNames, which the Python community eschews, versus TitleCaseNames, which are embraced for names of classes. > See PEP 008 for 'preferred Python Style' -- such as it is, but be > aware that if you join a project it is more important to follow the > conventions used there than to hop up and down saying 'This is not > PEP 008 !' Yes. If you're looking for a style guide, choose PEP 8, because your style will then be maximally familiar to others when you inevitably need to collaborate with some other people. If you're joining a community that doesn't have consistently-enforced, coherent conventinos, make a strong push for PEP 8 for the same reason. But if you're joining an existing community that has chosen a coherent convention which it enforces consistently, go with that. -- \ “We demand rigidly defined areas of doubt and uncertainty!” | `\—Vroomfondel, _The Hitch-Hiker's Guide To The Galaxy_, Douglas | _o__) Adams | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later?
boB Stepp writes: > My wife had an interesting request tonight: Would it be possible to > have two dbs, one that is the current working db, and the other an > archival db for students who have left the school? (Note that this isn't anything to do with Python per se, and would be better discussed on an SQLite-specific forum.) A relational database (such as implemented by SQLite) is designed to contain all the relevant truths, and is not designed to have truths split across different databases. So you will be better served by *adding* the distinction (“date when this student left the school”) to the database, and use that distinction in queries. To make your job easier, you can store the distinguishing field and prepare “views” which show only subsets (“students who have left the school”, “students who have not left the school”, “all students”) https://www.sqlite.org/lang_createview.html> against which you can perform further queries. > I realized that the method I was going to write a test for would not > be an easy thing to do. Which made me realize that the method I was > hoping to start coding tonight was ill-conceived! ARGH! To bed I now > go ... Is TDD the programmer's version of writer's block? ~(:>) No, it's the programmer's equivalent of saving time by having that realisation come *before* committing wasted time on a poor design :-) -- \ “If you don't fail at least 90 percent of the time, you're not | `\aiming high enough.” —Alan Kay | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later?
Alan Gauld writes: > A flag column that can be used to include/exclude students from > reports. Boolean flags very commonly indicate something that can be different at different times. When the name is of the form “currently_foo”, that's almost certainly something that is different at different points in time. So better than a boolean in the database, would be a timestamp (or just a date) indicating *when* the status changes. Either an ‘enrolled’ timestamp, or a ‘departed’ timestamp, or both. Then you can interrogate the database about past, present, or future, by comparing that value with whatever point in time is of interest. -- \ “Faith is the determination to remain ignorant in the face of | `\ all evidence that you are ignorant.” —Shaun Mason | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] OT: Searching Tutor Archives
"Ken G." writes: > Could someone explain how to found such an article At the end of every message to this forum you'll see this footer: > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor That address, https://mail.python.org/mailman/listinfo/tutor>, gives information about the forum, including where to find its archives. You can browse the archives using a web search, for example “site:mail.python.org/pipermail/tutor/ beachkidken” in DuckDuckGo https://duckduckgo.com/?q=site%3Amail.python.org%2Fpipermail%2Ftutor%2F+beachkidken>. -- \ “If sharing a thing in no way diminishes it, it is not rightly | `\ owned if it is not shared.” —Augustine of Hippo (354–430 CE) | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] indent error on if/elif/else
richard kappler writes: > Here's the Traceback: > > File "dataFeedTest.py", line 44 > else: >^ > IndentationError: expected an indented block A comment is not a statement. So, your second ‘elif’ block is empty, then immediately followed by an ‘else’; Python expected an indented block *of statements*. Yes, that's not exactly clear from the error message; don't feel bad :-) > Not a clue why it's doing this. Any help? If you want to show “I will write something useful here later”, try writing a named function, and immediately write an empty function that fits that interface:: def set_delay_real_time(): pass def read_timestamp(line): pass def create_offset(timestamp): pass def send_lin_iaw_time(timestamp, offset): pass if x == ord('1'): delay = 0 elif x == ord('2'): delay = 0.5 elif x == ord('3'): set_delay_real_time() timestamp = read_timestamp(line) offset = create_offset(timestamp) send_lin_iaw_server_time(timestamp, offset) else: print("bad choice, exiting") os.exit() That way, you express your intent in actual function names, which is vital to good code. You are exercising the discipline to think about what function to write at exactly the point where that's most important, i.e. at the point where the function is used. -- \ “To have the choice between proprietary software packages, is | `\ being able to choose your master. Freedom means not having a | _o__)master.” —Richard M. Stallman, 2007-05-16 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python 3.5 Question
Sasuke Uchiha writes: > Hi, I would like to know how to create a code similar to the result > below. Is this an assignment for you? We aren't a service to do homework. Can you show some code you have written to try solving the problem? We can discuss what you have already tried. You may also be interested in the Python Tutor forum https://mail.python.org/mailman/listinfo/tutor> which is specially focussed on collaboratively teaching Python beginners. -- \ “When I was born I was so surprised I couldn't talk for a year | `\and a half.” —Gracie Allen | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python 3.5 Question
Ben Finney writes: > You may also be interested in the Python Tutor forum > https://mail.python.org/mailman/listinfo/tutor> which is specially > focussed on collaboratively teaching Python beginners. Whoops, my apology! I failed to notice we are already in that forum :-) -- \ “He may look like an idiot and talk like an idiot but don't let | `\ that fool you. He really is an idiot.” —Groucho Marx | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python 3.5 Question
Mark Lawrence writes: > On 09/10/2015 16:47, Ben Finney wrote: > > Whoops, my apology! I failed to notice we are already in that forum > > :-) > > I simply had to roar with laughter at the signature you used for the > above as it just seemed so apt, nothing personal :) > > > \ “He may look like an idiot and talk like an idiot but don't let | > `\ that fool you. He really is an idiot.” —Groucho Marx | > _o__) | > Ben Finney > Yes. Good sigmonster, have a cookie! I don't pick the aphorisms, but I do get to see them before sending the message. I found it totally apt also :-) -- \ Fry: “Take that, poor people!” Leela: “But Fry, you’re not | `\ rich.” Fry: “No, but I will be someday, and then people like | _o__) me better watch out!” —Futurama | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] how to unittest cli input
Alex Kleider writes: > """ > I'm trying to follow a test driven development paradigm (using > unittest) but can't figure out how to test functions that collect > info from the command line such as the following. > """ > # collect.py > def collect_data(): > ret = {} > ret['first'] = input("Enter your first name: ") > ret['last'] = input("Enter your last name: ") > ret['phone'] = input("Your mobile phone #: ") > return ret To collect information from the command line, a program interrogates ‘sys.argv’. The example you show, rather, gets *interactive* input from the user. That's not command-line, so it's important to get the terminology right. You can write unit tests for this kind of function by making a “test double” for the ‘input’ function: an instrumented replacement (a “double”) that behaves exactly as you determine in the test case. One common way is to make a collection of data scenarios, and write test cases that use each scenario to set up the environment, call the function, and make one assertion about the result. import builtins import unittest import unittest.mock import testscenarios from .. import collect class collect_data_TestCase( testscenarios.WithScenarios, unittest.TestCase): """ Test cases for the `collect_data` function. """ scenarios = [ ('simple', { 'input_lines': [ "Lorem", "Ipsum", "+61 412 345 678", ], 'expected_result': { 'first': "Lorem", 'last': "Ipsum", 'phone': "+61 412 345 678", }, }), ('empty', { 'input_lines': [""] * 3, 'expected_result': { 'first': "", 'last': "", 'phone': ""}, }), ] def setUp(self): """ Set up test fixtures for the test case. """ # Perform setup from all superclasses. This ensures each # test case will get attributes assigned from the scenario. super().setUp() # Makes a ‘patcher’ to patch the ‘builtins.input’ # function, replacing it with an instrumented test double # (a MagicMock) that will return the next ‘input_lines’ # value each time it is called. func_patcher = unittest.mock.patch.object( builtins, "input", side_effect=self.input_lines) # Start the patcher (i.e. replace the real function) for # this test case. func_patcher.start() # Register the patcher's ‘stop’ (i.e. restore the original # function) as a clean-up action for this test case. self.addCleanup(func_patcher.stop) def test_returns_expected_result(self): """ Should return the result expected for the intputs. """ result = collect.collect_data() self.assertEqual(self.expected_result, result) The ‘testscenarios’ third-party library is recommended for data-driven tests https://pypi.python.org/pypi/testscenarios/>. It will, at run-time, create a separate test case for each test case function × each scenario defined for that function's class. All the produced test cases will run separately, identified by the test case method and the scenario name; and each one will fail or pass separately. This makes it very easy to test a matrix of assertions versus input/output expectations. The ‘unittest.mock’ library is part of the Python 3 standard library, and is good for creating powerful test doubles http://xunitpatterns.com/Test%20Double.html>. -- \ “Airports are ugly. Some are very ugly. Some attain a degree of | `\ugliness that can only be the result of a special effort.” | _o__) —Douglas Adams, _The Long Dark Tea-Time of the Soul_, 1988 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] how to unittest cli input
Alex Kleider writes: > Any comments about when/if to use 'if src != None:' vs 'if src is not > None:'? Express your intention in the code. If you want to express “is this value the ‘None’ singleton?”, compare identity with ‘is’/‘is not’. (This is what you almost always mean when comparing to ‘None’; I know of no useful exceptions to this.) If you want to express “is this value possibly different from ‘None’ but compares as equal?”, compare for equality with ‘==’/‘!=’. (As can be guessed from my description, I don't know of any good reason this would be preferred for ‘None’.) The distinction gets to the issue of object identity, as distinct from value equality. You don't need to know the details of that quite yet. Just know that you can choose whether to allow an object to declare it is equal to some other value, without actually being that same value. That's what you want in most comparisons (use ‘==’), but there is a large minority of comparisons where you instead want to know whether an object *is* some other object (use ‘is’). -- \“Pinky, are you pondering what I'm pondering?” “Wuh, I think | `\ so, Brain, but how will we get three pink flamingos into one | _o__) pair of Capri pants?” —_Pinky and The Brain_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
tutor@python.org
ਨਿਹੰਗ ਪੰਜਾਬੀ writes: > 'if (n & 1)' below works but I don't understand why/how. Kindly > help. Can you kindly help us understand your confusion? You chose a subject field that indicates why it works, so I don't know what your specific confusion is. -- \“Telling pious lies to trusting children is a form of abuse, | `\plain and simple.” —Daniel Dennett, 2010-01-12 | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] accessing modules found throughout a package?
James Hartley writes: > In my current project, I am developing a package. It makes sense to > embed tests throughout the package's directory structure as they > should be part of the package & its distribution. Yet, as you're finding, it also causes headaches. First, know that you don't need to scatter the test suite through out the rest of your code in order to meet the goal of including it in the distribution. You can distribute the test suite along with the rest, by specifying it as part of the source distribution. See the “manifest” for Distutils. To have your test suite run correctly when it's located separately from the system under test, you need to specify the top-level directory as being in the Python import path, during the test suite run. Then, you can have all the test suite modules do relative imports from that top level, to get the modules they need to import from the system under test. That way, the test suite imports modules the same way any other user of your code will import them: from the top level package. Look up “relative and absolute imports” to see how they work, and how they differ, in Python. > Any suggestions you may have will be very welcomed. I hope that helps. -- \ “Faith is generally nothing more than the permission religious | `\ people give to one another to believe things strongly without | _o__) evidence.” —Sam Harris, _Letter to a Christian Nation_ 2006 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] accessing modules found throughout a package?
Alex Kleider writes: > Should I add the following to the end of my ~/.bashrc file? > export PYTHONPATH="$PYTHONPATH:/home/alex/Py" No, because the entry should only be in PYTHONPATH *if* you want imports to come from that package. So the advice is: * For the run-time application, it should be installed using the Distutils system (‘python3 ./setup.py install’) and hence its modules will be available on the path as normal. That is, the normal operation of the code will *not* be to run it from the development working tree, so that path should not be in your normal PYTHONPATH. * THe ‘sys.path’ sequence is equivalent to the PYTHONPATH environment variable, and can be modified in your test suite's Python code as described elsewhere. But don't do that, because: * Python will automatically add a ‘sys.path’ entry for the directory containing the script named on the command line. So this: $ cd ~/Projects/lorem/ $ python3 ./setup.py test will run the ‘setup.py’ program with ‘sys.path’ already modified to contain the directory ‘/home/YOURUSERNAME/Projects/lorem’. Any packages in that directory are available for absolute import, *during* that test suite run. * For this reason (and others), it's recommended to have ‘setup.py’ at the top level of your working tree. Put all the other Python code in packages and modules importable from the same location as ‘setup.py’, and run ‘setup.py’ from that directory to allow the ‘sys.path’ modification to work as expected. -- \ “Alternative explanations are always welcome in science, if | `\ they are better and explain more. Alternative explanations that | _o__) explain nothing are not welcome.” —Victor J. Stenger, 2001-11-05 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] accessing modules found throughout a package?
Ben Finney writes: > * Python will automatically add a ‘sys.path’ entry for the directory > containing the script named on the command line. So this: > > $ cd ~/Projects/lorem/ > $ python3 ./setup.py test > > will run the ‘setup.py’ program with ‘sys.path’ already modified to > contain the directory ‘/home/YOURUSERNAME/Projects/lorem’. Any > packages in that directory are available for absolute import, *during* > that test suite run. This behaviour is detailed further in the documentation https://docs.python.org/3/using/cmdline.html#using-on-interface-options>. -- \ “The way to build large Python applications is to componentize | `\ and loosely-couple the hell out of everything.” —Aahz | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Working collaboratively (was: accessing modules found throughout a package?)
Alex Kleider writes: > I'm a long way from distributing packages! You can keep working at your own pace, and that's good. But even better, I would strongly recommend that you work with other people early and frequently. Programming is fundamentally a process of collaboration and communication with other human programmers. The habits you form alone can be eccentric and unhelpful, with no-one to comment on strange habits you may be forming without even noticing until they are too deeply entrenched to easily avoid. Working frequently with others on the same code base will not only flush out these oddities, but also help you to appreciate the consensus decisions made in the past by the Python community as a whole. So, while it's not essential, I would heartily encourage you to pick some of the PyPI projects you are enjoying, or want to improve, and contact their maintainers with your offer to fix specific things. Work with other Python programmers on a common code base, and watch your skills broaden and improve! -- \ “For man, as for flower and beast and bird, the supreme triumph | `\ is to be most vividly, most perfectly alive” —D.H. Lawrence | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Create complex dictionary
jarod_v6--- via Tutor writes: > Hi!!I would like to prepare a dictionary with complex structure: > > complex = {name ="value",surname="po",age=poi) That's invalid syntax (the braces don't match) and it seems to use names from elsewhere. If you mean a dictionary like this:: wibble = {'name': "value", 'surname': "po", 'age': 42} then that is a simple dictionary. So I don't know what you mean by a “complex” dictionary. > What is the most pythonic way to build a dictionary of > dictionary? You can assign any value to any key in a dictionary. Dictionaries are also values, so a dictionary can be assigned to a key just like any other value can be assigned to a key. wobble = { 'name': "Lorem Ipsum", 'age': 42, 'ratings': { 'badminton': 17.48, 'celery': None, 'fussball': 0.14, }, 'address': "175 West Arglbargle, Lower Snootbatten", } That has values that are themselves containers, so I suppose it counts as a “complex” dictionary. -- \ “I went to the museum where they had all the heads and arms | `\ from the statues that are in all the other museums.” —Steven | _o__) Wright | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] noob python question
bob5487 writes: > Reading *Learn Python the Hard Way* Zed Shaw > > All good so far but got to Ex 42 dealing with classes... Can you give a URL to the exact code so that we can know we're seeing the same thing that you are? > I get a TypeError: getattr(): attribute name must be a string when I > run the program... Please show the full text of the traceback, and preferably the code you ran which led to that error. -- \ “The WWW is exciting because Microsoft doesn't own it, and | `\ therefore, there's a tremendous amount of innovation | _o__) happening.” —Steve Jobs | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] super and __init__ methods
Sunil Tech writes: > Thanks I got it. Thanks for telling us! You should know that ‘super’ is a topic that confuses even quite experienced Python programmers. It is good to encounter this early, when you can learn about it. See the article “Python’s super() considered super!” https://rhettinger.wordpress.com/2011/05/26/super-considered-super/> by Raymond Hettinger, for a good guide to this interesting feature. -- \“A free press is one where it's okay to state the conclusion | `\ you're led to by the evidence.” —Bill Moyers | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] interface
Alex Kleider writes: > I'd be interested in any comments regarding this idea and would be > grateful for any suggestions as to frameworks that might be helpful. The collected wisdom of the community includes this page at the Python wiki https://wiki.python.org/moin/GuiProgramming>, and a brief comparison of toolkits is at https://wiki.python.org/moin/GUI%20Programming%20in%20Python>. > I've been looking at django but finding the learning curve to be steep > and it may not be the best solution. That seems a reasonable assessment; if you just want a UI for a not-particularly-website program, Django may be a poor fit. > Of late I've been using Python3; my platform is Ubuntu 14.4. I recommend you start with the default, heavily-documented Tkinter https://docs.python.org/3/library/tkinter.html> and the Ttk extension https://docs.python.org/3/library/tkinter.ttk.html>. Both of these are part of the Python 3 system in Ubuntu. You can find a good guide to Tk programming in Python as one stream of the excellent http://www.tkdocs.com/>. -- \“If you have the facts on your side, pound the facts. If you | `\ have the law on your side, pound the law. If you have neither | _o__) on your side, pound the table.” —anonymous | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] interface
Alex Kleider writes: > Thank you, gentlemen (Alan, Ben, Mark,) for your advice. > The consensus seems to be in favour of tkinter > so I'll head in that direction. Keep in mind that Tkinter is the “one obvious way to do it” for GUIs in Python. It is the general-purpose toolkit included with the standard library. There are other ways (i.e. other GUI toolkits for Python) that may be better suited to your specific case, but are not the obvious general default — and they impose a higher deployment burden because they are third-party libraries. So, start with Tkinter and get it working that way. Then, once you better understand your specific case by making a working solution, you can re-assess. Tkinter might be just fine, or you may want to try others. But start with Tkinter, yes. -- \ “It seems intuitively obvious to me, which means that it might | `\ be wrong.” —Chris Torek | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] interface
Alex Kleider writes: > On 2015-12-18 14:13, Mark Lawrence wrote: > > On 18/12/2015 18:38, Alex Kleider wrote: > > >> […] uses a syntax that is strongly discouraged Yes. It is discouraged in PEP 8 and in other guides for Pythonic code. Wildcard imports ( from import * ) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. https://www.python.org/dev/peps/pep-0008/#id17> For all new Python code, that should IMO be strongly enforced. > >> so my inclination is to use > >> import tkinter as tk > >> from tkinter import ttk > >> instead. > >> > >> Comments? I agree with that usage. ‘import inconvenientlongname as shortname’ is excellent code that combines the virtues of being explicit, concise, readable, and easily-introspected. > > from xyz import * is The Road To Hell. > > Vindicated! Note that the Python standard library documentation for Tkinter explicitly contradicts PEP 8 advice: […] usually, to use Tkinter all you need is a simple import statement: import tkinter Or, more often: from tkinter import * https://docs.python.org/3/library/tkinter.html#tkinter-modules> This is one of many cases where conventions have resolved after some significant code (and documentation) violating the convention entered the standard library. So, it is an uncomfortable fact that Python's Tkinter recommends un-Pythonic idioms — and that will likely remain the case. I applaud attempts to carve out an ever-increasing space where the more Pythonic idiom ‘import tkinter as tk’ is enforced. Be aware, though, that there is a lot of existing code – most of which shouldn't be changed only to fix this – which violates that idiom. -- \ “If we don't believe in freedom of expression for people we | `\ despise, we don't believe in it at all.” —Noam Chomsky, | _o__) 1992-11-25 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File reading-(encoding problems)
Ratheesh kumar writes: > Here is my code..try: > data=open('info.txt') […] Please be sure to present the code as distinct lines. You have posted it as plain text (good), the indentation is preserved (good). The problem here is that your commentary is mingled with the program code, so that it's difficult to see where the program begins and ends. > Man said: No you haven't! > Other Man said: Yes I have.The characters "" got added to the > contents of my file in the beginning. And again here, you've somehow got your commentary stuck directly onto the output example. Please be sure to use one empty line to surround any code examples or output examples. > Later identified it as a encoding problem. I cleared the problem by > adding the encoding arguments when opening the file( > data=open('info.txt',encoding='utf-8-sig')).Now my question is each > time do I have to make this change or is there away to make this > encoding a default one? Yes, you need to specify the encoding of text, when you input or output that text as bytes (e.g. in a file). Representing text as bytes is done with a text encoding, and you must be explicit about that encoding because guessing the encoding leads to heartache. Your use of an explicit encoding in that program is correct. -- \“I took it easy today. I just pretty much layed around in my | `\underwear all day. … Got kicked out of quite a few places, | _o__) though.” —Bug-Eyed Earl, _Red Meat_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using python 3 on Ubuntu 14.04
Jim Byrnes writes: > If I simply start it with python passwords.py it runs fine. If you type ‘python --version’ and ‘python3 --version’ you will see two different version numbers. Different versions of Python have their own separate run-time environments. Any modules you want a particular Python interpreter to import, must be installed specifically for that interperter to find. > There is no need to use python 3 on this particular program but if I > wanted to write for python 3 in the future what do I need to do to run > programs with it? You need to install the Python 3 modules for the correct Python 3 version. -- \“It is undesirable to believe a proposition when there is no | `\ ground whatever for supposing it true.” —Bertrand Russell, _The | _o__) Value of Scepticism_, 1928 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using python 3 on Ubuntu 14.04
Jim Byrnes writes: > Thanks for all the info guys. I got myself confused because I thought > that python 3 was the default for Ubuntu 14.04, but it is just > installed by default. Even if that were true, the ‘python’ command will likely still invoke a Python 2 interpreter. Most systems that install a Python 3 interpreter will install the command as ‘python3’. > I realize now that the modules need to be installed in the proper > environment. That also remains true when Python 3 is the default. > I know Pythoncard is not maintained any more. I have one program I > wrote using it that I use often so I wanted to see it worked on 14.04. > It will be a good learning experience to rewrite it for python 3 using > something else. Have you considered using Python 3 and the standard Tkinter tookit? https://docs.python.org/3/library/tkinter.html> https://docs.python.org/3/library/tkinter.ttk.html> http://www.tkdocs.com/> -- \ “I’ve been an atheist ever since I heard there was only a | `\ stairway to heaven.” —Stella Young, 1982–2014 | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] s.insert(i, x) explanation in docs for Python 3.4 confusing to me
boB Stepp writes: > So in this model of understanding negative list indexing, should it be: > > mylist = [ 100, 200, 300, 400, 500 ] > ^^^^^ ^ > -5 -4 -3 -2 -1 ? For completeness, let's use the rest of the integers also:: 012345 ↓↓↓↓↓↓ mylist = [ 100, 200, 300, 400, 500 ] ↑↑↑↑↑↑ −5 −4 −3 −2 −1? > But in this model, what should go in the place of "?"? You can use ‘len(mylist)’ for the index at the end of the sequence. There isn't a negative number which will address that position; it isn't needed, because there is already one obvious way :-) -- \“Without cultural sanction, most or all of our religious | `\ beliefs and rituals would fall into the domain of mental | _o__) disturbance.” —John F. Schumaker | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Source of MySQL Command Interpreter
Ricardo Martínez writes: > Hi, i wrote a small APP to execute MySQL commands and retrieve to a Treeview > > Share your comments and upgrades. You're addressing this to the wrong forum. If you want to discuss code, please post *small, complete* samples of code directly here in the forum and ask specific questions. Large code bases are not appropriate here; we are better geared to discussing specific problems and concepts. Links to code elsewhere are not appropriate here; this forum is geared to discussing the code in context with the messages. So please keep code examples small, and put them in your message for discussion. -- \ “I call him Governor Bush because that's the only political | `\ office he's ever held legally.” —George Carlin, 2008 | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Console application
Ali Moradi writes: > Hi, i don't have any clue how to write a console program that shows a > list of options which could be chosen with keyboard and when one item > was selected, a text shows there. A text shows where? Shows at the point of input, at the point of the option, at some other point? > I want to know, which things i need to write a program like that? I think you might want to address specific points in the grid of characters on the terminal. That's specific to each operating system, so you'll need an API which knows how to tell the terminal what you mean. The Python standard library includes such an API in the ‘curses’ library https://docs.python.org/3/library/curses.html>. Try using that and see whether it meets your needs. -- \“Telling pious lies to trusting children is a form of abuse, | `\plain and simple.” —Daniel Dennett, 2010-01-12 | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] s.insert(i, x) explanation in docs for Python 3.4 confusing to me
Alex Kleider writes: > May I trouble you further by specifically asking about 's/nor/not/'- I > don't get what that's about. He's using a common editor syntax (the ancient ‘ed’ editor's “substitute” command, which is inherited by Unix ‘sed’ and ‘vi’, among others) to represent “please replace the text ‘nor’ in that line, with the text ‘not’ instead”. -- \ “Do I believe in God? … without clarification of a kind I have | `\never seen, I don’t know whether I believe or don’t believe in | _o__)whatever a questioner has in mind.” —Noam Chomsky | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Should a "data" directory have a __init__.py file?
boB Stepp writes: > I can see no reason why I would need an __init__.py file for a data > directory. Yes, files will be read there, but there will be no code > there. Is this correct? That is correct. A directory of files is accessed just fine using the normal filesystem access features. What's more, I would say that if a directory is not positively intended to be a Python package, that directory *should not* contain any ‘__init__.py’ file. The module import system will only recognise a directory as a “package” (Python's technical term for “a point in the import hierarchy which contains other things to import”) if that directory contains a file named ‘__init__.py’. If you do not need the directory to also be recognised as a package, it should not have such a file. See https://docs.python.org/3/reference/import.html#packages> for the full details of how Python recognises and uses packages in the import system. Also be aware Python's use of “package” conflicts with the broader computing use of that term (“a unit of software to install on the operating system”); but it's too late to change either of them, unfortunately. -- \“The deepest sin against the human mind is to believe things | `\ without evidence.” —Thomas Henry Huxley, _Evolution and | _o__) Ethics_, 1893 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] An Advice to a dedicated beginner
Alan Gauld writes: > On 19/01/16 01:15, Michael Appiah Boachie wrote: > > I am a programming beginner. ... > > when i sat on my own with a couple of materials and videos, > > I have become very good at the basics of python and > > completing various beginner courses and projects with ease > > but however I have run into some kind of “beginner wall” > > where I don’t know where or what to take on next. > > The first thing to do is to find a concept or project > that you want to build. We can't really help you with > that, it has to come from you. But maybe there is a > routine task you perform that you could automate? That's a worthwhile recommendation. I usually recommend something different: Pick an *existing* code base that you're already using – Python is used in a great many tools that you probably rely on, so this shouldn't be difficult – and get the source code. Find small improvements to make, discuss them with peers and on this forum, and with the developers of that code base. Making small improvements to something you already use will avoid the “blank slate” paralysis from having too many options be motivational, while also being very motivational: you already can think of improvements you would like to make, and getting them implemented will be very satisfying. It also focusses on an often-dismissed aspect of learning to program: you need to program *with other people*, and your code is a means of communicating with those people. Learning how to do that, and learning (by doing) that there is no shame in starting small and unskilled, is a necessary part of the craft. -- \ “The long-term solution to mountains of waste is not more | `\ landfill sites but fewer shopping centres.” —Clive Hamilton, | _o__)_Affluenza_, 2005 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is the name "self" optional instead of mandatory?
boB Stepp writes: > So I really only have one question: Why not make Python's > *traditional* name, "self", mandatory? Why give the programmer this > kind of choice? For the same reason that four-space indentation is not mandatory, yet anyone who chooses a different indentation size needs to produce good reasons why. In both cases: Because nothing is broken, nor made especially ambiguous, by choosing differently. And because the Python community of programmers can be relied upon to enforce the convention, as with most other conventions. -- \ “When I was a little kid we had a sand box. It was a quicksand | `\ box. I was an only child... eventually.” —Steven Wright | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why do I not get an error when I mistakenly type "humdrum.sigh_strenght" instead of the correct "humdrum.sigh_strength"?
boB Stepp writes: > My intent was to deliberately introduce an error into my class definition: > > >>> class Hmm(object): > def __init__(self, sigh_type, sigh_strength): > self.sigh_type = sigh_type > self.sigh_strength = sigh_strength > def snort(self): > if self.sigh_strength == 'low': > print("snort") > elif self.sigh_strength == 'med': > print("Snort!") > elif self.sigh_strenght == 'high': > print("SNORT!!!") > else: > print("Hmm...") > def sigh(): > if self.sigh_type == 'quiet': > print("pss") > elif self.sigh_type == 'annoying': > print("Whoosh!") > elif self.sigh_type == 'loud': > print("HEAVY SIGH!!!") > else: > print("HMM!!!") > > I omitted "self" from the sigh() method to see what would happen What would happen, when? At the time of class definition, there are no errors that I can see. Python doesn't run every possible branch of your code ahead of time, just to find out what it will do. Most errors will be discovered only by encountering the combination of inputs that will trigger them at run time. For this and other reasons, it is highly recommended to develop unit tests with your code, to make explicit assertions about exactly what will trigger each branch of the code. This, in turn, will lead to making your code simpler and less-branching :-) -- \ “Do unto others twenty-five percent better than you expect them | `\ to do unto you. (The twenty-five percent is [to correct] for | _o__)error.)” —Linus Pauling's Golden Rule | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an OrderedDict not sliceable?
Albert-Jan Roskam writes: > Why is an OrderedDict not sliceable? Because slicing implies index access. The built-in ‘dict’ and ‘collections.OrderedDict’ both do not support indexed access:: >>> import collections >>> foo = collections.OrderedDict([ ... ('a', 1), ('b', 2), ('c', 3), ('d', 4)]) >>> foo[3] Traceback (most recent call last): File "", line 1, in KeyError: 3 >>> bar = dict([ ... ('a', 1), ('b', 2), ('c', 3), ('d', 4)]) >>> bar[3] Traceback (most recent call last): File "", line 1, in KeyError: 3 Index access with ‘foo[index]’ syntax, and slicing with ‘foo[start_index:stop_index:step]’ syntax, collide with the existing key-access meaning of ‘foo[key]’ for a mapping. -- \ “[I]t is impossible for anyone to begin to learn that which he | `\thinks he already knows.” —Epictetus, _Discourses_ | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an OrderedDict not sliceable?
Oscar Benjamin writes: > According to a narrow definition of indexed access. I would say that > d[k] is index access even if d is a dict and k a key. An index implies the ordinal position in a sequence. In a mapping, the key is *not* referring to the position in a sequence, so is not a key. So accessing an item in a mapping by key is not indexed access. -- \ “When we pray to God we must be seeking nothing — nothing.” | `\—Francis of Assisi | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an OrderedDict not sliceable?
Ben Finney writes: > Oscar Benjamin writes: > > > According to a narrow definition of indexed access. I would say that > > d[k] is index access even if d is a dict and k a key. The sense of “index” implied is used consistently throughout Python https://docs.python.org/3/glossary.html> to refer to the integer ordinal position in a sequence. It is not compatible with key access into a mapping. > An index implies the ordinal position in a sequence. In a mapping, the > key is *not* referring to the position in a sequence, so is not a key. “the key … is not an index”, I mean. > So accessing an item in a mapping by key is not indexed access. -- \ “Facts do not cease to exist because they are ignored.” —Aldous | `\Huxley | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to call the path of an input file
John Villarraga writes: > I would like to know what is the syntax to call the path of the input > file. It's not clear to me what “call the path of the input file” would mean. A filesystem path is not “callable” in a programming as you seem to be using it. > Below, my code is calling the input file, but not the path. Can you please ensure your messages are plain text (not re-formatted or marked up), to help your program code survive unmolested. -- \ “Men never do evil so completely and cheerfully as when they do | `\it from religious conviction.” —Blaise Pascal (1623–1662), | _o__) Pensées, #894. | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How do I test file operations (Such as opening, reading, writing, etc.)?
boB Stepp writes: > I don't want to mess with what will become the program's *real* > classifiers.txt (And other needed text files to come, that will > likewise be editable.), so how do I simulate these various needed file > operations in a way that tests the actual program code, but without > touching the actual data files? This is a common requirement: you want to test using fake filesystem entries, but *only* for certain filesystem entries. Other filesystem access should go through to the real filesystem as normal. > I was looking at "How to Mock Python's `open` function" at > http://www.ichimonji10.name/blog/6/, which looks potentially > promising, but looks complicated. Not only that, but filesystem access is especially problematic for running unit test suites: the invocation of test cases will itself often require real access to the filesystem, so fiddling with that inside your test case will make test failures much more difficult to debug. Common solutions include “ehhh, don't bother making test doubles for the filesystem then”, or “let the tests access loads of real files and hang the drain on speed”, or other unsatisfactory compromises. Would you – would other readers here – be sufficiently interested to work with me on refining a small library I wrote to address this problem? I haven't yet created a published project for it, but it would probably benefit from real-world use in more than the single code base I needed it for. If I could know there will be several people benefiting and providing feedback, that would be motivation to work on it further. -- \ “An expert is a man who has made all the mistakes which can be | `\ made in a very narrow field.” —Niels Bohr | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] [ANN] Gajja 0.1 (was: How do I test file operations (Such as opening, reading, writing, etc.)?)
Ben Finney writes: > I have today published a different approach, which I designed for one > code base ad is to date its only user. I'm looking for more feedback. > > https://pypi.python.org/pypi/gajja/> I forgot to mention the appropriate channels for feedback: Please contact me at if you have feedback on this, or report an issue at the project's homepage https://notabug.org/bignose/python-gajja>. You can also discuss this on the thread I've opened at the main Python forum https://mail.python.org/mailman/listinfo/python-list>. -- \ “That's all very good in practice, but how does it work in | `\ *theory*?” —anonymous | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How do I test file operations (Such as opening, reading, writing, etc.)?
"Martin A. Brown" writes: > Option A (tempfile): > > Create a directory and copy your pristine tree into the directory > and make the base directory for the important data files > configurable. Also known as parameterization. I consider that a poor option; real files complicate the test setup and cleanup, they are always going to be slower, and they can lead to false positives and false negatives in the test results. All of those will act as a disincentive to add lots of unit tests for filesystem-related areas of your code; and I think that's a disincentive we don't need. > Option D (use StringIO): > > If you are less concerned about filesystem interactions and really > just want an individual thingy that that behaves like a file, but > can be constructed in memory, use StringIO (or cStringIO). These are great if you can get away with them. But many programs use not just file objects, but also interrogate the filesystem: they use `os.stat`, `os.path.exists`, builtin `open`, etc. We need to be able to control not only the in-memory file objects, but the filesystem access for our fake files that don't actually exist on the real filesystem. > Option C (use pyfakefs): > > Use pyfakefs, which acts like a filesystem for testing purposes. > https://pypi.python.org/pypi/pyfakefs > https://github.com/jmcgeheeiv/pyfakefs I have today published a different approach, which I designed for one code base ad is to date its only user. I'm looking for more feedback. https://pypi.python.org/pypi/gajja/> See the ‘doc/tutorial.txt’ for a worked example of how it can be useful. (and I'm still writing more documentation for general use.) -- \ “I do not believe in immortality of the individual, and I | `\consider ethics to be an exclusively human concern with no | _o__) superhuman authority behind it.” —Albert Einstein, letter, 1953 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How do I test file operations (Such as opening, reading, writing, etc.)?
Alan Gauld writes: > File simulation is faster and fine for unit testing functionality, > but not so good for testing the overall system. Yes, I'm only advocating fake files for unit tests which, more than all other kinds of tests, need to be fast and numerous. For testing larger parts of the system than a single code unit, real files are better. But likewise, there should be fewer tests (because complete-coverage unit tests should be much more numerous) so the slower performance is not so much a problem. -- \“I got fired from my job the other day. They said my | `\ personality was weird. … That's okay, I have four more.” | _o__) —Bug-Eyed Earl, _Red Meat_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why define a function inside a function?
Ryan Smith writes: > In trying to understand the logic behind the code for my own > edification, I was wondering what is the reasoning of defining a > function in side another function (for lack of a better phrase)? Sometimes a function is so specific to the workings of another function that it would not make sense outside that context. Other times, the information needed to define the function – for example, a default value for one of the parameters – may be dynamically determined within the enclosing function. The statement defining the inner function would not work without that context. Yet other times, the inner function may be simpler to express by making use of the enclosing scope of the outer function. Names in the enclosing function can be referenced in the inner function, without needing to formally pass them as parameters. Defining the function at the point of its use keeps the code readable, and keeps the function simpler. Lastly, functions themselves are objects like any other in Python. Defining one function inside another, and then using the defined function object as a value to pass on for further processing, is a paradigm known as “functional programming” which Python has good support for. This is how it's done. -- \“Like the creators of sitcoms or junk food or package tours, | `\ Java's designers were consciously designing a product for | _o__) people not as smart as them.” —Paul Graham | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File extension change
Chelsea G writes: > import csvimport jsonimport sysimport osfrom collections import > defaultdictfrom collections import Counter Your email client has, probably without your consent, mangled the content of your message. Please ensure your email client does not attempt to apply pretty formatting. Set it explicitly to send messages as “plain text” only, so your deliberate code formatting will not be mangled. -- \ “Capitalism is the astounding belief that the most wickedest of | `\men will do the most wickedest of things for the greatest good | _o__) of everyone.” —John Maynard Keynes | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] date range
Chelsea G writes: > So I am taking in a csv file with several rows and one of those rows > in a date row. That doesn't make much sense, as a sepcification. CSV is by design a data format in which every data row has the same structure: the fields always have the same meaning, in the same order. > I am trying to see if I can read in a csv file and search for a > certain date range like 1/2/2016 to 1/5/2016. You can, by breaking the problem into simpler problems: * Get the rows into some collection of structured records. (The Python standard library's ‘csv.DictReader’ is your friend here.) * Identify which field of the record is the data on which you want to filter. (For a collection of records you retrieved from reading a ‘csv.DictReader’, you need to know which field name has the dates you're interested in.) * Construct an expression that takes an arbitrary date value as found in that field, and interrogates it by some comparison that evaluates to True when the value is in your specified range and False otherwise. * Construct a new collection of records, by iterating the full collection and only accumulating the ones which match your criteria. Each of those is much simpler that the original problem. Solve each of them separately, and it should then be much easier to put the solutions together to solve the larger problem. -- \ “Friendship is born at that moment when one person says to | `\another, ‘What! You too? I thought I was the only one!’” —C.S. | _o__) Lewis | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to write tests for main() function that does not return anything
Steven D'Aprano writes: > I think the right answer is that testing main() is *not* a unit test, > it's an integration test. You're testing that the application as a > whole works the way you expect, rather than testing individual units > of the application (functions, class, methods, modules). Alternatively, if you can define what ‘main’ should do in isolation from the rest of the program, then you *can* test it in unit tests. That requires designing ‘main’ such that you can explicitly describe its interactions with the rest of the program; inputs, outputs, side effects, expected behaviour when any of them change. That exercise may lead you to conclude “wow, this actually does quite a lot and it's difficult to describe” — and then it's a short step to realising you should re-design the function so it has a more narrow specification :-) -- \“The idea that He would take his attention away from the | `\ universe in order to give me a bicycle with three speeds is | _o__) just so unlikely that I can't go along with it.” —Quentin Crisp | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Enumerate vs DictReader object manipulation:
Ek Esawi writes: > I have a code that reads a csv file via DictReader. I ran into a peculiar > problem. The python interpreter ignores the 2nd code. That is if I put the > reader iterator 1st, like the code below, the enumerate code is ignored; if > I put the enumerate code 1st, the reader code is ignored. You have discovered the difference between an iterable (an object you can iterate over with ‘for’), versus a sequence (an object whose items remain in place and can be iterated many times). Every sequence is an iterable, but not vice versa. File objects are iterables, but not sequences. Each time you ask for the next item, you can't ask the file object for that item again; it is “consumed” by the act of iteration. -- \ “When I was little, my grandfather used to make me stand in a | `\ closet for five minutes without moving. He said it was elevator | _o__)practice.” —Steven Wright | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Enumerate vs DictReader object manipulation:
Alex Kleider writes: > How does a dict fit into this scheme? > Is it a sequence? No, a dict is not a sequence. But it is a container: all its items remain available and can be retrieved again and again, and you can interrogate whether a value is one of the items in that container. An instance of the built-in ‘set’ type is also a container and not a sequence. Containers are iterable too. > It is an iterable (in that for key in d: works although not in a > predictable manner and for this reason I tend NOT to think of it as a > sequence.) That's right, IMO. -- \ “The generation of random numbers is too important to be left | `\to chance.” —Robert R. Coveyou | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Syntax for list comps
Johan Martinez writes: > Where can I find syntax for list comps? The same place as other syntax descriptions: in the language reference https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries>. > I am confused how/whether they are evaluated left-right or right-left. According to the documentation: […] the elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached. > That's a bit confusing syntax for me. Sorry if I am not clear in > explaining it. Does that help? If not, please try re-phrasing the question. -- \ “The lift is being fixed for the day. During that time we | `\regret that you will be unbearable.” —hotel, Bucharest | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] recursion
noopy via Tutor writes: > But when "for cc in permutations([])" yields an empty list, why does > "for cc in permutations("Z")" then actually have an item so that > "yield [items[i]]+cc" will be executed? Does this help:: >>> i = 1 >>> "Z"[:i] + "Z"[i+1:] 'Z' Can you explain why that would be the case? -- \ “I think a good gift for the President would be a chocolate | `\ revolver. And since he's so busy, you'd probably have to run up | _o__) to him real quick and hand it to him.” —Jack Handey | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] recursion
Alan Gauld writes: > On 05/02/16 02:03, noopy via Tutor wrote: > > > def permutations(items): > > n = len(items) > > if n==0: yield [] > > else: > > I assume this bit is clear enough? I think it would be clearer without the needless opaque name ‘n’. Better:: def permutations(items): if not items: # ‘items’ is empty (or is not a container). yield [] else: for i in range(len(items)): … Binding a name that is used exactly once should be done only if the name clarifies the purpose. An opaque name like ‘n’ is not helpful. -- \ “Why doesn't Python warn that it's not 100% perfect? Are people | `\ just supposed to “know” this, magically?” —Mitya Sirenef, | _o__) comp.lang.python, 2012-12-27 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Mock filesystem operations only for specific test doubles (was: mock file reader object)
Anshu Kumar writes: > I need to mock file reader object , i tried using > @patch('__builtin__.open') but it will patch my all file open readers. For this reason I have written and published the Gajja library https://pypi.python.org/pypi/gajja/>. Its FileDouble objects will allow fine-grained control over exactly which file accesses are mocked, leaving the rest to behave normally. To date it is only used in one code base. I would be pleased to receive feedback either to my email address or at the “testing in Python” forum http://lists.idyll.org/listinfo/testing-in-python>. -- \ “I never forget a face, but in your case I'll be glad to make | `\ an exception.” —Groucho Marx | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] library terminology and importing
street.swee...@mailworks.org writes: > I get an error if I try > > from datetime.datetime import now, strftime ‘datetime.datetime’ is not a module, so you can not import objects from it. > But if I import all of os and datetime, I can use those functions by > writing the full 'path' 3 levels deep: > > os.path.expanduser('~') > datetime.datetime.now() Yes. That's a good way to do it, because it makes your code explicit and clear to read. > Is there a way to import individual functions from datetime.datetime? Don't try to do that. Namespaces are a honking good idea in Python, you should not seek to avoid them. -- \ “I may disagree with what you say, but I will defend to the | `\death your right to mis-attribute this quote to Voltaire.” | _o__) —Avram Grumer, rec.arts.sf.written, 2000-05-30 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Recommendations for best tool to write/run Python
Lisa Hasler Waters writes: > Could you please recommend the best Python tools for writing and > running our code for the long term? How much of a learning curve are you willing to accept? The best tools for the long term are inevitably those which require some investment of time to learn. -- \ “Unix is an operating system, OS/2 is half an operating system, | `\Windows is a shell, and DOS is a boot partition virus.” —Peter | _o__)H. Coffin | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Recommendations for best tool to write/run Python
Lisa Hasler Waters writes: > Ben, in terms of time for learning curve, I suppose we do have some > limitations as we are up against school schedules. However, if it is > something I could learn in a reasonable time that I could then more > quickly walk my students through then I'd be up for the challenge! In that case, my recommendation is to learn a good programmer's editor, and let your students gain exposure to that. Emacs and Vim are the unchallenged masters here; community-owned, free-software, cross-platform, mature and highly flexible with support for a huge range of editing tasks. Learning either of those will reward the student with a tool they can use broadly throughout whatever computing career they choose. They aren't a small investment, though. That “mature” comes at the cost of an entire ecosystem that evolved in decades past; concepts and commands are idiosynratic in each of them. It is highly profitable for any programmer to learn at least one of Emacs or Vim to competence, but it may be too much to confront a middle-school student in limited class time. Maybe let the class know they exist, at least. Short of those, I'd still recommend a community-owned, free-software, highly flexible programmer's editor. If you're on GNU+Linux, use the Kate or GEdit editors; they integrate very nicely with the default desktop environment and are well-maintained broadly applicable text editors. GEdit in particular has good Python support. I would recommend staying away from any language-specific IDE. Teaching its idiosyncracies will still be a large time investment, but will not be worth it IMO because the tool is so limited in scope. Better to teach a powerfuly general-purpose programmer's editor, and use the operating system's facilities for managing files and processes. -- \“Humanity has advanced, when it has advanced, not because it | `\ has been sober, responsible, and cautious, but because it has | _o__)been playful, rebellious, and immature.” —Tom Robbins | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Recommendations for best tool to write/run Python
Ben Finney writes: > Short of [the heavyweights Vim and Emacs], I'd still recommend a > community-owned, free-software, highly flexible programmer's editor. > If you're on GNU+Linux, use the Kate or GEdit editors; they integrate > very nicely with the default desktop environment and are > well-maintained broadly applicable text editors. GEdit in particular > has good Python support. In particular, when teaching students, please steer them away from proprietary software, regardless of price. Non-free software such as Sublime Text, PyCharms, Wing IDE, and the like, sometimes have a zero-dollar license, but your students should not be encouraged to use tools they are forbidden to learn about and share. In education, please use free-software tools – that is, software with license to inspect, modify, and share the changes – so your students can learn at any level their interest takes them. -- \ “What I resent is that the range of your vision should be the | `\ limit of my action.” —Henry James | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Recommendations for best tool to write/run Python
Ben Finney writes: > In that case, my recommendation is to learn a good programmer's > editor, and let your students gain exposure to that. > > Emacs and Vim are the unchallenged masters here […] > > They aren't a small investment, though. […] it may be too much to > confront a middle-school student in limited class time. Maybe let the > class know they exist, at least. > > Short of those, I'd still recommend a community-owned, free-software, > highly flexible programmer's editor. I have never used Atom https://atom.io/>, but it meets the criteria I would recommend. It is free software, community owned, has support for a broad variety of contemporary editing tasks, is cross-platform. On top of that it has advantages over Vim and Emacs: its terminology matches what today's computer users expect; it is written in and extensible with a commonly-used programming language; it UI is designed to match contemporary user expectations. The few reservations I have – it is not yet mature enough to have support for pretty much every editing tasks; it does not appear to have a text console mode (for use across an SSH link); it is presently dominated by a single corporation – should not stop you from presenting it to your students as a fine programmer's editor for their future. -- \ “Not using Microsoft products is like being a non-smoker 40 or | `\ 50 years ago: You can choose not to smoke, yourself, but it's | _o__) hard to avoid second-hand smoke.” —Michael Tiemann | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Recommendations for best tool to write/run Python :p:
Lisa Hasler Waters writes: > Thanks to everyone for such great tips/advice! Feel free to write about your actual experience with choosing and teaching your students a tool, and let the Python forum know it https://www.python.org/community/lists/#comp-lang-python>. I for one would be very interested to see that. -- \ “Pinky, are you pondering what I'm pondering?” “I think so, | `\Brain, but don't you need a swimming pool to play Marco Polo?” | _o__) —_Pinky and The Brain_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why does 01 give a syntax error, but 00 (or 00...0) does not?
boB Stepp writes: > >>> 01 > File "", line 1 > 01 > ^ > SyntaxError: invalid token As you later explain, this is because in Python 3 the obsolete “leading 0 for octal notation” is invalid syntax. (Superseded by “leading ‘0o’ for octal notation”). > >>> 00 > 0 > >>> -00 > 0 > >>> 000 > 0 > > Why do zeros not give a syntax error, but other numbers with a leading > zero do give a syntax error? Hmm. That is a confusing inconsistency, I agree. It is deliberate, and explicitly documented: Note that leading zeros in a non-zero decimal number are not allowed. This is for disambiguation with C-style octal literals, which Python used before version 3.0. https://docs.python.org/3/reference/lexical_analysis.html#integer-literals> which does not explain why “non-zero decimal number” was chosen, rather than simply any decimal number. > But then why is 00...0 valid, that is, does not give a syntax error? At one level, the answer is: because the language reference declares those rules for the syntax. At another level, the answer is: I don't know why that decision was made, and on the face of it I disagree. -- \“But it is permissible to make a judgment after you have | `\examined the evidence. In some circles it is even encouraged.” | _o__)—Carl Sagan, _The Burden of Skepticism_, 1987 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why does 01 give a syntax error, but 00 (or 00...0) does not?
Ben Finney writes: > Hmm. That is a confusing inconsistency, I agree. It is deliberate, and > explicitly documented: > > Note that leading zeros in a non-zero decimal number are not > allowed. This is for disambiguation with C-style octal literals, > which Python used before version 3.0. > > > https://docs.python.org/3/reference/lexical_analysis.html#integer-literals> > > which does not explain why “non-zero decimal number” was chosen, rather > than simply any decimal number. I have reported https://bugs.python.org/issue26490> to try to resolve this ambiguity. -- \ “They who can give up essential liberty to obtain a little | `\temporary safety, deserve neither liberty nor safety.” | _o__) —Benjamin Franklin, 1775-02-17 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Surprised that print("a" "b") gives "ab"
boB Stepp writes: > […] why was this feature implemented? You've been asking that a lot lately :-) This forum is unlikely to be able to give authoritative answers to “why was the language designed the way it is?”. We are more able to explain what justification there is for a behaviour remaining as it is. That's a different question, though. > Is there a use case where it is more desirable to not have a string > concatenation operator explicitly used? The only thing that comes to > my mind are strings spread over multiple lines, say > > print("This will be a ..." > "...very long string...") > > But is this preferable to > > print("This will be a ..." + > "...very long string...") > > ? I personally prefer the latter, so I am probably missing something. It is salient to this issue, that the two cases above are semantically different. The first one is defined (by the syntax for literals) to create a *single* string object. Semantically, the fragments are specifying one object in a single step. The second is semantically (i.e. by the semantics of how such expressions are defined to work) creating two distinct objects, then creating a third using an operation, then discarding the first two. For me, that makes a big difference. When strings need to be split over several lines, it is convenient to be able to express directly in the code “these fragments are intended to be all part of the same object”. And it helps to see that in other people's code, too. I am sympathetic to the small visible difference between your two examples, and I don't deny that others may not find this feature as convenient or elegant as I do. -- \ “The long-term solution to mountains of waste is not more | `\ landfill sites but fewer shopping centres.” —Clive Hamilton, | _o__)_Affluenza_, 2005 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Surprised that print("a" "b") gives "ab"
Ben Finney writes: > The first one is defined (by the syntax for literals) to create a > *single* string object. Semantically, the fragments are specifying one > object in a single step. > > The second is semantically (i.e. by the semantics of how such > expressions are defined to work) creating two distinct objects, then > creating a third using an operation, then discarding the first two. Because I know there are resident pedants who love to get into the details: I know that's not exactly how it works internally, and it doesn't matter. I'm not talking about what bytecode is produced, I'm talking about the semantics of what the language reference defines: ‘+’ implies that a new object will be created by calling ‘__add__’ or ‘__radd__’. What the optimiser decides to omit is not relevant to that point: the semantics of the ‘+’ operator imples that a third object will result from combining two other objects. -- \ Moriarty: “Forty thousand million billion dollars? That money | `\must be worth a fortune!” —The Goon Show, _The Sale of | _o__) Manhattan_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Surprised that print("a" "b") gives "ab"
boB Stepp writes: > Under the hood, are the two approaches above done in the same way? I > get your semantics point, but are there two string objects created in > both approaches or does the first in fact create only a single object? Sometimes, it does. That's an implementation detail, and the behaviour is not guaranteed and can change at any time, even within the exact same program. So it's not something worth considering when writing or reading that code for semantics. > If the first truly only creates a single object, then it seems that > this is a more efficient approach. That's the danger. Consider efficiency of the implementation to be not your job, when learning the language. Far more important are clear expression of intent, and ease of finding errors. -- \“You can't have everything; where would you put it?” —Steven | `\Wright | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] newbie in programming
Mark Lawrence writes: > I have found it very helpful to follow conversations if people don't > top post, but that seems once again to have been completely lost on > this list. Is it simply too difficult? Not too difficult, nor lost. By the nature of this forum, many people have only joined recently; so they do not automatically benefit from past conversations here. -- \ “DRM doesn't inconvenience [lawbreakers] — indeed, over time it | `\ trains law-abiding users to become [lawbreakers] out of sheer | _o__)frustration.” —Charles Stross, 2010-05-09 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to test function using random.randint()?
boB Stepp writes: > If I had a function to roll a die, such as: > > import random > > def roll_die(num_sides): > return random.randint(1, num_sides) > > How would I write unit tests for this? You need to make the system deterministic during the test run. Since the random number generator (RNG) is a dependency that your test cases don't entirely control, that is a dependency that makes the system non-deterministic. One way to do that is to allow the dependency – the RNG – to be specified as part of the API of the system under test:: def roll_die(num_sides, rng=None): This is known as the “dependency injection” pattern. The system makes a deliberate API for its dependencies, and allows the caller to specify the object that represents the dependency. https://en.wikipedia.org/wiki/Dependency_injection> The system does not directly use the external dependency; it uses the dependency supplied, as an abstraction:: import random def roll_die(num_sides, rng=None): """ Return a result from a random die of `num_sides` sides. :param num_sides: The number of sides on the die. :param rng: An instance of `random.Random`, the random number generator to use. Default: the `random.random` instance. :return: The integer result from the die roll. The die is defined to have equal-probability faces, numbered from 1 to `num_sides`. """ if rng is None: rng = random.random result = rng.randint(1, num_sides) return result In this case the dependency has a sensible default, so the caller doesn't *need* to specify the dependency. That's not always true, and dependency injection often entails re-designing the API and callers must adapt to that new API. With that re-design, the test module can create an RNG that behaves as expected. Your test cases can create their own RNG instance and specify its seed, which means the same numbers will be generated every time from that seed. import unittest import random from . import die_roller# The system under test. class roll_die_TestCase(unittest.TestCase): """ Test cases for the `roll_die` function. """ def setUp(self): """ Set up test fixtures. """ # Set the seed value such that the system can't anticipate # it, but such that we can re-use it any time. self.seed = id(self) self.rng = random.Random(self.seed) def test_result_in_expected_range(self): """ The result should be in the range expected for the die. """ test_num_sides = 6 expected_range = range(1, test_num_sides + 1) result = die_roller.roll_die(test_num_sides, rng=self.rng) self.assertIn(result, expected_range) def test_result_is_from_rng(self): """ The result should be produced by the supplied RNG. """ test_num_sides = 6 self.rng.seed(self.seed) expected_result = self.rng.randint(1, test_num_sides) self.rng.seed(self.seed) result = die_roller.roll_die(test_num_sides, rng=self.rng) self.assertEqual(result, expected_result) > And I do not see how I can test for an appropriate "randomness" to the > numbers the function generates without to a lot of iterations, That's the thing about randomness. By definition, you can't determine it :-) But by providing your own RNG that is under control of the test cases, you can know what numbers it will produce by re-setting it to a known seed. Hopefully you can take this as an example of how to better design systems so they don't have tightly-entangled external dependencies. -- \ “The good thing about science is that it's true whether or not | `\ you believe in it.” —Neil deGrasse Tyson, 2011-02-04 | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to test function using random.randint()?
boB Stepp writes: > On Sat, Mar 19, 2016 at 8:03 AM, Steven D'Aprano wrote: > > On Sat, Mar 19, 2016 at 04:05:58PM +1100, Ben Finney wrote: > >> if rng is None: > >> rng = random.random > > > > Typo: you want rng = random.randint. No, I meant what I wrote. The ‘rng’ parameter is expected to be bound to a RNG. If the caller has not specified a custom RNG instance, we bind ‘rng’ to the standard RNG instance found at ‘random.random’. > >> result = rng.randint(1, num_sides) > > > > And here you just want result = rng(1, num_sides). Otherwise you're > > trying to call random.randint.randint. > > And then this statement would be correct as Ben wrote it. Unlike some other examples I have posted, I actually bothered to demonstrate this working as expected before posting it :-) > Ben, please chime in if I have got it wrong. You have it right, Bob. -- \ “If consumers even know there's a DRM, what it is, and how it | `\ works, we've already failed.” —Peter Lee, Disney corporation, | _o__) 2005 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to test function using random.randint()?
Steven D'Aprano writes: > On Mon, Mar 21, 2016 at 12:18:01AM +1100, Ben Finney wrote: > > No, I meant what I wrote. The ‘rng’ parameter is expected to be > > bound to a RNG. If the caller has not specified a custom RNG > > instance, we bind ‘rng’ to the standard RNG instance found at > > ‘random.random’. Steven is right, that name is a function not an RNG. The code should read:: if rng is None: rng = random._inst which is the default RNG instance in the module. It is also named as an implementation-only attribute, not part of the module's API. So you may want to find a more reliable API to use. -- \ “Very few things happen at the right time, and the rest do not | `\ happen at all. The conscientious historian will correct these | _o__) defects.” —Mark Twain, _A Horse's Tale_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to test function using random.randint()?
boB Stepp writes: > On Sun, Mar 20, 2016 at 8:19 PM, Ben Finney > wrote: > > if rng is None: > > rng = random._inst > > > > which is the default RNG instance in the module. > > Can I not use: > > if rng is None: > rng = random.Random() That will work. It unfortunately creates a new random.Random instance every time that line is executed, making the function waste a lot of time. So instead, you many want to create a module-level instance, and refer to that as the default. # die_roller.py """ Functionality for rolling numbers from polyhedral dice. """ import random rng = random.Random() def roll_die(num_sides, rng=rng): # … -- \ “Give a man a fish, and you'll feed him for a day; give him a | `\religion, and he'll starve to death while praying for a fish.” | _o__) —Anonymous | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How python keeps track of data types
Abhishek Kumar writes: > I am a computer science student,I want to know how python keeps track > of data types of variables Python doesn't track the type of a variable, because a variable never has any information about type. What Python calls “variables” are names, referring to objects. Names have no type. Every object has a type, so Python doesn't “track” the type in the sense you mean. -- \ “Any sufficiently advanced bug is indistinguishable from a | `\ feature.” —Rich Kulawiec | _o__) | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fw: About the Round Function
Nacir Bouali writes: > My students and I are interested in knowing the rationale behind > Python's choice of the Banker's rounding algorithm to be the default > rounding algorithm in the third release of Python. Can you provide a link to the Python documentation for this? The term “Banker's rounding algorithm” is not familiar to me. What does the Python documentation say about it, and where? > We'd also like to know how the function is actually implemented. What kind of answer to “how it is implemented” do you want? At one level, it can be answered with the source code of CPython https://www.python.org/downloads/source/>. Perhaps you want a different answer, but what? -- \ “We spend the first twelve months of our children's lives | `\ teaching them to walk and talk and the next twelve years | _o__) telling them to sit down and shut up.” —Phyllis Diller | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor