Migrating to Qt6: Is there a method to finding long-form names? - pyqt5

I am migrating a codebase of PyQt5 to PyQt6. I read the stackoverflow question another user asked:
Migrating to Qt6/PyQt6: what are all the deprecated short-form names in Qt5?
My question is simply a variation of this, ie, in my case I've spent several hours trying to find the longer form for the following:
def flags(self, index: QModelIndex) -> Qt.QFlags:
return Qt.ItemIsDropEnabled | Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
Error received:
AttributeError: type object 'Qt' has no attribute 'ItemFlags'.
Previously I've been able to figure out the long-form equivalent required in Qt6, but in this case I can't figure it out. (When this one is solved, I will probably have to find the equivalence for
the return values in the code example above: Qt.ItemIsDropEnabled, etc.)
I would have been happy to have posted this in the form of a comment under the other posted question, but stackoverflow says I need 50 reputation pts to comment.

The "flags" (plural form) refers to the combination of enum values, which instead refer to each single value (see the documentation).
As written in the comment of the answer you linked, the PyQt maintainer seems to be very resistant to any "shorter" solution, and he chose to always use the Enum namespace for Python consistence even for flags, and even if some Qt enum/flag names are not consistent for backward compatibility; this might be very confusing, not to mention the fact that this obviously means even longer code lines (and we all know how we already struggle with the length of Qt object names).
To clarify, here's a typical and confusing case (in Qt terms, and valid with PyQt5):
Qt.AlignCenter is a Qt::AlignmentFlag, but its actually an enum (even if it's named "flag"); see the result for PyQt5:
>>> test = Qt.AlignCenter
>>> print(type(test))
<class 'PyQt5.QtCore.Qt.AlignmentFlag'>
>>> print(test)
132
Qt.AlignHCenter|Qt.AlignVCenter results in a Qt::Alignment, but it's actually a flag, even if it's actually equal to Qt.AlignCenter:
>>> test = Qt.AlignHCenter|Qt.AlignVCenter
>>> print(type(test))
<class 'PyQt5.QtCore.Alignment'>
>>> print(test)
<PyQt5.QtCore.Alignment object at 0xb30ff41c>
>>> print(int(test))
132
In any case, the point remains: if you want to use a value, you must use the enum namespace, which is Qt.ItemFlag without the trailing "s".
def flags(self, index: QModelIndex) -> Qt.QFlags:
return (
Qt.ItemFlag.ItemIsDropEnabled
| Qt.ItemFlag.ItemIsEnabled
| Qt.ItemFlag.ItemIsEditable
| Qt.ItemFlag.ItemIsSelectable
| Qt.ItemFlag.ItemIsDragEnabled
)
Remember to always refer to the official C++ API documentation of classes and objects in order to understand the different types and get their proper names: none of the Python docs are good for that, both PyQt and "Qt for Python" (aka, PySide).

Related

What is the difference between `matplotlib.rc` and `matplotlib.rcParams`? And which one to use?

I have been using matplotlib.rc in my scripts to preprocess my plots. But recently I have realized that using matplotlib.rcParams is much easier before doing a quick plot interactively (e.g. via IPython). This got me into thinking what difference between the two is.
I searched the matplotlib documentation wherein no clear answer was provided in this regard. Moreover, when I issue type(matplotlib.rc), the interpreter says that it is a function. On the other hand, when I issue type(matplotlib.rcParams), I am told that it is a class object. These two answers are not at all helpful and hence I would appreciate some help differentiating the two.
Additionally, I would like to know which one to prefer over the other.
Thanks in advance.
P.S. I went through this question: What's the difference between matplotlib.rc and matplotlib.pyplot.rc? but the answers are specific to the difference between the matplotlib instance and the pyplot instance of the two types I am enquiring about and, hence, is also not that helpful.
matplotlib.rc is a function that updates matplotlib.rcParams.
matplotlib.rcParams is a dict-subclass that provides a validate key-value map for Matplotlib configuration.
The docs for mpl.rc are at https://matplotlib.org/stable/api/matplotlib_configuration_api.html?highlight=rc#matplotlib.rc and the code is here.
The class definition of RcParams is here and it the instance is created here.
If we look at the guts of matplotlib.rc we see:
for g in group:
for k, v in kwargs.items():
name = aliases.get(k) or k
key = '%s.%s' % (g, name)
try:
rcParams[key] = v
except KeyError as err:
raise KeyError(('Unrecognized key "%s" for group "%s" and '
'name "%s"') % (key, g, name)) from err
where we see that matplotlib.rc does indeed update matplotlib.rcParams (after doing some string formatting).
You should use which ever one is more convenient for you. If you know exactly what key you want to update, then interacting with the dict-like is better, if you want to set a whole bunch of values in a group then mpl.rc is likely better!

Automatically detect security identifier columns using Visions

I'm interested in using the Visions library to automate the process of identifying certain types of security (stock) identifiers. The documentation mentions that it could be used in such a way for ISBN codes but I'm looking for a more concrete example of how to do it. I think the process would be pretty much identical for the fields I'm thinking of as they all have check digits (ISIN, SEDOL, CUSIP).
My general idea is that I would create custom types for the different identifier types and could use those types to
Take a dataframe where the types are unknown and identify columns matching the types (even if it's not a 100% match)
Validate the types on a dataframe where the intended type is known
Great question and use-case! Unfortunately, the documentation on making new types probably needs a little love right now as there were API breaking changes with the 0.7.0 release. Both the previous link and this post from August, 2020 should cover the conceptual idea of type creation in greater detail. If any of those examples break then mea culpa and our apologies, we switched to a dispatch based implementation to support different backends (pandas, numpy, dask, spark, etc...) for each type. You shouldn't have to worry about that for now but if you're interested you can find the default type definitions here with their backends here.
Building an ISBN Type
We need to make two basic decisions when defining a type:
What defines the type
What other types are our new type related to?
For the ISBN use-case O'Reilly provides a validation regex to match ISBN-10 and ISBN-13 codes. So,
What defines a type?
We want every element in the sequence to be a string which matches a corresponding ISBN-10 or ISBN-13 regex
What other types are our new type related to?
Since ISBN's are themselves strings we can use the default String type provided by visions.
Type Definition
from typing import Sequence
import pandas as pd
from visions.relations import IdentityRelation, TypeRelation
from visions.types.string import String
from visions.types.type import VisionsBaseType
isbn_regex = "^(?:ISBN(?:-1[03])?:?●)?(?=[0-9X]{10}$|(?=(?:[0-9]+[-●]){3})[-●0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[-●]){4})[-●0-9]{17}$)(?:97[89][-●]?)?[0-9]{1,5}[-●]?[0-9]+[-●]?[0-9]+[-●]?[0-9X]$"
class ISBN(VisionsBaseType):
#staticmethod
def get_relations() -> Sequence[TypeRelation]:
relations = [
IdentityRelation(String),
]
return relations
#staticmethod
def contains_op(series: pd.Series, state: dict) -> bool:
return series.str.contains(isbn_regex).all()
Looking at this closely there are three things to take note of.
The new type inherits from VisionsBaseType
We had to define a get_relations method which is how we relate a new type to others we might want to use in a typeset. In this case, I've used an IdentityRelation to String which means ISBNs are subsets of String. We can also use InferenceRelation's when we want to support relations which change the underlying data (say converting the string '4.2' to the float 4.2).
A contains_op this is our definition of the type. In this case, we are applying a regex string to every element in the input and verifying it matched the regex provided by O'Reilly.
Extensions
In theory ISBNs can be encoded in what looks like a 10 or 13 digit integer as well - to work with those you might want to create an InferenceRelation between Integer and ISBN. A simple implementation would involve coercing Integers to string and applying the above regex.

Unable to use pickAFile in TigerJython

In JES, I am able to use:
file=pickAFile()
In TigerJython, however, I get the following error
NameError: name 'pickAFile' is not defined
What am I doing wrong here?
You are not doing anything wrong at all. The thing is that pickAFile() is not a standard function in Python. It is actually rather a function that JES has added for convenience, but which you probably will not find it in any other environment.
Since TigerJython and JES are both based on Jython, you can easily write a pickAFile() function on your own that uses Java's Swing. Here is a possible simple implementation (the pickAFile() found in JES might be a bit more complex, but this should get you started):
def pickAFile():
from javax.swing import JFileChooser
fc = JFileChooser()
retVal = fc.showOpenDialog(None)
if retVal == JFileChooser.APPROVE_OPTION:
return fc.getSelectedFile()
else:
return None
Given that it is certainly a useful function, we might have to consider including it into our next update of TigerJython.
P.S. I would like to apologise for answering so late, I have just joined SO recently and was not aware of your question (I am one of the original authors of TigerJython).

Where is contains( Junction) defined?

This code works:
(3,6...66).contains( 9|21 ).say # OUTPUT: «any(True, True)␤»
And returns a Junction. It's also tested, but not documented.
The problem is I can't find its implementation anywhere. The Str code, which is also called from Cool, never returns a Junction (it does not take a Junction, either). There are no other methods contain in source.
Since it's autothreaded, it's probably specially defined somewhere. I have no idea where, though. Any help?
TL;DR Junction autothreading is handled by a single central mechanism. I have a go at explaining it below.
(The body of your question starts with you falling into a trap, one I think you documented a year or two back. It seems pretty irrelevant to what you're really asking but I cover that too.)
How junctions get handled
Where is contains( Junction) defined? ... The problem is I can't find [the Junctional] implementation anywhere. ... Since it's autothreaded, it's probably specially defined somewhere.
Yes. There's a generic mechanism that automatically applies autothreading to all P6 routines (methods, operators etc.) that don't have signatures that explicitly control what happens with Junction arguments.
Only a tiny handful of built in routines have these explicit Junction handling signatures -- print is perhaps the most notable. The same is true of user defined routines.
.contains does not have any special handling. So it is handled automatically by the generic mechanism.
Perhaps the section The magic of Junctions of my answer to an earlier SO Filtering elements matching two regexes will be helpful as a high level description of the low level details that follow below. Just substitute your 9|21 for the foo & bar in that SO, and your .contains for the grep, and it hopefully makes sense.
Spelunking the code
I'll focus on methods. Other routines are handled in a similar fashion.
method AUTOTHREAD does the work for full P6 methods.
This is setup in this code that sets up handling for both nqp and full P6 code.
The above linked P6 setup code in turn calls setup_junction_fallback.
When a method call occurs in a user's program, it involves calling find_method (modulo cache hits as explained in the comment above that code; note that the use of the word "fallback" in that comment is about a cache miss -- which is technically unrelated to the other fallback mechanisms evident in this code we're spelunking thru).
The bit of code near the end of this find_method handles (non-cache-miss) fallbacks.
Which arrives at find_method_fallback which starts off with the actual junction handling stuff.
A trap
This code works:
(3,6...66).contains( 9|21 ).say # OUTPUT: «any(True, True)␤»
It "works" to the degree this does too:
(3,6...66).contains( 2 | '9 1' ).say # OUTPUT: «any(True, True)␤»
See Lists become strings, so beware .contains() and/or discussion of the underlying issues such as pmichaud's comment.
Routines like print, put, infix ~, and .contains are string routines. That means they coerce their arguments to Str. By default the .Str coercion of a listy value is its elements separated by spaces:
put 3,6...18; # 3 6 9 12 15 18
put (3,6...18).contains: '9 1'; # True
It's also tested
Presumably you mean the two tests with a *.contains argument passed to classify:
my $m := #l.classify: *.contains: any 'a'..'f';
my $s := classify *.contains( any 'a'..'f'), #l;
Routines like classify are list routines. While some list routines do a single operation on their list argument/invocant, eg push, most of them, including classify, iterate over their list doing something with/to each element within the list.
Given a sequence invocant/argument, classify will iterate it and pass each element to the test, in this case a *.contains.
The latter will then coerce individual elements to Str. This is a fundamental difference compared to your example which coerces a sequence to Str in one go.

Is there a significant difference between data['column_name'] vs data.column_name [duplicate]

This question already has answers here:
Accessing Pandas column using squared brackets vs using a dot (like an attribute)
(5 answers)
Closed 4 years ago.
For example, I'm studying an example like this:
train['Datetime'] = pd.to_datetime(train.Datetime,format='%d-%m-%Y %H:%M')
If I run train['Datetime'].head() and train.Datetime.head(), the results are identical. So why use one over the other? Or why use both?
I have used both. I think the most important consideration is about how sustainable and flexible you want your code to be. For quick checks and "imperative programming" (like Jupyter Notebooks), you could use the minimal shorthand:
train.Datetime.head()
However pretty soon you will realize that when you want to pass variables around that may come from a UI or some other source or debug code efficiently, full notation like this:
train['Datetime'].head()
has main benefits, and it is good to make it a habit early on when programming.
First, in Integrated Development Environments (IDE's) used for editing code, the string 'Datetime' will be highlighted to remind you that it is a "hard dependency" in your code. Whereas the Datetime (no quotes, just a .) will not show the highlighting.
This may not sound like a big deal, but when you are looking a 100's of lines of code (or more), seeing where you have "hardcoded" a variable name is important.
The other main advantage of [] notation is that you can pass in string variables to the notation.
import pandas as pd
import numpy as np
# make some data
n=100
df = pd.DataFrame({
'Fruit': np.random.choice(['Apple', 'Orange', 'Grape'], n),
'Animal': np.random.choice(['Cat', 'Dog', 'Fish'], n),
'x1': np.random.randn(n)})
# some name from a user interface. It could be "Fruit" or "Animal"
group = "Animal"
# use that string variable in an expression (in this case, as a group by)
df.groupby(group).agg(['count', 'mean', 'std'])
Here, even in Stack overflow, you can see that in the df.groupby() that there are no hardcoded strings (in red text). This sepration of user inputs and code that does something is subtle, but extremely important.
Good luck!
There will be issue when the column name contain blank spaces, in that case indexing is must.