0

I'm writing a small program in python-3.6 to control my garden watering.

I have a file where I set the timers. For example:

Monday 7:00

The involved functions look like this:

def getTimerFile():
    """ Get timers from file an prepare them."""
    timerFile = config.get("Basic", "TimerFile")
    allowedDays = ["Monday",
                   "Tuesday",
                   "Wednesday",
                   "Thursday",
                   "Friday",
                   "Saturday",
                   "Sunday"]

    try:
        with open(timerFile) as f:
            d = dict(x.rstrip().split(" ", 1) for x in f)
        for key, value in d.items():
            time.strptime(value, "%H:%M")
            if key not in allowedDays:
                raise ValueError(" {}".format(key))

    except Exception as e:
        # TODO: Error handling
    return d


def setTimers(timerDict):
    """Set timer threads."""
    for key, value in timerDict.items():
        findDaySchedule(key, value)


def findDaySchedule(weekday, stTime):
    """Helper function
    for switch/case statement."""
    return {"Monday":  schedule.every().monday.at(stTime).do(mv),
            "Tuesday":  schedule.every().tuesday.at(stTime).do(mv),
            "Wednesday":  schedule.every().wednesday.at(stTime).do(mv),
            "Thursday":  schedule.every().thursday.at(stTime).do(mv),
            "Friday":  schedule.every().friday.at(stTime).do(mv),
            "Saturday":  schedule.every().saturday.at(stTime).do(mv),
            "Sunday":  schedule.every().sunday.at(stTime).do(mv)
            }.get(weekday, None)    # Default is None

This works as expected if I use only one timer per day. But if for ex. I want two timers on Saturday it will only take the last one.

So what would be the best solution to work with this duplicate keys. I tried something with 'defaultdict' but I didn't get the loop for the timers working correctly

Thank's in advance

rafaelc
  • 57,686
  • 15
  • 58
  • 82
DX667
  • 3
  • 3
  • 1
    You *can't*, by definition, have a dictionary with duplicate keys. (Look up how hash-mapping works if you're interested). Have you instead tried sticking the dict's keys in a list so you can put multiple timers in said list and iterate through it? –  Apr 21 '18 at 17:48
  • what if you had an `array` type as a value the `keys`? Would it not work? am I missing something? – iam.Carrot Apr 21 '18 at 17:50
  • 1
    I think you need `collections.defaultdict(list)` – Jean-François Fabre Apr 21 '18 at 17:51
  • On a sidenote, you don't really need to have such a huge dict in `findDaySchedule`. You could try something along the lines of: `return schedule.every().__getattribute__(weekday.lower()).at(stTime).do(mv)` to make the code shorter. – ForceBru Apr 21 '18 at 17:52

1 Answers1

2
  • You could use a mapping dict[weekday] -> list[times].
  • I would also recommend to not write your own config file parsing. There are several well-suited file formats in the python standard lib. I would go for json.
  • You can get rid of the switch by using getattr

times.json:

{
    "monday": ["07:00", "10:00"],
    "friday": ["09:00"]
}

and then use it:

import json
import schedule

with open('times.json') as f:
    times = json.load(f)

for day, times in times.items():
    for time in times:
        getattr(schedule.every(), day.lower()).at(time).do(stuff)
MaxNoe
  • 14,470
  • 3
  • 41
  • 46