I am using AzureML pipelines, where the interface between pipeline steps is through a folder or file.
When I am passing data into the pipeline, I point directly to a single file. No problem at all. Very useful when passing in configuration files which all live in the same folder on my local computer.
However, when passing data between different steps of the pipeline, I can't provide the next step with a file path. All the steps get is a path to some folder that they can write to. Then that same path is passed to the next step.
The problem comes when the following step is then supposed to load something from the folder.
Which filename is it supposed to try to load?
Approaches I've considered:
Use a standardized filename for everything. Problem is that I want to be able to run the steps locally too, independant of any pipeline. This makes very for a very poor UX for that use case.
Check if the path is to a file, if it isn't, check all the files in the folder. If there is only one file, then use it. Otherwise throw an exception. This is maybe the most elegant solution from a UX perspective, but it sounds overengineered to me. We also don't structurally share any code between the steps at the moment, so either we will have repetition or we will need to find some way to share code, which is non-trivial.
Allow custom filenames to be passed in optionally, otherwise use a standard filename. This helpes with the UX, but often the filenames are supposed to be defined by the configuration files being passed in, so while we could do some bash scripting to get the filename into the command, it feels like a sub-par solution.
Ultimately it feels like none of the solutions I have come up with are any good.
It feels like we are making things more difficult for ourselves in the future if we assume some default filename. F.x. we work with multiple file types, so it would need to omit an extension.
But any way to do it without default filenames would also cause maintainence headache down the line, or incurr substantial upfront cost.
The question is am I missing something? Any potential traps, better solutions, etc. would be appreciated. It definately feels like I am somewhat under- and/or overthinking this.
I am currently working with python and Qt which is kind of new for me coming from the C++ version and I realised that in the oficial documentation it says that an UI file can be loaded both from .ui or creating a python class and transforming the file into .py file.
I get the benefits of using .ui it is dynamically loaded so no need to transform it into python file with every change but what are the benefits of doing that?, Do you get any improvements in run time? Is it something else?
Thanks
Well, this question is dangerously near to the "Opinion-based" flag, but it's also a common one and I believe it deserves at least a partial answer.
Conceptually, both using the pyuic approach and the uic.loadUi() method are the same and behave in very similar ways, but with some slight differencies.
To better explain all this, I'll use the documentation about using Designer as a reference.
pyuic approach, or the "python object" method
This is probably the most popular method, especially amongst beginners. What it does is to create a python object that is used to create the ui and, if used following the "single inheritance" approach, it also behaves as an "interface" to the ui itself, since the ui object its instance creates has all widgets available as its attributes: if you create a push button, it will be available as ui.pushButton, the first label will be ui.label and so on.
In the first example of the documentation linked above, that ui object is stand-alone; that's a very basic example (I believe it was given just to demonstrate its usage, since it wouldn't provide a lot of interaction besides the connections created within Designer) and is not very useful, but it's very similar to the single inheritance method: the button would be self.ui.pushButton, etc.
IF the "multiple inheritance" method is used, the ui object will coincide with the widget subclass. In that case, the button will be self.pushButton, the label self.label, etc.
This is very important from the python point of view, because it means that those attribute names will overwrite any other instance attribute that will use the same name: if you have a function named "saveFile" and you name the button "saveFile", you won't have any [direct] access to that instance method any more as soon as setupUi is returned. In this case, using the single inheritance method might be helpful - but, in reality, you could just be more careful about function and object names.
Finally, if you don't know what the pyuic generated file does and what's it for, you might be inclined to use it to create your program. That is wrong for a lot of reasons, but, most importantly, because you might certainly realize at some point that you have to edit your ui, and merging the new changes with your modified code is clearly a PITA you don't want to face.
I recently answered a related question, trying to explain what happens when setupUi() is called in much more depth.
Using uic.loadUi
I'd say that this is a more "modular" approach, mostly because it's much more direct: as already pointed out in the question, you don't have to constantly regenerate the ui files each time they're modified.
But, there's a catch.
First of all: obviously the loading, parsing and building of an UI from an XML file is not as fast as creating the ui directly from code (which is exactly what the pyuic file does within setupUi()).
Then, there is at least one relatively small bug about layout contents margins: when using loadUi, the default system/form margins might be completely ignored and set to 0 if not explicitly set. There is a workaround about that, explained in Size of verticalLayout is different in Qt Designer and PyQt program (thanks to eyllanesc).
A comparison
pyuic approach
Pros:
it's faster; in a very simple test with a hundred buttons and a tablewidget with more than 1200 items I measured the following bests:
pyuic loading: 33.2ms
loadUi loading: 51.8ms
this ratio is obviously not linear for a multitude of reasons, but you can get the idea
if used with the single inheritance method, it can prevent accidental instance attribute overwritings, and it also means a more "contained" object structure
using python imports ensures a more coherent project structure, especially in the deployment process (having non-python files is a common source of problems)
the contents of those files are actually instructive, especially for beginners
Cons:
you always must remember to regenerate the python files everytime you update an ui; we all know how easy is to forget an apparently meaningless step like this might be, expecially after hours of coding: I've seen plenty of situations for which people was banging heads on desks (hopefully both theirs) for hours because of untraceable issues, before realizing that they just forgot to run pyuic or didn't run it on the right files; my own forehead still hurts ;-)
file tracking: you have to count two files for each ui, and you might forget one of them along the way when migrating/forking/etc, and if you forgot an ui file it possibly means that you have to recreate it completely from scratch
n00b alert: beginners are commonly led to think that the generated python file is the one to be used to create their programs, which is obviously wrong; unfortunately, the # WARNING! message is not clear enough (I've been almost begging the head PyQt developer about this); while this is obviously not an actual problem of this approach, right now it results in being so
some of the contents of a pyuic generated files are usually unnecessary (most importantly, the object name, which is used only for specific cases), and that's pretty obvious, since it's automatically generated ("you might need that, so better safe than sorry"); also, related to the issue above, people might be led to think that everything pyuic creates is actually needed for a GUI, resulting in unnecessary code that decreases its readability
loadUi method
Pros:
it's direct and immediate: you edit your ui on Designer, you save it (or, at least, you remember to do it...), and when you run your code it's already there; no fuss, no muss, and desks/foreheads are safe(r)
file tracking and deployment: it's just one file per ui, you can put all those ui files in a separate folder, you don't have to do anything else and you don't risk to forget something on the way
direct access to widgets (but this can be achieved using the multiple inheritance approach also)
Cons:
the layout issue mentioned above
possible instance attribute overwriting and no "ui" object "containment"
slightly slower loading
path and deployment: loading is done using os relative paths and system separators, so if you put the ui in a directory different from the py file that loads that .ui you'll have to consider that; also, some package managers use to compress everything, resulting in access errors unless paths are correctly managed
In my opinion, all considering, the loadUi method is usually the better choice. It doesn't distract me, it allows better conceptual compartmentation (which is usually good and also follows a pattern similar to MVC much more closely, conceptually speaking) and I strongly believe it as being far less prone to programmer errors, for a multitude of reasons.
But that's clearly a matter of choice.
We should also and always remember that, like every other choice we do, using ui files is an option.
There is people who completely avoids them (as there is people who uses them literally for anything), but, like everything, it all and always depends on the context.
A big benefit of using pyuic is that code autocompletion will work.
This can make programming much easier and faster.
Then there's the fact that everything loads faster.
pyuic6-Tool can be used to automate the call of pyuic6 when the application is run and only convert .ui files when they change.
It's a little bit longer to set up than just using uic.loadUi but the autocompletion is well worth it if you use something like PyCharm.
I'm writing a single-page JavaScript application and I'm using Atom as my text-editor. (It's an Electron application, but that's besides the point.)
I'm also using the linter-jshint plugin for Atom. This is great, as it shows immediately in the text-editor when I make a typo in a variable, among other useful things.
Lately, my app has been getting very long. Naturally, I want to try and split it up across multiple files. After doing some research on StackOverflow, I've determined that I can use Grunt to automatically concatenate JavaScript files together. This is great because I don't have to refactor my code - I can just copy paste my existing functions into separate files. Easy!
However, once I do this, Atom fills up with warnings and errors from JSHint, because it can't find variables and functions that are located in the other files!
Now, I could just abandon the JHint plugin in Atom altogether and use the JSHint plugin for Grunt after the concatenation has already occured. But that sucks! I want the code that I'm going to be writing to be checked on the fly like a real IDE.
Is there a way to tell Atom/JSHint to assume that a bunch of JavaScript files will all be concatenated together? Or am I just approaching this problem completely wrong?
You can split your electron application with Node Common Modules, and use require('./state.js'); within your application.
Although I don't use Atom, that should allow for it to understand how you're using your variables and functions in other files.
Also this should eliminate your need for concatenation as the single-page app will have all it's dependencies accounted for.
Is there a way to tell the sbt-onejar SBT plugin to produce a JAR in such way that the .class files of my project are in "expanded" form and not under lib/myproject.jar?
Alternatively, is it possible to tell sbt-onejar to produce a JAR that, when it's loaded, it actually unpacks/expands the nested JARs into a temporary folder and loads them from there, so that things like getResource(...) return paths to physical files as opposed to jar:file:... URLs?
Alternativel, I'd also happy with any vanilla OneJar solutions that help me produce a fat JAR wherein my own .class files would be directly under the fat JAR as opposed to under lib/myproject.jar.
I'm asking because Jetty does not seem to be able to load JSP files from inside of nested JAR files. There does seem to be a workaround by using a custom resource loader (see http://dev.eclipse.org/mhonarc/lists/jetty-users/msg01174.html for a report of the same problem and the workaround) but I don't seem to be able to get my servlets to actually use the overridden getResource method provided in the workaround.
After having read sbt-onejar's source code:
packageOptions in oneJar ++=
Seq(sbt.Package.ManifestAttributes(
new java.util.jar.Attributes.Name("One-Jar-Expand") -> "some-file.txt"))
However, I've realized using OneJar with Jetty is quite a problematic beast due to how Jetty loads JSP files—doesn't seem to work with nested JARs—so I'm looking into alternatives now.
EDIT: I've found https://github.com/xerial/sbt-pack and it seems to achieve the same effect as OneJar with the difference of being standard and thus free of problems, much faster, more customizable, and allows defining of convenient custom program entry points.
When I perform a refactoring (extract variable for instance) in a .mxml file, IntelliJ reformats the contents whole <mx:Script> element. We don't want it to do that because it makes the commits noisier than it needs to be. This in turn complicates merges.
Part of the problem is that we're transitioning from Eclipse to IntelliJ - which has generally been a big improvement - and we're still getting our code style sorted out. So there are some inconsistencies in the format actually present in a particular file. A problem, which to some degree pre-dates our migration. We are working on getting a standard format published, which will help. But we don't need the merge conflicts. This is out of character for IntelliJ. How do we prevent this?
It's a known bug, you can track it at http://youtrack.jetbrains.com/issue/IDEA-64985.
It may help if you change your code style to be similar between Eclipse and IDEA so that reformat doesn't change it.