[Tutor] Critique of program
Kent Johnson
kent37 at tds.net
Thu Nov 18 12:08:45 CET 2004
Bill,
To me, it seems a little strange to be using introspection every time
you want a list of all the lineEdits. I think it would be more
straightforward to keep a list of all the lineEdits with their
attributes and iterate the list. This would avoid searching through
self.__dict__ and trying to figure out what is in it.
I'll try to sketch out this solution:
Start with a list of everything you need to know about a lineEdit. This
includes ID, OD and maybe the label you use on the form -
pipes = [
( '1/2"', .622),
('3/4"', .824),
('1"', 1.049),
# etc
]
You might divide this up into four pieces, one for each page.
Now create the forms based on data in the list, and while you do it
create a new list (or maybe a dict, if you ever need access to a data
about a specific lineEdit) that keeps a reference to the lineEdit and
the data about it:
lineEdits = []
for od, id in pipes:
lineEdit = ... # however you create this
lineEdits.append( (lineEdit, od, id) )
# or maybe lineEdits[lineEdit] = (od, id) for a dict
Now you calc loop looks like this:
for w, od, id in lineEdits:
length = w.displayText()
if length: # Note: this is same as if not length == ""
length = int(length) # No need for str or 10
x = volCalc(id, length)
stack.append(x)
and the clear loop is just
for w, od, id in lineEdits:
w.clear()
Kent
Bill Burns wrote:
> You will see in the code below there are several places where I have
> replaced the line "if isinstance():" with "if hasattr():". After reading some
> posts on c.l.p, I got the feeling that it is better to use hasattr() instead
> of isinstance(). Is this correct?? You can find the posts I'm talking about
> by "googling" c.l.p for the phrase "isinstance considered harmful".
> Either way, I'm not really trying to check whether the object has a certain
> attribute that I desire, I just want to know if it's the object that I'm
> looking for. IOW, are you a lineEdit or are you a button, if you're a button
> then go away I only like lineEdits ;-) The code seems to work no matter which
> function I use.
> <CODE>
> #! /usr/bin/env python
>
> """
> Pipe Volume Calc - calculates the water volume (in U.S. gallons) contained
> inside various types and sizes of pipe.
>
> The user selects a type of pipe, a size of pipe and then enters a length (in
> feet). Water volume is automatically calculated and displayed as the data is
> entered into the form.
>
> There's a GUI front-end which is separate from this module. I made the GUI
> using Qt Designer, PyQt and pyuic. The GUI is a tabbed dialog containing
> multiple lineEdits. Each lineEdit corresponds to a specific size of pipe,
> i.e., 1/2", 3/4", etc. Each tabbed page corresponds to a different type of
> pipe (steel, copper or PVC). The user selects the page containing the type
> of pipe and then enters the total footage.
>
> The first dictionary below (pipeDict) holds all the inside diameters (in
> inches) for the various pipes. The inside diameter (and length) are needed
> to calculate water volume.
>
> The lineEdit "groups" are broken out as follows:
>
> lineEdit1 -> lineEdit25 (standard steel pipe)
> lineEdit1_1 -> lineEdit25_1 (extra strong steel pipe)
> lineEdit1_2 -> lineEdit15_2 (type L copper pipe)
> lineEdit1_3 -> lineEdit13_3 (schedule 40 PVC pipe)
> lineEdit1_4 -> lineEdit13_4 (schedule 80 PVC pipe)
> """
>
> pipeDict = \
> {'lineEdit1': .622, 'lineEdit2': .824, 'lineEdit3': 1.049,
> 'lineEdit4': 1.38, 'lineEdit5': 1.61, 'lineEdit6': 2.067,
> 'lineEdit7': 2.469, 'lineEdit8': 3.068, 'lineEdit9': 3.548,
> 'lineEdit10': 4.026, 'lineEdit11': 5.047, 'lineEdit12': 6.065,
> 'lineEdit13': 7.981, 'lineEdit14': 10.02, 'lineEdit15': 12.00,
> 'lineEdit16': 13.25, 'lineEdit17': 15.25, 'lineEdit18': 17.25,
> 'lineEdit19': 19.25, 'lineEdit20': 21.25, 'lineEdit21': 23.25,
> 'lineEdit22': 29.25, 'lineEdit23': 35.25, 'lineEdit24': 41.25,
> 'lineEdit25': 47.25,
>
> 'lineEdit1_1': .546, 'lineEdit2_1': .742, 'lineEdit3_1': .957,
> 'lineEdit4_1': 1.278, 'lineEdit5_1': 1.50, 'lineEdit6_1': 1.939,
> 'lineEdit7_1': 2.323, 'lineEdit8_1': 2.90, 'lineEdit9_1': 3.364,
> 'lineEdit10_1': 3.826, 'lineEdit11_1': 4.813, 'lineEdit12_1': 5.761,
> 'lineEdit13_1': 7.625, 'lineEdit14_1': 9.75, 'lineEdit15_1': 11.75,
> 'lineEdit16_1': 13.00, 'lineEdit17_1': 15.00, 'lineEdit18_1': 17.00,
> 'lineEdit19_1': 19.00, 'lineEdit20_1': 21.00, 'lineEdit21_1': 23.00,
> 'lineEdit22_1': 29.00, 'lineEdit23_1': 35.00, 'lineEdit24_1': 41.00,
> 'lineEdit25_1': 47.50,
>
> 'lineEdit1_2': .585, 'lineEdit2_2': .830, 'lineEdit3_2': 1.075,
> 'lineEdit4_2': 1.32, 'lineEdit5_2': 1.565, 'lineEdit6_2': 2.055,
> 'lineEdit7_2': 2.545, 'lineEdit8_2': 3.035, 'lineEdit9_2': 3.525,
> 'lineEdit10_2': 4.015, 'lineEdit11_2': 5.00, 'lineEdit12_2': 5.985,
> 'lineEdit13_2': 7.925, 'lineEdit14_2': 9.875, 'lineEdit15_2': 11.845,
>
> 'lineEdit1_3': .731, 'lineEdit2_3': .937, 'lineEdit3_3': 1.182,
> 'lineEdit4_3': 1.52, 'lineEdit5_3': 1.755, 'lineEdit6_3': 2.221,
> 'lineEdit7_3': 2.672, 'lineEdit8_3': 3.284, 'lineEdit9_3': 4.263,
> 'lineEdit10_3': 6.345, 'lineEdit11_3': 8.303, 'lineEdit12_3': 10.385,
> 'lineEdit13_3': 12.344,
>
> 'lineEdit1_4': .693, 'lineEdit2_4': .896, 'lineEdit3_4': 1.136,
> 'lineEdit4_4': 1.469, 'lineEdit5_4': 1.70, 'lineEdit6_4': 2.157,
> 'lineEdit7_4': 2.599, 'lineEdit8_4': 3.20, 'lineEdit9_4': 4.163,
> 'lineEdit10_4': 6.193, 'lineEdit11_4': 8.125, 'lineEdit12_4': 10.157,
> 'lineEdit13_4': 12.063}
>
> """
> This dictionary (sizeDict) holds all of the pipe sizes. Each size
> corresponds to a matching lineEdit on the GUI. I'm thinking I may
> use this dict to generate some kind of report. Something that the
> user can print out or save. I don't know if this is the right
> direction or not but I'll figure it out later!
> """
>
> sizeDict = \
> {'lineEdit1': '1/2"', 'lineEdit2': '3/4"', 'lineEdit3': '1"',
> 'lineEdit4': '1-1/4"', 'lineEdit5': '1-1/2"', 'lineEdit6': '2"',
> 'lineEdit7': '2-1/2"', 'lineEdit8': '3"', 'lineEdit9': '3-1/2"',
> 'lineEdit10': '4"', 'lineEdit11': '5"', 'lineEdit12': '6"',
> 'lineEdit13': '8"', 'lineEdit14': '10"', 'lineEdit15': '12"',
> 'lineEdit16': '14"', 'lineEdit17': '16"', 'lineEdit18': '18"',
> 'lineEdit19': '20"', 'lineEdit20': '22"', 'lineEdit21': '24"',
> 'lineEdit22': '30"', 'lineEdit23': '36"', 'lineEdit24': '42"',
> 'lineEdit25': '48"',
>
> 'lineEdit1_1': '1/2"', 'lineEdit2_1': '3/4"', 'lineEdit3_1': '1"',
> 'lineEdit4_1': '1-1/4"', 'lineEdit5_1': '1-1/2"', 'lineEdit6_1': '2"',
> 'lineEdit7_1': '2-1/2"', 'lineEdit8_1': '3"', 'lineEdit9_1': '3-1/2"',
> 'lineEdit10_1': '4"', 'lineEdit11_1': '5"', 'lineEdit12_1': '6"',
> 'lineEdit13_1': '8"', 'lineEdit14_1': '10"', 'lineEdit15_1': '12"',
> 'lineEdit16_1': '14"', 'lineEdit17_1': '16"', 'lineEdit18_1': '18"',
> 'lineEdit19_1': '20"', 'lineEdit20_1': '22"', 'lineEdit21_1': '24"',
> 'lineEdit22_1': '30"', 'lineEdit23_1': '36"', 'lineEdit24_1': '42"',
> 'lineEdit25_1': '48"',
>
> 'lineEdit1_2': '1/2"', 'lineEdit2_2': '3/4"', 'lineEdit3_2': '1"',
> 'lineEdit4_2': '1-1/4"', 'lineEdit5_2': '1-1/2"', 'lineEdit6_2': '2"',
> 'lineEdit7_2': '2-1/2"', 'lineEdit8_2': '3"', 'lineEdit9_2': '3-1/2"',
> 'lineEdit10_2': '4"', 'lineEdit11_2': '5"', 'lineEdit12_2': '6"',
> 'lineEdit13_2': '8"', 'lineEdit14_2': '10"', 'lineEdit15_2': '12"',
>
> 'lineEdit1_3': '1/2"', 'lineEdit2_3': '3/4"', 'lineEdit3_3': '1"',
> 'lineEdit4_3': '1-1/4"', 'lineEdit5_3': '1-1/2"', 'lineEdit6_3': '2"',
> 'lineEdit7_3': '2-1/2"', 'lineEdit8_3': '3"', 'lineEdit9_3': '4"',
> 'lineEdit10_3': '6"', 'lineEdit11_3': '8"', 'lineEdit12_3': '10"',
> 'lineEdit13_3': '12"',
>
> 'lineEdit1_4': '1/2"', 'lineEdit2_4': '3/4"', 'lineEdit3_4': '1"',
> 'lineEdit4_4': '1-1/4"', 'lineEdit5_4': '1-1/2"', 'lineEdit6_4': '2"',
> 'lineEdit7_4': '2-1/2"', 'lineEdit8_4': '3"', 'lineEdit9_4': '4"',
> 'lineEdit10_4': '6"', 'lineEdit11_4': '8"', 'lineEdit12_4': '10"',
> 'lineEdit13_4': '12"'}
>
> import sys
> import types
> from qt import *
>
> from pipeCalcGUI import PipeForm
>
> class PipeConnector(PipeForm):
> def __init__(self, parent=None):
> PipeForm.__init__(self, parent)
> self.connect(self.buttonClear,SIGNAL("clicked()"), self.clearLineEdits)
> self.connect(self.buttonExit,SIGNAL("clicked()"),self,SLOT("close()"))
> self.connect(self.buttonPrint,SIGNAL("clicked()"), self.report)
> self.lineEditTotal.setAlignment(QLineEdit.AlignRight)
>
> for name in self.__dict__:
> w = getattr(self, name)
> if name != "lineEditTotal":
> if hasattr(w, "displayText"): # if isinstance(w, QLineEdit):
> self.connect(w,SIGNAL("textChanged(const QString &)"),
> self.calc)
> w.setAlignment(QLineEdit.AlignRight)
> validator=QIntValidator(0.00, 9999999.00, w)
> w.setValidator(validator)
>
> def report(self):
> pass
> """Maybe I can use some variation of this to build a dictionary
> that contains the values from sizeDict and the lengths that
> the user has entered. At some point in time, I'm going to want
> a nicely formatted report or print out.
> """
> """
> reportDict = {}
> for name in self.__dict__:
> w = getattr(self, name)
> if name != "lineEditTotal":
> if hasattr(w, "displayText"): # if isinstance(w, QLineEdit):
> length = w.displayText()
> if not length == "":
> length = int(str(length),10)
> #size = sizeDict[name]
> #reportDict[size] = length
> reportDict[name] = length
> print reportDict
> """
>
> def calc(self):
> """First I create an empty list, then iterate through all the objects
> in self.__dict__, then "weed out" all of the objects / instances
> that are NOT lineEdits, grab the text from each lineEdit, skipping
> any lineEdit with and empty string, pull an inside diameter for
> each corresponding lineEdit from the dictionary, send that data
> to volCalc() to calculate gallons in the pipe, pop each gallon
> calculation on to the stack, send the data on the stack to add()
> to be summed and finally, set lineEditTotal to display the total
> gallons
> """
> stack = []
> for name in self.__dict__:
> w = getattr(self, name)
> if name != "lineEditTotal":
> if hasattr(w, "displayText"): #if isinstance(w, QLineEdit):
> length = w.displayText()
> if not length == "":
> length = int(str(length),10)
> ID = pipeDict[name]
> x = volCalc(ID, length)
> stack.append(x)
> total = add(stack)
> self.lineEditTotal.setText(total)
>
> def clearLineEdits(self):
> """Clears the data in every lineEdit
> """
> for name in self.__dict__:
> w = getattr(self, name)
> if hasattr(w, "displayText"): # if isinstance(w, QLineEdit):
> w.clear()
> self.lineEditTotal.setText("")
>
> def volCalc(ID, length):
> """ Calculates the water volume inside of the pipe
> """
> gal = ((ID*.5)**2)*3.14159265*(12*length)/(230.9429931)
> gal = "%0.2f" % gal
> return gal
>
> def add(args):
> """Sums all of the values on the stack
> """
> sum = 0
> for i in args:
> i = float(i)
> sum = sum + i
> sum = str(sum)
> return sum
>
> if __name__ == "__main__":
> app = QApplication(sys.argv)
> QObject.connect(app, SIGNAL("lastWindowClosed()"),
> app, SLOT("quit()"))
> win = PipeConnector()
> app.setMainWidget(win)
> win.show()
> app.exec_loop()
> </CODE>
> _______________________________________________
> Tutor maillist - Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
More information about the Tutor
mailing list