Path: ...!3.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: David Brown Newsgroups: comp.lang.c Subject: Re: Baby X is bor nagain Date: Thu, 20 Jun 2024 12:34:43 +0200 Organization: A noiseless patient Spider Lines: 204 Message-ID: References: <20240613002933.000075c5@yahoo.com> <20240613174354.00005498@yahoo.com> <20240617002924.597@kylheku.com> <20240618115650.00006e3f@yahoo.com> <20240618184026.000046e1@yahoo.com> <877celzx14.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Thu, 20 Jun 2024 12:34:44 +0200 (CEST) Injection-Info: dont-email.me; posting-host="658fd1c388c737e8ccffa21e0a91fad6"; logging-data="2672306"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+MTQ/Q9OJqxavk9xOWsWnHOKGLb3LVcU0=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Cancel-Lock: sha1:5j9wMuWL3UerqUo5rsssZXnlav8= In-Reply-To: Content-Language: en-GB Bytes: 10955 On 19/06/2024 23:51, bart wrote: > On 19/06/2024 21:42, Malcolm McLean wrote: >> On 19/06/2024 18:49, David Brown wrote: >>> On 19/06/2024 18:52, Malcolm McLean wrote: >>> >>>> Yes, but that's not quite what we want. A typical input would go. >>> >>> It's extremely hard to guess what you want (not "we", but "you" - no >>> one else wants this kind of thing) when you have bizarre requirements >>> and only give bits of them.  So modifying the Python code is left as >>> an exercise if you are interested, especially as it is off-topic. >>> >> This was a work project, so "we". I would never set up such a system. >> But we hasd light-themed and dark-themed icons and they hsd to be >> arranged just so so that the program would find them and show the >> right theme. And as you can imagine, it was a nuisance to we >> programmers to set up the resource scripts so that eveything was right. >> >> So why not get Python to do the job? But there wasn't much enthusiasm. >> So, despite not knowing Python, I decided to have a go, and I got a >> sorted list of icons quite easily, and it looked promising. But now >> the special requirement for a little deviation from alphabetical sort. >> And I couldn't work out how to do that. >> >> And it wasn't what I was supposed to be doing or paid to do. We used >> to have a weekly meeting where we discussed work done. If I said "oh, >> and I spent an afternoon knocking up this little Python script to help >> get those resource files together", then that's OK. If I say that was >> my main focus for the week, no, and if I say I spent substantial time >> on it and it didn't even work - well that really wouldn't go down well. >> So I had to abandon it once it became clear that it would take many >> hours of trawling through docs and online tips to try to work out a >> way. And no-one has posted a solution here. And, whilst there will be >> a way, I suspect that it just doesn't use the mainstream langage >> facilities. I suspect that Python isn't really a programming language >> - a language designed to make it easy to apply arbitrary transforms to >> data - it's a scripting language - a language designed to make it easy >> to call pre-existings code to do the things it is designed to do. >> >> But maybe I'm unfair. >> > > No; I don't like Python either. It's big. It has lots of advanced, > hard-to-grasp features. There's a dozen unwieldy, usually incompatible > ways of getting anything done. Like any major language, for any given programmer there will be things they like, and things they don't like. Python is very flexible, which has its advantages and disadvantages. And both the language and the standard library are very big - again that has pros and cons. I find that you can make good use of Python without knowing anything about its more advanced language features, so I never found the size overwhelming even as a beginner. > > Pretty much everything can be assigned to (the only exception is > reserved words). Because every user identifer (even if declared with def > or class or module) is a variable. The concept of "variable" in Python is quite different from that of C. You can pretend they are similar for very simple Python snippets, but then you will end up thinking there are lots of arbitrary rules for when assignment and function parameters are by value or by reference. It is better to think that all "things" in Python are anonymous reference-counted objects on the heap. When it looks like you have a variable, you actually just have a named reference to such objects. Imagine it more like your "variables" are all "void *" pointers or references, while all other types and structures are malloc'd. These references have no type information - but the objects they point to are all strongly typed. And the objects have reference-counted garbage collection. > > Take a simple feature like a struct with mutable fields: > >    typedef struct {int x, y;} Point; > > How do you do that in Python; maybe a class: > >    class Point: >        pass > >    p = Point()             # create an instance >    p.x = 100               # fill in the fields >    p.qwghheghergh = 200 > > But here you type gobbledygook instead of 'y'; it still works! You can > have an unlimited number of attributes. Yes. It is a dynamic language, and the default is to let you do all sorts of things like this. In particular, every object has a "__dict__" - a hash-map of all fields, including data members and methods. Once an object is created, you can add, change or remove these fields as you want. That lets you do all kinds of useful and interesting things at run-time - but of course it also lets you make all kinds of mistakes. But you can restrict your types in various ways if you want - you can even add type annotations and use a static checker. The way to restrict a type here is using __slots__ : class Point : __slots__ = "x", "y" def __init__(self, x = 0, y = 0) : self.x = x self.y = y def __repr__(self) : return f"point({self.x}, {self.y})" You don't /need/ the __init__ or __repr__, but it's nice to have them. It is the __slots__ entry that is special, because it removes the normal __dict__. Now your type has only data members "x" and "y", and you can't add new ones - intentionally or by mistake. > > Maybe a tuple is better, but those are indexed by number, not by name. > So you use a module providing NamedTuples - except those fields are > immutable. You can only update the lot. > Point = namedtuple("point", ["x", "y"]) Named tuples are indeed a way to do this, and are very common for the purpose. And yes, they are immutable - that's a feature as well as a restriction. It means, amongst other things, that they can be used as keys in dictionaries. You can use the _replace method to change one (or several) fields, while leaving the rest unchanged. Since the tuples are immutable, it returns a new tuple rather than changing the existing one. >>> p = Point(2, 3) >>> p2 = p._replace(x = 45) > Here's one I've just seen (that '@' line is a 'decorator'; don't ask me > what it means): Then let me tell you - "dataclass" is a function that takes a class (the type itself, not instants of the class) and returns a new class with some aspects changed. (That's the kind of thing you can do when classes are objects, and objects can normally be modified in all sorts of ways.) So the syntax here means a class "Point" is defined in the way you wrote it, then passed to the "dataclass" decorator which creates a new class (by adding an __init__ and a __repr__ methods), and then this new class gets the name "Point", hiding the original class. It sounds a bit complicated, but it is a useful concept, and works for classes, functions and other things. > >   from dataclasses import dataclass > >   @dataclass >   class Point: >      x: int >      y: int > >   p = Point(10, 20) >   print (p) > > This looks promising. Then I tried 'p.z = 30'; it still works. You can use @dataclass(slots = True) to make the class use slots, and then you can't create new fields like "p.z". ========== REMAINDER OF ARTICLE TRUNCATED ==========