简体   繁体   中英

Why does my if and elif statements only work for one button at a time?

I have my program display a list of buttons stored in a json file. I have each button's stored time, honey , compared to the current time, time.time() and the delay that the user inputs.

For some reason the conditional only works when there is one button. Once I add an additional button the program turns the first button green to indicate its early and the new button turns yellow to indicate that it is early. Once the new button turns red the first button turns red as well.

I have timed the program and the program runs at the correct time. Why am I having this problem and how would I fix it? Code:

class MainApp(App):
    def build(self): # build() returns an instance
        self.store = JsonStore("streak.json") # file that stores the streaks:
        Clock.schedule_interval(self.check_streak, 1/30.)

        return presentation

    def check_streak(self, dt):

        for child in reversed(self.root.screen_two.ids.streak_zone.children):
            honey = float(child.id)

            with open("streak.json", "r") as read_file:
                data = json.load(read_file)

            for value in data.values():
                if value['delay'] is not None:
                    delay = int(value['delay'])

                    if delay > time.time() < honey: # early (yellow)
                        child.background_normal = ''
                        child.background_color = [1, 1, 0, 1]

                    elif delay > time.time() > honey: # on time (green)
                        child.background_normal = ''
                        child.background_color = [0, 1, 0, 1]


                    elif delay < time.time() > honey: # late (red)
                        child.background_normal = ''
                        child.background_color = [1, 0, 0, 1]

def display_btn(self):
        # display the names of the streaks in a list on PageTwo
        with open("streak.json", "r") as read_file:
            data = json.load(read_file)

        for value in data.values():
            if value['delta'] is not None:
                print(f"action={value['action']}, delta={value['delta']}, grace={value['delay']}")
                streak_button = StreakButton(id=str(value['delta']), text=value['action'],
                                            on_press=self.third_screen, size=(400,50),
                                            size_hint=(None,None))
                self.root.screen_two.ids.streak_zone.add_widget(streak_button)

total = ((int(self.streak.day) * 86400) + (int(self.streak.hour) * 3600) +
                    (int(self.streak.minute) * 60)) # convert into seconds

            self.current_time = time.time()
            self.count = self.current_time + total
            grace = (int(self.streak.delay) * 60) + self.count # aka delay

            parsed = True

            # delete later just used to test
            print("[seconds:", total,']' , "[action:", self.streak.action,']',
                 "[grace:", grace,']')

            # store streak attributes inside "streak.json"
            self.store.put(self.streak.action, action=self.streak.action,
                          delay=grace, seconds=total,
                          score=0, delta=self.count)

streak.json file: {"one": {"action": "one", "delay": 1557095861.2131674, "seconds": 60, "score": 0, "delta": 1557095801.2131674}, "two": {"action": "two", "delay": 1557096131.7338686, "seconds": 60, "score": 0, "delta": 1557096071.7338686}}

It works for only one button because the if...elif statements are outside the for loop.

Solution

Move the if...elif block into the if value['delay'] is not None: block inside the for loop.

Snippets

def check_streak(self, dt):

    for child in reversed(self.root.screen_two.ids.streak_zone.children):
        honey = float(child.id)

        with open("streak.json", "r") as read_file:
            data = json.load(read_file)

        for value in data.values():
            if value['delay'] is not None:
                delay = int(value['delay'])

                # fix for later
                if delay > time.time() < honey: # early (yellow)
                    child.background_normal = ''
                    child.background_color = [1, 1, 0, 1]

                elif delay > time.time() > honey: # on time (green)
                    child.background_normal = ''
                    child.background_color = [0, 1, 0, 1]

                elif delay < time.time() > honey: # late (red)
                    child.background_normal = ''
                    child.background_color = [1, 0, 0, 1]

The problem was that having two loops caused my data to get mismatched. I needed to be able to either iterate over the button objects and only use the correct json file dictionary entry for each, or iterate over the json file and only modify the corresponding child. I decided to use the former.

I set up the code so that for every child in the streak_zone name = child.text

I then compare every key in my json file to the name of the button aka child

if the name of the key is equal to name then we get the value of the nested key delay

New code:

def check_streak(self, dt):

        for child in reversed(self.root.screen_two.ids.streak_zone.children):
            honey = float(child.id)
            name = child.text


            with open("streak.json", "r") as read_file:
                data = json.load(read_file)


            for key in data.keys():
                if key == name:
                    delay = data.get(key, {}).get('delay')


                if delay > time.time() < honey: # early (yellow)
                    child.background_normal = ''
                    child.background_color = [1, 1, 0, 1]

                elif delay > time.time() > honey: # on time (green)
                    child.background_normal = ''
                    child.background_color = [0, 1, 0, 1]


                elif delay < time.time() > honey: # late (red)
                    child.background_normal = ''
                    child.background_color = [1, 0, 0, 1]

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