4
\$\begingroup\$

My aim was to build a small, simple program that would show me my school timetable for the present day as well as the following day. I am new to PyQt(5) and programming in general. I started programming about 5 months ago on and off just as a fun side hobby. I started with basic text-based programs which gradually got more complex and this is my first (useful) GUI program. Any thoughts/suggestions?

import datetime
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QHBoxLayout, QApplication, QWidget, QLabel)
from PyQt5.QtGui import (QIcon, QPixmap)

#My weekly school timetable
Mon = '\n1       Spanish\n2       Spanish\n3       Music\n4       Music\n5       English Literature\n6       English Literature\n7       History\n8       History'
Tue = '\n1       Social Studies\n2       Social Studies\n3       Spanish\n4       Spanish\n5       Information Technology\n6       Information Technology\n7       English Literature\n8       English Language'
Wed = '\n1       English Literature\n2       English Literature\n3       Information Technology\n4       Information Technology\n5       HSB\n6       HSB\n7       Mathematics\n8       Mathematics'
Thu = '\n1       History\n2       History\n3       English Language\n4       English Language\n5       HSB\n6       HSB\n7       Mathematics\n8       Mathematics'
Fri = '\n1       Music\n2       Music\n3       English Language\n4       English Language\n5       Mathematics\n6       Mathematics\n7       Social Studies\n8       Social Studies'

#Returns day in terms of Monday = 0, Tuesday = 1...
day = datetime.datetime.today().weekday()

if day==0:
    the_day = Mon
    tomorrow = Tue
if day==1:
    the_day = Tue
    tomorrow = Wed
if day==2:
    the_day = Wed
    tomorrow = Thu
if day==3:
    the_day = Thu
    tomorrow = Fri
if day==4:
    the_day = Fri
    tomorrow = ''
elif day==5 or day==6:
    the_day = ''
    tomorrow = Mon

if day in range(5):
    today = '<b>Today\'s Timetable:<\b>'
    next_day = '<b>Tomorrow\'s Timetable:<\b>'
else:
    today = ''
    next_day = '<b>Monday\'s Timetable:<\b>'

class timetable(QWidget):               

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):
        if day==4:
            lbl = QLabel(self)
            pixmap = QPixmap('weekend.jpg')
            smaller_pixmap = pixmap.scaled(160, 300, Qt.KeepAspectRatio, Qt.FastTransformation)
            lbl.setPixmap(smaller_pixmap)
            lbl.move(-3, 162)
            lbl.show()

        elif day==5 or day==6:
            lbl = QLabel(self)
            pixmap = QPixmap('weekend.jpg')
            smaller_pixmap = pixmap.scaled(160, 300, Qt.KeepAspectRatio, Qt.FastTransformation)
            lbl.setPixmap(smaller_pixmap)
            lbl.move(-3, 0)
            lbl.show()            

        title0 = QLabel(today, self)
        title0.move(5,5)  

        schedule0 = QLabel(the_day, self)
        schedule0.move(5, 16)

        title1 = QLabel(next_day, self)
        title1.move(5,150)

        schedule1 = QLabel(tomorrow, self)
        schedule1.move(5, 160)

        self.setGeometry(7, 30, 150, 287)
        self.setFixedSize(self.size())
        self.setWindowTitle('Timetable')
        self.setWindowIcon(QIcon('icon.png'))      
        self.show()




if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = timetable()
    ex.show()
    sys.exit(app.exec_())  
    #created with PyQt5 using Python 3.5
\$\endgroup\$
3
  • 1
    \$\begingroup\$ This is a code dump. Please tell us more about your specifications, what is it supposed to do and whether it lives up to your expectations. \$\endgroup\$ – Mast Apr 21 '17 at 20:11
  • \$\begingroup\$ Tough crowd. I have added additional information about the purpose of the program and my motivation to build the program. Thoughts/Suggestions for the program itself would be much appreciated. \$\endgroup\$ – DaveyH-cks Apr 21 '17 at 20:25
  • 1
    \$\begingroup\$ Much better :-) \$\endgroup\$ – Mast Apr 21 '17 at 20:44
3
\$\begingroup\$

I would change your setup code to take a list of lists, where the inner lists are lists of subjects on that day and the outer list collects all these lists:

schedule = [['Spanish', 'Spanish', 'Music', 'Music', 'English Literature', 'English Literature', 'History', 'History'],
            ...]

def format_day(day_schedule):
    return "\n" + "\n".join("{}       {}".format(i, subject)
                            for i, subject in enumerate(day_schedule, 1))

today = date.datetime.today().weekday()

try:
    the_day = format_day(schedule[today])
except IndexError:
    the_day = ''
try:
    tomorrow = format_day(schedule[today + 1])
except IndexError:
    tomorrow = format_day(schedule[0])

This could actually be moved into the class, which could just take the schedule and day as parameters (which would make it a lot easier to run this, e.g for two different schedules):

import datetime
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QHBoxLayout, QApplication, QWidget, QLabel)
from PyQt5.QtGui import (QIcon, QPixmap)


def format_day(day_schedule):
    return "\n" + "\n".join("{}       {}".format(i, subject)
                            for i, subject in enumerate(day_schedule, 1))


class Timetable(QWidget):               

    def __init__(self, schedule, day):
        super().__init__()
        self.schedule = schedule
        self.day = day
        self.init_UI()


    def init_UI(self):
        try:
            today = format_day(self.schedule[self.day])
        except IndexError:
            today = ''
        try:
            tomorrow = format_day(self.schedule[self.day + 1])
        except IndexError:
            tomorrow = format_day(self.schedule[0])

        if self.day <= 5:
            today_header = '<b>Today\'s Timetable:<\b>'
            tomorrow_header = '<b>Tomorrow\'s Timetable:<\b>'
        else:
            today_header = ''
            tomorrow_header = '<b>Monday\'s Timetable:<\b>'

        if self.day in (4, 5, 6):
            lbl = QLabel(self)
            pixmap = QPixmap('weekend.jpg')
            smaller_pixmap = pixmap.scaled(160, 300, Qt.KeepAspectRatio, Qt.FastTransformation)
            lbl.setPixmap(smaller_pixmap)
            if self.day == 4:
                lbl.move(-3, 162)
            else:
                lbl.move(-3, 0)
            lbl.show()      

        title0 = QLabel(today_header, self)
        title0.move(5, 5)
        schedule0 = QLabel(today, self)
        schedule0.move(5, 16)

        title1 = QLabel(tomorrow_header, self)
        title1.move(5, 150)
        schedule1 = QLabel(tomorrow, self)
        schedule1.move(5, 160)

        self.setGeometry(7, 30, 150, 287)
        self.setFixedSize(self.size())
        self.setWindowTitle('Timetable')
        self.setWindowIcon(QIcon('icon.png'))      
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)

    schedule = [['Spanish', 'Spanish', 'Music', 'Music', 'English Literature', 'English Literature', 'History', 'History'],
                ...]
    today = date.datetime.today().weekday()
    ex = Timetable(schedule, today)
    ex.show()
    sys.exit(app.exec_())
    #created with PyQt5 using Python 3.5

Note that I also renamed some of your variables (there is now a today and a today_header and a tomorrow and tomorrow_header.

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

While @Graipher's answer is much better and more thorough, I just thought I'd point out a non-class solution to iterate through your days. If you define a list of days, you can pick variables today and tomorrow from list_of_days[index] and list_of_days[index+1] provided that you break the loop before the index reaches the last element. This way, you don't need to specify today and tomorrow for each if condition.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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