PEP-8, Line Length, And All That

2023-01-20 Thread Thomas Passin
In another thread ("Improvement to imports, what is a better way ?") 
there was a lot of talk about line length, PEP-8, etc.  I realized that 
one subject did not really come up, yet it can greatly affect the things 
we were talking about.


I'm referring to the design of the functions, methods, and classes. 
When they are well designed, or more likely, refactored over and over 
again, they can lead to code that reads almost like pseudo-code.  Here's 
an example from one of my little projects.  You don't need to know 
anything about the details of the functions or exactly what a "root" is 
to see what I mean.


fileinfo = language, path, ext = getExeKind(root)
processor = getProcessor(*fileinfo)
runfile(path, processor, ext)

[Please don't try to guess exactly what this code needs to do or explain 
how it could be done differently.  That's not the point.]


In words, given a source of information (root), we can get some 
information about a file.  Given that information, we can find a 
suitable processor for it.  And given that processor, we can "run" it.


When I first put this together, the functionality was not cleanly 
separated, the various functions did more than one thing, and I had some 
long lines.  Each line did not necessarily convey cleanly what it was doing.


It took many iterations while I learned how to make the details work 
before I was able to see how to structure this part of the functionality 
into these three nice, clear lines.


In fact, the restructuring isn't quite finished, because the near-final 
version of runfile() does not actually use "ext" (the extension of a 
file) any more.  Its presence is leftover from when runfile() tried to 
do too much.


Why did I assign the (language, path, ext) tuple to fileinfo?  Because 
it was easier and shorter when used as the argument for getProcessor(), 
and I thought it conveyed the intent more clearly than the tuple.


Some people might think to write

processor = getProcessor(*getExeKind(root))

Oops, that doesn't expose path and ext.  Well, not if we are going to 
avoid using a walrus operator, anyway, and if we used it, well, 
readability would go out the window.


In a different context, a "fluent" style can be very readable and 
pleasant to work with.  Here are some lines from a Windows batch file 
that invokes a small Python library written in a fluent style.  The 
first line defines a processing pipeline, and the second passes a data 
file to it ("xy1" is the feeble name for a batch file that calls the 
fluent processing library):


set process=low(30).diff().norm_last_n(%N%).write()
type "c:\data\%1" |xy1 %process% >> %temp%

In words, we smooth the data with a LOWESS smooth using a window width 
of 30, differentiate it, normalize it in a specific way (norm_last_n), 
and write it out (to stdout).


Not shown here, we eventually pipe it to a plotting program.

I intended from the start that this library would work in a "fluent" 
manner.  It took a lot of iterations before I worked out how to design 
it so the it could be invoked in a clean, simple way by a batch file.


All this is to say that program design and refactoring can play a large 
role in writing code that can be understood relatively easily, follow 
the style guidelines as closely as possible, and be as easy as possible 
to maintain.

--
https://mail.python.org/mailman/listinfo/python-list


Re: ok, I feel stupid, but there must be a better way than this! (finding name of unique key in dict)

2023-01-20 Thread Rob Cliffe via Python-list

On 20/01/2023 15:29, Dino wrote:


let's say I have this list of nested dicts:

[
  { "some_key": {'a':1, 'b':2}},
  { "some_other_key": {'a':3, 'b':4}}
]

I need to turn this into:

[
  { "value": "some_key", 'a':1, 'b':2},
  { "value": "some_other_key", 'a':3, 'b':4}
]

Assuming that I believe the above, rather than the code below, this works:

listOfDescriptors = [
    { **  (L := list(D.items())[0])[1], **{'value' : L[0] } }
    for D in origListOfDescriptors]

I believe that from Python 3.9 onwards this can be written more 
concisely as:


listOfDescriptors = [
    { (L := list(D.items())[0])[1] } | {'value' : L[0] }
    for D in origListOfDescriptors]     # untested

Best wishes
Rob Cliffe



I actually did it with:

listOfDescriptors = list()
for cd in origListOfDescriptors:
    cn = list(cd.keys())[0] # There must be a better way than this!
    listOfDescriptors.append({
    "value": cn,
    "type": cd[cn]["a"],
    "description": cd[cn]["b"]
    })

and it works, but I look at this and think that there must be a better 
way. Am I missing something obvious?


PS: Screw OpenAPI!

Dino


--
https://mail.python.org/mailman/listinfo/python-list


Re: ok, I feel stupid, but there must be a better way than this! (finding name of unique key in dict)

2023-01-20 Thread Oscar Benjamin
On Fri, 20 Jan 2023 at 17:30, Dino  wrote:
>
> let's say I have this list of nested dicts:
>
> [
>{ "some_key": {'a':1, 'b':2}},
>{ "some_other_key": {'a':3, 'b':4}}
> ]
>
> I need to turn this into:
>
> [
>{ "value": "some_key", 'a':1, 'b':2},
>{ "value": "some_other_key", 'a':3, 'b':4}
> ]

You want both the key and the value so you can use items():

In [39]: L = [
...:{ "some_key": {'a':1, 'b':2}},
...:{ "some_other_key": {'a':3, 'b':4}}
...: ]

In [40]: [{"value": k, **m} for l in L for k, m in l.items()]
Out[40]:
[{'value': 'some_key', 'a': 1, 'b': 2},
 {'value': 'some_other_key', 'a': 3, 'b': 4}]

--
Oscar
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: ok, I feel stupid, but there must be a better way than this! (finding name of unique key in dict)

2023-01-20 Thread Jon Ribbens via Python-list
On 2023-01-20, Dino  wrote:
>
> let's say I have this list of nested dicts:
>
> [
>{ "some_key": {'a':1, 'b':2}},
>{ "some_other_key": {'a':3, 'b':4}}
> ]
>
> I need to turn this into:
>
> [
>{ "value": "some_key", 'a':1, 'b':2},
>{ "value": "some_other_key", 'a':3, 'b':4}
> ]

[{"value": key, **value} for d in input_data for key, value in d.items()]

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: ok, I feel stupid, but there must be a better way than this! (finding name of unique key in dict)

2023-01-20 Thread Dino

On 1/20/2023 11:06 AM, Tobiah wrote:

On 1/20/23 07:29, Dino wrote:




This doesn't look like the program output you're getting.


you are right that I tweaked the name of fields and variables manually 
(forgot a couple of places, my bad) to illustrate the problem more 
generally, but hopefully you get the spirit.


"value": cn,
"a": cd[cn]["a"],
"b": cd[cn]["b"]

Anyway, the key point (ooops, a pun) is if there's a more elegant way to 
do this (i.e. get a reference to the unique key in a dict() when the key 
is unknown):


cn = list(cd.keys())[0] # There must be a better way than this!

Thanks

--
https://mail.python.org/mailman/listinfo/python-list


Re: ok, I feel stupid, but there must be a better way than this! (finding name of unique key in dict)

2023-01-20 Thread Tobiah

On 1/20/23 07:29, Dino wrote:


let's say I have this list of nested dicts:

[
   { "some_key": {'a':1, 'b':2}},
   { "some_other_key": {'a':3, 'b':4}}
]

I need to turn this into:

[
   { "value": "some_key", 'a':1, 'b':2},
   { "value": "some_other_key", 'a':3, 'b':4}
]


This doesn't look like the program output you're getting.




--
https://mail.python.org/mailman/listinfo/python-list


ok, I feel stupid, but there must be a better way than this! (finding name of unique key in dict)

2023-01-20 Thread Dino



let's say I have this list of nested dicts:

[
  { "some_key": {'a':1, 'b':2}},
  { "some_other_key": {'a':3, 'b':4}}
]

I need to turn this into:

[
  { "value": "some_key", 'a':1, 'b':2},
  { "value": "some_other_key", 'a':3, 'b':4}
]

I actually did it with:

listOfDescriptors = list()
for cd in origListOfDescriptors:
cn = list(cd.keys())[0] # There must be a better way than this!
listOfDescriptors.append({
"value": cn,
"type": cd[cn]["a"],
"description": cd[cn]["b"]
})

and it works, but I look at this and think that there must be a better 
way. Am I missing something obvious?


PS: Screw OpenAPI!

Dino
--
https://mail.python.org/mailman/listinfo/python-list