简体   繁体   中英

How do I incorporate my Python methods in the Kivy code?

I coded a small program in Python that randomly picks between two categories and subset the dataframe accordingly. Once done, it picks a row and presents the question and a potential choice. The question and the choice are found in the row of the dataframe under two different columns. So far, it's working well; the problem is when I tried to incorporate this with kivy.

I don't understand how the sequence of actions in taken place. Basically, I want to be able to include the question and the choice on the screen via the kivy file. So far, I'm able to show them, but it looks like the value from the question doesn't match the value from the choice column. My intuition tells me that my kivy file runs the "Choosing_category" twice instead of just running it once and taking the appropriate outputs. Does anyone knows how I can solve this issue?

Here is what I have so far:

tryapp.py

import kivy
from kivy.app import App
import pandas as pd
import numpy as np

from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
kivy.require('1.11.1')

class QuestionWindows(Screen):
    def __init__(self,  **kwargs):
        super(QuestionWindows, self).__init__(**kwargs)
        self.prob = ''
        self.word = ''
        self.choice1 = ''
        self.word = ''
        self.df = pd.DataFrame()

    def _get_df(self):
        df = pd.DataFrame([['new', 'What is you favorite color?', 'blue?', 'blue', 0,0,0,0,0],
                           ['familiar', 'What is your favorite fruit?', 'apple?', 'apple', 0,0,0,0,0],
                           ['new', 'What is your favorite vegetable?', 'carrot?', 'carrot',0,0,0,0,0]],
                          columns=['state', 'questions', 'choice1', 'answer', 'cnt', 'count_correct', 'error_count', 'total_error', 'total_correct'])
        return df

    def choosing_category(self):
        # Loading the dataframe
        self.df = self._get_df()

        # Generating the category for which the question/answer will be sampled from
        self.prob = np.random.choice(['new', 'familiar'], 1, p=[0.7, 0.3])
        # Dealing with the condition on whether the state 'familiar' is not found in the data set
        if self.prob not in self.df['state'].values:
            self.prob = ['new']
            self.prob = self.prob
        else:
            self.prob = self.prob
        # Making sure to present a question/answer that hasn't been presented recently
        if len(self.df[(self.df['state'] == self.prob[0]) & (self.df['cnt'] == 0)]) > 0:
            self.tmp_df = self.df[(self.df['state'] == self.prob[0]) & (self.df['cnt'] == 0)]

        elif len(self.df[(self.df['state'] == prob)]) > 0:
            self.tmp_df = self.df[(self.df['state'] == prob)]
        else:
            self.prob = ['familiar']
            self.tmp_df = self.df[(self.df['state'] == self.prob) & (self.df['cnt'] == 0)]

        # Getting the question from the temporary dataframe
        self.word = np.random.choice(self.tmp_df['questions'])

        # Getting the choice from the question that was previously selected
        self.choice1 = self.df.loc[self.tmp_df[self.tmp_df['questions'] == self.word].index, "choice1"].values
        return str(self.word), str(self.choice1[0])


class QuestionsApp(App):

    def build(self):
        self.screen_manager = ScreenManager()
        self.question_page = QuestionWindows()
        self.screen_manager.add_widget(self.question_page)
        return self.screen_manager


if __name__ == "__main__":

    tryapp = QuestionsApp()
    tryapp.run()

questions.kv

    <SmoothButton@Button>:
    background_color: (0.0, 0.4, 0.95, 1)
    background_normal: ''
    font_size: 20

<QuestionButton@Button>:
    background_color: (0,0,0,0)
    background_normal: ''
    back_color: (0.0, 0.4, 0.95, 1)
    border_radius: [2,2,22,22]
    color: (0.0, 0.4, 0.95, 1)
    bold: True
    canvas.before:
        Color:
            rgba: self.back_color
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: self.border_radius

<QuestionWindows>
    #id: question_page
    name: "question_page"
    FloatLayout:
        QuestionButton:
            id: question
            text: root.choosing_category()[0]
            pos_hint: {'x': 0.1, 'y': 0.77}
            size_hint: 0.8, 0.17
            back_color: 1, 1, 1, 1
            background_normal: ''
            font_size: 20
            background_down: ''
        SmoothButton:
            id: choice1
            text: root.choosing_category()[1]
            pos_hint: {'x': 0.1, 'y': 0.27}
            size_hint: 0.8, 0.1

You are right about the choosing_category() method getting called twice. A good way to fix that is to use the on_enter() method as I suggested. You can modify your QuestionWindows class as:

class QuestionWindows(Screen):
    word = StringProperty('')
    choice1 = StringProperty('')
.
.
.

    def choosing_category(self):
        # Loading the dataframe
        self.df = self._get_df()
        .
        .
        .
        # Getting the question from the temporary dataframe
        self.word = np.random.choice(self.tmp_df['questions'])

        # Getting the choice from the question that was previously selected
        # Note the added [0] at the end of this line
        self.choice1 = self.df.loc[self.tmp_df[self.tmp_df['questions'] == self.word].index, "choice1"].values[0]
        # return str(self.word), str(self.choice1[0])


    def on_enter(self, *args):
        self.choosing_category()

This adds two properties to the QuestionWindows class that are updated by the choosing_categroy() method, and can be referenced within the kv :

<QuestionWindows>:
    #id: question_page
    name: "question_page"
    FloatLayout:
        QuestionButton:
            id: question
            text: root.word
            pos_hint: {'x': 0.1, 'y': 0.77}
            size_hint: 0.8, 0.17
            back_color: 1, 1, 1, 1
            background_normal: ''
            font_size: 20
            background_down: ''
        SmoothButton:
            id: choice1
            text: root.choice1
            pos_hint: {'x': 0.1, 'y': 0.27}
            size_hint: 0.8, 0.1

An advantage of this approach is that you can simply call choosing_category() and the question and choice will update.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM