Re: Techniques to extend code without modifying it? (besides modules and decorators)
Paul Thanks! I'm glad there is theory about my concern. I knew I wasn't the only one with that question. cs > > https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle > > Also: > > https://en.wikipedia.org/wiki/Expression_problem -- https://mail.python.org/mailman/listinfo/python-list
Re: How to test?
Given your replies, 'now' might be a good time to take a look at Pytest, and see how you could use it to help build better code - by building tested units/functions which are assembled into ever-larger tested-units... (there is a range of choice/other testing aids if Pytest doesn't take your fancy) I have to admit I chose unittest. Simply because it is in the standard lbrary. As so many people seem to prefer pytest I should take a look at it. Not at all! This is a personal bias - I happen to have been using Pytest. Your objective is learning to program in Python. 'Chopping and changing' between ancillary tools would be a distraction and time-sink. If you have already started learning unittest, keep going. We all have to start 'somewhere'! At the learning stage, any one of these tools will help you with testing, and testing should improve your overall programming skills. Once your expertise, in both Python and the testing tool, matures; you will be better placed to survey the opportunities and to choose the best alternative for you and your applications... -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to avoid a global variable
On 28/04/20 7:36 PM, Chris Angelico wrote: "Best"? Not sure about that. Functions are first-class objects in Python, so a function *is* a callable object. You don't have to create a custom class with a call method just to be able to attach attributes to your function. ChrisA Using a mutable object as a function default parameter value and changing it inside the function looks like a "trick" according to me. Sure. But you're contrasting this to a suggestion to literally just attach attributes to a function. Python lets you actually do that. You don't have to simulate the feature by creating a custom class and making it callable - you just straight-up add attributes to a function. Sure, what you suggested works, but there's no reason to. Functions are objects too! I regularly point-out this powerful facility, and its affordances, but... Yes, it's perfectly reasonable and even sensible to attach an attribute; BUT do many people expect to find such? If we were to collectively survey our own application code, how many examples would we find - as a percentage of such a corpus? Expectation: it would be v.v.low. Accordingly, whilst perfectly-implemented Python, and thus not a "trick", at least it is something that is easy for 'an ordinary person' to 'miss' (or misunderstand). The same cognitive logic applies to function parameters. Use of these is laced with 'gotchas', because people assume a different logic to/fail to properly understand Python. Hence such style decisions as 'use None, or not at all'. Personal opinion: I've never really liked closures, and have tended to associate them with other languages that actually need them in order to accomplish common-constructs or have them as a tenet/pillar of their language-design philosophy. Python does not, so... The choice of global variable should not be completely discounted - we have been given the global statement for a reason! However, its use in this case has been rightly-criticised (elsewhere) as an unnecessary 'pollution'. Which leaves us (or me!) with the overly-wordy wrapping-in-a-class option. The use of a class-attribute seems natural and is a well-worn pattern often used for counting instances, totalling a value across instances, or indeed limiting (usually to one, single) instantiations. Opinion: The function attribute is most efficient, in terms of programmer time or LoC. However the class-construct seems more-readily recognisable. That said, the OP's stated specification is to limit the depth of a stack. Many would have implemented the stack as a (derived) class, and thus adding a class-attribute control-variable would become only part of a wider whole - rather than the class being created merely to replace a simpler and more-concise function. Contrarily, if we (all) use function-attributes and enjoy the simplicity and power justifying the reasons they were given to us, they would become second-nature to code AND to read! -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to avoid a global variable
On Sat, May 2, 2020 at 9:14 AM DL Neil via Python-list wrote: > > On 28/04/20 7:36 PM, Chris Angelico wrote: > >>> "Best"? Not sure about that. Functions are first-class objects in > >>> Python, so a function *is* a callable object. You don't have to create > >>> a custom class with a call method just to be able to attach attributes > >>> to your function. > >>> > >>> ChrisA > >>> > >> > >> Using a mutable object as a function default parameter value > >> and changing it inside the function looks like a "trick" > >> according to me. > > > > Sure. But you're contrasting this to a suggestion to literally just > > attach attributes to a function. Python lets you actually do that. You > > don't have to simulate the feature by creating a custom class and > > making it callable - you just straight-up add attributes to a > > function. Sure, what you suggested works, but there's no reason to. > > > Functions are objects too! I regularly point-out this powerful facility, > and its affordances, but... > > > Yes, it's perfectly reasonable and even sensible to attach an attribute; > BUT do many people expect to find such? If we were to collectively > survey our own application code, how many examples would we find - as a > percentage of such a corpus? > > Expectation: it would be v.v.low. Accordingly, whilst > perfectly-implemented Python, and thus not a "trick", at least it is > something that is easy for 'an ordinary person' to 'miss' (or > misunderstand). > One of the problems with the use of function attributes is that there's no way to say "this function". You have to use its name. Otherwise, it would be easy to write self-contained idioms such as static variables or omitted arg detection without the risk of polluting the namespace: def some_function(x, y, z=object()): if z is me.__defaults__[0]: z = x + y ... def static(**kw): def deco(f): for name, initial in kw.items(): setattr(f, name, initial) return f return deco @static(called=0) def other_function(): me.called += 1 ... Obviously the name "me" can't be used, as it'd break a bunch of code, but conceptually this would be incredibly helpful. It'd also be a reliable idiom for recursion optimization - any "me()" is guaranteed to be recursion and may potentially give info to an optimizer. Perhaps, if Python had a way to identify the current function, it would feel less odd to attach attributes to it. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to avoid a global variable
I still think that the use of a keyword like "static" would be easiest. def foo(arg): static counter = 0 counter += 1 if counter ... And in this case static just means that it's a variable only readable inside foo() and it should maintain it's value between calls. A "global" without the name pollution. Or is this too simple ??? On Fri, May 1, 2020 at 4:30 PM Chris Angelico wrote: > On Sat, May 2, 2020 at 9:14 AM DL Neil via Python-list > wrote: > > > > On 28/04/20 7:36 PM, Chris Angelico wrote: > > >>> "Best"? Not sure about that. Functions are first-class objects in > > >>> Python, so a function *is* a callable object. You don't have to > create > > >>> a custom class with a call method just to be able to attach > attributes > > >>> to your function. > > >>> > > >>> ChrisA > > >>> > > >> > > >> Using a mutable object as a function default parameter value > > >> and changing it inside the function looks like a "trick" > > >> according to me. > > > > > > Sure. But you're contrasting this to a suggestion to literally just > > > attach attributes to a function. Python lets you actually do that. You > > > don't have to simulate the feature by creating a custom class and > > > making it callable - you just straight-up add attributes to a > > > function. Sure, what you suggested works, but there's no reason to. > > > > > > Functions are objects too! I regularly point-out this powerful facility, > > and its affordances, but... > > > > > > Yes, it's perfectly reasonable and even sensible to attach an attribute; > > BUT do many people expect to find such? If we were to collectively > > survey our own application code, how many examples would we find - as a > > percentage of such a corpus? > > > > Expectation: it would be v.v.low. Accordingly, whilst > > perfectly-implemented Python, and thus not a "trick", at least it is > > something that is easy for 'an ordinary person' to 'miss' (or > > misunderstand). > > > > One of the problems with the use of function attributes is that > there's no way to say "this function". You have to use its name. > Otherwise, it would be easy to write self-contained idioms such as > static variables or omitted arg detection without the risk of > polluting the namespace: > > def some_function(x, y, z=object()): > if z is me.__defaults__[0]: > z = x + y > ... > > def static(**kw): > def deco(f): > for name, initial in kw.items(): > setattr(f, name, initial) > return f > return deco > > @static(called=0) > def other_function(): > me.called += 1 > ... > > Obviously the name "me" can't be used, as it'd break a bunch of code, > but conceptually this would be incredibly helpful. It'd also be a > reliable idiom for recursion optimization - any "me()" is guaranteed > to be recursion and may potentially give info to an optimizer. > > Perhaps, if Python had a way to identify the current function, it > would feel less odd to attach attributes to it. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > -- Listen to my FREE CD at http://www.mellowood.ca/music/cedars Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: b...@mellowood.ca WWW: http://www.mellowood.ca -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to avoid a global variable
On 2/05/20 11:30 AM, Chris Angelico wrote: On Sat, May 2, 2020 at 9:14 AM DL Neil via Python-list wrote: On 28/04/20 7:36 PM, Chris Angelico wrote: "Best"? Not sure about that. Functions are first-class objects in Python, so a function *is* a callable object. You don't have to create a custom class with a call method just to be able to attach attributes to your function. ChrisA Using a mutable object as a function default parameter value and changing it inside the function looks like a "trick" according to me. Sure. But you're contrasting this to a suggestion to literally just attach attributes to a function. Python lets you actually do that. You don't have to simulate the feature by creating a custom class and making it callable - you just straight-up add attributes to a function. Sure, what you suggested works, but there's no reason to. Functions are objects too! I regularly point-out this powerful facility, and its affordances, but... Yes, it's perfectly reasonable and even sensible to attach an attribute; BUT do many people expect to find such? If we were to collectively survey our own application code, how many examples would we find - as a percentage of such a corpus? Expectation: it would be v.v.low. Accordingly, whilst perfectly-implemented Python, and thus not a "trick", at least it is something that is easy for 'an ordinary person' to 'miss' (or misunderstand). One of the problems with the use of function attributes is that there's no way to say "this function". You have to use its name. Otherwise, it would be easy to write self-contained idioms such as static variables or omitted arg detection without the risk of polluting the namespace: def some_function(x, y, z=object()): if z is me.__defaults__[0]: z = x + y ... def static(**kw): def deco(f): for name, initial in kw.items(): setattr(f, name, initial) return f return deco @static(called=0) def other_function(): me.called += 1 ... Obviously the name "me" can't be used, as it'd break a bunch of code, but conceptually this would be incredibly helpful. It'd also be a reliable idiom for recursion optimization - any "me()" is guaranteed to be recursion and may potentially give info to an optimizer. Perhaps, if Python had a way to identify the current function, it would feel less odd to attach attributes to it. The trouble is, functions seem to have an existential crisis: they know their own __name__ but have no sense of self! However, all is not lost because they are still very __func__-y. (apologies to anyone reading this whilst drinking) Unfortunately, Shakespeare is not the only one to ask: what's in a name, Rosie? >>> def double( x ): ... return x + x ... >>> double( 2 ) 4 >>> double.__name__ 'double' ### so-far, so-good - but let's pick-up the pace: >>> pasodoble = double >>> pasodoble( 2 ) 4 >>> pasodoble.__name__ 'double' ### You're so tired (from working quickly, perhaps) that you can't even remember your own __name__? (by extrapolation, I estimate; but you (@Chris) will no doubt, educate) I'm assuming this has something to do with "decorators"? In relation to the wider part of the problem-mentioned, a class is instantiated to become a second, and separate-but-linked, object. Whereas the two function-names are merely multiple labels to the same object (and id()): >>> pasodoble >>> double ### Whereas:- >>> class C(): ... '''Docstring that says nothing about a class that does just as much.''' ... >>> c = C() >>> C.__name__ 'C' >>> c.__name__ Traceback (most recent call last): File "", line 1, in AttributeError: 'C' object has no attribute '__name__' ### Wait a minute! Have you forgotten your own name? ### What else don't you know? >>> c.self Traceback (most recent call last): File "", line 1, in AttributeError: 'C' object has no attribute 'self' >>> c.__doc__ 'Docstring that says nothing about a class that does nothing.' ### (yes, I know, *I* caused the first of these two!) ### However, they are separate entities. Proof: >>> id( C ) 94619010560432 >>> id(c) 140014684436880 Hence, being empowered to accomplish a lot more with instantiated classes. Although methods are merely functions, a method enjoys 'extra' by virtue of being an attribute of a class's instance and being able to call-upon further attributes within the same namespace. -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Function to avoid a global variable
On 2/05/20 12:00 PM, Bob van der Poel wrote: I still think that the use of a keyword like "static" would be easiest. def foo(arg): static counter = 0 counter += 1 if counter ... And in this case static just means that it's a variable only readable inside foo() and it should maintain it's value between calls. A "global" without the name pollution. Or is this too simple ??? No, it's not "too simple" an example/request. Although they are often considered more complex than materials suitable for 'beginner' (?simple) training, generator functions (and async-gen-func-s) already offer this (without the static-statement) def gen( args ): counter = 0 while counter < max_depth: yield counter counter will retain its value ("maintain state") between iterations. -- Regards =dn -- https://mail.python.org/mailman/listinfo/python-list
error in CSV resetting with seek(0)
consider the following code import csv import numpy as np with open("D:\PHD\obranking\\demo.csv", mode='r') as csv_file1, open("D:\PHD\obranking\\demo.csv", mode='r') as csv_file2: csv_reader1 = csv.DictReader(csv_file1) csv_reader2 = csv.DictReader(csv_file2) filename = "cell_split_demo.csv" with open("D:\PHD\obranking\\cell_split_demo.csv", 'w') as csvfilew1: fields = (range(0, 300)) csvwriter1 = csv.DictWriter(csvfilew1, fieldnames=fields) csvwriter1.writeheader() for i, row in enumerate(csv_reader1): print(f"value_i({i}) label({row['label']})") for j, line in enumerate(csv_reader2): if j <= i: matrixrows[j] = [] if row['label'] != line['label']: print(f"value_j({j})Unequal label({line['label']})") else: print(f"value_j({j}) equal label({line['label']})") pass else: break csv_file2.seek(0) Here is some of the out_put samples value_i(0) label(BW) value_j(0) equal label(BW) value_i(1) label(BW) value_j(0) Unequal label(label) value_j(1) equal label(BW) value_i(2) label(BW) value_j(0) Unequal label(label) value_j(1) equal label(BW) value_j(2) equal label(BW) You can see for j=0 while i goes from 1 to n it is not able to acess line['label'] value. Kindly help what is wrong with this? -- https://mail.python.org/mailman/listinfo/python-list
Re: error in CSV resetting with seek(0)
Rahul Gupta wrote: > consider the following code > import csv > import numpy as np > > with open("D:\PHD\obranking\\demo.csv", mode='r') as csv_file1, > open("D:\PHD\obranking\\demo.csv", mode='r') as csv_file2: > csv_reader1 = csv.DictReader(csv_file1) > csv_reader2 = csv.DictReader(csv_file2) > > > filename = "cell_split_demo.csv" > with open("D:\PHD\obranking\\cell_split_demo.csv", 'w') as csvfilew1: > fields = (range(0, 300)) > csvwriter1 = csv.DictWriter(csvfilew1, fieldnames=fields) > csvwriter1.writeheader() > > for i, row in enumerate(csv_reader1): > print(f"value_i({i}) label({row['label']})") > for j, line in enumerate(csv_reader2): > if j <= i: > matrixrows[j] = [] > if row['label'] != line['label']: > print(f"value_j({j})Unequal > label({line['label']})") > else: > print(f"value_j({j}) equal > label({line['label']})") pass > else: > break > csv_file2.seek(0) > Here is some of the out_put samples > value_i(0) label(BW) > value_j(0) equal label(BW) > value_i(1) label(BW) > value_j(0) Unequal label(label) > value_j(1) equal label(BW) > value_i(2) label(BW) > value_j(0) Unequal label(label) > value_j(1) equal label(BW) > value_j(2) equal label(BW) > You can see for j=0 while i goes from 1 to n it is not able to acess > line['label'] value. Kindly help what is wrong with this? Without looking closely I would guess that seek(0) causes the reader to mistake the header for a data row. If your data fits into memory you can do rows = list(csv_reader1) for i, outer_row in enumerate(rows): ... for j, inner_row in enumerate(rows): ... With this aproach csv_reader2 is not needed at all. If that fails for lack of memory build a new csv_reader2 on every iteration csv_reader1 = csv.DictReader(csv_file1) for i, outer_row in enumerate(csv_reader1): csv_reader2 = csv.DictReader(csv_file2) ... for j, inner_row in enumerate(csv_reader2) ... csv_file2.seek(0) -- https://mail.python.org/mailman/listinfo/python-list