Re: How to have python 2 and 3 both on windows?
The question is not one of conversion. The question is this: When I have both python 2 and python3, why is my python 2 script breaking? And when I remove python3 the problem goes away? In both cases (regardless of installing python 3 or not) I am using only python 2 to run the python2 script. Why does the installation of python3 affect the python2, and how can I get them to work without stepping on one another? On Saturday, April 23, 2022, 09:59:46 PM PDT, Dennis Lee Bieber wrote: On Sun, 24 Apr 2022 01:19:38 + (UTC), Sunil KR declaimed the following: > >-- Why are my strings being sent to python3, so that I get the unicode related >error? >-- in other cases I see error pertaining to the print function In python2, the default for strings is BYTES -- you must explicitly ask for unicode (for literals, using u'literal' notation). Python3 strings are, by default, interpreted as unicode (with the encoding for source code [and hence, literals] specified somewhere via a special comment). Getting a normal python2 string requires using the b'literal' notation to indicate /bytes/. Also, in Python2, print is a language statement, not a function. If you have any print statements that do not have ( ) surrounding the output items, it WILL fail in Python3. >In my case, I don't own the python2 scripts and so I am not allowed to change >any part of them. And I wouldn't need to either, if I can make python 2 and 3 >coexist on my system > Even if you are not "allowed to change" those scripts, have you tried feeding them through the 2to3 conversion script just to see what type of changes would be required? https://docs.python.org/3/library/2to3.html -- Wulfraed Dennis Lee Bieber AF6VN [email protected] http://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: How to have python 2 and 3 both on windows?
On 2022-04-24 01:19:38 +, Sunil KR via Python-list wrote: > But the real question/s for me is/are > > -- Why are my strings being sent to python3, so that I get the unicode > related error? You haven't shown us how you invoke those scripts, so we can't answer that question with the information you gave us. hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | [email protected] |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
dn schreef op 24/04/2022 om 0:04: Disagreeing with @Chris in the sense that I use tail very frequently, and usually in the context of server logs - but I'm talking about the Linux implementation, not Python code! If I understand Marco correctly, what he want is to read the lines from bottom to top, i.e. tac instead of tail, despite his subject. I use tail very frequently too, but tac is something I almost never use. -- "Peace cannot be kept by force. It can only be achieved through understanding." -- Albert Einstein -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
Op 23/04/2022 om 20:57 schreef Chris Angelico: On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: What about introducing a method for text streams that reads the lines from the bottom? Java has also a ReversedLinesFileReader with Apache Commons IO. 1) Read the entire file and decode bytes to text 2) Split into lines 3) Iterate backwards over the lines Tada! Done. And in Python, quite easy. The downside, of course, is that you have to store the entire file in memory. Why not just do: tail = collections.deque(text_stream, maxlen = nr_of_lines) tail.reverse() ... -- Antoon Pardon -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
On Sun, 24 Apr 2022 at 21:11, Antoon Pardon wrote: > > > > Op 23/04/2022 om 20:57 schreef Chris Angelico: > > On Sun, 24 Apr 2022 at 04:37, Marco Sulla > > wrote: > >> What about introducing a method for text streams that reads the lines > >> from the bottom? Java has also a ReversedLinesFileReader with Apache > >> Commons IO. > > > > 1) Read the entire file and decode bytes to text > > 2) Split into lines > > 3) Iterate backwards over the lines > > > > Tada! Done. And in Python, quite easy. The downside, of course, is > > that you have to store the entire file in memory. > > Why not just do: > > tail = collections.deque(text_stream, maxlen = nr_of_lines) > tail.reverse() > ... > You still need to read the entire file, and you also restrict the max line count, so you can't iterate this to take the next block of lines. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
I have been getting confused by how many interpretations and conditions for chasing tail people seem to be talking about. A fairly normal task is to want to see just the last N lines of a text-based file. A variant is the "tail -f" command from UNIX that continues to follow a growing file, often into a pipeline for further processing. The variant now being mentioned is a sort of "reverse" that has nothing to do with that kind of "tail" except if the implementation is to read the file backwards. A very straightforward way to reverse a file takes perhaps two lines of Python code by reading forward to fill a list with lines of text then using an index that reverses it. The issues being considered are memory and whether to read the entire file. I would think reading a file forwards in big chunks to be far faster and simpler than various schemes mentioned here for reading it backwards. It only makes sense if the goal is not reversal of all the contents. Also noted is that memory use can be minimized various ways so that only thefinal results are kept around. And if you really want more random access to files that you view as being organized as lines of text with a fixed or maximum width,then storing in some database format, perhaps indexed, may be a way to go. A time stamped log file is a good example. So which problem is really supposed to be solved for the original question? -Original Message- From: Roel Schroeven To: [email protected] Sent: Sun, Apr 24, 2022 5:19 am Subject: Re: tail dn schreef op 24/04/2022 om 0:04: > Disagreeing with @Chris in the sense that I use tail very frequently, > and usually in the context of server logs - but I'm talking about the > Linux implementation, not Python code! If I understand Marco correctly, what he want is to read the lines from bottom to top, i.e. tac instead of tail, despite his subject. I use tail very frequently too, but tac is something I almost never use. -- "Peace cannot be kept by force. It can only be achieved through understanding." -- Albert Einstein -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: How to have python 2 and 3 both on windows?
On 4/23/22, Sunil KR via Python-list wrote: > > I am happy with how the python starts up. When I use python I get > python 2. I am ok with using py -3 for my new scripts, even using the > shebang like #!py -3 `#!py -3` is not a valid shebang for the py launcher. Use `#!python3` to run a script with the highest version of Python 3 that's registered on your system. Or for cross-platform support, use `#!/usr/bin/python3`. > I don't want to put a unix (or for that matter windows) path in the shebang, > as it is not platform portable The launcher supports builtin virtual shebangs, including: * #!python[X[.Y][-32|-64]] * #!/usr/bin/python[X[.Y][-32|-64]] * #!/usr/bin/env python[X[.Y][-32|-64]] * #!/usr/local/bin/python[X[.Y][-32|-64]] The implementation of the `/usr/bin/env` virtual shebang searches PATH for a given command that's exactly "python" (no version spec) or any command that doesn't start with "python". If a "python" command has a version spec, then PATH is not searched, and it works the same as a `#!pythonX[.Y]` shebang. The latter is because a normal Python installation doesn't include versioned executable names, so the launcher doesn't even try to search PATH for something like "python3.11.exe". You can set the default version to use via the PY_PYTHON environment variable, e.g. `set PY_PYTHON=3.9`. If Python 3 is requested without a specific version (e.g. via `py -3` at the command line, or the shebang `#!python3`), then the default 3.x version to run can be set via the PY_PYTHON3 environment variable, e.g. `set PY_PYTHON3=3.10`. The default for Python 2 is set similarly via PY_PYTHON2. The launcher also supports real file paths in shebangs. Generally you'd only use a real path in order to run in a virtual environment, such as #!"C:\Path\to\venv\Scripts\python.exe". -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
On Sat, 23 Apr 2022 at 23:18, Chris Angelico wrote: > Ah. Well, then, THAT is why it's inefficient: you're seeking back one > single byte at a time, then reading forwards. That is NOT going to > play nicely with file systems or buffers. > > Compare reading line by line over the file with readlines() and you'll > see how abysmal this is. > > If you really only need one line (which isn't what your original post > suggested), I would recommend starting with a chunk that is likely to > include a full line, and expanding the chunk until you have that > newline. Much more efficient than one byte at a time. > Well, I would like to have a sort of tail, so to generalise to more than 1 line. But I think that once you have a good algorithm for one line, you can repeat it N times. I understand that you can read a chunk instead of a single byte, so when the newline is found you can return all the cached chunks concatenated. But will this make the search of the start of the line faster? I suppose you have always to read byte by byte (or more, if you're using urf16 etc) and see if there's a newline. -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
On Sun, 24 Apr 2022 at 00:19, Cameron Simpson wrote: > An approach I think you both may have missed: mmap the file and use > mmap.rfind(b'\n') to locate line delimiters. > https://docs.python.org/3/library/mmap.html#mmap.mmap.rfind > Ah, I played very little with mmap, I didn't know about this. So I suppose you can locate the newline and at that point read the line without using chunks? -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
On Mon, 25 Apr 2022 at 01:47, Marco Sulla wrote: > > > > On Sat, 23 Apr 2022 at 23:18, Chris Angelico wrote: >> >> Ah. Well, then, THAT is why it's inefficient: you're seeking back one >> single byte at a time, then reading forwards. That is NOT going to >> play nicely with file systems or buffers. >> >> Compare reading line by line over the file with readlines() and you'll >> see how abysmal this is. >> >> If you really only need one line (which isn't what your original post >> suggested), I would recommend starting with a chunk that is likely to >> include a full line, and expanding the chunk until you have that >> newline. Much more efficient than one byte at a time. > > > Well, I would like to have a sort of tail, so to generalise to more than 1 > line. But I think that once you have a good algorithm for one line, you can > repeat it N times. > Not always. If you know you want to read 5 lines, it's much more efficient than reading 1 line, then going back to the file, five times. Disk reads are the costliest part, with the possible exception of memory usage (but usually only because it can cause additional disk *writes*). > I understand that you can read a chunk instead of a single byte, so when the > newline is found you can return all the cached chunks concatenated. But will > this make the search of the start of the line faster? I suppose you have > always to read byte by byte (or more, if you're using urf16 etc) and see if > there's a newline. > Massively massively faster. Try it. Especially, try it on an artificially slow file system, so you can see what it costs. But you can't rely on any backwards reads unless you know for sure that the encoding supports this. UTF-8 does (you have to scan backwards for a start byte), UTF-16 does (work with pairs of bytes and check for surrogates), and fixed-width encodings do, but otherwise, you won't necessarily know when you've found a valid start point. So any reverse-read algorithm is going to be restricted to specific encodings. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: tail
On Sun, 24 Apr 2022 at 11:21, Roel Schroeven wrote: > dn schreef op 24/04/2022 om 0:04: > > Disagreeing with @Chris in the sense that I use tail very frequently, > > and usually in the context of server logs - but I'm talking about the > > Linux implementation, not Python code! > If I understand Marco correctly, what he want is to read the lines from > bottom to top, i.e. tac instead of tail, despite his subject. > I use tail very frequently too, but tac is something I almost never use. > Well, the inverse reader is only a secondary suggestion. I suppose a tail is much more useful. -- https://mail.python.org/mailman/listinfo/python-list
RE: tail
> -Original Message- > From: dn > Sent: Saturday, April 23, 2022 6:05 PM > To: [email protected] > Subject: Re: tail > > NB quite a few of IBM's (extensively researched) algorithms which formed > utility > program[me]s on mainframes, made similar such algorithmic choices, in the > pursuit of efficiencies. WRT the mentioned IBM utility program[me]s, the non-Posix part of the IBM mainframe file system has always provided record-managed storage since the late 1960's (as opposed to the byte-managed storage of *ix systems) so searching for line endings was (and is) irrelevant and unnecessary in that environment. That operating system also provides basic "kernel-level" read-backwards API's for the record-managed file system, so there was never any need to build reverse-read into your code for that environment. The byte-managed file storage used by the Posix kernel running under the actually-in-charge IBM mainframe operating system is, of course, subject to the same constraints and (in)efficiencies discussed in this thread. Peter -- -- https://mail.python.org/mailman/listinfo/python-list
Re: Style for docstring
On 23/04/2022 12.43, Avi Gross wrote:
Given what you added, Michael, your function is part of a larger collection of
functions and being compatible with the others is a valid consideration.
Whatever you decide, would ideally be done consistently with all or most of
them.
And, of course, it others in the collection also can handle multiple ways to
specify a permutation, it may be simpler to have each call something like
as.permutation() that handlesmultiple forms and converts to the one easiest for
you to use.
I am not sure that is needed as I suspect the simplest storage is something
like a list: [0,3,2,4,5,6,7,1,9,8] but could also be shown with each cycle as
a sub-list or something like anumpy vector or a customized class.
Since you ask, I'm using dictionaries as the internal representation.
If you think about it, a python dictionary *is* a function from one
finite set to another, mathematically. And a (finite) permutation is
a bijection from a (finite) set to itself.
For convenience, the module provides two methods of defining a permutation
other than just entering a dictionary:
>>> import PermGroups as pg
>>> a = {'1':'2', '2':'1', '3':'3'}
>>> b = pg.ParsePerm( '(12)(3)' )
>>> c = pg.ParseDomImg( '123', '213' )
>>> a==b
True
>>> b==c
True
>>>
All of the other functions work on these dictionaries.
I had thought about defining a permutation object, but the conceptual
match between "dict" and "permutation" was too good to discard.
Clearly if you control the package and how it is used, errors from bad data may
not be a concern.
An invalidly-constructed permutation will cause an exception, so
the function won't return.
>>> d = {'1':'2', '2':'2', '3':'3'}
>>> pg.ValidateDict(d)
False
>>>
If I was to do it over, I would have named this function something
like IsValidPermutation(), hiding the internal representation as
well as making the function's Boolean nature explicit.
--
Michael F. Stemper
No animals were harmed in the composition of this message.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Style for docstring
On 24/04/2022 08.24, Michael F. Stemper wrote:
On 23/04/2022 12.43, Avi Gross wrote:
Given what you added, Michael, your function is part of a larger collection of
functions and being compatible with the others is a valid consideration.
Whatever you decide, would ideally be done consistently with all or most of
them.
And, of course, it others in the collection also can handle multiple ways to
specify a permutation, it may be simpler to have each call something like
as.permutation() that handlesmultiple forms and converts to the one easiest for
you to use.
I am not sure that is needed as I suspect the simplest storage is something
like a list: [0,3,2,4,5,6,7,1,9,8] but could also be shown with each cycle as
a sub-list or something like anumpy vector or a customized class.
Since you ask, I'm using dictionaries as the internal representation.
If you think about it, a python dictionary *is* a function from one
finite set to another, mathematically. And a (finite) permutation is
a bijection from a (finite) set to itself.
For convenience, the module provides two methods of defining a permutation
other than just entering a dictionary:
>>> import PermGroups as pg
>>> a = {'1':'2', '2':'1', '3':'3'}
>>> b = pg.ParsePerm( '(12)(3)' )
>>> c = pg.ParseDomImg( '123', '213' )
>>> a==b
True
>>> b==c
True
>>>
All of the other functions work on these dictionaries.
I had thought about defining a permutation object, but the conceptual
match between "dict" and "permutation" was too good to discard.
Clearly if you control the package and how it is used, errors from bad data may
not be a concern.
An invalidly-constructed permutation will cause an exception, so
the function won't return.
The below was *not* intended to illustrate what I said above. It
shows the validation function provided by the module. This allows
the user to avoid the consequences of an invalidly-constructed
permutation. (It's only for users who don't subscribe to "EAFP",
of course.)
>>> d = {'1':'2', '2':'2', '3':'3'}
>>> pg.ValidateDict(d)
False
>>>
If I was to do it over, I would have named this function something
like IsValidPermutation(), hiding the internal representation as
well as making the function's Boolean nature explicit.
--
Michael F. Stemper
Psalm 82:3-4
--
https://mail.python.org/mailman/listinfo/python-list
Re: tail
On Sun, 24 Apr 2022 12:21:36 -0400, declaimed the following: > >WRT the mentioned IBM utility program[me]s, the non-Posix part of the IBM >mainframe file system has always provided record-managed storage since the >late 1960's (as opposed to the byte-managed storage of *ix systems) so >searching for line endings was (and is) irrelevant and unnecessary in that >environment. That operating system also provides basic "kernel-level" >read-backwards API's for the record-managed file system, so there was never >any need to build reverse-read into your code for that environment. > IBM wasn't the only one... Xerox Sigma running CP/V default for text files (those created using a text editor) used numeric ISAM keys (as record numbers -- which is how their FORTRAN IV compiler did random access I/O without requiring fixed length records). The system supported three access methods: consecutive (similar to UNIX "stream" files, for files that didn't require editing, these saved disk space as the ISAM headers could be disposed of), the aforesaid keyed, and "random" (on this system, "random" meant the ONLY thing the OS did was know where the file was on disk -- files had to be contiguous and pre-allocated, and what data was in the file was strictly up to the application to manage). VAX/VMS had lots of different file structures managed by the RMS system services. The default for FORTRAN text files was a segmented model, making use of chunks of around 250 bytes [it has been years and I no longer have the documentation] in which the start of each chunk had a code for "first chunk", "last chunk", "intermediate chunk" (and maybe length of data in the chunk). A record that fit completely within one chunk would have both "first" and "last" codes set (intermediate chunks have neither code). One had to go out of their way to create a "stream" file in DEC FORTRAN 77 (open the file with CARRIAGECONTROL=CARRIAGERETURN). Other languages on the OS had different default file structures, but RMS would handle all of them transparently. -- Wulfraed Dennis Lee Bieber AF6VN [email protected]://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Style for docstring
On 25/04/2022 01.24, Michael F. Stemper wrote:
> On 23/04/2022 12.43, Avi Gross wrote:
>> Given what you added, Michael, your function is part of a
>> larger collection of functions and being compatible with the others
>> is a valid consideration. Whatever you decide, would ideally be done
>> consistently with all or most of them.
>> And, of course, it others in the collection also can handle multiple
>> ways to specify a permutation, it may be simpler to have each call
>> something like as.permutation() that handlesmultiple forms and
>> converts to the one easiest for you to use.
>> I am not sure that is needed as I suspect the simplest storage is
>> something like a list: [0,3,2,4,5,6,7,1,9,8] but could also be shown
>> with each cycle as a sub-list or something like anumpy vector or a
>> customized class.
>
> Since you ask, I'm using dictionaries as the internal representation.
> If you think about it, a python dictionary *is* a function from one
> finite set to another, mathematically. And a (finite) permutation is
> a bijection from a (finite) set to itself.
>
> For convenience, the module provides two methods of defining a permutation
> other than just entering a dictionary:
>
> >>> import PermGroups as pg
> >>> a = {'1':'2', '2':'1', '3':'3'}
> >>> b = pg.ParsePerm( '(12)(3)' )
> >>> c = pg.ParseDomImg( '123', '213' )
> >>> a==b
> True
> >>> b==c
> True
> >>>
>
> All of the other functions work on these dictionaries.
>
> I had thought about defining a permutation object, but the conceptual
> match between "dict" and "permutation" was too good to discard.
>
>> Clearly if you control the package and how it is used, errors from bad
>> data may not be a concern.
>
> An invalidly-constructed permutation will cause an exception, so
> the function won't return.
>
> >>> d = {'1':'2', '2':'2', '3':'3'}
> >>> pg.ValidateDict(d)
> False
> >>>
>
> If I was to do it over, I would have named this function something
> like IsValidPermutation(), hiding the internal representation as
> well as making the function's Boolean nature explicit.
Yes, we live and learn!
(but 'technical debt'...)
Naming something based upon its implementation, eg ValidateDict(),
rather than its purpose, is a definite no-no - and while I'm
nit-picking, is that a function? (and thus validate_dict())
The idea of representing perms as dicts is good-thinking!
Please review UserDict
(https://docs.python.org/3/library/collections.html#collections.UserDict).
Sub-classing UserDict gives the advantages of a dict, without some of
the methods you don't want/need, and the ability to gather custom
permutation-methods into the class.
For a discussion about sub-classing dict or using UserDict, may I
recommend Trey Hunner's analysis, aka "there's no such thing as a free
lunch"
(https://treyhunner.com/2019/04/why-you-shouldnt-inherit-from-list-and-dict-in-python/)
Since then, we've been given (and I haven't had a reason to try it, yet)
"PEP 589 – TypedDict: Type Hints for Dictionaries with a Fixed Set of
Keys" which may offer an alternate approach. This comes with the
advantage of 'compile-time' static analysis/checking
(https://peps.python.org/pep-0589/). When I get around to experimenting
with this, I'll be referring to "TypedDict vs dataclasses in Python"
(https://dev.to/meeshkan/typeddict-vs-dataclasses-in-python-epic-typing-battle-onb)
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: tail
On 25/04/2022 04.21, [email protected] wrote: >> -Original Message- >> From: dn >> Sent: Saturday, April 23, 2022 6:05 PM >> To: [email protected] >> Subject: Re: tail >> > >> NB quite a few of IBM's (extensively researched) algorithms which formed >> utility >> program[me]s on mainframes, made similar such algorithmic choices, in the >> pursuit of efficiencies. > > WRT the mentioned IBM utility program[me]s, the non-Posix part of the IBM > mainframe file system has always provided record-managed storage since the > late 1960's (as opposed to the byte-managed storage of *ix systems) so > searching for line endings was (and is) irrelevant and unnecessary in that > environment. That operating system also provides basic "kernel-level" > read-backwards API's for the record-managed file system, so there was never > any need to build reverse-read into your code for that environment. > > The byte-managed file storage used by the Posix kernel running under the > actually-in-charge IBM mainframe operating system is, of course, subject to > the same constraints and (in)efficiencies discussed in this thread. Thanks for the clarification (and @wlfraed's addition). Apologies if misunderstood. The above comment was about utilities which would choose between algorithms, based on some rapid, initial, assessment of the task. It was not about 'tail' utility/ies specifically - and I don't recall using a 'tail' on mainframes, but... Thus, the observation that the OP may find that a serial, read-the-entire-file approach is faster is some situations (relatively short files). Conversely, with longer files, some sort of 'last chunk' approach would be superior. -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Style for docstring
Yes, Michael, a dictionary is an excellent way to represent a closed set of
transitions which your permutations are.
You examples use numerals but obviously a dictionary will allow transformations
of anything that can be hashed which mostly is items that are not mutable.
Of course for the purposes you may be using these permutations, accessing them
may be done carefully as you need to have nothing else in the dictionary and
must access all the keys and make sure you know which keys have already been
visited from another item.
Some other data structures may work better or faster on smaller examples.
I think you have satisfied my curiosity and your main and only question really
was on suggested wording of a Docstring.
Now if only the Docstring idea was replaced by a Dictionary too! Things like:
Dictstring = {"Purpose": "Text", "Args": "Text", "Return(s)": "Text",
"Optional-Note": "Text", "French version": DocStringFrench}
Too late to seriously change the language now!
-Original Message-
From: Michael F. Stemper
To: [email protected]
Sent: Sun, Apr 24, 2022 9:24 am
Subject: Re: Style for docstring
On 23/04/2022 12.43, Avi Gross wrote:
> Given what you added, Michael, your function is part of a larger collection
> of functions and being compatible with the others is a valid consideration.
> Whatever you decide, would ideally be done consistently with all or most of
> them.
> And, of course, it others in the collection also can handle multiple ways to
> specify a permutation, it may be simpler to have each call something like
> as.permutation() that handlesmultiple forms and converts to the one easiest
> for you to use.
> I am not sure that is needed as I suspect the simplest storage is something
> like a list: [0,3,2,4,5,6,7,1,9,8] but could also be shown with each cycle
> as a sub-list or something like anumpy vector or a customized class.
Since you ask, I'm using dictionaries as the internal representation.
If you think about it, a python dictionary *is* a function from one
finite set to another, mathematically. And a (finite) permutation is
a bijection from a (finite) set to itself.
For convenience, the module provides two methods of defining a permutation
other than just entering a dictionary:
>>> import PermGroups as pg
>>> a = {'1':'2', '2':'1', '3':'3'}
>>> b = pg.ParsePerm( '(12)(3)' )
>>> c = pg.ParseDomImg( '123', '213' )
>>> a==b
True
>>> b==c
True
>>>
All of the other functions work on these dictionaries.
I had thought about defining a permutation object, but the conceptual
match between "dict" and "permutation" was too good to discard.
> Clearly if you control the package and how it is used, errors from bad data
> may not be a concern.
An invalidly-constructed permutation will cause an exception, so
the function won't return.
>>> d = {'1':'2', '2':'2', '3':'3'}
>>> pg.ValidateDict(d)
False
>>>
If I was to do it over, I would have named this function something
like IsValidPermutation(), hiding the internal representation as
well as making the function's Boolean nature explicit.
--
Michael F. Stemper
No animals were harmed in the composition of this message.
--
https://mail.python.org/mailman/listinfo/python-list
--
https://mail.python.org/mailman/listinfo/python-list
