9
\$\begingroup\$

This program tells me what lessons I have tomorrow then emails them to me.

This program works fine, but I was wondering whether there is a way to simplify the script or make it more efficient. I have removed my email and password and who it is to for privacy, but it does work.

import smtplib
import time
import datetime
from datetime import date

days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
English = ["MondayA", "WednesdayA", "ThursdayA", "FridayA", "TuesdayB", "WednesdayB", "ThursdayB"]
Maths = ["MondayA", "TuesdayA", "WednesdayA", "ThursdayA", "FridayA", "TuesdayA", "FridayB"]
Bioligy = []    #I will fill the following three
Physics = []
Chemistry = []
Computing = ["TuesdayA", "WednesdayA", "ThursdayA", "WednesdayB", "ThursdayB"]
History = ["MondayA", "TuesdayA", "MondayB", "TuesdayB", "WednesdayB"]
PE = ["ThursdayA", "WednesdayB", "FridayB"]
BaV = ["TuesdayA", "FridayB"]
French = ["MondayA", "FridayA", "MondayB", "TuesdayB", "FridayB"]
Course42 = ["MondayB"]
lesson = []
Comma = (", ")

day1 = (datetime.datetime.today().weekday())
day = (days[day1 + 1])

def WeekA(a):
    Oday = (a + "A")

    if Oday in English:
        lesson.append("English")

    if Oday in Maths:
        lesson.append("Maths")

    if Oday in Bioligy:
        lesson.append("Bioligy")

    if Oday in Physics:
        lesson.append("Physics")

    if Oday in Chemistry:
        lesson.append("Chemistry")

    if Oday in Computing:
        lesson.append("Computing")

    if Oday in History:
        lesson.append("History")

    if Oday in PE:
        lesson.append("PE")

    if Oday in BaV:
        lesson.append("B&V")

    if Oday in French:
        lesson.append("French")

    if Oday in Course42:
        lesson.append("Course42")

def WeekB(b):
    Oday = (b + "B")

    if Oday in English:
        lesson.append("English")

    if Oday in Maths:
        lesson.append("Maths")

    if Oday in Bioligy:
        lesson.append("Bioligy")

    if Oday in Physics:
        lesson.append("Physics")

    if Oday in Chemistry:
        lesson.append("Chemistry")

    if Oday in Computing:
        lesson.append("Computing")

    if Oday in History:
        lesson.append("History")

    if Oday in PE:
        lesson.append("PE")

    if Oday in BaV:
        lesson.append("B&V")

    if Oday in French:
        lesson.append("French")

    if Oday in Course42:
        lesson.append("Course42")


WeekA(day)



content = ("You have " + Comma.join(lesson) + ".")

mail = smtplib.SMTP('smtp.gmail.com',587)

mail.ehlo()

mail.starttls()

mail.login('*email*','*password*')

mail.sendmail('*email*','*email*', content)

mail.close()
\$\endgroup\$
1
  • \$\begingroup\$ does Oday stand for today? Why is it used before it is defined? \$\endgroup\$
    – Caridorc
    Commented Sep 6, 2016 at 20:43

2 Answers 2

13
\$\begingroup\$

I would change the data organization to be the opposite way, to have a dict mapping to the two week types containing a dict with a mapping from the weekday to the lessons:

timetable = {"A": {"Monday": ["English", "Maths", ...],
                   "Tuesday": ["Maths", "Computing", ...],
                   ...},
             "B": {"Monday": ["History", ...],
                   ...}}

By the way, it is spelled Biology, not Bioligy.

Then you can just use it like this:

import smtplib
import datetime

TIMETABLE = {"A": [["English", "Maths", ...],
                   ["Maths", "Computing", ...],
                   ...],
             "B": [["History", ...],
                   ...]}

SEMESTER_START = datetime.datetime(2016, 9, 1)


def calculate_week_type(date, start_date):
    """Even weeks since start_date are "A" weeks, uneven are "B" weeks"""
    return "A" if ((date-start_date).days / 7) % 2 == 0 else "B"

def lessons(timetable, start_date, date):
    week_type = calculate_week_type(date, start_date)
    return timetable[week_type][date.weekday()]

def mail_lessons(lessons, to_email='*email*'):
    content = "You have {} today.".format(", ".join(lessons))
    mail = smtplib.SMTP('smtp.gmail.com', 587)
    mail.ehlo()
    mail.starttls()
    mail.login('*email*', '*password*')
    mail.sendmail('*email*', to_email, content)
    mail.close()

if __name__ == '__main__':
    today = datetime.datetime.today()
    mail_lessons(lessons(TIMETABLE, SEMESTER_START, today))

I put the different responsibilities into separate functions, got rid of most of the global variables, and fixed some small differences to PEP8, python's official style-guide. I used a format string, because it is in general faster than string addition (it is usually more readable as well).

I also made the mapping now using numerical weekdays as indices into the internal list of lists, because this is what datetime returns. This way there is no need to translate between the two.

\$\endgroup\$
2
\$\begingroup\$

I would add all the classes into an dictionary

Courses = {
    English : ["MondayA", "WednesdayA", "ThursdayA", "FridayA", "TuesdayB", "WednesdayB", "ThursdayB"]
...
,   Course42 : ["MondayB"]
}

then turn your current two functions into one with another argument (also have a sensible name for them) and loop over the dictionary putting the key of any array that contains the current day to be tested

def Week( weekday, whichWeek ):
    testDay = weekday + whichWeek
    for course, days in courses.items():
        if testDay in days:
            lesson.append( course )

also instead of calling , 'Comma' I would use 'Separator'

\$\endgroup\$
1
  • \$\begingroup\$ also instead of calling , 'Comma' I would use 'Separator' Definitely. It's akin to a magic number. One day comma may not be , and it'll just look odd to read. \$\endgroup\$
    – N.J.Dawson
    Commented Sep 8, 2016 at 10:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.