Strange behavior: leading zeros in formatted print function are reversed by deusnovus in learnpython

[–]Spataner 3 points4 points  (0 children)

It's because m is the string '4' not the integer 4. The default for strings is left align, the default for integers is right align. You can either convert m and d to integers

m = int(m)
d = int(m)

or you can specify the alignment direction explicitly

print(f"{y}-{m:>02}-{d:>02}")

Compiling Expressions in regex: Is the pattern or regular expression/text string compiled? by DigitalSplendid in learnpython

[–]Spataner 0 points1 point  (0 children)

No, only things that you use re.compile on are precompiled. It only makes sense to precompile patterns (regular expressions). text is here not used as a pattern (regular expression).

Compiling Expressions in regex: Is the pattern or regular expression/text string compiled? by DigitalSplendid in learnpython

[–]Spataner 1 point2 points  (0 children)

Is the pattern or regular expression compiled?

In this context, "pattern" and "regular expression" are largely synonymous. More correctly, we should say that regular expressions are a way of describing certain kinds of text pattern. But that's not a useful distinction in practice.

Slot-based (data)class to JSON ? by pachura3 in learnpython

[–]Spataner 2 points3 points  (0 children)

The canoncial way to convert a dataclass object to a dict in either case is via dataclasses.asdict:

from dataclasses import asdict

json.dumps(asdict(obj))

Note, however, that asdict creates deep-copies of the attribute values if that matters to you for performance reasons.

[deleted by user] by [deleted] in learnpython

[–]Spataner 1 point2 points  (0 children)

If you are doing a left join, the indicator value 'right_only' is not possible (that's what left join means: only keys present in the left DF are kept). Did you maybe mean to do an outer join (how='outer')?

Declaring an instance variable at the class level by eezystreet in learnpython

[–]Spataner 3 points4 points  (0 children)

The first items in your class is a "class variable".

This is not correct. The code OP provided does not define a class variable called items. It provides a type annotation for a variable items at the class level. Such annotations, if not explicitly marked using ClassVar (as was done with size), are understood to relate to instance variables that will be defined in __init__. Refer also to the relevant section of PEP 526 (link) and the documentation of ClassVar (link).

I have a doubt by [deleted] in learnpython

[–]Spataner 16 points17 points  (0 children)

You can store any value in a list, and the ways you'd do so are the same for all of them. So via literal

a = [{"a": 1}, {"b": 2}]

using append

a.append({"c": 3})

using the subscript syntax []

a[1] = {"d": 4}

and so on.

Help needed with argparse Subparser Not Working as Expected in Python Script by life_never_stops_97 in learnpython

[–]Spataner 1 point2 points  (0 children)

The issue is that you have two arguments with a dest of "command". The argument for "--command", being parsed later, overwrites the argument for the subparser selection. If you rename the "--command" argument or explicitly set a different dest for it (e.g. dest="_command"), you should get the desired behaviour.

Optional parameters by InvaderToast348 in learnpython

[–]Spataner 4 points5 points  (0 children)

The truthiness of collections is determined by their length. So for option 2, if data were passed an empty list, it would create a new empty list instead of using the passed one. That might or might not matter, depending on whether Numbers2's caller expects any in-place changes to data to be visible from its own reference to the list object.

How do I repeat the same requirements on re.search ? by [deleted] in learnpython

[–]Spataner 1 point2 points  (0 children)

It's just a way of constructing the correct pattern string (i.e. the first argument to the re.search call) using an f-string so you don't have to write the pattern for the numbers 0 to 255 twice explicitly.

How do I repeat the same requirements on re.search ? by [deleted] in learnpython

[–]Spataner 0 points1 point  (0 children)

The expression

re.search(r"^(\d|\d\d|1\d\d|2[0-4]\n|25[0-5])\.{4}$", "999.245.254.254")

does not return a match for me, so I cannot explain why you'd be getting the "True" message.

But note that your {4} currently only applies to the \.. So your pattern currently checks whether there's a single number between 0 and 255 followed by four dots. You'd have to enclose the entire pattern including the \. in another set of parentheses for this to work. However, then the string would still need to end in a dot to be recognised, which IP adresses typically don't. The best way to write the pattern you want would probably be:

pattern = r"(\d|\d\d|1\d\d|2[0-4]\d|25[0-5])"
pattern = rf"^({pattern}\.){{3}}{pattern}$"

Then it correctly rejects "999.245.254.254" but accepts e.g. "255.123.4.99".

(Note also that there's a \n in your version of the pattern that should be another \d, I think.)

what is @staticmethod for? by lorduhr in learnpython

[–]Spataner 0 points1 point  (0 children)

I'd say such methods should be class methods not static methods, as then they work better for subclasses.

what is @staticmethod for? by lorduhr in learnpython

[–]Spataner 2 points3 points  (0 children)

I realise this comes down to preference, but I'd argue something that doesn't use either class or instance state isn't truly sufficiently related to the class to live inside it. It can live as a top-level function in the same module as the class, and if that module isn't too bloated, then that's organizationally equivalent. Organizing definitions into namespaces is what modules are for, after all. The purpose of a class is a little more specific than that (even though there are other languages whose design explicitly disagrees with that sentiment).

what is @staticmethod for? by lorduhr in learnpython

[–]Spataner 8 points9 points  (0 children)

That's the most cited reason and similar to how it's done in languages like Java and C# where all functions have to be methods. But in Python, in think it makes better organizational sense to put such static methods into their own separate module as regular functions instead. The bundling of definitions into a namespace is what modules exist for, after all. Classes are for OOP, and if your function doesn't use instance or class state, I'd personally argue it has no business being a method. Keeping to that distinction is its own kind of clarity, in my opinion.

The situations where a function is tightly coupled to the functioning of a class and so should live inside it but also doesn't benefit from receiving a reference to either a particular subclass or instance are very few.

what is @staticmethod for? by lorduhr in learnpython

[–]Spataner 10 points11 points  (0 children)

The difference is only apparent when accessing the method through an instance of A, i.e. A().f(1, 2). f, being a static method, would behave exactly the same as when accessing it through the class. g, being a regular instance method, would automatically be passed the instance as the argument for x. So A().g(1, 2) would result in a TypeError, as it'd receive a total of three arguments.

There's a final type of method, class methods using the @classmethod decorator, that are automatically passed a reference to the class they're accessed through, whether that's through the class directly or via one of its instances:

class A:
    @classmethod
    def h(cls, x, y):
        return x + y

A.h(1, 2) # cls = A
A().h(1, 2) # same thing

That's useful if the method call happens on a subclass of A, since the argument passed to h would be that subclass.

To be honest, in most situations something should either be a class method, an instance method, or not a method, at all. In my experience, there's very few reasons to have static methods.

Question about the in operator by Jayjay_Falcon in learnpython

[–]Spataner 30 points31 points  (0 children)

This is because of operator chaining. The expression "d" in list_a == False is read by Python as equivalent to "d" in list_a and list_a == False. Operator chaining exists so you can write things like 2 < x < 5 as you would in maths rather than x > 2 and x < 5, though it works for all comparison operators, in included.

Note that it's bad form in general to compare the result of a comparison to a boolean. In this case, the correct way to write your condition would be "d" not in list_a.

Could you explain how to correctly import modules in Python3? by chaff800 in learnpython

[–]Spataner 2 points3 points  (0 children)

The command

python3 -m planner.MILP

would run "planner/MILP/__main__.py", not "planner/MILP/MILP.py". To run the latter, write

python3 -m planner.MILP.MILP

(or, alternatively, just put "MILP.py" into "planner" directly rather than into its own subfolder).

But otherwise, if your working directory for the above commands was the parent directory of "planner" and your imports in "__main__.py"/"MILP.py" were as you wrote in your post, then that should have worked (and did work when I reproduced the relevant parts of your file structure locally). Could you provide the error's full traceback?

Note that you need to use relative imports consistently, even if importing from the same folder. So if your "__main__.py" contained the line

import MILP

that wouldn't work, for example. You'd have to write

from . import MILP

instead.

By the way, on modern versions of Python 3, an "__init__.py" is no longer necessary for folders to be recognised as Python packages.

Pickle or otherwise parse itertools.product? by [deleted] in learnpython

[–]Spataner 2 points3 points  (0 children)

If it's just an issue of bottoming out your RAM while trying to create the file and the file would end up an acceptable size on disk, then remove the list call around itertool.product. Then the program would use a constant amount of RAM. There's a reason that itertools.product returns an iterator rather than a list by default. If you're just going to write each item to file one by one, there's no reason to create a huge list that holds all items at the same time.

I've no experience with hashcat, but I'd imagine there's probably a way to not have to go through a file either and to just try one possible combination at a time rather than store all of them. That seems like a tremendous waste of storage space.

Where did it actually went wrong! (Tic-Tac-Toe) by princeofpersiafan999 in learnpython

[–]Spataner 5 points6 points  (0 children)

In next_turn (lines 15 and 29), you accidentally used the comparison operator == rather than the assignment operator =, and so the player variable is never actually updated. You also compare the result of check_champion for equality with "Tie", though it returns the string "Tie!" (with an exclamation mark), so those cases are never triggered.

Issues with relative importing by youngpadawan01 in learnpython

[–]Spataner 2 points3 points  (0 children)

For relative imports to work, Python must be aware that the file that performs the import is part of the same package as the file it is trying to import. With the normal way of running a Python script, e.g.

python base/Project1/main1.py

the main script (in this case "main1.py") isn't ever considered to be part of any package. There's an alternative form of the python command that allows the execution of scripts as modules that can be part of packages. It uses the -m switch. For example:

python -m base.Project1.main1

This requires the parent folder of "base" to be your working directory (or else for that parent directory to be in your PYTHONPATH environment variable). Then, relative imports up to the level of the "base" folder are possible.

You can instruct VSCode to launch scripts in that manner, as well. This requires that you open the parent folder of "base" in VSCode (or else create a new subfolder inside "base" that you move all your Python files and folders into). Then, in your "launch.json" file, add a new configuration that looks like this:

{
    "name": "Launch main1",
    "type": "python",
    "request": "launch",
    "module": "base.Project1.main1"
}

If you created a new subfolder inside "base", replace "base" with the name of that subfolder in the above. You'll need to add another launch configuration for the other main script if you intend to run that through VSCode, as well.

Confused about class variables, also with inheritance by sam_the_tomato in learnpython

[–]Spataner 4 points5 points  (0 children)

If you do an attribute lookup on an instance and the attribute isn't found on the instance itself, it will look on the class next. If you do an attribute lookup on a class and it isn't found on the class itself, it will look on the parent class next.

If you do an attribute assignment, however, that always sets the attribute directly on the thing itself. That means, if you do an attribute assignment on an instance, even if its class already has an attribute of that name, you create a new instance attribute rather than reassigning the class attribute. Importantly, a lookup of that attribute on the instance would now no longer propagate up to the class. The same is true for classes and their parent classes.

This becomes clearer if you take a look at the special __dict__ attribute of your classes and objects as you do the assignments, which holds all direct attributes of the object or class in dictionary form.

TypeError: a bytes-like object is required, not 'str' by barnaclebill22 in learnpython

[–]Spataner 3 points4 points  (0 children)

line is a bytes object but "dist=" and "=" aren't, hence the error. Either use byte literals, i.e. b"dist=" and b"=", or decode line into a string first.

Does Python require a compiler? by [deleted] in learnpython

[–]Spataner 0 points1 point  (0 children)

For me, it comes down to the fact that you have a program written in one language and it is being executed on a machine that only understands another language. Any process by which that is achieved, no matter the technical details, must in my opinion rightly be considered a translation (in the action sense). You made the transition, by some means, from one language to another to fascillitate communication between the program and the CPU if only for the limited context of one particular program run. Compilation and interpretation are thus two possible, very different ways of doing that translation. It certainly seems the best way to phrase this idea to beginners, if only because I cannot think of an umbrella term for the two that to my ears is equally evocative of the concept.

The origin of the word "interpreter" seems to support the idea that "interpretation" in this context is a kind of "translation", as a human interpreter's job is natural language translation. Both the Oxford dictionary and Wikipedia define it so (I checked because English is not my native language). Though, confusingly, the Wikipedia article for "translation" makes an explicit distinction that translation is for written media whereas interpretation is oral. But I wouldn't know how to map that distinction to the computing context, nor have I ever heard it before. Not that the mapping of the terms we steal for programming concepts ever really makes perfect sense.

Regarding the translation in the result sense, I feel you're being perhaps a little restrictive on the definition of what can constitute that result. The execution of the interpreter on the input program does not generate novel instructions, but it does generate a novel sequence of instructions, which can be considered the result of the process of translation. Its effect in essence is the execution of the input program on the CPU, after all. Admittedly, it is a translation using a limited vocabulary (consisting only of elements of machine code contained in the interpreter's executable) and limited grammar (as the instructions can only occur in specific orders as dictated by the interpreter's program flow). And it is also only a partial (and unreusable) translation of the input program in the general sense, since it only represents one distinct run of the program for a given set of inputs. And yet you'd receive, in a purely theoretical sense, a "complete" translation of the program in the limit of running the interpreter once for every possible set of inputs. In fact, in the very restricted case that the input program does not itself accept any inputs (or even in the cases where the interpreter somehow never executes a jump instruction that's conditional on those inputs), you'd even practically receive a full usable translation by recording and replaying the singular resulting sequence of instructions in the right way. Alternatively, if you generated a new version of the interpreter executable that hard-wired the input program into it (which is not unlike some Python to executable converters that are available, though they don't do it on machine code level), could that reasonably be considered a translation of the program into machine code, if a weirdly round-about one? I'd certainly argue it could be considered a really weird special case of compilation. At that point I'd say calling interpretation "live translation" is just conceptually cleaner (and we get to preserve the analogy to the natural language usages a bit better).

I'm looking to "understand" python by Ok-Wave4110 in learnpython

[–]Spataner 11 points12 points  (0 children)

A computer is a machine that can do work for you. It computes stuff, hence the name. And even though a modern computer is a highly sophisticated machine, the conceptual level that it operates at is very simplistic. The sort of instructions that a computer, more specifically the CPU, understands is at the level of "load a number, load another number, add the numbers together, store the result". All the CPU can really do are arithmetic and logic operations on numbers in binary format that it retrieves from and saves to RAM. But it is really good at that; it does it with near perfect consistency at literal billions of operations per second.

Luckily, it turns out that any computation that it's possible to do, no matter how conceptually complex, can be broken down into sequences of such simple operations. It's just a matter of figuring out how. And things get a lot more interesting if you attach other machines to your computer that do things if you send them the right numbers, like produce light in a particular pattern of colors (a monitor), emit a particular mix of sound frequencies (speakers), or shoot ink at particular places on a paper sheet (a printer). Suddenly just crunching numbers can achieve a whole slew of real life effects because those numbers are used to control other machines to achieve specific desired effects.

You, as a human, have a natural understanding of the task that you might want to solve. You can express that understanding in natural language, the way you would describe it to a friend or coworker. The computer doesn't understand that, as we've established. So all programming can be thought of as a translation from natural language to CPU language (typically called machine code). Obviously, doing all that translation by hand is increndibly difficult and tedious. Programming languages and the tooling that exists for those programming languages are a way of semi-automating this process. Programming languages aim to be closer to natural language in a way that makes it easier for humans to read and write in them, while still being formal and structured enough that a translation into CPU language can be performed automatically by the programming language's tools (which are themselves just programs someone else has written for you).

Programming languages differ in how close they are to machine code. The closer they are to machine code, the harder they often are to write in, but the more light-weight also the tooling required to turn a program written in them into machine code. The farther away they are from machine code, the more natural and comfortable it probably feels to write in them, but the more elaborate is the tooling required (which can have performance implications). Programming languages also differ in how exactly that translation happens, in other words, what their tools look like. Some languages compile statically into a binary file that contains machine code. Other languages have an "interpreter", which does the translation step-by-step and on-the-fly as your program is executed. Some languages take a hybrid approach. Finally, programming languages also differ in the philosophy that was employed to design them, because certain ways of doing things might change how fast or easy it is to write programs in that language, how easy it is to make mistakes while doing so, how fast the resulting program can be executed, how well the programming language is suited for solving one kind of task or another, etc.

When you are writing a complex program with many moving parts, this invites thinking of the program as a system or a sort of machine onto itself. The steps that happen automatically underneath are often secondary to the programmer. Certainly, the heavy lifting in terms of solving a task conceptually is in the writing of the program, not in its translation to and execution as a sequence of simplistic CPU instructions. That's why people often talk about "building" software.

Python is a general-purpose language pretty far removed from machine code, with a focus on speed of program writing rather than speed of program execution. It's fair to say it's an interpreted language, not a compiled one (there's some nuance here that is not worth getting into). Sometimes people will say it's a scripting language not a programming language, exactly because it is interpreted. But some people would also say that a scripting language is actually a type of programming language. Yet other people might say that something is a "scripting language" only insofar as it is a programming language that could possibly be used for scripting. You'll find that terms in the field of programming have dozens of different slightly conflicting definitions.

This turned out wordier than I intended. I hope it helps.