Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Space Kablooey
May 6, 2009


Dominoes posted:

The code I posted is straight from the declarative base page you linked. AttributeError: type object 'Person' has no attribute 'query', and I can't find your syntax on that page, although I've seen it mentioned before. Can you provide an example of querying from the model, without the syntactic sugar I posted?

Actually I can't. :(

Apparently what I said is a bunch of poo poo that Flask-SQLAlchemy adds on top of SQLAlchemy to make it more palatable, and I'm so used to writing queries in that way that I didn't know it wasn't a default thing. Sorry for that. :(


Dominoes posted:

Regarding queries as generators: Per this article, they're not lazy:

I should have said "behaves like" instead of "functions". My point still stands, though. You really shouldn't gobble up the Query object returned by the db.session.query function.

Besides, a few database drivers do support database cursors. Postgres' psycopg2 does, for example. Though if SQLAlchemy does take advantage of that or not, I don't know.

Adbot
ADBOT LOVES YOU

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
Running into an issue with the Kodi plugin Watchdog on Xubuntu 15.04:

code:
05:16:30 T:139988456277760   ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
   - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
  Error Type: <type 'exceptions.ImportError'>
  Error Contents: /usr/local/lib/python2.7/lib-dynload/_ctypes.so: undefined symbol: PyUnicodeUCS2_FromUnicode
  Traceback (most recent call last):
    File "/home/tv/.kodi/addons/service.watchdog/service.py", line 25, in <module>
      from core import main
    File "/home/tv/.kodi/addons/service.watchdog/core/main.py", line 28, in <module>
      import emitters
    File "/home/tv/.kodi/addons/service.watchdog/core/emitters.py", line 21, in <module>
      from watchdog.observers.api import BaseObserver
    File "/home/tv/.kodi/addons/service.watchdog/lib/watchdog/observers/__init__.py", line 63, in <module>
      from .inotify import InotifyObserver as Observer
    File "/home/tv/.kodi/addons/service.watchdog/lib/watchdog/observers/inotify.py", line 74, in <module>
      from .inotify_buffer import InotifyBuffer
    File "/home/tv/.kodi/addons/service.watchdog/lib/watchdog/observers/inotify_buffer.py", line 20, in <module>
      from watchdog.observers.inotify_c import Inotify
    File "/home/tv/.kodi/addons/service.watchdog/lib/watchdog/observers/inotify_c.py", line 23, in <module>
      import ctypes
    File "/usr/local/lib/python2.7/ctypes/__init__.py", line 10, in <module>
      from _ctypes import Union, Structure, Array
  ImportError: /usr/local/lib/python2.7/lib-dynload/_ctypes.so: undefined symbol: PyUnicodeUCS2_FromUnicode
  -->End of Python script error report<--
Googling around for "undefined symbol: PyUnicodeUCS2_FromUnicode" hasn't seemed to yield anything useful yet. Any ideas?

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug
That custom Python installation (in /usr/local) seems to be broken. What happens if you run /usr/local/bin/python and try import ctypes at the interactive prompt? Where did this Python installation come from?

(Incidentally, Xubuntu 15.04 is no longer receiving security updates, and you should probably consider upgrading to 15.10 very soon.)

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Lysidas posted:

That custom Python installation (in /usr/local) seems to be broken. What happens if you run /usr/local/bin/python and try import ctypes at the interactive prompt? Where did this Python installation come from?

(Incidentally, Xubuntu 15.04 is no longer receiving security updates, and you should probably consider upgrading to 15.10 very soon.)

code:
tv@htpc:~$ /usr/local/bin/python
Python 2.7.9 (default, Oct 16 2015, 08:09:06)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
I don't think I ever changed the python installation. It should be whatever the default one is. I just upgraded to 15.10 and I'm seeing the same issue.

hooah
Feb 6, 2006
WTF?
I need a little help translating a scripta from Python 2 to Python 3, since I haven't really worked with 2. The script is from https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/multilabel/, namely trans_class.py. I know enough about the differences to clean up the print, split, and join statements, but I don't really understand what's going on in line 51 (my edit). Any help?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

hooah posted:

I need a little help translating a scripta from Python 2 to Python 3, since I haven't really worked with 2. The script is from https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/multilabel/, namely trans_class.py. I know enough about the differences to clean up the print, split, and join statements, but I don't really understand what's going on in line 51 (my edit). Any help?

Looks like you need to get rid of the brackets around the lambda argument. i.e. "(num)" should be "num"

That might be all you need to do.

hooah
Feb 6, 2006
WTF?
Thanks, worked like a charm.

SurgicalOntologist
Jun 17, 2004

This is a super specific question, but I'm wondering if anyone has any troubleshooting suggestions here.

I'm using IPython notebooks to demonstrate visual phenomena in a Perception class I'm teaching (i.e. optical illusions and the like). I usually use ipywidgets to let students play with the stimulus and see how the effect changes. It works great with static stimuli. Getting keypresses, clicks, and typed responses sequentially was a bitch to get working but I've figured that out as well. Now I'm doing motion perception so the displays are animated. Combining matplotlib animations with ipywidgets sliders was a bit tricky, but I thought I got it to work. Let me share my code before continuing.

Python code:
class PhiMotion:
    def __init__(self, ax, n_circles=10, outer_radius=1, circle_radius=0.15, color='black'):
        self.ax = ax
        
        self.circles = []
        for angle in np.linspace(0, 2 * np.pi, n_circles + 1)[:-1]:
            circle = Circle(outer_radius * np.array([np.cos(angle), np.sin(angle)]), circle_radius, color=color)
            ax.add_patch(circle)
            self.circles.append(circle)
        
    def update(self, i):
        self.circles[i % len(self.circles)].set_visible(False)
        self.circles[(i - 1) % len(self.circles)].set_visible(True)

fig = plt.figure(figsize=(6, 6))
ax = fig.add_axes([0, 0, 1, 1], frameon=False, xticks=[], yticks=[], aspect='equal')
ax.set_xlim([-2, 2])
ax.set_ylim([-2, 2])

@interact(animation_speed=(1, 120, 1))
def phi_sliders(animation_speed):
    # Need to clear circles from previous settings, if any.
    for child in ax.get_children():
        if isinstance(child, Circle):
            child.remove()
    phi = PhiMotion(ax)

    anim = FuncAnimation(fig, phi.update, interval=1000 * animation_speed/framerate_hz)
    display(fig)
    return anim
This works great for me with the %matplotlib notebook backend. Removing the display call or not returning the animation make it not work. I don't fully understand why they're necessary.

The lab where I teach has Macbooks with Anaconda installed. As always I tested it on the instructor laptop to make sure it works there. All good.

Come lab time, it didn't work for most anyone else. It worked on the instructor Macbook and two others (out of 16). I called a break and got to work frantically troubleshooting. I could find no differences between the laptops that worked and those that didn't. Same versions of all libraries. I ended up resorting to the osx backend, which worked great but opens up the figure in a new window, so you need to awkwardly rearrange the browser window to see the slider and the figure at the same time.

Anyways, the class went fine from there, but I'm still curious on this one. Any idea what was going wrong? Or just stuff to try?

Jose Cuervo
Aug 25, 2004
GUI development question.

This is my first time programming a simple GUI around a small simulation I wrote. The idea is to have one window where people can change the values of various simulation parameters before hitting next and moving on to the second window, a second window where they can press a button to run the model with the new parameters before hitting next and moving on to the third window, and finally a third window where they can see the output of the simulation when it is done.

I am using Enaml (http://nucleic.github.io/enaml/docs/index.html) as the GUI framework(?).

Here is my code:

Python code:
# sim_gui.py
import enaml
from enaml.qt.qt_application import QtApplication

class SimParams:
    def __init__(self,
                 duration=0, num_reps=None, 
                 fuel_epsilon=0.1, pns_epsilon=0.03, eql_epsilon=0.03):
        self.duration = float(duration)
        self.num_reps = num_reps
        self.fuel_epsilon = float(fuel_epsilon)
        self.pns_epsilon = float(pns_epsilon)
        self.eql_epsilon = float(eql_epsilon)


if __name__ == '__main__':
	params = SimParams()

	with enaml.imports():
		from sim_params_view import SimParamsView
		from sim_run_view import SimRunView

	app = QtApplication()
	
	param_view = SimParamsView(params=params)
	param_view.show()
	app.start()
	
	run_view = SimRunView()	
	run_view.show()
	app.start()
code:
# sim_params_view.enaml
from enaml.widgets.api import (Window, Label, Field, Form, PushButton)
from enaml.stdlib.fields import FloatField, IntField

enamldef SimParamsForm(Form):
	attr params
	attr sim_params_window

	Label:
		text = "Simulation duration (days)"
	FloatField:
		value << params.duration
		value := params.duration
		
	Label:
		text = "Number of replications"
	IntField:
		value << 0
		value := params.num_reps

	Label:
		text = "Fuel epsilon"
	FloatField:
		value << params.fuel_epsilon
		value := params.fuel_epsilon
		
	Label:
		text = "PNS epsilon"
	FloatField:
		value << params.pns_epsilon
		value := params.pns_epsilon
		
	Label:
		text = "EQL epsilon"
	FloatField:
		value << params.eql_epsilon
		value := params.eql_epsilon

	PushButton:
		text = 'Finished setting simulation parameters'
		pass

enamldef SimParamsView(Window): sim_params_window:
	attr params
	title << "Simulation Parameters"
	
	SimParamsForm:
		params := parent.params
code:
#sim_run_view.enaml
from enaml.widgets.api import (Container, Window, Label, Field, Form, PushButton)
from enaml.stdlib.fields import FloatField, IntField

enamldef SimRunView(Window): sim_run_window:
	title = "Run Simulation"
	
	Container:
		PushButton:
			text = 'Begin Simulation Run'
			clicked :: sim_run_window.close()
I am trying to figure out how to "move" from the first window (SimParamsView) to the next window (SimRunView) when the PushButton at the bottom of the first window is pushed.

I think the logic should be to close the param_view window and open the run_view window, which is what I have in sim_gui.py, but even if this is correct, I don't know how to achieve it.

QuarkJets
Sep 8, 2008

By "move", you mean that you don't want to just close the previous window and open a new window, but rather have the contents of the new window replacing the contents of the old window?

Try using states:
http://doc.qt.io/qt-4.8/statemachine-api.html
http://doc.qt.io/qt-5/qtwidgets-statemachine-eventtransitions-example.html

States allow you to define properties for various widgets that should change depending on which state you're in. So you could hide some widgets in state 1, reveal them and hide other widgets in state 2, and then hide even more widgets and reveal others in state 3. And if you want to get all web2.0 about it then you can define cute animations or whatever as part of those transitions, but as a simple first attempt tutorial you can follow the statemachine-api example and just change the contents of a QLabel when you transition between states.

QuarkJets
Sep 8, 2008

This is with Qt mind you, I don't know what enamel is or whether it might have a simpler way to solve your problem. But Qt States are pretty straightforward on their own, so you could try that since enamel is apparently based on Qt, per your imports

Dominoes
Sep 20, 2007

Looking for an Anaconda Wizard.

I was trying to use Qt5, but now want both Jupyter QTconsole and matplotlib.

After installing PyQt5 from a binstar repo and uninstalling pyqt[4]?, PyQt5 works, jupyter qtconsole works, spyder doesn't work, and matplotlib doesn't work. After uninstall PyQt5 and reinstalling pyqt, PyQt4 works, jupyter console's broken, and spyder and matplotlib work.

It looks lib/site-packages/qtconsole/qt_loaders.py is having probs; I get a graphical error from that file. Any ideas? I just need matplotlib and qtconsole working at the same time.

QuarkJets
Sep 8, 2008

I don't really know how to fix your problem, but presumably the issue is matplotlib and spyder getting built against a different version of Qt4 than jupyter qtconsole. One solution could be to try installing Qt5, set up your virtual environment normally, and then compile new version of matplotlib and spyder that link against Qt5. Another could be to do the reverse: recompile jupyter notebook with Qt4.

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.
Is there a stupid simple unconstrained non-linear solver for python similar to Matlab's fminunc?

OnceIWasAnOstrich
Jul 22, 2006

KernelSlanders posted:

Is there a stupid simple unconstrained non-linear solver for python similar to Matlab's fminunc?

https://docs.scipy.org/doc/scipy/reference/optimize.html

Jose Cuervo
Aug 25, 2004

QuarkJets posted:

By "move", you mean that you don't want to just close the previous window and open a new window, but rather have the contents of the new window replacing the contents of the old window?

Try using states:
http://doc.qt.io/qt-4.8/statemachine-api.html
http://doc.qt.io/qt-5/qtwidgets-statemachine-eventtransitions-example.html

States allow you to define properties for various widgets that should change depending on which state you're in. So you could hide some widgets in state 1, reveal them and hide other widgets in state 2, and then hide even more widgets and reveal others in state 3. And if you want to get all web2.0 about it then you can define cute animations or whatever as part of those transitions, but as a simple first attempt tutorial you can follow the statemachine-api example and just change the contents of a QLabel when you transition between states.

Bah, I cannot figure out how to get this to work. Perhaps I should explain what I am trying to do overall and then see what people think is the best way to accomplish it.

I have a small simulation written in Python which I would like to have a GUI so that someone can specify the input scenario, run the simulation, and see the output of the simulation without having to muck about with the code.

Ideally the user flow through the GUI will be:
code:
1. Front page/screen: the user will choose whether to load an existing scenario (via a file) or 
create their own scenario
1. a) Load scenario screen: screen where the user can choose the file to load the scenario from
2. Scenario screen:  This will basically be a form that lists the various entities in the scenario.  If 
the user loaded a scenario then the fillable fields are pre-filled with the values from the file, otherwise 
they are empty and require the user to fill them.  The caveat here is that I would like to update the page 
dynamically in response to edits made by the user.  An example of this is the following: The simulation 
scenario must contain at least three nodes, but can contain more nodes if the user wishes to add 
them to the scenario.  So when the page/screen first loads it would have fields to specify the 
attributes of the three nodes that must be part of the scenario, but I would also like to have a 
button so that the user can "add a node" and the page updates to have additional fields to specify 
the attributes of the additional node.
3. Simulation parameters screen:  This is a screen where various simulation parameters can 
be specified (length of simulation, number of replications, etc) by the user.  It will be 
pre-populated with defaults that the user can change.
4. Progress screen: A screen that displays the progress of the simulation (simply calculated as 
the number of simulation replications completed divided by the total number of replications to 
be performed)
5. Results screen: A screen that shows the results of the simulation (various graphs, averages 
with confidence intervals, etc) that would ideally change based on the user selecting between 
different types data analysis from a drop-down list.
I don't know if building a GUI application is the easiest way to accomplish the above, or if I should try building a web application (which I think means I would use HMTL pages in a broswer as the GUI on a local server, correct?). Any thoughts and advice is welcome as I clearly don't know how to approach this problem but need to get started doing something.

Also, if there is a better place for this question please let me know.

QuarkJets
Sep 8, 2008

Which part are you having trouble with, specifically? Transitions from one window to the next? Understanding signals and slots? Making any GUI at all?

Qt has widgets and tools to do basically everything that you listed, so it's a totally feasible idea.

Jose Cuervo
Aug 25, 2004

QuarkJets posted:

Which part are you having trouble with, specifically? Transitions from one window to the next? Understanding signals and slots? Making any GUI at all?

Qt has widgets and tools to do basically everything that you listed, so it's a totally feasible idea.

I guess I am running into a few problems:
1. I have never built a GUI before, so I don't quite understand what the "flow" of building one should look like, what things I need to have in order to make the transitions from one window to the next, and I had not heard about signals and slots until you mentioned them.
2. I was trying to use Enaml (http://nucleic.github.io/enaml/docs/) since the pitch for it was its ease of implementation:
https://www.youtube.com/watch?v=ycFEwz_hAxk
but the documentation leaves something to be desired (perhaps the documentation is good and the pieces are all there, I just don't understand how to put them together?)
3. I am under a time constraint and was looking for the easiest method to have something up and running.

I guess the first question is, should I give up on using Enaml and use something else? If so, what?

QuarkJets
Sep 8, 2008

If enaml doesn't have enough documentation to at least get you going, then you should abandon it; ease of implementation is meaningless if you don't adequately inform people on how to use your framework.

Try pyside instead. Pyside is based on Qt and officially supported by Qt. There are a million tutorials for it and Qt is well-known for having extensive documentation and a huge community of users. Even if someone is answering a question for the C++ implementation of Qt, it's usually straightforward to translate that C++ answer into a Python answer. PySide itself is pretty easy to use and is usually the thread's go-to recommendation for "how do I make a GUI?"

If you're rushed, maybe skip to the Hello World example, figure out how to add buttons and labels to a GUI, figure out how to make multiple windows, and then just A) define all of the windows that you want to use and B) create buttons for each window that unhides each subsequent window while hiding the previous window. That's a simple, easy implementation that doesn't require any weird tricks.
https://wiki.qt.io/PySide_Tutorials

You don't have to deal with XML or any of that poo poo, you can just write your GUI entirely in Python and have something basic up and running in relatively short order if you're willing to use buttons that literally just hide and reveal various predefined windows.

Jose Cuervo
Aug 25, 2004

QuarkJets posted:

If enaml doesn't have enough documentation to at least get you going, then you should abandon it; ease of implementation is meaningless if you don't adequately inform people on how to use your framework.

Try pyside instead. Pyside is based on Qt and officially supported by Qt. There are a million tutorials for it and Qt is well-known for having extensive documentation and a huge community of users. Even if someone is answering a question for the C++ implementation of Qt, it's usually straightforward to translate that C++ answer into a Python answer. PySide itself is pretty easy to use and is usually the thread's go-to recommendation for "how do I make a GUI?"

If you're rushed, maybe skip to the Hello World example, figure out how to add buttons and labels to a GUI, figure out how to make multiple windows, and then just A) define all of the windows that you want to use and B) create buttons for each window that unhides each subsequent window while hiding the previous window. That's a simple, easy implementation that doesn't require any weird tricks.
https://wiki.qt.io/PySide_Tutorials

You don't have to deal with XML or any of that poo poo, you can just write your GUI entirely in Python and have something basic up and running in relatively short order if you're willing to use buttons that literally just hide and reveal various predefined windows.

Thanks! This is what I needed to get started, I have been going through the Zetcode Pyside tutorials. I am sure I will have more specific questions, but for now I can at least moving.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

WRT Python desktop apps...

Another way to go that I quite like (though I've just tinkered with it and haven't done any serious development this way yet), is to build a python web app with Django or Flask or web.py or whatever is needs-suiting, add html/css/js and bundle it with Electron or QTWebKit.

It's not for everyone or every situation, but it seems to work very well.

You can also skip the Electron or QTWebKit part and just use the users browser.

QuarkJets
Sep 8, 2008

I've never used any of that stuff so I don't know how easy it is to implement, but it sounds pretty complicated compared to just writing a pyside script

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

It all depends on what you're doing and what you're familiar with.

One way or the other certainly isn't clearly better in the general case than the other.

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

Thermopyle posted:

WRT Python desktop apps...

Another way to go that I quite like (though I've just tinkered with it and haven't done any serious development this way yet), is to build a python web app with Django or Flask or web.py or whatever is needs-suiting, add html/css/js and bundle it with Electron or QTWebKit.

It's not for everyone or every situation, but it seems to work very well.

You can also skip the Electron or QTWebKit part and just use the users browser.

I've looked at that as well. The nice part is that you get access to a ton of nice web ui kits like bootstrap

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Hubis posted:

I've looked at that as well. The nice part is that you get access to a ton of nice web ui kits like bootstrap

Yeah, I was going to say something along these lines in my last post but I was phone posting.

Qt isn't exactly a hotbed of new UI toolkit development. I mean, you could make the argument that that's because it and it's paradigm has reached the perfect state, but...

Generally speaking I'd rather design a UI with the tools available to the web rather than what you've got for developing Qt-ish applications.

Again, that all depends on your needs though. If you feel it's very important that your application use native widgets*, or you just need to get the user to answer a couple questions, or whatever, pyside is where it's at.

As far as the "extra complexity" argument goes...on the one hand it is more complicated at one level, but on the other hand most of that extra complexity is hid from the developer by the tools available...as long as you're already familiar with developing UI with web technologies.


*I question the importance of this. In the age of the web where every site has it's own UI/UX, people seem to manage just fine.

SurgicalOntologist
Jun 17, 2004

I don't use regex that much, and I could use some advice on best practices. I've got a pretty long multiline regex pattern (14 lines, some lines have 400+ characters). Speed isn't a concern, I'm just thinking about readability, PEP8, "doing it right", etc.

First of all, am I correct in my observation that if I use a triple-quoted string prefixed with r, then I can't escape newlines to break up the longer lines? If so, then PEP8 is out the window without splitting up the pattern across multiple strings.

More generally, I'm wondering if I should compile the pattern in the main module namespace, put it within the function where it's used, or something else. Is it a common practice to put a long regex pattern in a separate file? I've never seen it done but it might make sense here. At least it would stop my editor from getting upset with me for the long lines.

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

SurgicalOntologist posted:

First of all, am I correct in my observation that if I use a triple-quoted string prefixed with r, then I can't escape newlines to break up the longer lines? If so, then PEP8 is out the window without splitting up the pattern across multiple strings.

I generally use re.VERBOSE. For spaces in the pattern you need to match it with a character class like [ ].

quote:

More generally, I'm wondering if I should compile the pattern in the main module namespace, put it within the function where it's used, or something else. Is it a common practice to put a long regex pattern in a separate file? I've never seen it done but it might make sense here. At least it would stop my editor from getting upset with me for the long lines.

I tend to put it at the module level if I'm going to pre-compile it at all.
Since the compiled patterns get cached you don't need to worry about compiling before a tight loop, just if you have an operation requiring a regex that you can't afford the latency of compiling beforehand.

SurgicalOntologist
Jun 17, 2004


Thanks, that's exactly what I needed.

BigRedDot
Mar 6, 2008

Chris (from the video) is a colleague of mine. AFAIK, Enaml is no longer under active development (so I probably wouldn't recommend it). He and his team are spending all their time on PhosphorJS, which is the basis of Jupyter 5.0 and beyond.

Jose Cuervo
Aug 25, 2004

QuarkJets posted:

I've never used any of that stuff so I don't know how easy it is to implement, but it sounds pretty complicated compared to just writing a pyside script

So after doing some tutorials and looking at questions on StackOverflow, I finally have the following GUI layout:

and the code to produce this is:
Python code:
import sys
from PySide import QtGui, QtCore


# noinspection PyPep8Naming,PyUnresolvedReferences,PyAttributeOutsideInit
class TabbedScreens(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(TabbedScreens, self).__init__(parent)
        self.init_tabbed_screens()

    def init_tabbed_screens(self):
        # Menu Bar
        exit_action = QtGui.QAction('&Exit', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Exit.')
        exit_action.triggered.connect(self.close)

        self.statusBar()

        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu('&File')
        file_menu.addAction(exit_action)

        # Tabs
        self.tab_widget = QtGui.QTabWidget()
        self.setCentralWidget(self.tab_widget)

        # Main Tab
        main_tab = QtGui.QWidget()
        self.tab_widget.addTab(main_tab, 'Main')

        new_scenario_btn = QtGui.QPushButton("Define New Simulation Scenario", main_tab)
        new_scenario_btn.clicked.connect(self.move_to_next_tab)
        load_scenario_btn = QtGui.QPushButton("Load Existing Simulation Scenario", main_tab)
        load_scenario_btn.setToolTip("Load an existing scenario from a *.tfsp file")
        load_scenario_btn.clicked.connect(self.browse_for_files)

        vbox = QtGui.QVBoxLayout()
        vbox.addStretch(2)
        vbox.addWidget(new_scenario_btn)
        vbox.addStretch(1)
        vbox.addWidget(load_scenario_btn)
        vbox.addStretch(20)

        hbox = QtGui.QHBoxLayout()
        hbox.addStretch(1)
        hbox.addLayout(vbox)
        hbox.addStretch(30)

        main_tab.setLayout(hbox)


        # Define Scenario Tab
        define_scenario_tab = QtGui.QWidget()
        self.tab_widget.addTab(define_scenario_tab, 'Simulation Scenario')


        # Define Simulation Parameters Tab
        define_sim_params_tab = QtGui.QWidget()
        self.tab_widget.addTab(define_sim_params_tab, 'Simulation Parameters ')


        # Run Simulation Tab
        run_sim_tab = QtGui.QWidget()
        self.tab_widget.addTab(run_sim_tab, 'Run Simulation')

        self.sim_progress_bar = QtGui.QProgressBar(run_sim_tab)
        self.sim_progress_bar.setGeometry(30, 40, 200, 25)

        self.progress_btn = QtGui.QPushButton('Start', run_sim_tab)
        self.progress_btn.clicked.connect(self.doAction)

        self.output_analysis_btn = QtGui.QPushButton('View Output Analysis', run_sim_tab)
        self.output_analysis_btn.clicked.connect(self.move_to_next_tab)
        self.output_analysis_btn.setEnabled(False)

        phbox = QtGui.QHBoxLayout()
        pvbox = QtGui.QVBoxLayout()
        pvbox.addWidget(self.sim_progress_bar)
        pvbox.addWidget(self.progress_btn)
        pvbox.addWidget(self.output_analysis_btn)
        phbox.addStretch(3)
        phbox.addLayout(pvbox)
        phbox.addStretch(3)
        run_sim_tab.setLayout(phbox)

        self.timer = QtCore.QBasicTimer()
        self.step = 0


        # Output Analysis Tab
        analysis_tab = QtGui.QWidget()
        self.tab_widget.addTab(analysis_tab, 'Output Analysis')


        # Program Geometry
        self.setGeometry(300, 300, 750, 550)
        self.setWindowTitle('Program Title')
        self.setWindowIcon(QtGui.QIcon('new_icon.png'))
        self.show()

    def move_to_next_tab(self):
        self.tab_widget.setCurrentIndex(self.tab_widget.currentIndex() + 1)

    def browse_for_files(self):
        file_name, _ = QtGui.QFileDialog.getOpenFileName(parent=self, caption='Open file',
                                                         dir='/home', filter="*.txt")

    def timerEvent(self, e):
        if self.step >= 100:
            self.timer.stop()
            self.progress_btn.setEnabled(False)
            self.output_analysis_btn.setEnabled(True)
            return
        self.step += 1
        self.sim_progress_bar.setValue(self.step)

    def doAction(self):
        if self.timer.isActive():
            self.timer.stop()
            self.progress_btn.setText('Start')
        else:
            self.timer.start(100, self)
            self.progress_btn.setText('Stop')


def main():
    app = QtGui.QApplication(sys.argv)
    # noinspection PyUnusedLocal
    main_screen = TabbedScreens()
    # sys.exit(app.exec_())

    app.exec_()


if __name__ == '__main__':
    main()
My questions:
1. The way I am programming this (which is based on examples I have seen), it looks like all my code is going to end up in a single file in a single class (TabbedScreens). Is this the normal/correct way to structure the program, or is there a better way?
2. When do/should you specify the parent of a widget? For instance when I declare a QPushButton I add the parent widget to the initialization (again based on examples I have seen), but when I declared the QTabWidget I did not, and things seemed to work just fine.
3. From what I could find online it seemed like having a QTabWidget would be a good way for me to accomplish the hiding and revealing of new screens. Is this a reasonable approach, or should I switch to something different given what I hope to accomplish?
4. Is there a name/id attribute to a tab that I can use so that the move_to_next_tab() function doesn't rely on the index of the tab?
5. Are there coding issues that you can see with what I have so far?

Dominoes
Sep 20, 2007

Video criticizing OOP.
https://www.youtube.com/watch?v=QM1iUe6IofM

What do y'all think? Personally, I rarely create classes. Exceptions being database models, GUI bits, and complex chunks of code that share variables [that might be better off as separate files.]. There's a stock broker API I use that implements a full-blown OOP Java API from Python, and it embodies one of the video's critiques: Objects wrapping objects wrapping objects; everything obfuscated and opaque.

The video reminded me of one of the cool things about Python: It's flexible and multi-paradigm. I scoffed the OOP part of it, but love its functional and numerical sides.

Dominoes fucked around with this message at 19:37 on Apr 3, 2016

QuarkJets
Sep 8, 2008

Jose Cuervo posted:

So after doing some tutorials and looking at questions on StackOverflow, I finally have the following GUI layout:

and the code to produce this is:
Python code:
snip
My questions:
1. The way I am programming this (which is based on examples I have seen), it looks like all my code is going to end up in a single file in a single class (TabbedScreens). Is this the normal/correct way to structure the program, or is there a better way?
2. When do/should you specify the parent of a widget? For instance when I declare a QPushButton I add the parent widget to the initialization (again based on examples I have seen), but when I declared the QTabWidget I did not, and things seemed to work just fine.
3. From what I could find online it seemed like having a QTabWidget would be a good way for me to accomplish the hiding and revealing of new screens. Is this a reasonable approach, or should I switch to something different given what I hope to accomplish?
4. Is there a name/id attribute to a tab that I can use so that the move_to_next_tab() function doesn't rely on the index of the tab?
5. Are there coding issues that you can see with what I have so far?

1. Totally fine for a project of this size, for a larger project you might do one class per screen, one file per class.

2. The most useful part about declaring a parent is that when the parent gets deleted, so do all of its children. This makes memory management way easier, which is really great when writing C++. Python, however, does its own memory management as things fall out of scope, which can result in some interesting bugs when using pyside if you're not using parent-child relationships properly. The best way to prevent problems is to be diligent about making sure that parents are being set. There are also some situations where changing an object (perhaps by resizing a window) will result in all of the children of that object being modified (perhaps resizing them as well), and this only works if you're setting parents properly. For your project, it's small enough and simple enough that you could probably skip setting parents, but it's good practice and incredibly easy to do so you should do it anyway

3. This is a totally reasonable approach so long as you're okay with users possibly going back one or more steps, since they're able to click the tabs themselves.

4. I don't think so. If you wanted to more Pythonic about it you could do something like this:
code:
id_counter = 0
self.tab_widget.addTab(main_tab, 'Main')
self.id_main = id_counter
id_counter += 1
...
self.tab_widget.addTab(define_scenario_tab, 'Simulation Scenario')
self.id_scenario = id_counter
id_counter += 1
... #etc
And then you could have a button on each tab that calls the appropriate next tab based on the id that you've stored in your class, which would mean that you could add more tabs later and not have to worry about reordering things. This is overkill if you don't plan on having more tabs in the future.

5. Looks fine to me, but I didn't exactly comb through it

QuarkJets
Sep 8, 2008

Dominoes posted:

Video criticizing OOP.
https://www.youtube.com/watch?v=QM1iUe6IofM

What do y'all think? Personally, I rarely create classes. Exceptions being database models, and complex chunks of code that share variables [that might be better off as separate files.]. There's a stock broker API I use that implements a full-blown OOP Java API from Python, and it embodies one of the video's critiques: Objects wrapping objects wrapping objects; everything obfuscated and opaque.

The video reminded me of one of the cool things about Python: It's flexible and multi-paradigm. I scoffed the OOP part of it, but love its functional and numerical sides.

OOP has plenty of valid uses, the problem is when people go hog wild over trying to apply OOP to everything. That's why I dislike Java; it has a one-size fits all approach and suffers for it. But OOP can be useful in many circumstances, and the people who vehemently oppose OOP in all of its forms are basically the hipsters of the software world and are, frankly, wrong. This is also why I don't like using languages without classes or languages with lovely stapled-on class implementations, like MATLAB.

Python and C++ sit in a sweet spot where you can use classes, if you need them, but you don't have to use them for everything.

Dominoes
Sep 20, 2007

QuarkJets posted:

This is also why I don't like using languages without classes or languages with lovely stapled-on class implementations, like MATLAB.
I'll sell you on Julia if you'd like!

Cingulate
Oct 23, 2012

by Fluffdaddy
Isn't one of the lessons of the success of Python that it can be good to have a language you can use functionally or OO?

Most of my personal (scientific analysis) scripting is functional, but my (very limited) dev work (for scientific analysis libraries) is OO. It makes sense to have our brain data as objects, and it makes sense to use functions if I want to do like 3 things with them. And sometimes it makes more sense to do np.mean(), and sometimes np.array().mean().

QuarkJets
Sep 8, 2008

Dominoes posted:

I'll sell you on Julia if you'd like!

I know all about Julia and played around with it when it was 0.2, and then again when it was 0.3, and then again when it was 0.4. It didn't really suit me in beta form due to poor documentation and some weird undocumented stuff going on some of the time, so I'm hoping to return to Julia once it's in 1.0 and stable and well-documented. In the meantime I mostly write Python for development speed and versatility, and if I need certain bits of code to run faster then I compile them with Numba.

weird
Jun 4, 2012

by zen death robot

Dominoes posted:

Video criticizing OOP.
https://www.youtube.com/watch?v=QM1iUe6IofM

What do y'all think? Personally, I rarely create classes. Exceptions being database models, GUI bits, and complex chunks of code that share variables [that might be better off as separate files.]. There's a stock broker API I use that implements a full-blown OOP Java API from Python, and it embodies one of the video's critiques: Objects wrapping objects wrapping objects; everything obfuscated and opaque.

The video reminded me of one of the cool things about Python: It's flexible and multi-paradigm. I scoffed the OOP part of it, but love its functional and numerical sides.

he said that oop is about pass by value, not inheritance or polymorphism. then he discussed pros and cons of abstraction, and of global variables

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!

Cingulate posted:

Isn't one of the lessons of the success of Python that it can be good to have a language you can use functionally or OO?

To slightly nitpick here, Python can be used procedurally (a la C or other non-OO imperative languages); it's not particularly good at the functional programming aspect - it's just not where the expressiveness was prioritized in the language.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
And it doesn't have tail call elimination :arghfist:

Adbot
ADBOT LOVES YOU

Cingulate
Oct 23, 2012

by Fluffdaddy

Asymmetrikon posted:

To slightly nitpick here, Python can be used procedurally (a la C or other non-OO imperative languages); it's not particularly good at the functional programming aspect - it's just not where the expressiveness was prioritized in the language.
Certainly not prioritized, but it does seem to me it's quite possible to do tasks of moderate complexity in idiomatic Python in a functional way. E.g., toolz.

  • Locked thread