سؤال

أحاول إنشاء وحدة python 2.7 tkinter التي تستخدم بيانات عنصر واجهة المستخدم للتأثير على فهم القائمة الذي يختار بين الحيوانات التي يتم تمثيل سماتها الاحتمالية كقائمة من القوائم.تقوم الوحدة بفرز وعرض الحيوانات الثلاثة بترتيب تنازلي عند النقر فوق "إرسال" وتفعيل الأمر المرتبط.

في هذا المثال، تبلغ نسبة الحيوانات الثلاثة 33% بعد النقر فوق "إرسال" لأنها تشترك في نفس بيانات الاحتمالية.تختلف الحيوانات فقط بين بيانات عناصر واجهة المستخدم الخاصة بالمقياس في العمود 2 من قائمة القوائم حيث أن كل منها إما مائي أو أرضي أو كليهما.

from Tkinter import BOTH, BOTTOM, Button, E, END, Entry, FLAT, Frame, Grid, HORIZONTAL, Label, LEFT, N, NO, Pack, RAISED, RIGHT, S, Scale, Text, Tk, TOP, W, YES

from operator import mul

root = Tk()
root.title('Example')

class Environment:
    def __init__(self, parent):

        # layout
        self.myParent = parent

        self.main_frame = Frame(parent, background="light blue")
        self.main_frame.pack(expand=YES, fill=BOTH)

        self.main_left_frame = Frame(self.main_frame, background="light blue")
        self.main_left_frame.pack(side=LEFT, expand=YES, fill=BOTH)

        self.main_right_frame = Frame(self.main_frame, background="light blue")
        self.main_right_frame.pack(side=RIGHT, expand=YES, fill=BOTH)

        self.water = Scale(self.main_right_frame, from_=0.01, to=1.00, orient=HORIZONTAL, bd=0, label="Aquatic",
        background="white", troughcolor="cyan", length=50, width=10, sliderlength=10, resolution=0.01)
        self.water.pack()
        self.water.set(1.00)

        self.soil = Scale(self.main_right_frame, from_=0.01, to=1.00, orient=HORIZONTAL, bd=0, label="Terrestrial",
        background="white", troughcolor="saddle brown", length=50, width=10, sliderlength=10, resolution=0.01)
        self.soil.pack()
        self.soil.set(1.00)

        self.id_frame = Frame(self.main_left_frame, background="white")
        self.id_frame.pack(side=BOTTOM)

        # submit button
        self.submitbutton = Button(self.main_left_frame,text="Submit", background="black", foreground="white",
        width=6, padx="2m", pady="1m")
        self.submitbutton.pack(side=TOP)
        self.submitbutton.bind("<Button-1>", self.submitbuttonclick)
        self.submitbutton.bind("<Return>", self.submitbuttonclick)

        #Animal Matrix
        self.animal = [
        ('Odocoileous virginiana','White-tailed Deer',self.soil.get,0.99,0.01,0.99),
        ('Anguilla anguilla','American Eel',self.water.get,0.99,0.01,0.99),
        ('Trachemys scripta','Slider',lambda:self.soil.get()*self.water.get(),0.99,0.01,0.99)]

    def submitbuttonclick(self, event):
        self.id_frame.destroy()
        self.id_frame = Frame(self.main_left_frame, background="white")
        self.id_frame.pack(side=BOTTOM)

        A=self.animal

        #equation
        sigma = float(sum(reduce(mul,item[3:]) for item in A))
        B = [(item[0], "%.2f" % (item[2]()*reduce(mul, item[3:])/sigma)) for item in A]
        C = sorted(B, key=lambda item: item[1], reverse=True)  

        Label(self.id_frame, text = C[0], background = "white").pack(side=TOP, anchor = W)
        Label(self.id_frame, text = C[1], background = "white").pack(side=TOP, anchor = W)
        Label(self.id_frame, text = C[2], background = "white").pack(side=TOP, anchor = W)

environment = Environment(root)       
root.mainloop()

بفضل العديد من التحسينات المساهمة، يعمل هذا الرمز!

هل كانت مفيدة؟

المحلول

أول شيء ألاحظه هو أنك تحدد A ليكون قاموسًا فارغًا، ثم قم بالكتابة فوق هذا القاموس الفارغ باستخدام self.animal, ، وهي قائمة.

    A={}
    A=self.animal

لذلك لست متأكدًا مما تقصد القيام به هنا.ثم في تعريفك ل B أنت تقطعها:

    B = [(A[0], "%.2f" % (reduce(mul,A[3:])*A[2][i]/sigma*A[2][i])) for A in A]

هذا لا يتناسب مع أيضاً تعريف ال A, ، لأنه لا يمكنك تقطيع الإملاء، ولكن فهرس البداية الذي اخترته هو 3, ، وأعلى مؤشر في self.animal يكون 2.مربك!لكن بالنظر عن كثب، يصبح من الواضح أن المشكلة تكمن في إعادة الاستخدام A كمتغير فهرسة.أنت حقًا لا ينبغي أن تفعل ذلك؛يجعل هذا الرمز بشكل لا يصدق مربك.

يمكن أن يسبب أخطاء أيضًا.خذ بعين الاعتبار هذا الرمز:

>>> a = range(10)
>>> [a for a in a]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
9

كما ترون، فإن فهم القائمة يسبب a للإشارة إلى القيمة الأخيرة في التسلسل المعروف سابقًا باسم a.لا يحدث هذا في التعليمات البرمجية الخاصة بك لأنك استخدمت تعبير المولد.لكن لا يزال من الصعب قراءتها ومربكًا.أنا بقوة أوصي بالقيام بذلك بدلاً من ذلك:

    sigma = float(sum(reduce(mul,item[3:]) for item in A))
    B = [(item[0], "%.2f" % (reduce(mul,item[3:])/sigma)) for item in A] 

تحديث:حسنًا، بعد إجراء هذه التغييرات، لا تزال بحاجة إلى ذلك get البيانات من المقاييس.في تعريفك ل self.animal, ، انت تستخدم self.soil.get(), ، مثل ذلك:

('Odocoileous virginiana','White-tailed Deer',self.soil.get(),0.99,0.01,0.99)

وهذا يضع قيمة الإرجاع لـ self.soil.get() في صف.ولكن بعد ذلك تكون هذه القيمة ثابتة، ولن تتغير أبدًا.عليك أن تتصل صراحة self.soil.get() كل مرة تريد القيمة المحدثة.كما أن استيعاب قائمتك لا يصل أبدًا إلى القيمة التي يتم إرجاعها هناك.أنت تقطعهم هكذا:

>>> l = ('Odocoileous virginiana','White-tailed Deer',
...      self.soil.get(), 0.99, 0.01, 0.99)
>>> l[3:]
(0.98999999999999999, 0.01, 0.98999999999999999)

تذكر أن الفهرسة في القوائم والصفوف تبدأ بـ 0 - هكذا في الصف أعلاه l, l[0] == 'Odocoileous virginiana'.لذلك، إذا كنت تريد كل شيء ما عدا الشيئين الأولين، فيجب عليك القطع من الفهرس 2:

>>> l[2:]
(0.55000000000000004, 0.98999999999999999, 0.01, 0.98999999999999999)

ولكن هذا لا يحل المشكلة الجذرية، وهي أنه يجب عليك الاتصال self.soil.get() للحصول على البيانات المحدثة.إحدى الطرق التي يمكنك من خلالها القيام بذلك هي ببساطة إعادة الإنشاء self.animal في كل مرة يتم الضغط على زر الإرسال.سيكون ذلك مضيعة لكنه سينجح.قد يكون النهج الأقل إهدارًا (ولكنه لا يزال محرجًا) هو حفظ الوظيفة نفسها في الصف، بدلاً من نتيجة الوظيفة.ستفعل ذلك على النحو التالي:

>>> l = ('Odocoileous virginiana','White-tailed Deer',
...      self.soil.get, 0.99, 0.01, 0.99)

لاحظ غياب () بعد self.soil.get.الآن لا يحتوي الصف على قيمة النقطة العائمة، بل يحتوي على دالة تُرجع قيمة النقطة العائمة.يجب عليك الاتصال به للحصول على القيمة، ولكنه يُرجع القيمة المحدثة بالكامل في كل مرة.للجمع بين الوظائف، يمكنك استخدام lambda:

>>> l = ('Odocoileous virginiana','White-tailed Deer',
...      lambda: self.soil.get() * self.water.get(), 0.99, 0.01, 0.99)

الآن يمكنك الاتصال l[2] للحصول على قيمة:

>>> l[2]()
0.30250000000000005

لذا، لتجميع كل ذلك معًا، عليك تقسيم فهم القائمة أكثر قليلًا للاتصال به بشكل صريح l[2], ، ولكن بمجرد القيام بذلك، من المفترض أن ينجح هذا الأمر.هذا ليس إعدادًا مثاليًا، ولكن أخشى أنني يجب أن أترك إنشاء بنية محسنة كتمرين للقارئ.

نصائح أخرى

A[2][i]/sigma*A[2][i]تحاول هذه القطعة فهرسة التعويم.هل ينبغي أن يكون هذا: A[i]/sigma*A[i] بدلاً من؟

لقد افترضت أن القيم الموجودة في A كلها عوامات.

ال for A in A الجزء يبدو مراوغًا بعض الشيء بالنسبة لي.قد يكون صحيحًا من الناحية النحوية، ولكن من الأكثر وضوحًا استخدام أسماء مختلفة للمجموعات والعناصر الموجودة في تلك المجموعات.

أيضًا for isolates in A: i = A.index(isolates) يمكن جعلها أكثر فعالية باستخدام for i, isolates in enumerate(A), ، مثل A.index(isolates) يمكن أن يستغرق وقتًا طويلاً عندما يكون A كبيرًا.

أعلم أن هذا ليس إجابة لسؤالك حقًا، ولكن آمل أن يكون مفيدًا مع ذلك.

لتسهيل تصحيح الأخطاء (ولمساعدتك فعليًا)، يرجى إعادة كتابة هذا:

[(A[0], "%.2f" % (reduce(mul,A[3:])*A[2][i]/sigma*A[2][i])) for A in A]

إلى شيء أكثر قابلية للقراءة.إذا قمت بتقسيمه إلى شيء يحتوي على أسطر متعددة، فيمكنك بالفعل استخدام مصحح الأخطاء، ورؤية المتغير "العائم" بسهولة ومكان فهرسته.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top