[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r5766 - in grc/branches/jblum_work/src: . Elements Gra
From: |
jblum |
Subject: |
[Commit-gnuradio] r5766 - in grc/branches/jblum_work/src: . Elements Graphics SignalBlockDefs |
Date: |
Mon, 11 Jun 2007 15:43:16 -0600 (MDT) |
Author: jblum
Date: 2007-06-11 15:43:15 -0600 (Mon, 11 Jun 2007)
New Revision: 5766
Added:
grc/branches/jblum_work/src/DataTypes.py
Removed:
grc/branches/jblum_work/src/DataType.py
Modified:
grc/branches/jblum_work/src/ActionHandler.py
grc/branches/jblum_work/src/Actions.py
grc/branches/jblum_work/src/Elements/GraphicalConnection.py
grc/branches/jblum_work/src/Elements/GraphicalParam.py
grc/branches/jblum_work/src/Elements/GraphicalSignalBlock.py
grc/branches/jblum_work/src/Elements/GraphicalSocket.py
grc/branches/jblum_work/src/Elements/SignalBlock.py
grc/branches/jblum_work/src/Elements/Socket.py
grc/branches/jblum_work/src/Graphics/Dialogs.py
grc/branches/jblum_work/src/Graphics/USRPDiagnostics.py
grc/branches/jblum_work/src/MathExprParser.py
grc/branches/jblum_work/src/Messages.py
grc/branches/jblum_work/src/ParseXML.py
grc/branches/jblum_work/src/Preferences.py
grc/branches/jblum_work/src/SignalBlockDefs/Coders.py
grc/branches/jblum_work/src/SignalBlockDefs/Conversions.py
grc/branches/jblum_work/src/SignalBlockDefs/Filters.py
grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
grc/branches/jblum_work/src/SignalBlockDefs/Misc.py
grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py
grc/branches/jblum_work/src/SignalBlockDefs/Operators.py
grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py
grc/branches/jblum_work/src/SignalBlockDefs/Sources.py
grc/branches/jblum_work/src/SignalBlockDefs/Trellis.py
grc/branches/jblum_work/src/SignalBlockDefs/USRP.py
grc/branches/jblum_work/src/SignalBlockDefs/__init__.py
grc/branches/jblum_work/src/StateCache.py
grc/branches/jblum_work/src/Variables.py
Log:
renamed DataType module to DataTypes, added doxygen comments to all root level
python files
Modified: grc/branches/jblum_work/src/ActionHandler.py
===================================================================
--- grc/branches/jblum_work/src/ActionHandler.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/ActionHandler.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -36,13 +36,20 @@
import Messages
class ActionHandler:
- """ The action handler will create all the major window components
and handle state changes.
- The action handler also contains methods to handle the action buttons
and state changes. """
+ """
+ The action handler will setup all the major window components,
+ and handle button presses and flow graph operations from the GUI.
+ """
def __init__(self, input_arg_file_path=''):
- """ Parse the config files for signals blocks and gtk actions.
Connect the actions to the handler method.
- Create a new Flow Graph and main_window as well as a few misc
dialog boxes. Enter the gtk main loop. """
+ """!
+ ActionHandler constructor.
+ Parse the config files for signals blocks and gtk actions.
Connect the actions to the handler method.
+ Create a new main window, intialize preferences and the message
handler.
+ Finally, enter the gtk main loop and block
+ @param input_arg_file_path a flow graph file passed from
command line
+ """
if PY_GTK_ICON:
gtk.window_set_default_icon_from_file(PY_GTK_ICON)
- for action in ACTIONS_LIST: action.connect('activate',
self.handle_actions)
+ for action in ACTIONS_LIST: action.connect('activate',
self._handle_actions)
self.pid_file = None
### create the main window and setup the Messages ###
self.main_window = Graphics.MainWindow(self.handle_states)
@@ -50,8 +57,8 @@
Messages.register_messenger(sys.stdout.write)
Messages.send_init()
self.flow_graph = self.main_window.flow_graph
- self.main_window.connect('delete_event', self.quit)
- self.main_window.connect('key_press_event',
self.handle_key_press)
+ self.main_window.connect('delete_event', self._quit)
+ self.main_window.connect('key_press_event',
self._handle_key_press)
Preferences.load(self.main_window)
self.main_window.show()#show after resize in preferences
# determine the initial flow graph file, preference to
command line input #
@@ -64,10 +71,14 @@
gtk.main()
gtk.gdk.threads_leave()
- def handle_key_press(self, widget, event):
- """ Handle key press events and translate key combos into
actions.
- Key combinations that do not include special keys, such
as ctrl or Fcn*,
- require that the flow graph has mouse focus."""
+ def _handle_key_press(self, widget, event):
+ """
+ Handle key presses from the keyboard.
+ Translate key combos into actions.
+ Key combinations that do not include special keys, such as ctrl
or Fcn*,
+ Also, require that the flow graph has mouse focus when choosing
to handle keys.
+ @return true if the flow graph is in active use
+ """
keyname = gtk.gdk.keyval_name(event.keyval)
#print 'Key "%s" (%d) was pressed' % (keyname, event.keyval)
if event.state & gtk.gdk.CONTROL_MASK: print "Control was being
held down"
@@ -112,25 +123,35 @@
#propagate this if the fg is not in focus or nothing is selected
return self.flow_graph.get_focus_flag() and
self.flow_graph.is_selected()
- def quit(self, window, event):
- """ Handle the delete event from the main window, like
pressing X to close, alt+f4, or right click+close.
- This method in turns calls the state handler with a 'quit'
string so all quitting can be handled in one place. """
+ def _quit(self, window, event):
+ """!
+ Handle the delete event from the main window.
+ Generated by pressing X to close, alt+f4, or right click+close.
+ This method in turns calls the state handler to quit.
+ @return true
+ """
self.handle_states(APPLICATION_QUIT)
return True
- def handle_actions(self, event):
- """ Handle all of the activate signals from the gtk actions.
The action signals derive from clicking on a
- toolbar or menu bar button. The name of the action is
passed through the event and a series of
- if/elif statements handle the action appropriately.
"""
+ def _handle_actions(self, event):
+ """
+ Handle all of the activate signals from the gtk actions.
+ The action signals derive from clicking on a toolbar or menu
bar button.
+ Forward the action to the state handler.
+ """
name = event.get_name()
self.handle_states(name)
def handle_states(self, state):
- """ Handle all of the state changes that arise from the action
handler or other Graphics and
- inputs in the application. The state passed to the
handle_states method is a string descriping
- the change. A series of if/elif statements handle the
state by greying out action buttons, causing
- changes in the flow graph, saving/opening files...
The handle_states method is passed to the
- contructors of many of the classes used in this
application enabling them to report any state change. """
+ """!
+ Handle the state changes in the GUI.
+ Handle all of the state changes that arise from the action
handler or other Graphics and
+ inputs in the application. The state passed to the
handle_states method is a string descriping
+ the change. A series of if/elif statements handle the state by
greying out action buttons, causing
+ changes in the flow graph, saving/opening files... The
handle_states method is passed to the
+ contructors of many of the classes used in this application
enabling them to report any state change.
+ @param state a string describing the state change
+ """
print '>>>',state
##############################################################################################
# Initalize/Quit
@@ -159,9 +180,9 @@
Messages.send_fail_load(e)
self.flow_graph_file_path = ''
self.handle_states(APPLICATION_INITIALIZE)
- self.set_saved_state(True)
+ self._set_saved_state(True)
elif state == APPLICATION_QUIT:
- if self.loose_changes():
+ if self._loose_changes():
self.handle_states(FLOW_GRAPH_STOP)
Preferences.set_default_flow_graph(self.flow_graph_file_path)
Preferences.save(self.main_window)
@@ -185,40 +206,40 @@
##############################################################################################
elif state == SIGNAL_BLOCK_MOVE:
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == SIGNAL_BLOCK_ROTATE_LEFT:
if self.flow_graph.rotate_selected(DIR_LEFT):
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == SIGNAL_BLOCK_ROTATE_RIGHT:
if self.flow_graph.rotate_selected(DIR_RIGHT):
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == ELEMENT_DELETE:
if self.flow_graph.delete_selected():
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
self.handle_states(NOTHING_SELECT)
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == CONNECTION_CREATE or state ==
SIGNAL_BLOCK_CREATE:
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
self.handle_states(NOTHING_SELECT)
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == SIGNAL_BLOCK_INC_TYPE:
if self.flow_graph.type_controller_modify_selected(1):
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == SIGNAL_BLOCK_DEC_TYPE:
if self.flow_graph.type_controller_modify_selected(-1):
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == SOCKET_CONTROLLER_INC:
if self.flow_graph.socket_controller_modify_selected(1):
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == SOCKET_CONTROLLER_DEC:
if
self.flow_graph.socket_controller_modify_selected(-1):
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
##############################################################################################
# Window stuff
##############################################################################################
@@ -240,17 +261,17 @@
if dimensions != None:
self.flow_graph.set_size_request(dimensions[0],
dimensions[1])
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
##############################################################################################
# Variable and Param Modifications
##############################################################################################
elif state == SIGNAL_BLOCK_PARAM_MODIFY:
if self.flow_graph.param_modify_selected():
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == VARIABLE_MODIFY:
self.state_cache.save_new_state(self.flow_graph.to_nested_data())
- self.set_saved_state(False)
+ self._set_saved_state(False)
self.flow_graph.update()
##############################################################################################
# Undo/Redo
@@ -260,22 +281,22 @@
if nested_data != None:
self.handle_states(NOTHING_SELECT)
self.flow_graph.from_nested_data(nested_data)
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == FLOW_GRAPH_REDO:
nested_data = self.state_cache.get_next_state()
if nested_data != None:
self.handle_states(NOTHING_SELECT)
self.flow_graph.from_nested_data(nested_data)
- self.set_saved_state(False)
+ self._set_saved_state(False)
##############################################################################################
# New/Open/Save
##############################################################################################
elif state == FLOW_GRAPH_NEW:
- if self.loose_changes():
+ if self._loose_changes():
self.flow_graph_file_path = ''
self.handle_states(APPLICATION_INITIALIZE)
elif state == FLOW_GRAPH_OPEN:
- if self.loose_changes():
+ if self._loose_changes():
fc = Graphics.FlowGraphFileDialog('open',
self.flow_graph_file_path)
file_path = fc.run()
if file_path != None:
@@ -286,10 +307,10 @@
else:
try:
ParseXML.to_file(ParseXML.to_xml(self.flow_graph.to_nested_data()),
self.flow_graph_file_path)
- self.set_saved_state(True)
+ self._set_saved_state(True)
except IOError:
Messages.send_fail_save(self.flow_graph_file_path)
- self.set_saved_state(False)
+ self._set_saved_state(False)
elif state == FLOW_GRAPH_SAVE_AS:
fc = Graphics.FlowGraphFileDialog('save',
self.flow_graph_file_path)
file_path = fc.run()
@@ -311,7 +332,7 @@
elif state == FLOW_GRAPH_EXEC:
if self.pid_file == None:
self.handle_states(FLOW_GRAPH_SAVE)
- if self.flow_graph_file_path != '': RUN(self)
+ if self.flow_graph_file_path != '':
ExecFlowGraphThread(self)
elif state == FLOW_GRAPH_STOP:
while not MUTEX.testandset(): pass #try to lock
repeatedly until lock is aquired
if self.pid_file!= None:
@@ -326,9 +347,15 @@
# hide/show the reports window based on the preferences #
self.main_window.show_reports_window(Preferences.show_reports_window())
- def set_saved_state(self, saved):
- ''' If saved is True, disable the save button and modify the
title.
- If saved is False, enable the save button and modify the title
with a *. '''
+ def _set_saved_state(self, saved):
+ """!
+ Update GUI elements based on the saved state of the flow graph.
+ If saved is true, the flow graph was just saved:
+ set the window title and grey out the save button.
+ If saved is false, the flow graph has unsaved changes:
+ set the window title with a * and activate the save
button.
+ @param saved true when saved
+ """
if saved:
get_action_from_name(FLOW_GRAPH_SAVE).set_sensitive(False)
if self.flow_graph_file_path == '':
@@ -340,14 +367,22 @@
self.main_window.set_title(NEW_FLOGRAPH_TITLE +
'*')
else:
self.main_window.set_title(self.flow_graph_file_path + '*')
- def loose_changes(self):
- ''' True if the save is disabled or the user says to discard
changes. '''
+ def _loose_changes(self):
+ """!
+ Loose unsaved changes to flow graph?
+ If the save was not greyed-out, the user is presented with a
dialog.
+ @return true if save is greyed-out, or the user's choice.
+ """
return not
get_action_from_name(FLOW_GRAPH_SAVE).get_sensitive() or\
(Graphics.LooseChangesMessage().run())
-class RUN(Thread):
- ''' Run the flow graph as a new process and wait on it to finish
'''
+class ExecFlowGraphThread(Thread):
+ """Execute the flow graph as a new process and wait on it to finish."""
def __init__ (self, action_handler):
+ """!
+ ExecFlowGraphThread constructor.
+ @param action_handler an instance of an ActionHandler
+ """
Thread.__init__(self)
self.action_handler = action_handler
self.pid_file = self.action_handler.pid_file =
'/tmp/grc-%d.pid'%os.getpid()
@@ -359,6 +394,7 @@
self.start()
def run(self):
+ """Execute the flow graph."""
cmd = '%s "%s" --pid_file="%s" 2>
"%s"'%(DEFAULT_FLOW_GRAPH_EXEC, self.flow_graph_file_path, self.pid_file,
self.report_file)
os.system(cmd)
try:
Modified: grc/branches/jblum_work/src/Actions.py
===================================================================
--- grc/branches/jblum_work/src/Actions.py 2007-06-11 07:41:42 UTC (rev
5765)
+++ grc/branches/jblum_work/src/Actions.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -79,7 +79,7 @@
# actions
######################################################################################################
-ACTIONS_LIST = [
+ACTIONS_LIST = (
gtk.Action(FLOW_GRAPH_NEW, '_New', 'Create a new flow graph',
'gtk-new'),
gtk.Action(FLOW_GRAPH_OPEN, '_Open', 'Open a flow graph from file',
'gtk-open'),
gtk.Action(FLOW_GRAPH_SAVE, '_Save', 'Save this flow graph',
'gtk-save'),
@@ -101,10 +101,15 @@
gtk.Action(FLOW_GRAPH_EXEC, '_Execute', 'Execute the flow graph',
'gtk-execute'),
gtk.Action(FLOW_GRAPH_STOP, '_Stop', 'Stop the flow graph', 'gtk-stop'),
gtk.Action(FLOW_GRAPH_SCREEN_CAPTURE, 'S_creen Capture', 'Create a
screen capture of the flow graph', 'gtk-print'),
-]
+)
def get_action_from_name(action_name):
- """ Retrieve the action from the above list given its name. """
+ """!
+ Retrieve the action from the action list.
+ Search the list and find an action with said name.
+ @param action_name the action name(string)
+ @return a gtk action object
+ """
for action in ACTIONS_LIST:
if action.get_name() == action_name: return action
return None
Deleted: grc/branches/jblum_work/src/DataType.py
Copied: grc/branches/jblum_work/src/DataTypes.py (from rev 5765,
grc/branches/jblum_work/src/DataType.py)
===================================================================
--- grc/branches/jblum_work/src/DataTypes.py (rev 0)
+++ grc/branches/jblum_work/src/DataTypes.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -0,0 +1,501 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
+"""
+ DataTypes.py
+ Josh Blum
+ All the data types for sockets and params. Contains parsing and
validity checks.
+"""
+
+import MathExprParser
+import Variables
+from gnuradio import gr
+
+class DataType:
+ """
+ The base class for all data types.
+ Hold data and provide parsing.
+ Do not use, this is a base class only.
+ """
+ base_type = None
+ def __init__(self, data='0', min=None, max=None):
+ """!
+ DataType constructor.
+ @param data the data
+ @param min the minimum
+ @param max the maximum
+ """
+ self.set_data(data)
+ self.max = max
+ self.min = min
+ self.msg = '' #parser messages
+ def set_data(self, data):
+ """!
+ Store the data as a string.
+ @param data the data
+ """
+ self.data = str(data)
+ def get_data(self):
+ """!
+ Get the data as a string.
+ @return the data """
+ return self.data
+ def parse(self):
+ """!
+ Substitute in variables.
+ Replace all variable instances with the variable's string
representation.
+ @return the data without variables"""
+ return Variables.replace_var_instances(self.get_data())
+ def is_valid(self):
+ """!
+ Is this data type valid?
+ True if the data can be parsed, otherwise False.
+ If min or max was specified,
+ the parsed value must be less than or equal to min and/or
+ greater than or equal to max. If the parsed value is a vector,
+ then the value is the length of the vector.
+ @return boolean, true if valid
+ """
+ try:
+ value = self.parse()
+ self.msg = ''
+ return True
+ except Exception, e:
+ self.msg = str(e)
+ return False
+ def get_type(self):
+ """!
+ Get a string describing the specific data type.
+ @return type string
+ """
+ return self.type
+ def get_base_type(self):
+ """!
+ Get a string describing the base (category) of this data type.
+ @return base type string
+ """
+ return self.base_type
+ def get_num_bytes(self):
+ """!
+ How man bytes in this data type?
+ @return number of bytes
+ """
+ return self.num_bytes
+ def _verify_bounds(self, value):
+ """!
+ Is the value within the bounds of this data type?
+ @throw ValueError out of bounds.
+ """
+ if self.max != None and value > self.max: raise
ValueError('Value "%s" was greater than the max "%s".'%(value, self.max))
+ if self.min != None and value < self.min: raise
ValueError('Value "%s" was greater than the min "%s".'%(value, self.min))
+
+#############################################################################################
+# Regular Types
+#############################################################################################
+class Number(DataType):
+ """
+ A number data type.
+ The base class for numeric data types.
+ Do not use, this is a base class only.
+ """
+ base_type = 'number'
+ def parse(self):
+ """!
+ Evaluate the math expressions in the data type.
+ @return a number
+ """
+ num = MathExprParser.eval_expr(DataType.parse(self))
+ parsed = self.parser(num)
+ self._verify_bounds(parsed)
+ return parsed
+
+class Int(Number):
+ """The integer data type."""
+ type = 'int'
+ num_bytes = gr.sizeof_int
+ def parser(self, value):
+ """!
+ Parse the data for an integer value or raise an error.
+ @throw Exception non integer
+ @return integer
+ """
+ return MathExprParser.verify_int(value)
+
+class Byte(Int):
+ """The byte data type is identical to int. """
+ type = 'byte'
+ num_bytes = gr.sizeof_char
+
+class Short(Int):
+ """The short data type is identical to int."""
+ type = 'short'
+ num_bytes = gr.sizeof_short
+
+class Float(Number):
+ """The float data type."""
+ type = 'float'
+ num_bytes = gr.sizeof_float
+ def parser(self, value):
+ """!
+ Parse the data for an float value or raise an error.
+ @throw Exception non float
+ @return float
+ """
+ return MathExprParser.verify_float(value)
+
+class Complex(Number):
+ """The complex data type."""
+ type = 'complex'
+ num_bytes = gr.sizeof_gr_complex
+ def parser(self, value):
+ """!
+ Parse the data for an complex value or raise an error.
+ @throw Exception non complex
+ @return complex
+ """
+ return MathExprParser.verify_complex(value)
+
+#############################################################################################
+# Special Types
+#############################################################################################
+class RawExpr(DataType):
+ """A raw mathematical expression."""
+ type = 'raw'
+ def __init__(self, data=''):
+ """!
+ Raw data type contructor.
+ @param data the data
+ """
+ DataType.__init__(self, data)
+ def parse(self):
+ """!
+ Get the raw data returned by the math parser.
+ @throw Exception malformed expression
+ @return the evaluated mathematical expression
+ """
+ data = DataType.parse(self)
+ return MathExprParser.eval_expr(data)
+
+class String(DataType):
+ """The string data type."""
+ type = 'string'
+ def __init__(self, data='', min=None, max=None):
+ """!
+ String data type contructor.
+ @param data the data
+ @param min the minimum length of the string
+ @param max the maximum length of the string
+ """
+ DataType.__init__(self, data, min, max)
+ def parse(self):
+ """!
+ Get the data as a string.
+ @throw Exception string length out of bounds
+ @return the data
+ """
+ string = DataType.parse(self)
+ self._verify_bounds(len(string))
+ return string
+
+class Hex(DataType):
+ """The hex data type."""
+ type = 'hex'
+ def parse(self):
+ """!
+ Get the data as an integer parsed from a hex string.
+ @return the data
+ """
+ return int(DataType.parse(self),16)
+
+class File(String):
+ """A file data type. Do not use, this is a base class only."""
+ base_type = 'file'
+ def __init__(self, data='', allow_blank=False):
+ """!
+ File data type contructor.
+ Allow blank lets blank filename pass validation.
+ @param data the file path
+ @param allow_blank allow empty paths(true/false)
+ """
+ String.__init__(self, data)
+ self.allow_blank = allow_blank
+
+class FileOpen(File):
+ """A file data type for choosing existing files."""
+ type = 'fileopen'
+ def is_valid(self):
+ """!
+ Does the file path exist?
+ @return true if valid
+ """
+ if self.allow_blank and self.parse() == '': return True
+ from os import path
+ return path.isfile(self.parse())
+
+class FileSave(File):
+ """A file data type for choosing files to save."""
+ type = 'filesave'
+ def is_valid(self):
+ """!
+ Is the file path possible?
+ The directory must exist and the filename must not be an
existing directory.
+ @return true if validcannonical name
+ """
+ if self.allow_blank and self.parse() == '': return True
+ from os import path
+ my_path = self.parse()
+ # Return False if the directory does not exist or the path is
just a directory. #
+ if not path.exists(path.dirname(my_path)) or
path.isdir(my_path): return False
+ # True if the basename is not an empty string. #
+ return path.basename(my_path) != ''
+
+class Variable(DataType):
+ """
+ The variable data type.
+ Takes properties from an enumerated data type of data types.
+ """
+ def __init__(self, enum_data_type, data='0', index=None, min=None,
max=None):
+ """!
+ Variable constructor.
+ The enumerated type must contain other data types in its
choices.
+ The index is the index of the data type in the enum's tuple.
+ If index is None, enum must parse to a data type.
+ @param enum_data_type an enumerated data type
+ @param data the data
+ @param index the index of the data type in the enum's choice
+ @param min the minimum
+ @param max the maximum
+ """
+ DataType.__init__(self, data, min, max)
+ self.enum_data_type = enum_data_type
+ self.index = index
+ def parse_enum_data_type(self):
+ """!
+ Parse the selected data type.
+ If there is an index, get the data type from a tuple instead.
+ @return the data type
+ """
+ if self.index is None: return self.enum_data_type.parse()
+ else: return self.enum_data_type.parse()[self.index]
+ def get_type(self):
+ """!
+ Get the type from the enumerated data type.
+ @return the type
+ """
+ return self.parse_enum_data_type().get_type()
+ def get_base_type(self):
+ """!
+ Get the base type from the enumerated data type.
+ @return the base type
+ """
+ return self.parse_enum_data_type().get_base_type()
+ def get_num_bytes(self):
+ """!
+ Get the number of bytes from the enumerated data type.
+ @return the number of bytes.
+ """
+ return self.parse_enum_data_type().get_num_bytes()
+ def parse(self):
+ """!
+ Use the parser from the enumerated data type.
+ @return the parsed data
+ """
+ data_type = self.parse_enum_data_type()
+ data_type.set_data(self.get_data())
+ return data_type.parse()
+
+class Enum(DataType):
+ """The enumerated data type.
+ The enumerated type holds a finite set of choices.
+ The selected choice is determined by the data.
+ The data must represent an integer index. """
+ type = 'enum'
+ base_type = 'enum'
+ def __init__(self, choices=[('',0)], data='0'):
+ """!
+ Enum constructor.
+ choices = [(cname0, choice0),(cname1, choice1),...]
+ @param choices the list of choices
+ @param data the choice index 0-> len(choices)-1
+ """
+ self.choices = choices
+ DataType.__init__(self, data)
+ def set_data(self, data):
+ """!
+ Set the data.
+ Try to use data as an index for choices.
+ @param data the data
+ @throw Exception bad index
+ """
+ self.choices[int(data)]
+ DataType.set_data(self, data)
+ def parse(self):
+ """!
+ Parse the data by returning the current selection pointed to by
the data.
+ @return the choice at the index held in data
+ """
+ return self.choices[int(self.get_data())][1]
+ def get_cname(self):
+ """!
+ Get the cannonical name of the currently selected choice.
+ @return the cannonical name
+ """
+ return self.choices[int(self.get_data())][0]
+ def get_cnames_list(self):
+ """!
+ Get a list of the cannonical names from the choices (in order).
+ @return a list of all the cannonical names
+ """
+ cnames = list()
+ for cname,choice in self.choices: cnames.append(cname)
+ return cnames
+
+class VariableKeySelector(DataType):
+ """
+ The variable key selector data type.
+ This data type allows the user to select a variable key in the variable
registry.
+ """
+ type = 'variable enum'
+ base_type = 'variable enum'
+ def __init__(self, data='', all_variables=False):
+ """!
+ Variable key selector contructor.
+ If the all variables flag is true, this data type can represent
any variable key.
+ If the all variables flag is false, variables with ranges will
not be allowed.
+ @param data the variable key
+ @param all_variables boolean to allow certain variables
+ """
+ DataType.__init__(self, data)
+ self.all_variables = all_variables
+ def parse(self):
+ """!
+ Parse the data by returning the current key.
+ @return the var key
+ """
+ return self.get_data().strip()
+ def is_valid(self):
+ """!
+ Is the variable key valid?
+ The data must be in the keys list.
+ @return true if valid"""
+ return self.parse() in self.get_variables_list()
+ def get_variables_list(self):
+ """!
+ Get a list of the keys.
+ Use all_variables to restrict the list.
+ @return a list of possible keys
+ """
+ var_keys = list()
+ for key in Variables.get_keys():
+ # use the key if we specified all variables or the key
was not for a ranged variable
+ if self.all_variables or not Variables.is_ranged(key):
var_keys.append(key)
+ return var_keys
+
+class Bool(Enum):
+ """
+ The boolean data type.
+ This boolean type is an Enum with two choices.
+ One choice will parse to True, the other False. """
+ type = 'bool'
+ def __init__(self, true='True', false='False', default=True):
+ """!
+ Bool contructor.
+ @param true the cname for the true choice
+ @param false the cname for the false choice
+ @param default the default choice
+ """
+ if default: data = 0 #determine the default index
+ else: data = 1
+ Enum.__init__(self, choices=[(true, True), (false, False)],
data=data)
+
+#############################################################################################
+# Vectors Types
+#############################################################################################
+class Vector(DataType):
+ """
+ A vector data type.
+ The base class for vectors.
+ Do not use, this is a base class only.
+ """
+ base_type = 'vector'
+ def parse(self):
+ """!
+ Parse the vector data type.
+ The length of the vector must be within bounds.
+ The data must pass the math expression parser.
+ @throw Exception not in bounds
+ @throw Exception invalid syntax
+ @return the vector
+ """
+ elements = MathExprParser.eval_expr(DataType.parse(self))
+ if type(elements) != type(list()): elements = [elements]
#ensure that elements is a list
+ self._verify_bounds(len(elements))
+ return map(lambda v: self.parser(v), elements)
+
+class ByteVector(Vector, Byte):
+ """A vector of bytes."""
+ type = 'byte vector'
+
+class IntVector(Vector, Int):
+ """A vector of ints."""
+ type = 'int vector'
+
+class ShortVector(Vector, Short):
+ """A vector of shorts."""
+ type = 'short vector'
+
+class FloatVector(Vector, Float):
+ """A vector of floats."""
+ type = 'float vector'
+
+class ComplexVector(Vector, Complex):
+ """A vector of complex."""
+ type = 'complex vector'
+
+def can_connect(dt1, dt2):
+ """!
+ Can these data types connect?
+ @param dt1 a data type
+ @param dt2 another data type
+ @return true if the types match
+ """
+ return dt1.get_type() == dt2.get_type()
+
+def vectorize(data_type):
+ """!
+ Take a regular data type and return its vector form.
+ @param data_type a regular data type
+ @return a vector data type
+ """
+ type = data_type.get_type()
+ regular_to_vector_dict = {
+ Byte().get_type() : ByteVector(),
+ Short().get_type() : ShortVector(),
+ Int().get_type() : IntVector(),
+ Float().get_type() : FloatVector(),
+ Complex().get_type() : ComplexVector(),
+ }
+ if type in regular_to_vector_dict.keys():
+ return regular_to_vector_dict[type]
+ return data_type #otherwise return the input data type
+
+if __name__ == '__main__':
+ """Use the main method to test data types."""
+ pass
+
+
\ No newline at end of file
Modified: grc/branches/jblum_work/src/Elements/GraphicalConnection.py
===================================================================
--- grc/branches/jblum_work/src/Elements/GraphicalConnection.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/Elements/GraphicalConnection.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
The graphical connection for input/output sockets.
"""
-import DataType
+import DataTypes
import Utils
from Connection import Connection
from GraphicalElement import GraphicalElement
@@ -89,6 +89,6 @@
""" is this connection valid, ie: do the input and output data
types match? """
import Preferences #preferences
return not Preferences.check_connections() or\
- DataType.can_connect(self.sockets[0].get_data_type(),
self.sockets[1].get_data_type())
+ DataTypes.can_connect(self.sockets[0].get_data_type(),
self.sockets[1].get_data_type())
Modified: grc/branches/jblum_work/src/Elements/GraphicalParam.py
===================================================================
--- grc/branches/jblum_work/src/Elements/GraphicalParam.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/Elements/GraphicalParam.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -23,7 +23,7 @@
"""
from Param import Param
-from DataType import *
+from DataTypes import *
import pygtk
pygtk.require('2.0')
import gtk
Modified: grc/branches/jblum_work/src/Elements/GraphicalSignalBlock.py
===================================================================
--- grc/branches/jblum_work/src/Elements/GraphicalSignalBlock.py
2007-06-11 07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/Elements/GraphicalSignalBlock.py
2007-06-11 21:43:15 UTC (rev 5766)
@@ -29,7 +29,7 @@
from GraphicalElement import GraphicalElement
from GraphicalSocket import GraphicalInputSocket,GraphicalOutputSocket
from Constants import *
-from DataType import Enum,Int
+from DataTypes import Enum,Int
import pygtk
pygtk.require('2.0')
import gtk
Modified: grc/branches/jblum_work/src/Elements/GraphicalSocket.py
===================================================================
--- grc/branches/jblum_work/src/Elements/GraphicalSocket.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/Elements/GraphicalSocket.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -25,7 +25,7 @@
import Utils
from Socket import Socket
from GraphicalElement import GraphicalElement
-from DataType import *
+from DataTypes import *
from Constants import *
import Colors
import pygtk
Modified: grc/branches/jblum_work/src/Elements/SignalBlock.py
===================================================================
--- grc/branches/jblum_work/src/Elements/SignalBlock.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/Elements/SignalBlock.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -26,7 +26,7 @@
import Utils
from Socket import OutputSocket,InputSocket
from Param import Param
-from DataType import Enum,Int,Vector
+from DataTypes import Enum,Int,Vector
class SignalBlock(Element):
""" SignalBlock is an Element with an index from the list of
Modified: grc/branches/jblum_work/src/Elements/Socket.py
===================================================================
--- grc/branches/jblum_work/src/Elements/Socket.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/Elements/Socket.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -23,7 +23,7 @@
"""
from Element import Element
-import Utils,DataType
+import Utils,DataTypes
from Connection import TooManyConnectionsException
class Socket(Element):
@@ -72,7 +72,7 @@
def get_data_type(self):
''' Get the data type. If the parsed vlen > 1, then return the
vectorized data type.'''
- if self.vlen != None and self.vlen.is_valid() and
self.vlen.parse() > 1: return DataType.vectorize(self.data_type)
+ if self.vlen != None and self.vlen.is_valid() and
self.vlen.parse() > 1: return DataTypes.vectorize(self.data_type)
return self.data_type
def get_index(self):
Modified: grc/branches/jblum_work/src/Graphics/Dialogs.py
===================================================================
--- grc/branches/jblum_work/src/Graphics/Dialogs.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/Graphics/Dialogs.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -26,7 +26,7 @@
import pygtk
pygtk.require('2.0')
import gtk
-from DataType import *
+from DataTypes import *
from Constants import *
from Elements import GraphicalParam
import Preferences
Modified: grc/branches/jblum_work/src/Graphics/USRPDiagnostics.py
===================================================================
--- grc/branches/jblum_work/src/Graphics/USRPDiagnostics.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/Graphics/USRPDiagnostics.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -27,7 +27,7 @@
import gtk
from Actions import USRP_DIAGNOSTICS_DISPLAY,get_action_from_name
from Elements import GraphicalParam
-from DataType import *
+from DataTypes import *
from Dialogs import TextDisplay
def enable_usrp_diagnostics():
Modified: grc/branches/jblum_work/src/MathExprParser.py
===================================================================
--- grc/branches/jblum_work/src/MathExprParser.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/MathExprParser.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -32,7 +32,7 @@
_WHITESPACE = (' ', '\t', '')
-_CONSTANTS = { #constans must be lower case
+_CONSTANTS = { #constants must be lower case
'pi' : cmath.pi,
'e' : cmath.e,
'j' : 1j,
@@ -45,50 +45,66 @@
}
#########################################################
-## Number parsers
+# Number parsers
#########################################################
def verify_complex(num):
- ''' Verify that the number is a complex number.
- Raise an exception if number cannot be cast to a complex.
- Return the value as a complex. '''
+ """!
+ Verify that the number is a complex number.
+ @param num the potential complex number
+ @throw ValueError not a number
+ @return a complex number
+ """
try: c_num = complex(num) #ensure that the num can be complex
except: raise ValueError('"%s" is not a number.'%(num,))
return c_num
def verify_float(num):
- ''' Verify that the number has no imaginary part.
- Raise an exception if the imaginary part is non zero.
- Return the value as a float. '''
+ """!
+ Verify the number as a float.
+ The number can have no imaginary part.
+ @param num the potential float number
+ @throw ValueError imaginary part is non zero.
+ @return a float number
+ """
c_num = verify_complex(num) #ensure that the num can be complex
if c_num.imag != 0: raise ValueError('Expected a float but found
"%s".'%(c_num,))
return float(c_num.real)
def verify_int(num):
- ''' Verify that the number has no imaginary part.
- Verify that the number has no decimal part.
- Otherwise raise an exception.
- Return the value as a int '''
+ """!
+ Verify the number as an integer.
+ The number can have no imaginary part.
+ The number can have no decimal part.
+ @param num the potential integer number
+ @throw ValueError imaginary or decimal part is non zero.
+ @return an integer number
+ """
f_num = verify_float(num)
if f_num - int(f_num) != 0: raise ValueError('Expected an integer but
found "%s".'%(f_num,))
return int(f_num)
def verify_number(num):
- ''' Try to cast the number into its most primative form.
- In this order: int, float, or complex.
- Raise an exception if num is not a number.
- Return a number of type listed above. '''
+ """!
+ Try to cast the number into its most primative form: int, float, or
complex.
+ @throw ValueError num is not a number.
+ @return a number of int, float, or complex type
+ """
try: return verify_int(num) #try int
except:
try: return verify_float(num) #try float
except: return verify_complex(num) #complex or fail
#########################################################
-## Complex mathematical functions
+# Complex mathematical functions
#########################################################
def _complex_abs_v(*args):
- ''' Compute the abs of a complex number or vector. '''
+ """!
+ Compute the abs of a complex number or vector (recursively).
+ @param args list of numbers
+ @return the abs of args
+ """
sum = 0
for arg in args:
if _is_list(arg): sum = sum + _complex_abs_v(*arg)
@@ -98,7 +114,11 @@
return verify_number(cmath.sqrt(sum))
def _complex_real_v(*args):
- ''' Get the real part of a number or vector. '''
+ """!
+ Get the real part of a number or vector (recursively).
+ @param args list of numbers
+ @return the real of args
+ """
result = list()
for arg in args:
if _is_list(arg): result.append(_complex_real_v(*arg))
@@ -106,7 +126,11 @@
return result
def _complex_imag_v(*args):
- ''' Get the imaginary part of a number or vector. '''
+ """!
+ Get the imaginary part of a number or vector (recursively).
+ @param args list of numbers
+ @return the imaginary of args
+ """
result = list()
for arg in args:
if _is_list(arg): result.append(_complex_imag_v(*arg))
@@ -114,7 +138,11 @@
return result
def _complex_conj_v(*args):
- ''' Get the complex conjugate of a number or vector. '''
+ """!
+ Get the conjugate part of a number or vector (recursively).
+ @param args list of numbers
+ @return the conjugate of args
+ """
result = list()
for arg in args:
if _is_list(arg): result.append(_complex_conj_v(*arg))
@@ -122,14 +150,20 @@
return result
def _complex_arg(arg):
- ''' Get the angle of the complex number (radians). '''
+ """!
+ Get the angle of the complex number.
+ @param arg a complex number
+ @return the angle in radians
+ """
return verify_number(math.atan2(verify_complex(arg).imag,
verify_complex(arg).real))
def _handle_filter(filter, *filter_args):
- ''' Pass the filter arguments to the filter function.
- Format the arguments to floats and ints.
- Raise errors for invalid filter arguments.
- Return a list of taps. '''
+ """!
+ Pass the filter arguments to the filter function.
+ Use a look up method to format the arguments to floats and ints before
calling the filter function.
+ @throw Exception invalid filter arguments.
+ @return a list of taps.
+ """
filter_args = list(filter_args) #make filter args a list
filter_props = { # map a filter to filter argument properties:
# (allowed lengths of args), (args that are floats), (args that
are ints)
@@ -208,7 +242,7 @@
}
#########################################################
-## Boolean tests for special characters and symbols
+# Boolean tests for special characters and symbols
#########################################################
def _is_list(symbol): return type(symbol) == type(list())
@@ -253,13 +287,21 @@
}[bracket]
#########################################################
-## Symbolic operations
+# Symbolic operations
#########################################################
def _handle_operation(op, arg1, arg2):
- ''' Handle basic operations specified in the order of operations.
- All calculations are complex, some vector operations are
supported.
- Return the number/list representing the result. '''
+ """!
+ Handle basic operations specified in the order of operations
(recursively).
+ All calculations are complex, some vector operations are supported.
+ @param op the operator
+ @param arg1 first argument to the operator
+ @param arg2 second argument to the operator
+ @throw NameError unknown operations
+ @throw ZeroDivisionError divide by zero
+ @throw ArithmeticError impossible operations
+ @return the nested data representing the result (numbers and lists)
+ """
if op not in _ORDER_OF_OPS: raise NameError('Unknown operator:
"%s".'%(op))
arg1_is_list = _is_list(arg1)
arg2_is_list = _is_list(arg2)
@@ -296,16 +338,19 @@
raise ArithmeticError('Operation of "%s" cannot be performed on "%s",
"%s".'%(op, arg1, arg2))
#########################################################
-## Evaluate the expression string
+# Evaluate the expression string
#########################################################
def _separate_expression(expr_str):
- ''' Separate the string into a list of elements.
- Use only the lower-cased version of the expression string.
- Terminating characters will dictate the separations.
- Terminating characters will be included in the list.
- Whitespace characters will be removed from the list.
- Return a list of strings representing each element. '''
+ """!
+ Separate the string into a list of elements.
+ Use only the lower-cased version of the expression string.
+ Terminating characters will dictate the separations.
+ Terminating characters will be included in the list.
+ Whitespace characters will be removed from the list.
+ @param expr_str the expression string
+ @return a list of strings representing each element
+ """
elements = list()
element = ''
for char_str in expr_str.lower():
@@ -319,11 +364,14 @@
return filter(lambda elem: not _is_whitespace(elem), elements)
def _rectify_operators(elements):
- ''' Rectify the functionality of the minus sign (-),
- and the plus sign (+) (in the floating point format).
- Determine if the minus sign is used as a negative,
- and replace it with -1* or ^-. Also rejoin floating point
formats.
- Return the list of elements with minus and plus used only as
operators. '''
+ """!
+ Rectify operators.
+ Fix the functionality of the minus sign (-) and the plus sign (+)
in the floating point format,
+ which would have been separated by separate_expression.
+ If the minus sign is used as a negative replace it with -1* or ^-.
+ @param elements a list of strings
+ @return the list of elements with minus and plus used only as operators
+ """
rectified_elements = list()
for i,element in enumerate(elements):
if i == 0 and element == '-': #first element was a minus
@@ -348,10 +396,15 @@
return rectified_elements
def _nest_elements(elements, open_bracket=''):
- ''' Read through the elements, recursing at each open bracket.
- Put elements inside bracket pairs into a list.
- Raise an Error if bracket pairs do not match.
- Return the nested elements. '''
+ """!
+ Put the elements into a nested data format (recursively).
+ Read through the elements, recursing at each open bracket.
+ Put elements inside bracket pairs into a list.
+ @param a list of strings (rectified)
+ @param open_bracket the last open bracket
+ @throw SyntaxError bracket pairs do not match
+ @return the nested elements.
+ """
nested_elements = list()
while elements: #continue until elements is empty
element = elements.pop(0)
@@ -367,11 +420,16 @@
return nested_elements
def _simplify_nested_elements(nested_elements):
- ''' Read through the nested elements and simplify expressions.
- Work according to the order of operations specified above.
- Recurse at each list, substitute constans, parse numbers,
handle functions.
- Make comma separated values into lists (represent vectors).
- Return the final value of the expression. '''
+ """!
+ Read through the nested elements and simplify expressions (recursively).
+ Work according to the order of operations.
+ Recurse at each list, substitute constans, parse numbers, handle
functions.
+ Make comma separated values into lists to represent vectors.
+ @param nested_elements nested elements (strings and lists)
+ @throw SyntaxError bad syntax
+ @throw NameError unknown symbol
+ @return the final value of the expression.
+ """
for i,element in enumerate(nested_elements):
# simplify the nested lists #
if _is_list(element): nested_elements[i] =
_simplify_nested_elements(element)
@@ -388,7 +446,7 @@
if not _is_list(args): args = [args]
try: ans = _FUNCTIONS[function](*args)
except Exception, e:
- raise ValueError('Function "%s" with arguments
"%s" failed.\n\t%s'%(function, nested_elements[i+1], e))
+ raise SyntaxError('Function "%s" with arguments
"%s" failed.\n\t%s'%(function, nested_elements[i+1], e))
if not _is_list(ans): ans = [ans] # ans must be a
list
ans_with_commas = list()
for an in ans: ans_with_commas.extend([an, ','])
@@ -424,9 +482,11 @@
return vector #otherwise return vector
def eval_expr(expr_str):
- ''' Evaluate a mathematical expression string with numbers, and
operators.
- Raise an exception on failue.
- Return a list containing the parsed expression. '''
+ """!
+ Evaluate a mathematical expression string with numbers, and operators.
+ @throw Exception failue
+ @return nested data (numbers and lists)
+ """
separated_elements = _separate_expression(expr_str)
#print "separated", separated_elements
rectified_elements = _rectify_operators(separated_elements)
@@ -437,7 +497,7 @@
return simplified
if __name__ == '__main__':
- ''' Evaluate expressions passed by argv(1). '''
+ """Evaluate expressions passed by argv1."""
import sys
if len(sys.argv) > 1: print eval_expr(sys.argv[1])
else: print "No expressions passed!"
Modified: grc/branches/jblum_work/src/Messages.py
===================================================================
--- grc/branches/jblum_work/src/Messages.py 2007-06-11 07:41:42 UTC (rev
5765)
+++ grc/branches/jblum_work/src/Messages.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -24,15 +24,21 @@
from Constants import VERSION,PREFERENCES_FILE_PATH
-# A list of methods that can receive a message. #
+## A list of methods that can receive a message.
MESSENGERS_LIST = list()
def register_messenger(messenger):
- """ Append the given messenger to the list of messengers. """
+ """!
+ Append the given messenger to the list of messengers.
+ @param messenger a method thats takes a string
+ """
MESSENGERS_LIST.append(messenger)
def send(message):
- """ Give the given message to each of the messengers. """
+ """!
+ Give the message to each of the messengers.
+ @param message a message string
+ """
for messenger in MESSENGERS_LIST: messenger(message)
###########################################################################
Modified: grc/branches/jblum_work/src/ParseXML.py
===================================================================
--- grc/branches/jblum_work/src/ParseXML.py 2007-06-11 07:41:42 UTC (rev
5765)
+++ grc/branches/jblum_work/src/ParseXML.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -26,17 +26,31 @@
import xml.dom.ext
def find_data(nested_data, my_tag):
- """ Helper function for dealing with nested data. """
+ """!
+ Find a tag one level deep.
+ Helper function for dealing with nested data.
+ @param nested_data the data to search
+ @param my_tag the tag to search for
+ @return the data associated with the tag, None if not found
+ """
for tag,data in nested_data:
if tag == my_tag: return data
return None
def from_xml(doc):
- ''' Create nested data from an xml doc using the from xml helper.
'''
+ """!
+ Create nested data from an xml doc using the from xml helper.
+ @param doc the xml doc
+ @return the nested data
+ """
return __from_xml(doc.firstChild)
def __from_xml(doc):
- ''' Recursivly parse the xml doc into nested data format. '''
+ """!
+ Recursivly parse the xml doc into nested data format.
+ @param doc the xml doc
+ @return the nested data
+ """
#print doc.nodeType,doc.localName,doc.nodeValue,doc.childNodes
tag_name = doc.localName
if len(doc.childNodes) == 0:
@@ -50,13 +64,22 @@
return tag_name,nested_data
def to_xml(nested_data):
- ''' Create an xml doc and use the to xml helper method to load it.
'''
+ """!
+ Create an xml doc and use the to xml helper method to load it.
+ @param nested_data the nested data
+ @return the xml doc
+ """
doc = xml.dom.minidom.Document()
doc.appendChild(__to_xml(nested_data, doc))
return doc
def __to_xml(nested_data, doc):
- ''' Recursivly parse the nested data into xml doc format. '''
+ """!
+ Recursivly parse the nested data into xml doc format.
+ @param nested_data the nested data
+ @param the xml doc
+ @return the xml doc
+ """
tag_name,value = nested_data
child = doc.createElementNS(None, tag_name)
if type(value) == type(list()):
@@ -69,16 +92,22 @@
return child
def to_file(doc, file_path):
- ''' Save the xml doc to the file path. '''
+ """!
+ Save the xml doc to the file path.
+ @param doc the xml doc
+ @param file_path the destination xml-file
+ """
xml.dom.ext.PrettyPrint(doc, open(file_path,'w'))
def from_file(file_path):
- ''' Load an xml doc from the file path. '''
+ """!
+ Load an xml doc from the file path.
+ @param file_path the source xml-file
+ @return the xml doc
+ """
return xml.dom.minidom.parse(open(file_path, 'r'))
if __name__ == '__main__':
- nested = ('version', [('one',[('k','l'),('h','y')]),('two','2')])
- xml.dom.ext.PrettyPrint(to_xml(nested), open('test.xml','w'))
- print from_xml(xml.dom.minidom.parse(open('test.xml', 'r')))
- print nested
+ """Use the main method to test parse xml's functions."""
+ pass
\ No newline at end of file
Modified: grc/branches/jblum_work/src/Preferences.py
===================================================================
--- grc/branches/jblum_work/src/Preferences.py 2007-06-11 07:41:42 UTC (rev
5765)
+++ grc/branches/jblum_work/src/Preferences.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -22,7 +22,7 @@
Holds global preferences stored as GraphicalParams.
"""
-from DataType import Bool,FileOpen,Enum,Int
+from DataTypes import Bool,FileOpen,Enum,Int
from Elements import GraphicalParam
import time,socket #for tagging saved files
from Constants import *
@@ -55,8 +55,7 @@
# List of Preferences
###########################################################################
-PREFS_LIST = [ #list of all prefs the be saved, restored, and displayed in the
pref's dialog
-#(title, notes, list of preferences)
+PREFS_LIST = [ #(title, notes, list of preferences)
("Verification", '', [
CONNECTION_CHECKING_PREF,
PARAM_CHECKING_PREF,
@@ -91,14 +90,21 @@
# Preference Access Methods
###########################################################################
-def get_value(param):
- """ If the param is valid, return the parsed value of the param.
- Otherwise return a blank string. """
+def _get_value(param):
+ """!
+ Get the value of the given parameter.
+ If the param is valid, return the parsed value of the param, otherwise
return a blank string.
+ @param param the parameter
+ @return the value of the parameter
+ """
if param.get_data_type().is_valid(): return
param.get_data_type().parse()
else: return ''
-def to_nested():
- """ Convert the param's data to nested format """
+def _to_nested():
+ """!
+ Convert the param's data to nested format.
+ @return the nested format
+ """
categories = list()
nested_data = ('preferences', [
('timestamp', str(time.time())),
@@ -111,8 +117,11 @@
for param in params: prefs.append(('pref',
param.get_data_type().get_data()))
return nested_data
-def from_nested(nested_data):
- """ Parse the nested data to retrieve each preference. """
+def _from_nested(nested_data):
+ """!
+ Parse the nested data to retrieve each preference.
+ @param nested_data the nested data
+ """
find_data = ParseXML.find_data
preferences = find_data([nested_data], 'preferences')
categories = find_data(preferences, 'categories')
@@ -125,17 +134,25 @@
except: pass
def load(window=None):
+ """!
+ Load the preferences from the preferences file.
+ @param window optional flow graph window
+ """
try:
-
from_nested(ParseXML.from_xml(ParseXML.from_file(PREFERENCES_FILE_PATH)))
- if window: window.resize(get_value(MAIN_WINDOW_WIDTH_PREF),
get_value(MAIN_WINDOW_HEIGHT_PREF))
+
_from_nested(ParseXML.from_xml(ParseXML.from_file(PREFERENCES_FILE_PATH)))
+ if window: window.resize(_get_value(MAIN_WINDOW_WIDTH_PREF),
_get_value(MAIN_WINDOW_HEIGHT_PREF))
except: Messages.send_fail_load_preferences()
def save(window=None):
+ """!
+ Save the preferences to the preferences file.
+ @param window optional flow graph window
+ """
if window:
width,height = window.get_size()
MAIN_WINDOW_WIDTH_PREF.get_data_type().set_data(width)
MAIN_WINDOW_HEIGHT_PREF.get_data_type().set_data(height)
- try: ParseXML.to_file(ParseXML.to_xml(to_nested()),
PREFERENCES_FILE_PATH)
+ try: ParseXML.to_file(ParseXML.to_xml(_to_nested()),
PREFERENCES_FILE_PATH)
except IOError: Messages.send_fail_save_preferences()
###########################################################################
@@ -143,34 +160,34 @@
###########################################################################
def set_default_flow_graph(file_path):
''' Set the new default flow graph path, only if the restore option is
true. '''
- if get_value(RESTORE_FLOW_GRAPH_PREF):
+ if _get_value(RESTORE_FLOW_GRAPH_PREF):
DEFAULT_FLOW_GRAPH_PREF.get_data_type().set_data(file_path)
def get_default_flow_graph():
''' Get the default flow graph path. Return a blank string if the path
is invalid. '''
if DEFAULT_FLOW_GRAPH_PREF.get_data_type().is_valid():
- return get_value(DEFAULT_FLOW_GRAPH_PREF)
+ return _get_value(DEFAULT_FLOW_GRAPH_PREF)
return ''
def check_connections():
- return get_value(CONNECTION_CHECKING_PREF)
+ return _get_value(CONNECTION_CHECKING_PREF)
def check_sockets():
- return get_value(SOCKET_CHECKING_PREF)
+ return _get_value(SOCKET_CHECKING_PREF)
def check_params():
- return get_value(PARAM_CHECKING_PREF)
+ return _get_value(PARAM_CHECKING_PREF)
def show_reports_window():
- return get_value(REPORTS_WIN_SHOW_PREF)
+ return _get_value(REPORTS_WIN_SHOW_PREF)
def get_grid_size():
- return get_value(GRID_SIZE_PREF)
+ return _get_value(GRID_SIZE_PREF)
def snap_to_grid():
- return get_value(SNAP_TO_GRID_PREF)
+ return _get_value(SNAP_TO_GRID_PREF)
def show_grid():
- return get_value(SHOW_GRID_PREF)
+ return _get_value(SHOW_GRID_PREF)
\ No newline at end of file
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Coders.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Coders.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Coders.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Encode and Decode.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
def ConstellationDecoder(sb):
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Conversions.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Conversions.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Conversions.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Convert between data types.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import all_choices,all_vector_choices
from Constants import MAX_NUM_SOCKETS
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Filters.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Filters.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Filters.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Taps generators are from gr.firdes. Most FIR filters are implemented
and a few misc ones.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import default_samp_rate,all_choices
Modified: grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
2007-06-11 07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
2007-06-11 21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Various graphical sinks.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import default_samp_rate
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Misc.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Misc.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Misc.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -22,7 +22,7 @@
These blocks were not categorized. Try to keep the number of misc
blocks small.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import default_samp_rate,all_choices
from Constants import MAX_NUM_SOCKETS
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Various modulation schemes.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
def FrequencyModulation(sb):
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Operators.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Operators.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Operators.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
These blocks implement basic mathematical operations + - * / log10...
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from Constants import *
Modified: grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
2007-06-11 07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
2007-06-11 21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Constants used by the signal block definitions.
"""
-from DataType import *
+from DataTypes import *
all_choices = [
('Complex', Complex()),
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Various data sinks.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import *
from Constants import DEFAULT_FILE_PATH,MUTEX
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Sources.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Sources.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Sources.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Various data sources.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import *
from Constants import DEFAULT_FILE_PATH
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Trellis.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Trellis.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Trellis.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,7 +22,7 @@
Trellis Blocks by: Achilleas Anastasopoulos
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
from SignalBlockConstants import all_choices
from Constants import DEFAULT_FILE_PATH
Modified: grc/branches/jblum_work/src/SignalBlockDefs/USRP.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/USRP.py 2007-06-11 07:41:42 UTC
(rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/USRP.py 2007-06-11 21:43:15 UTC
(rev 5766)
@@ -22,7 +22,7 @@
The source and sink blocks for the USRP.
"""
-from DataType import *
+from DataTypes import *
from gnuradio import gr
def set_freq(u, which, subdev, freq, verbose=False):
Modified: grc/branches/jblum_work/src/SignalBlockDefs/__init__.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/__init__.py 2007-06-11
07:41:42 UTC (rev 5765)
+++ grc/branches/jblum_work/src/SignalBlockDefs/__init__.py 2007-06-11
21:43:15 UTC (rev 5766)
@@ -22,5 +22,4 @@
Build a signal block represented by a specific tag.
"""
-from DataType import *
from SignalBlockTree import SB_TREE,get_signal_block,TagNotFoundException
Modified: grc/branches/jblum_work/src/StateCache.py
===================================================================
--- grc/branches/jblum_work/src/StateCache.py 2007-06-11 07:41:42 UTC (rev
5765)
+++ grc/branches/jblum_work/src/StateCache.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -26,13 +26,18 @@
from Constants import STATE_CACHE_SIZE
class StateCache:
- """ The state cache is an interface to a list to record data/states and
to revert to previous states. """
+ """
+ The state cache is an interface to a list to record data/states and to
revert to previous states.
+ States are recorded into the list in a circular fassion by using an
index for the current state,
+ and counters for the range where states are stored.
+ """
def __init__(self, initial_state):
- """ The initial state is given as well as the handler for the
windows
- so that redo/undo/save can be properly handled. """
+ """!
+ StateCache constructor.
+ @param initial_state the intial state (nested data)
+ """
self.states = list()
- for i in range(STATE_CACHE_SIZE):
- self.states.append(None)
+ for i in range(STATE_CACHE_SIZE): self.states.append(None)
self.current_state_index = 0
self.num_prev_states = 0
self.num_next_states = 0
@@ -41,40 +46,50 @@
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
def save_new_state(self, state):
- """ Place the new state at the next index and add one to the
number of previous states. """
+ """!
+ Save a new state.
+ Place the new state at the next index and add one to the number
of previous states.
+ @param state the new state
+ """
self.current_state_index = (self.current_state_index +
1)%STATE_CACHE_SIZE
self.states[self.current_state_index] = state
self.num_prev_states = self.num_prev_states + 1
- if self.num_prev_states == STATE_CACHE_SIZE:
- self.num_prev_states = STATE_CACHE_SIZE - 1
+ if self.num_prev_states == STATE_CACHE_SIZE:
self.num_prev_states = STATE_CACHE_SIZE - 1
self.num_next_states = 0
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(True)
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
def get_current_state(self):
- """ get the state at the current index """
+ """!
+ Get the state at the current index.
+ @return the current state (nested data)
+ """
return self.states[self.current_state_index]
def get_prev_state(self):
- """ get the previous state if possible and decrement the
current index. """
+ """!
+ Get the previous state and decrement the current index.
+ @return the previous state or None
+ """
if self.num_prev_states > 0:
self.current_state_index = (self.current_state_index +
STATE_CACHE_SIZE -1)%STATE_CACHE_SIZE
self.num_next_states = self.num_next_states + 1
self.num_prev_states = self.num_prev_states - 1
- if self.num_prev_states == 0:
-
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(False)
+ if self.num_prev_states == 0:
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(False)
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(True)
return self.get_current_state()
return None
def get_next_state(self):
- """ get the next state if possible and increment the
current index. """
+ """!
+ Get the nest state and increment the current index.
+ @return the next state or None
+ """
if self.num_next_states > 0:
self.current_state_index = (self.current_state_index +
1)%STATE_CACHE_SIZE
self.num_next_states = self.num_next_states - 1
self.num_prev_states = self.num_prev_states + 1
- if self.num_next_states == 0:
-
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
+ if self.num_next_states == 0:
get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(False)
get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(True)
return self.get_current_state()
return None
Modified: grc/branches/jblum_work/src/Variables.py
===================================================================
--- grc/branches/jblum_work/src/Variables.py 2007-06-11 07:41:42 UTC (rev
5765)
+++ grc/branches/jblum_work/src/Variables.py 2007-06-11 21:43:15 UTC (rev
5766)
@@ -24,8 +24,9 @@
from Constants import DEFAULT_SLIDER_STEPS
-''' Hold the current variables for the running program. The dictionary
- maps keys to values,ranges. '''
+
+""" Hold the current variables for the running program.
+The dictionary maps keys to values,ranges. """
VARS_DICT = dict()
VAR_MARKER = '$' #place this character before a variable
@@ -33,16 +34,25 @@
get_keys = VARS_DICT.keys #get a list of variable keys
def clear_vars():
- ''' Call unregister on every var. '''
+ """ Call unregister on every var. """
for key in VARS_DICT.keys(): unregister(key)
def register(key, value, min='', max='', step=''):
- ''' Change/Add the value,range for a given key.
+ """!
+ Register the value and a [range] for a given key.
+ The range is a min, max, and a step size.
If no range is specified, value can be any string.
If a range is specified min, max, and step numbers have to be parsable
as floats.
Partially completed ranges will be intelligently filled in.
Partially blanked ranges will be cleared.
- All parameters must be strings! '''
+ All parameters must be strings!
+ @param key the variable key
+ @param value the value
+ @param min the mimimum of the variable's range
+ @param max the maximum of the variable's range
+ @param step the step size for the variable's range
+ @throw Exception invalid arguments
+ """
# make sure that all parameters are strings #
for var in (key, value, min, max, step):
if type(var) != type(str()): raise TypeError('"%s" var is not
of type string'%var)
@@ -81,8 +91,12 @@
VARS_DICT[key] = (value, min, max, step)
def is_key_name_valid(key_name):
- ''' True if the key name is valid. Valid keys start with a letter and
- may contain only letters, numbers, underscrores(_). '''
+ """!
+ Is the key valid?
+ Valid keys start with a letter and may contain only letters, numbers,
underscrores(_).
+ @param key_name the potential key name (string)
+ @return true if the key name is valid
+ """
if len(key_name) == 0 or len(key_name) > 20: return False
for i,char in enumerate(key_name):
if i == 0 and not char.isalpha(): return False
@@ -90,29 +104,52 @@
return True
def unregister(key):
- ''' Remove a key if it exisits '''
+ """!
+ Remove a key if it exisits.
+ @param key the variable key to remove
+ """
if has_key(key): del VARS_DICT[key]
def has_key(key):
- ''' Is the key in this dict? '''
+ """!
+ Is the key in this registry?
+ @param key the variable key potentially in the registry
+ @return true if key is in the registry
+ """
return key in VARS_DICT
def get_values(key):
- ''' Get the tuple for this key. '''
+ """!
+ Get the valuesfor this key.
+ @param key the variable key
+ @return the (value,min,max,step) tuple
+ """
return VARS_DICT[key]
def is_ranged(key):
- ''' Does this variable have a range:
- min, max, and step are not blank. '''
+ """!
+ Does this variable have a range?
+ The variable has a range if min, max, and step are non-blank.
+ Only check the minimum for non-blankness.
+ @param key the variable key
+ @return true if the variable has a range
+ """
return get_values(key)[1] != ''
def get_value(key):
- ''' Get the value for this key. '''
- return VARS_DICT[key][0]
+ """!
+ Get the value for this key.
+ @param key the variable key
+ @return the value
+ """
+ return get_values(key)[0]
def replace_var_instances(string):
- ''' Replace every instance of a marker + variable key
- with the string representation of the variable. '''
+ """!
+ Replace every instance of a marker + variable key with the string
representation of the variable.
+ @param string the input string
+ @return the string with variables substituted out
+ """
for key in get_keys(): string = string.replace(VAR_MARKER + key,
get_value(key))
return string
@@ -120,9 +157,13 @@
## Import the Variables
##########################################################################
def from_nested_data(nested_data):
- ''' Clear all of the registered variables,
- and load all variables from nested data.
- Return a list of keys, in the order they were added. '''
+ """!
+ Load the variables from nested data.
+ Clear all of the registered variables,
+ and load all variables from nested data.
+ @param nested_data the nested data for variables
+ @return a list of keys, in the order
+ """
import ParseXML,Messages
find_data = ParseXML.find_data
clear_vars()
@@ -153,9 +194,8 @@
pass #dont register!
return keys
-if __name__ == '__main__':
- print is_key_name_valid('sdfa13_fsf_dsd')
- print is_key_name_valid('2sdfa13_fsf_dsd')
- print is_key_name_valid('sdfa13._fsf_fdsd')
+if __name__ == '__main__':
+ """Use the main method to test variable's functions."""
+ pass
\ No newline at end of file
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r5766 - in grc/branches/jblum_work/src: . Elements Graphics SignalBlockDefs,
jblum <=