Sunday, July 13, 2014

Python IDEs: Pycharm versus Spyder

After just a day with Pycharm (and a few weeks with Spyder), it is clear that for PySide coding, Pycharm wins. However, for scientific computing, especially for those who prefer a quick-responding Matlab-like IDE, Spyder definitely deserves drive space.  

I've been using the Spyder IDE for a few months now. Strangely, while tab completion works in its Python shell, it is minimal in the Spyder editor (as discussed at http://code.google.com/p/spyderlib/issues/detail?id=1254).

I never thought this would be a big deal, but yesterday, as I watched some excellent PySide tutorials (found at http://www.yasinuludag.com/blog/?p=98), it seemed Yasin Uludag was able to type PySide code at mach speeds partly because of the IDE he was using (and also partly because he is a badass PySide ninja). To see for myself, I installed the free version of Pycharm yesterday.

First good thing I noticed: no install hell. Installation was easy on Windows 7. It automatically saw my Anaconda distribution of Python, and automatically used iPython for command line work.

Upon firing it up, the first thing I noticed was that Pycharm was really sluggish in response to basic commands (even entering text or surfing the menu system). Thankfully, it grew more responsive over time (or perhaps my temporal expectations adapted to its intrinsic pace). Despite the slow start, after about five minutes of exploring (with the help of the Getting Started page), I started to appreciate the crazy horsepower under my fingertips. This really shined when I used PySide. Pyside is a sprawling package, with lots of invocation of sub-sub-subclasses, in which case tab completion can really increase productivity.

I haven't really touched the surface of Pycharm. I still feel like a 16 year-old who just learned how to drive stick, and was given the keys to a Ferrari. A bit in over my head, but excited nonetheless. Pycharm seems seamlessly integrated with version control, unit testing frameworks, has all sorts of refactoring functionality built in, among other things I have not yet explored and have never used before. I won't go over all the details, as I am just starting to learn them myself, so if interested I'd ask Google.

Tuesday, July 08, 2014

PySide event handling: pos versus globalpos

I'm playing around with Qt in Python using PySide. It is one of the steepest learning curves I've ever been on. I figure I'll start dropping little examples here. The following is a really simple example to demonstrate the difference between the pos and globalPos of an event in a window. Fire up the program, click within the window, and then drag the window and click within it again. It will print out globalPos() and pos() of a mouse click in the command line, and should be fairly self-explanatory.
# -*- coding: utf-8 -*-  
''' 
Click to see coordinates to get a feel for pos versus globalPos of an event  
''' 
   
from PySide import QtGui, QtCore  
   
class MousePos(QtGui.QWidget):  
    def __init__(self):  
        QtGui.QWidget.__init__(self)  
        self.initUI()  
       
    def initUI(self):  
        self.setGeometry(50,50,300,250)  
        self.show()  
   
    def mousePressEvent(self,event):  
        if event.button() == QtCore.Qt.LeftButton:  
            msg="event.globalPos: <{0}, {1}>\n".format(event.globalPos().x(), event.globalPos().y())  
            msg2="event.pos(): <{0}, {1}>\n".format(event.pos().x(), event.pos().y())  
            print msg + "  " + msg2  
       
def main():  
    import sys  
    qtApp=QtGui.QApplication(sys.argv)  
    myMousePos=MousePos()  
    sys.exit(qtApp.exec_())  
   
if __name__=="__main__":  
    main()  
One of my goals is to see if this code formatting worked in blogger. I did it at codeformatter.blogspot.com but am looking for better ways to do it. I want examples to be simple: cut, paste, and it works in your interpreter. Python is all about using space for syntax, and I had to do too much futzing to get the syntax right.

Sunday, March 23, 2014

iPython: clear current line

When you have some junk on the command line, and want to clear it, many interpreters (e.g., Matlab) would use <ctrl>-c. For reasons I don't understand, in the iPython command line, <shift><esc> will clear it up (while <ctrl>-z will undo your most recent action). If you really wanna go crazy, <ctrl>-l clears the entire screen.

Saturday, February 15, 2014

Saving an entire project in Code::Blocks

You are working with projectx in Code::Blocks, and want a copy of  the entire project with all its files
(e.g., header files). You try to save your project by entering File-->Save Project As, but it only saves a single cbp file. What do you do? You could copy over all the files individually, but that would be very time consuming for complex projects.

A more efficient method exists, but is not obvious from the Code::Blocks menu system. It involves two easy steps: 
1. Save template of projectx 
With projectx open, click File-->Save Project as Template and enter whatever name you want for this template. 
2. Open a new project from that template 
Click File-->New-->From Template, then pick the name you entered In Step 1. After clicking Go the program will request a folder to place the project. When it asks if you want to change the project name, you should do so unless you want it to have the exact same name as the template from Step 1. 

That's it. Those steps should give you an exact duplicate (potentially with a different name) of projectx.

Sunday, December 15, 2013

List comprehensions in Python

I was thinking of writing a post about the topic, but discovered an excellent introduction to list comprehensions that is about the level I was going to pitch it (An Introduction to List Comprehensions in Python). Highly recommended.

Why am I writing about Python at a neuroscience blog? Because of Brian.

Wednesday, December 04, 2013

Getting output from a Matlab GUI

Let's say you have a GUI like the one on the right as part of a program that runs a mouse in a simple behavioral task. The GUI requires the user to manually enter some data (the animal's name) and verify that the power is on in your setup. We want the GUI to close and return the relevant outputs when the 'Start Program' button is pressed by the user.

There are three tweaks you will need to make this work, if you made your GUI using the GUIDE functionality in Matlab (note if you want to tinker with an example, I've included one at the end of this post).

1) Make the GUI wait before it returns outputs
The GUI will try to return outputs right when it is invoked, well before any of the values can be specified by the user. To block such behavior, you can pause program execution using the uiwait command within OpeningFcn:
   uiwait(hObject);  
This will make the GUI wait until some additional action is performed (e.g., uiresume is called to resume program flow, or the GUI (with handle hObject) is closed). This gives the user time to enter the actual values. Note you should put this command at the end of OpeningFcn.

2) Specify the output variables
Within OutputFcn, use varargout to specify what outputs you want returned from the GUI. Something like:
 varargout{1} = handles.data1; 
 varargout{2} = handles.data2;
Matlab typically passes information among the different elements of a GUI using the handles variable, so this code just exploits this fact. Once the outputs are specified as above, they will be returned as outputs to the calling function for the main GUI:
 [data1, data2]=GUI_Practice; 
Where GUI_Practice is the name of the m-file that defines the GUI.

Caveat: you will probably define the desired outputs (such as handles.data1) within a callback function (using something like handles.data1=x). When you do so, be sure to enter the following within the callback function:
guidata(hObject, handles); 
This saves the local variable handles to the GUI handle, so they will not be annihilated outside the scope of the callback function.

3) Tell the program when to resume
If you only did the above steps, after calling uiwait the program would hang indefinitely. You need to call the uiresume command to bump the program out of wait mode. To resume program flow when the user clicks Start Program, add uiresume to CloseRequestFcn:
%When user clicks button, check to see if GUI is in wait  %mode. If it is, resume program; otherwise close GUI
 if isequal(get(hObject, 'waitstatus'), 'waiting')
     uiresume(hObject);
 else
     delete(hObject);
 end
Note: you should also add the  line delete(hObject); to the end of outputFcn. Otherwise, the user will have to attempt to close the GUI twice: once to resume program flow with uiresume, and again to close the GUI with delete.
   

Example
Below is a simple example called GUI_Practice (m-file and fig file are both needed for this to run, as it was made with GUIDE). Once the files are in your Matlab path, you can instantiate the GUI by entering animal_name=GUI_Practice;
GUI_Practice.m
GUI_Practice.fig

Acknowledgment
I got some of the ideas for this from Mathworks (here). If you are having trouble getting it to work, let me know in the comments, and I'll try to help.

 

Saturday, April 06, 2013

Matlab question marks and exclamation points

Random Matlab things I find cool or perplexing. Updated periodically. Some of the comments are very dense, basically just lines of code I will likely forget, but will want to remember at some point.

5/6/13
To check what mfile is currently running, enter mfilename (useful in debug mode).


4/6/13
1. Filtering an image stored in matrix M:
%build the filter to convolve with the image
imFilt=fspecial('gaussian',10,10);
%convolve them
smoothed=imfilter(M,imFilt,'symmetric','conv');
 
2. To change your gridlines to solid grey without changing the colors of the tick labels:
grid
%make gridlines solid
set(gca,'gridlinestyle','-'); 
%make them grey
set(gca,'Xcolor',[.8 .8 .8],'Ycolor',[.8 .8 .8])
%unfortunately, the above changes everything to grey

%copy the axes
c=copyobj(gca,gcf);
%redo them in black. 
set(c,'color','none','xcolor','k','xgrid','off', ...
    'ycolor','k','ygrid','off','Box','off');

8/24/12
If your Windows machine doesn't show the .mat file extension (and you have already unclicked 'Hide extensions for known file types' in your folder options menu) you can fix it within an open folder. First, select Tools->Folder Options->File Types-->New. A GUI to create a new extension will open: type MAT in the field. Then click 'Advanced' and select Matlab Data from the list. It will warn you that this is already associated with a different file type. Accept the change. Problem solved. I stole this simple solution here, and Matlab has a page about it here.

7/9/12
1. If you have a cell array that contains strings, and want to get a numeric array with 1's where a particular string occurs, and 0's otherwise, you can use the cellfun function coupled with strfind: 
>>out=~cellfun('isempty', strfind(cell_array,'string'));

2. Why doesn't the following yield a 1?
>>NaN==NaN


3/24/12
You can use plotyy to display data on different y axes in the same figure. While there isn't presently a scatteryy command (why?), you can try something like the following:
>>[ax,h1,h2]=plotyy(x1,y1,x2,y2);
>>set(h1,'LineStyle','o');

2/17/12
1. It would be cool if, on a documentation page for a function, it let you click on a 'function history' link that showed when the function was introduced, and the changes added with each version.

2. Check out the grpstats function. Enter your data, and the group assigned to each data point, and it calculates all sorts of statistics sorted by group (e.g., mean, standard error, standard deviation, etc). I had done this on my own, but their function is better than what I had.

3. Why isn't the following legal?
>>scatter(x,y,'Color',[a b c])
Why must we use CData (and not Color) for scatter plots?