By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,923 Members | 1,655 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,923 IT Pros & Developers. It's quick & easy.

dynamic plotting inside wx

P: 1
hello everyone, i need some help regarding my python code.

it is a medical plotter/display program with wxagg backend. it reads 3 kinds of data from a text file: ecg, heart rate, and oxygen saturation. ecg data is plotted by embedding matplotlib inside wx, while the other two is wxStaticText. to differentiate them, a buffer character was introduced before each reading and parsed accordingly.

my PROBLEM is i want to make the program work without using wxYield. i've read somewhere that as much as possible it should be avoided. im thinking maybe use threading but i cant make it work like it should be. if i comment out the wxYield line the plot is updated, but the other two readings won't.

here is my code and the input textfile(truncated version of 'data.txt').

it requires wxpython,pyserial, and matplotlib modules.

Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3. # generated by wxGlade 0.4.1 on Thu Aug 16 11:20:21 2007
  4.  
  5. from matplotlib.numerix import arange
  6. import matplotlib
  7.  
  8. # uncomment the following to use wx rather than wxagg
  9. #matplotlib.use('WX')
  10. #from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas
  11.  
  12. # comment out the following to use wx rather than wxagg
  13. matplotlib.use('WXAgg')
  14. from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
  15. from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg,Toolbar
  16.  
  17. from matplotlib.figure import Figure
  18.  
  19. import wx
  20. import serial
  21.  
  22. class MyFrame(wx.Frame):    
  23.  
  24.     count = 1000     # this is the number of samples to display at a time
  25.     t = arange(0.0,count,1)
  26.     data = [0.3 for i in range(count)]  # storage for ECG graph data
  27.     #ser = serial.Serial(port = '/dev/ttyUSB0', baudrate = 57600)  # for COM 1: port = 0, etc
  28.     #ser = serial.Serial(port = 'COM2', baudrate = 57600)  # for COM 1: port = 0, etc
  29.     txtfile = open('data.txt','r')  
  30.  
  31.     def __init__(self, *args, **kwds):
  32.         # begin wxGlade: MyFrame.__init__
  33.         kwds["style"] = wx.DEFAULT_FRAME_STYLE
  34.         wx.Frame.__init__(self, *args, **kwds)
  35.         self.sizer_8_staticbox = wx.StaticBox(self, -1, "")
  36.         self.sizer_7_staticbox = wx.StaticBox(self, -1, "")
  37.  
  38.         self.spo2_display = wx.StaticText(self, -1, "0")
  39.         self.spo2_statictxt = wx.StaticText(self, -1, "% Sp02")
  40.         self.spo2_header = wx.StaticText(self, -1, "blood-oxygen saturation")
  41.         self.bpm_display = wx.StaticText(self, -1, "0")
  42.         self.bpm_statictxt = wx.StaticText(self, -1, "bpm")    
  43.         self.bpm_header = wx.StaticText(self, -1, "heart rate")
  44.  
  45.         # Menu Bar
  46.         # File menu
  47.         self.Main_Menu = wx.MenuBar()
  48.         self.SetMenuBar(self.Main_Menu)
  49.         self.File = wx.Menu()
  50.         self.Start_Display = wx.MenuItem(self.File, wx.NewId(), "Start Display", "", wx.ITEM_NORMAL)
  51.         self.File.AppendItem(self.Start_Display)
  52.         self.Exit = wx.MenuItem(self.File, wx.NewId(), "Exit", "", wx.ITEM_NORMAL)
  53.         self.File.AppendItem(self.Exit)
  54.         self.Main_Menu.Append(self.File, "File")
  55.         # Edit menu
  56.         self.Edit = wx.Menu()
  57.         self.Options = wx.MenuItem(self.Edit,wx.NewId(),"Options","",wx.ITEM_NORMAL)
  58.         self.Edit.AppendItem(self.Options)
  59.         self.Main_Menu.Append(self.Edit,"Edit")
  60.         # Help menu
  61.         self.Help = wx.Menu()
  62.         self.About = wx.MenuItem(self.Help,wx.NewId(),"About","",wx.ITEM_NORMAL)
  63.         self.Help.AppendItem(self.About)
  64.         self.Main_Menu.Append(self.Help,"Help")
  65.         # Menu Bar end
  66.  
  67.         # Status bar
  68.         self.Telemed_statusbar = self.CreateStatusBar(1, 0)
  69.  
  70.         # embed matplotlib
  71.         self.figure = Figure()
  72.         self.axes = self.figure.add_subplot(111)    # 111 means 1 row, 1 column on subplot #1
  73.  
  74.         #self.line, = self.axes.plot(self.t, self.data, 'r', linewidth = 3.0,color='#FF523A')
  75.         self.line, = self.axes.plot(self.t, self.data, 'r', linewidth = 3.0,color='#FF351A')
  76.  
  77.  
  78.         self.canvas = FigureCanvas(self, -1, self.figure)
  79.         self.axes.set_title('ECG Waveform')
  80.         #self.axes.set_ylim(0,3.3)
  81.         self.axes.set_ylim(0.4,2.2)
  82.         #self.axes.set_ylim(0,2.5)
  83.         self.axes.grid(True)
  84.         #self.sizer_1.Add(self.canvas, 0, wx.LEFT | wx.TOP | wx.GROW)
  85.  
  86.         # Toolbar for matplotlib canvas
  87.         #self.toolbar = NavigationToolbar2WxAgg(self.canvas)
  88.         self.toolbar = Toolbar(self.canvas)
  89.         self.toolbar.Realize()
  90.         if wx.Platform == '__WXMAC__':
  91.             # Mac platform (OSX 10.3, MacPython) does not seem to cope with
  92.             # having a toolbar in a sizer. This work-around gets the buttons
  93.             # back, but at the expense of having the toolbar at the top
  94.             self.SetToolBar(self.toolbar)
  95.         else:
  96.             # On Windows platform, default window size is incorrect, so set
  97.             # toolbar width to figure width.
  98.             tw, th = self.toolbar.GetSizeTuple()
  99.             fw, fh = self.canvas.GetSizeTuple()
  100.             # By adding toolbar in sizer, we are able to put it at the bottom
  101.             # of the frame - so appearance is closer to GTK version.
  102.             # As noted above, doesn't work for Mac.
  103.             #self.toolbar.SetSize(wx.Size(fw, th))
  104.             self.toolbar.SetSize(wx.Size(1000, th))
  105.  
  106.  
  107.         self.toolbar.update()
  108.  
  109.         self.__set_properties()
  110.         self.__do_layout()
  111.         self.__bind_events()
  112.         # end wxGlade
  113.  
  114.     def __set_properties(self):
  115.         # begin wxGlade: MyFrame.__set_properties
  116.         self.SetTitle("Telemed")
  117.         self.SetSize((1280, 700))
  118.  
  119.         self.canvas.SetMinSize((1000, 501))
  120.         self.canvas.SetPosition((40,40))
  121.  
  122.         self.spo2_header.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Sans"))
  123.         self.spo2_header.SetForegroundColour(wx.Colour(35, 142, 35))
  124.         self.spo2_display.SetMinSize((130, 78))
  125.         self.spo2_display.SetBackgroundColour(wx.Colour(255, 255, 255))
  126.         self.spo2_display.SetFont(wx.Font(45, wx.MODERN, wx.NORMAL, wx.BOLD, 0, "Sans"))
  127.         self.spo2_display.SetForegroundColour(wx.Colour(35, 142, 35))
  128.         self.spo2_statictxt.SetMinSize((103, 60))
  129.         self.spo2_statictxt.SetFont(wx.Font(20, wx.MODERN, wx.ITALIC, wx.NORMAL, 0, "Sans"))
  130.         self.spo2_statictxt.SetForegroundColour(wx.Colour(35, 142, 35))
  131.  
  132.         self.bpm_header.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Sans"))
  133.         self.bpm_header.SetForegroundColour(wx.Colour(50, 50, 204))
  134.         self.bpm_display.SetMinSize((130, 78))
  135.         self.bpm_display.SetFont(wx.Font(45, wx.MODERN, wx.NORMAL, wx.BOLD, 0, "Sans"))
  136.         self.bpm_display.SetForegroundColour(wx.Colour(50, 50, 204))
  137.         self.bpm_statictxt.SetMinSize((60, 60))
  138.         self.bpm_statictxt.SetFont(wx.Font(20, wx.MODERN, wx.ITALIC, wx.NORMAL, 0, "Sans"))       
  139.         self.bpm_statictxt.SetForegroundColour(wx.Colour(50, 50, 204))
  140.         #self.bpm_statictxt.SetBackgroundColour(wx.Colour(50, 50, 204))
  141.  
  142.  
  143.  
  144.         #self.canvas.SetBackgroundColour(wx.Colour(239, 235, 231))
  145.  
  146.         self.Telemed_statusbar.SetStatusWidths([-1])
  147.         # statusbar fields
  148.         Telemed_statusbar_fields = ["Ready"]
  149.         for i in range(len(Telemed_statusbar_fields)):
  150.             self.Telemed_statusbar.SetStatusText(Telemed_statusbar_fields[i], i)
  151.         # end wxGlade
  152.  
  153.     def __do_layout(self):
  154.         # begin wxGlade: MyFrame.__do_layout
  155.         sizer_1 = wx.BoxSizer(wx.VERTICAL)
  156.         sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
  157.         sizer_6 = wx.BoxSizer(wx.VERTICAL)
  158.         sizer_8 = wx.StaticBoxSizer(self.sizer_8_staticbox, wx.HORIZONTAL)
  159.         sizer_7 = wx.StaticBoxSizer(self.sizer_7_staticbox, wx.HORIZONTAL)
  160.         #sizer_2.Add(self.panel_7, 1, wx.EXPAND, 0)
  161.         #sizer_2.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
  162.         sizer_2.Add(self.canvas, 0, wx.LEFT | wx.TOP | wx.GROW | wx.EXPAND)
  163.  
  164.         sizer_6.Add(self.spo2_header, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
  165.         sizer_7.Add(self.spo2_display, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 1)
  166.         sizer_7.Add(self.spo2_statictxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 2)
  167.         sizer_6.Add(sizer_7, 1, wx.EXPAND, 0)
  168.  
  169.         sizer_6.Add(self.bpm_header, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
  170.         sizer_8.Add(self.bpm_display, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 1)
  171.         sizer_8.Add(self.bpm_statictxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 2)
  172.         sizer_6.Add(sizer_8, 1, wx.EXPAND, 0)
  173.         sizer_6.Add((20, 80), 0, wx.ADJUST_MINSIZE, 0)
  174.         sizer_6.Add((20, 80), 0, wx.ADJUST_MINSIZE, 0)
  175.         sizer_6.Add((20, 80), 0, wx.ADJUST_MINSIZE, 0)
  176.         sizer_2.Add(sizer_6, 1, wx.EXPAND, 0)
  177.         sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
  178.         self.SetAutoLayout(True)
  179.         self.SetSizer(sizer_1)
  180.         self.Layout()
  181.         # end wxGlade
  182.  
  183.     def __bind_events(self):
  184.         self.Bind(wx.EVT_MENU, self.startPlot, self.Start_Display)
  185.         self.Bind(wx.EVT_MENU, self.onExit, self.Exit)
  186.         #self.Bind(wx.EVT_MENU, self.onAbout, self.About)
  187.  
  188.     def onExit(self, event): # wxGlade: MyFrame.<event_handler>
  189.         #self.ser.close()
  190.         self.txtfile.close()
  191.         self.Close()
  192.  
  193.     def startPlot(self, event): # wxGlade: MyFrame.<event_handler>
  194.  
  195.         #self.ser.flushInput()
  196.         print 'ok here'
  197.         buf = 30    #number of samples to take before redrawing ecg graph
  198.  
  199.         while 1:
  200.             #input = self.ser.readline().strip('\r\n')
  201.             input = self.txtfile.readline().strip('\r\n')
  202.             #self.txtfile.write(input + '\n')
  203.             #print input
  204.             # check if input is from pulse ox or from ECG
  205.             if input[0] == '-':
  206.                 if input.count('.') != 0:
  207.                     continue
  208.                 if input.count('-') != 1:
  209.                     continue
  210.                 if input.count('+') != 0:
  211.                     continue
  212.                 self.spo2_display.SetLabel(input.strip('-'))
  213.                 #wx.Yield()
  214.             elif input[0] == '+':
  215.                 if input.count('.') != 0:
  216.                     continue
  217.                 if input.count('-') != 0:
  218.                     continue
  219.                 if input.count('+') != 1:
  220.                     continue
  221.                 self.bpm_display.SetLabel(input.strip('+'))
  222.                 #wx.Yield()
  223.             elif input[0] == '.':
  224.                 if input.count('.') != 2:
  225.                     continue
  226.                 if input.count('-') != 0:
  227.                     continue
  228.                 if input.count('+') != 0:
  229.                     continue
  230.                 del self.data[0]
  231.                 self.data.append(input.strip('.'))
  232.                 buf-= 1
  233.                 if buf <= 0:
  234.                     buf = 30
  235.                     self.line.set_data(self.t, self.data)
  236.                     self.canvas.draw()
  237.                     #wx.Yield()
  238.  
  239.     def OnPaint(self, event):
  240.         self.canvas.draw()
  241.  
  242. # end of class MyFrame
  243.  
  244.  
  245. class MyApp(wx.PySimpleApp):
  246.     """Application class."""
  247.     def OnInit(self):
  248.         wx.InitAllImageHandlers()
  249.         self.frame=MyFrame(None,-1,"")
  250.         self.frame.Show()
  251.         self.SetTopWindow(self.frame)
  252.         return True
  253.  
  254. def main():
  255.     app = MyApp()
  256.     app.MainLoop()
  257.  
  258. if __name__ == "__main__":
  259.     main()
  260.  
[contents of data.txt]
-97
+83
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-97
+83
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-97
+83
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-98
+83
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-98
+83
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.1.851
.2.000
.2.000
.2.000
.1.639
.2.000
.2.000
.2.000
-98
+83
.1.373
.1.859
.2.000
.2.000
.1.482
.0.996
.2.000
.2.000
.1.529
.0.572
.2.000
.2.000
.1.780
-98
+83
.0.580
.1.812
.2.000
.2.000
.0.580
.0.745
.2.000
.2.000
.0.580
.0.564
.2.000
.2.000
.0.580
.0.572
-99
+83
.2.000
.2.000
.0.572
.0.580
.1.733
.2.000
.0.603
.0.580
.1.082
.2.000
.1.208
.0.588
.0.564
-99
+83
.2.000
.1.467
.0.588
.0.572
.2.000
.1.835
.0.588
.0.572
.1.733
.1.898
.0.580
.0.580
.1.161
.2.000
-97
+83
.0.588
.0.580
.0.564
.1.922
.0.580
.0.588
.0.572
.1.906
.0.572
.0.580
.0.572
.1.475
.0.564
-97
+83
.0.588
.0.580
.1.098
.0.713
.0.588
.0.580
.0.564
.0.933
.0.588
.0.580
.0.572
.1.169
.0.588
.0.580
-97
+83
.0.572
.1.302
.0.588
.0.588
.0.580
.1.098
.0.580
.0.588
.0.580
.0.721
.0.572
.0.588
.0.580
-97
+83
.0.698
.0.564
.0.588
.0.580
.0.572
.0.556
.0.588
.0.580
.0.580
.0.564
.0.588
.0.580
.0.580
.0.572
-97
+83
.0.588
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
-99
+83
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.580
.0.588
-97
+83
.0.580
.0.580
.0.580
.0.580
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
-97
+83
.0.572
.0.588
.0.580
.0.580
.0.572
.0.588
.0.580
.0.580
.0.572
.0.580
.0.588
.0.580
.0.580
-97
+153
.0.588
.0.588
.0.580
.0.580
.0.572
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
-97
+153
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.580
.0.588
.0.588
.0.580
.0.580
.0.588
-97
+153
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.580
-97
+153
.0.580
.0.588
.0.580
.0.580
.0.580
.0.580
.0.588
.0.588
.0.580
.0.580
.0.588
.0.588
.0.580
.0.580
-97
+199
.0.588
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.2.000
.2.000
.2.000
-97
+199
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-97
+199
.1.145
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
-97
+199
.0.580
.0.580
.0.580
.0.588
.0.588
.0.588
.0.580
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
-97
+199
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
-94
+199
.0.580
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.580
.0.580
.0.588
.0.580
-94
+199
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.705
.2.000
.2.000
.2.000
-94
+199
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-94
+127
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-94
+127
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.0.588
.0.580
-94
+127
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
-94
+127
.0.580
.0.588
.0.588
.0.588
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
-94
+127
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.588
.0.588
-94
+127
.0.588
.0.588
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
-94
+127
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.588
.0.588
.0.588
.0.588
-94
+127
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
-94
+127
.0.572
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-93
+127
.2.000
.2.000
.2.000
.2.000
.0.572
.0.580
.0.580
.2.000
.0.588
.0.580
.0.588
.1.773
.0.580
.0.580
-93
+127
.0.588
.1.059
.2.000
.0.580
.0.588
.1.443
.2.000
.0.588
.0.588
.0.745
.2.000
.0.580
.0.580
-93
+153
.0.564
.2.000
.0.572
.0.580
.0.580
.2.000
.1.529
.0.580
.0.580
.2.000
.2.000
.0.580
.0.588
.2.000
-93
+153
.2.000
.0.580
.0.588
.1.122
.2.000
.0.580
.0.580
.0.572
.2.000
.0.580
.0.580
.0.580
.2.000
-93
+153
.0.580
.0.580
.0.580
.2.000
.2.000
.0.580
.0.588
.2.000
.2.000
.0.580
.0.588
.1.027
.2.000
.0.580
-93
+187
.0.588
.0.572
.2.000
.0.588
.0.588
.0.588
.0.588
.0.580
.2.000
.2.000
.1.490
.0.588
.0.580
-93
+187
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.0.580
.0.580
-93
+187
.0.588
.0.580
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.588
.0.580
.0.588
.0.580
-93
+187
.0.580
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
-93
+187
.0.588
.0.588
.0.580
.0.588
.0.588
.0.588
.0.588
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
-93
+187
.0.588
.0.580
.0.588
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.588
-93
+187
.0.580
.0.588
.0.588
.0.588
.0.580
.0.580
.0.580
.0.580
.0.580
.0.580
.0.580
.0.588
.0.580
-97
+187
.0.588
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
.0.588
.0.580
.0.580
.0.580
-97
+187
.0.588
.0.588
.0.564
.2.000
.0.588
.0.588
.0.564
.2.000
.0.580
.0.580
.0.572
.2.000
.0.556
.0.580
-97
+187
.0.580
.2.000
.1.851
.0.588
.0.580
.2.000
.2.000
.0.588
.0.580
.1.757
.2.000
.0.588
.0.588
-97
+187
.2.000
.2.000
.0.580
.0.588
.0.572
.2.000
.0.556
.0.588
.0.580
.0.588
.0.580
.2.000
.2.000
.2.000
-97
+187
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
.2.000
-97
+187
.2.000
.2.000
.2.000

[/end of data.txt]
Aug 19 '07 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.