6 Replies - 593 Views - Last Post: 05 September 2016 - 05:47 AM Rate Topic: -----

#1 Go4Bouvier  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 03-September 16

How to pass a class as a parameter of another class

Posted 04 September 2016 - 03:48 AM

Hi All,

I'm new to Python, and would be very pleased if you can help me driving through my programming issue.

There are a couple of weeks ago, i've decided to spend some time learning how to code using Python.
I wished to create a kind of template that can be easily re-used for several data parsing purposes.

With such idea in mind, i wrote a code (object oriented) using specific classes, but I'm now facing an issue for getting the functions being usable through the classes.

As per the code below, when i press the 'Execute' button, the function 'function_sel' from the 'RadioB' class should double-check the status of an entry field and then, based on the variable associated with the the Radio button, should execute the function matching with the variable. Unfortunately, it doesn't work because there is no link between classes, and re-calling a class by using another variable looks to me not to be a good practice (see 'TextArea' class and 'get_output' function). The solution might be to pass the class as a parameter of another class, but i did not succeed to put this idea into practice without creating loops (between the classes RadioB and MainFrame).("maximum recursion depth exceeded in __instancecheck__."). Could you please help me that, by showing me how the 'function_sel' (commented) should be coded.

Many thanks in advance.
Python 3.4 - Mac OsX El Capitan

P.S. Sorry for my poor level of english. :-)

import os
import subprocess
import shlex
import tkinter as tk
from tkinter import filedialog
from tkinter import Toplevel
from tkinter.ttk import *
import tkinter.scrolledtext as tkst
import datetime
import sys


class Dialog(tk.Frame):
    def __init__(self, master):
        self.master = master
        self.file_opt = options = {}
        options['filetypes'] = [('all files', '.*'), ('text files', '.txt')]
        options['initialfile'] = 'Watt.txt'
        options['parent'] = master

    def export_result(self, Var1):
        self.filename = filedialog.asksaveasfile(mode='w', defaultextension='.txt', **self.file_opt)
        if self.filename is None:
            return
        self.filename.write(Var1)
        self.filename.close()

    def message(self):
        self.newWindow = Toplevel(self.master)
        self.newwindow.title('Warning - Empty Field')


class RadioB(tk.Frame):
    def __init__(self, parent):
        self.dialo = Dialog(parent)
        self.parent = parent
        tk.Frame.__init__(self, parent)

        LIST = [
            ('Order Type/Tote Location Check', 'OTC'),
            ('Tote Decoupling Check', 'TDC'),
            ('Tracking Tote Id', 'TTid'),
            ('List Pickers', 'LP'),
            ('Send Message To Picker(s)[csv]', 'SM'),
            ('Kill Pid(s)[csv]', 'Kid')
        ]
        self.v = tk.StringVar()
        self.v.set('OTC')
        val = 0
        for text, mode in LIST:
            self.radio = tk.Radiobutton(parent, text=text, variable=self.v, value=mode, bg='#ECECEC')
            self.radio.grid(row=0, column=val)
            val += 1

    # def function_sel(self):
    #     if self.v != None and self.entry1_1.select_present:
    #         if self.v == 'OTC':
    #             self.ordertype()
    #         elif self.v == 'TDC':
    #             self.q_down_load()
    #         elif self.v == 'TTid':
    #             self.adbridge2()
    #     else:
    #         self.dialo.message()


class TextArea(tk.Frame):
    def __init__(self, parent):
        self.parent = parent
        self.dial = Dialog(parent)

        tk.Frame.__init__(self, parent)

        self.bill = tkst.ScrolledText(width=150, height=40, bg='#ECECEC')
        self.bill.grid(row=1, column=0)

    def print_output(self, a):
        self.bill.insert('end', a)

    def clear_screen(self):
        self.bill.delete('0.0', 'end')

    def get_output(self):
        self.Var0 = self.bill.get('1.0', 'end')
        self.dial.export_result(self.Var0)




class MainFrame(tk.Frame):
    def __init__(self, master):
        Frame.__init__(self, master)


        self.master = master

        self.frameH1 = Frame(self.master)
        self.frameH1.grid(row=0, column=0)

        self.radiobutton0_0 = RadioB(self.frameH1)
        self.radiobutton0_0.grid(row=0, column=0, sticky=tk.E + tk.W)

        self.label1_0 = Label(self.frameH1, text='Tote Id')
        self.label1_0.grid(row=1, column=0, sticky=tk.E, pady=5)

        self.sep1_0 = Separator(self.frameH1, orient='horizontal')
        self.sep1_0.grid(row=0, column=0, columnspan=6, sticky=tk.W + tk.E + tk.S)

        self.entry1_1 = tk.StringVar()
        self.entry1_1 = Entry(self.frameH1, textvariable=self.entry1_1.get())
        self.entry1_1.grid(row=1, column=1)

        self.label1_2 = Label(self.frameH1, text='Pid')
        self.label1_2.grid(row=1, column=2, sticky=tk.E)

        self.entry1_3 = Entry(self.frameH1)
        self.entry1_3.grid(row=1, column=3)

        self.label1_4 = Label(self.frameH1, text='Picker Id')
        self.label1_4.grid(row=1, column=4, sticky=tk.E)

        self.entry1_5 = Entry(self.frameH1)
        self.entry1_5.grid(row=1, column=5)

        self.sep2_0 = Separator(self.frameH1, orient='horizontal')
        self.sep2_0.grid(row=1, column=0, columnspan=6, sticky=tk.W + tk.E + tk.S)

        self.sep3_0 = Separator(self.frameH1, orient='horizontal')
        self.sep3_0.grid(row=3, column=0, columnspan=6, sticky=tk.W + tk.E + tk.S)

        self.button2_0 = Button(self.frameH1, text='Execute', command=self.q_down_load)
        self.button2_0.grid(row=2, column=1, pady=5)

        self.frameH2 = Frame(self.master)
        self.frameH2.grid(row=1, column=0)

        self.tex = TextArea(self.frameH2)
        self.tex.grid(row=1, column=0)

        self.button2_3 = Button(self.frameH1, text='Clear Screen')
        self.button2_3.bind('<Button-1>', lambda e: self.tex.clear_screen(), add='+')
        self.button2_3.bind('<Button-1>', lambda e: self.entry1_1.delete('0', 'end'), add='+')
        self.button2_3.grid(row=2, column=3)

        self.button2_5 = Button(self.frameH1, text='Quit', command=self.frameH1.quit)
        self.button2_5.grid(row=2, column=5, padx=15)

        self.frameH3 = Frame(master)
        self.frameH3.grid(row=2, column=0)

        self.label4_0 = Label(self.frameH3, text='PTL Server Network Status')
        self.label4_0.grid(row=0, column=0, pady=5, padx='10')

        self.c4_1 = tk.Checkbutton(self.frameH3, bg='#ECECEC')
        self.c4_1.grid(row=0, column=1, padx='10')

        self.label4_2 = Label(self.frameH3, text='Controller Network Status')
        self.label4_2.grid(row=0, column=2, padx='10')

        self.c4_3 = tk.Checkbutton(self.frameH3, bg='#ECECEC')
        self.c4_3.grid(row=0, column=3, padx='10')

        self.label4_4 = Label(self.frameH3, text='PLC Network Status')
        self.label4_4.grid(row=0, column=4, padx='10')

        self.c4_5 = tk.Checkbutton(self.frameH3, bg='#ECECEC')
        self.c4_5.grid(row=0, column=5, padx='10')

        self.button4_6 = Button(self.frameH3, text='Export Screen Result')
        self.button4_6.bind('<Button-1>', lambda e: self.tex.get_output())
        self.button4_6.grid(row=0, column=6, padx='90')

    def ordertype(self):
        filename = 'logptlcont'
        filepath = os.path.abspath(filename)
        command_line = '''awk -F, 'match ($0,toteID) {T=$4} END {print T}' filePath'''
        argos = shlex.split(command_line)
        argos[2] = 'match ($0, %s ) {T=$4} END {print T}' % self.entry1_1.get()
        argos[3] = filepath
        self.p = subprocess.check_output(argos)
        self.output1 = self.p.decode(sys.stdout.encoding)
        self.out = self.entry1_1.get() + str('-') + self.output1
        self.tex.print_output(self.out)

    def q_down_load(self):
        fileName = 'q_down_load'
        filePath = os.path.abspath(fileName)
        self.cat = subprocess.Popen(['cat', filePath], stdout=subprocess.PIPE, )
        self.grep1 = subprocess.Popen(['grep', '.'], stdin=self.cat.stdout, stdout=subprocess.PIPE, )
        self.grep2 = subprocess.Popen(['grep', '-B1', self.entry1_1.get()], stdin=self.grep1.stdout,
                                      stdout=subprocess.PIPE, universal_newlines=True)
        self.out, err = self.grep2.communicate()
        if self.out == '':
            self.out = str('%s - %s - No Such Tote Found\n' % (datetime.date.today(), self.entry1_1.get()))
        self.tex.print_output(self.out)

    def adbridge2(self):
        filename = 'logptlcont'
        filePath = os.path.abspath(filename)
        self.grep1 = subprocess.Popen(['grep', '-i', 'STAT1', filePath], stdout=subprocess.PIPE, )
        self.grep2 = subprocess.Popen(['grep', self.entry1_1.get(), '--color=auto'], stdin=self.grep1.stdout,
                                      stdout=subprocess.PIPE, universal_newlines=True)
        self.out, err = self.grep2.communicate()
        if self.out == '':
            self.out = str('%s - %s - No Such Tote Found\n' % (datetime.date.today(), self.entry1_1.get()))
        self.tex.print_output(self.out)



def main():
    root = tk.Tk()
    root.title('Watt v1.0 - Yves')
    root.configure(background='#ECECEC')

    MainFrame(root)
    root.mainloop()


if __name__ == '__main__':
    main()



Is This A Good Question/Topic? 0
  • +

Replies To: How to pass a class as a parameter of another class

#2 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: How to pass a class as a parameter of another class

Posted 04 September 2016 - 04:34 AM

I hope this may be helpful:
When I need information to pass between classes, I often let the classes in question inheritances from a common super-class; and place the info to be shared in this super-class.
Was This Post Helpful? 0
  • +
  • -

#3 Go4Bouvier  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 03-September 16

Re: How to pass a class as a parameter of another class

Posted 04 September 2016 - 07:15 AM

Hi DK3250,

Thanks a lot for your feedback on this, much appreciated :) . I'm not really familiar with the Super-classes. Do you have a link or a sample of code that could illustrate their use ?
Was This Post Helpful? 0
  • +
  • -

#4 jon.kiparsky  Icon User is offline

  • Chinga la migra
  • member icon


Reputation: 10681
  • View blog
  • Posts: 18,289
  • Joined: 19-March 11

Re: How to pass a class as a parameter of another class

Posted 04 September 2016 - 07:28 AM

Quote

I'm not really familiar with the Super-classes. Do you have a link or a sample of code that could illustrate their use ?


Quick example:

class Foo:
  self.template = "the %s %s %p the %s"

  def sentence(self):
    return self.template % (self.subject, self.verb, self.preposition, self.object)

class Bar(Foo):
  subject = "cat"
  verb = "sat"
  preposition = "on"
  object = "mat"

class Baz(Foo):
  subject = "bear"
  verb = "pooped"
  preposition = "in"
  object = "woods"



if bar is an instance of Bar, then bar.sentence will return "The cat sat on the mat", while baz.sentence will return "The bear pooped in the woods"
The superclass, Foo, collects the shared understanding of what Bar and Baz think a sentence looks like and how to produce it.
Was This Post Helpful? 2
  • +
  • -

#5 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: How to pass a class as a parameter of another class

Posted 04 September 2016 - 07:53 AM

Further to jon.kiparskys answer:

If a sub-class is asked for an attribute or a method not defined in the class, it will look-up in the super-class for the item.
jon.kiparsky just demonstrated this for a method; I'll include a very simple example for an attribute:
class Super():
    name = "My_Name"

class Child(Super):
    pass

child = Child()
print(child.name)

Running this code will produce the output My_Name
The class Child do not have an attribute called name, so it looks up the Super() class and finds it.
Was This Post Helpful? 2
  • +
  • -

#6 Go4Bouvier  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 03-September 16

Re: How to pass a class as a parameter of another class

Posted 04 September 2016 - 08:20 AM

Thanks to you both, i will try to put your recommandations into practice and will let you know how it went.
Was This Post Helpful? 0
  • +
  • -

#7 Go4Bouvier  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 03-September 16

Re: How to pass a class as a parameter of another class

Posted 05 September 2016 - 05:47 AM

Hi All,

I followed your recommendations and i put all the redundant attributes within one super class independently and the error message 'maximum recursion depth exceeded in __instancecheck__' went away. :clap:


It also help me to review my own code and i finally found why the class 'function_el' was not working properly. The entry1_1 field and the self.v were missing the .get() extension for the comparisons.

Thanks a lot for your help.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1