This site is from a past semester! The current version will be here when the new semester starts.
TE3201 2020
  • Full Timeline
  • Week 1 [Jan 13]
  • Week 2 [Jan 20]
  • Week 3 [Jan 27]
  • Week 4 [Feb 3]
  • Week 5 [Feb 10]
  • Week 6 [Feb 17]
  • Week 7 [Mar 2]
  • Week 8 [Mar 9]
  • Week 9 [Mar 16]
  • Week 10 [Mar 23]
  • Week 11 [Mar 30]
  • Week 12 [Apr 6]
  • Week 13 [Apr 13]
  • SE Textbook
  • Programming Textbook
  • Admin Info
  • Forum
  • Instructors
  • Announcements
  • repl.it link
  • Files (slides, handouts etc.)
  • Project Info
  • TE3201 Software Engineering


    Module overview

    TIC2002 Software Engineering contains roughly a 50-50 balance of theory and practice of SE. It covers the knowledge/skills necessary to do small software projects.


    Using this module website

    The Schedule page is your main source of information for TE3201. You will need to refer to it weekly. For an overview of the full schedule, refer to the Full Timeline page.

    More details for the upcoming weeks will be added as the weeks progress. In general, information given for more than 1 week into the future should be treated as tentative.

    Browser compatibility

    Most of this will work on most mainstream Browsers, but embedded slides are best viewed using Chrome.

    Information layers

    This book tries to layer information so that readers can decide to omit less important layers if they wish to.

    More important information are in bold or highlighted while less important information are dimmed or in collapsed panels such as the below.

    Less important info

    Less important info

    Less important info

    Tabs indicate alternative formats of the same content (e.g. video vs text). You can choose the one you like and ignore the other tabs.

    Some textual description of X

    Video describing X

    Dotted underlines indicate tool tips (activated by hovering over it) and dashed underlines indicate modal windows (activated by clicking) containing additional information.

    Tooltip Example
    Additional information
    Additional information

    This website uses a star rating system to indicate the priority level of contents.

    Star Rating System

    We use a star rating system indicate the importance of module components. Start with things that are rated one-star and progress to things with more stars. Things rated four stars are optional.

    Star ratings for topics (and textbook sections):

    • One-star topics are essential to keep up with the module. We recommend you to learn these topics if you want to pass the module (i.e. up to a C grade).

    • Two-stars topics can get you up to a B+.

    • Three-stars topics can get you up to an A.

    • Four-stars topics : OPTIONAL can push you beyond the limits of the module, and help you get into a level above those who merely limit themselves to the topics of the module. They are not examinable.

    • Topics marked with two icons e.g., : , : , : are relevant topics you are expected to have learned in prerequisite modules. They are given for reference, but are examinable. The number of stars indicates the progression of topics, similar to the star rating system above i.e., one-star prerequisite topics are the most basic and the most important. four-star pre-requisite topics can be ignored without affecting CAP.

    Star ratings for other things e.g., admin info sections:

    • The module uses a similar star rating system to indicate the importance of other info in this website. i.e., information rated as one-star are the most essential. Info rated four stars are non-essential and can be ignored without affecting your ability to follow the module.

    Conventions used

    Shorthand headings

    Meaning of some shortened headings:

    • What : the meaning of the concept in concern

    • Why : the motivation behind the concept in concern

    • How : the usage of the concept in concern

    • When : the pros and cons of the concept in concern, when to use the concept

    Boxed-text styles

    additional info warning positive message important message an error to avoid tip definition

    Meaning of icons

    extra : tangential info, can be ignored if not interested
    : direct link to the LO. Ctrl+Click to open the LO in new window/tab.
    : learning outcomes
    : prerequisite learning outcome
    : examples
    : resources
    : exercises
    : printable version
    : preview/more info
    : video
    >_ : a command to be run in a terminal
    : textual description
    : slides
    : output produced by running code
    question without answer
    question with answer

    : tasks to do
    : lecture
    : tutorial
    : evidence you can use to prove you have achieved a learning outcome
    ⏰ : deadline

    Searching for keywords

    Use the search box in the top navigation bar to search for keywords in the website pages. If you cannot find the content related to a keyword, let us know by posting in the forum so that we can add the missing keyword to our search index.

    Saving as PDF files

    1. Use Chrome to load the page you want to save as pdf.

    2. Click on the Print option in Chrome’s menu.

    3. Set the destination to Save as PDF, then click Save to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below.

    Printing Textbook Content

    Printer-friendly version (indicated by icon) have been provided for each chapter and the whole book. You can use them for saving as pdf files or printing.

    Making this Website Better

    This website was generated using the MarkBind software developed at NUS. We welcome bug reports, suggestions, and contributions, to be submitted at the website issue tracker.


    Instructors

    Damith Chatura RAJAPAKSE
    Associate Professor, NUS School of Computing
    PhD, Software Engineering, NUS, 2002-2006
    BSc, Computer Science & Engineering, University of Moratuwa, 1996-2001
    damith[at]comp.nus.edu.sg
    COM2-02-57
    651 64359
    https://www.comp.nus.edu.sg/~damithch


    Lectures

    Tuesdays 1800-2130
    Venue E3-06-15

    Lectures will not be webcast as the venue does not have a webcast facility. Please bring your laptop to the lecture as you will need to be using it for the most part of the lecture.

    The rough break-down of a typical lecture:

    • 1800-1830: No formal lecture. This is a time for you to talk to the prof and clarify doubts about the previous week's topics.
    • 1830-1900: Doing exercises related to previous week topics.
    • 1900-2000: SE topics for the current week.
    • 2000-2100: Programming topics for the current week. Those who are already familiar with programming and not interested in learning Python can leave early.
    • 2100-2130: You can stay back and do exercises for the current week. Approach prof for help as needed.

    Lecture slides will be uploaded to LumiNUS after the lecture, usually by midnight of the same day. Lecture slides are not suitable to be used as reference materials as they have been i.e., heavy use of graphics and animationsoptimized for lecture delivery instead.

    If slides are not in LumiNUS by the expected times, please feel free to ping the lecturer.


    Tutorials

    There is no formal tutorial. Instead, tutorial-like activities are integrated into the lecture.


    Textbook

    Software Engineering Textbook:

    A customized online text book is used for this module. Topic coverage may not follow the exact topic sequence in the book. There are several ways for you to access the text book.

    • Full version is here: The relevant sections are embedded under the corresponding week in the schedule page.
    • Printable version is here. You are encouraged to use the online full version when possible (instead of the printable version or the PDF version), as it has more content videos, exercises, etc.

    Programming Textbook:

    An additional guide on programming basics is provided for you to get started or programming. The topics in that textbook are to help you do the programming part of the project; they are not examinable in the final exam. Furthermore, we try to use external resources as much as possible in our guide so that you can continue your learning using those resources beyond the scope of this module.


    Programming Language

    This module uses Python programming language to teach you programming basics required for software engineering. However, Python is not examinable.

    Install Python (the latest 3.x version) in your computer.


    Programming Exercises

    In some weeks, there will be some programming exercises for you to submit (on Repl.it). You should do the exercises as you learn the topics.

    Learn the topic first before trying the exercises. While these are exercises provided to self-test your knowledge, the more important thing is to read and understand the topic content. Furthermore, not all topics are tested by exercises.

    Project

    • The project is to be done individually.
    • The project based on a generic project called Monty.
    • In the project, you will build a small chatbot, using Python (if you wish to use a different programming language, please ask for permission first).
    • The project is to be done in small increments. You will be given a schedule of what increments to be done in each week.
    • Some project increments will be common to all students, while some will vary from student to student (to be announced near to the date). That means your final product will be unique in terms of total features, but some features will be common to other students in the class.
    • Constraints:
      1. You should not use relational/SQL databases e.g., MySQL
      2. The software should work in a Windows computer that has Python 3. If your software needs other software to be installed (e.g., third-party libraries), please get prof's permission first.

    Week 1:

    • Use the exercise Week 1 Project Submission on repl.it to do this week's project task given below.
    Programming   Level 1. Echo Once

    Level 1 Echo Once

    Write a Python program to read in one user command and repeat it back to the user. An example output is given below.

    >>> Hello, my name is Monty
    >>> What can I do for you?
    foo
    >>> Your command is: foo
    >>> Bye!
    print('>>> Hello, my name is Monty')
    # ADD MORE CODE HERE

    Week 2:

    • Add the following increment to your project. As before (and also in future weeks), copy-paste-submit the updated code via the weekly exercise named Week N Project Submission where N is the week number e.g., submit this week's project code via the repl exercise named Week 2 Project Submission.
    Programming   Level 2. Recognize Known Commands

    Level 2 Recognize Known Commands

    Extend Monty 1 code to work as follows:

    • It recognizes the list command and responds with a fixed message.
    • It recognizes the exit command and exits the program if user confirms.
    • For all other inputs, it responds with a fixed error message.

    A sample session is given below.

    You are highly encouraged to give the software a different name (i.e., not Monty), define your own command formats (e.g., show instead of list), and even a different personality (e.g., you can make its questions/responses sound similar to a popular video game character). Differentiating your software in those ways will reduce the risk of plagiarism concerns.

    >>> Hello, my name is Monty
    >>> What can I do for you?

    list
    >>> Nothing to list
    >>> What can I do for you?

    foo
    >>> OOPS! Unknown command
    >>> What can I do for you?

    exit
    >>> Are you sure? y/n
    n
    >>> What can I do for you?

    exit
    >>> Are you sure? y/n
    y
    >>> Bye!
    print('>>> Hello, my name is Monty')
    while True:
    print('>>> What can I do for you?')
    # ADD MORE CODE HERE
    print('>>> Bye!')

    Week 3:

    Programming   Level 3. Use Functions

    Level 3 Use Functions

    Restructure the Monty Level 2 code to fit the following structure, while keeping the behavior same as before.

    import sys


    # ADD MISSING FUNCTIONS


    def main():
    print_greeting()
    while True:
    command = read_command()
    execute_command(command)


    main()
    import sys

    def is_exit_confirmed():
    print('>>> Are you sure? y/n')
    response = input()
    return response == 'y'


    def execute_command(command):
    if command == '':
    return
    elif command == 'exit':
    if is_exit_confirmed():
    print('>>> Bye!')
    sys.exit()
    # ...


    def main():
    print_greeting()
    while True:
    command = read_command()
    execute_command(command)


    main()

    Week 4:

    Programming   Level 4. Collect Tasks in Memory

    Level 4 Collect Tasks in Memory

    Enhance the Monty Level 3 code to improve the functionality as per the sample output given below.

    >>> Hello, my name is Monty
    >>> What can I do for you?

    list
    >>> Nothing to list
    >>> What can I do for you?

    add read book
    >>> What can I do for you?

    list
    >>> List of items:
    1. read book
    >>> What can I do for you?

    add return book
    >>> What can I do for you?

    list
    >>> List of items:
    1. read book
    2. return book
    >>> What can I do for you?

    exit
    >>> Are you sure? y/n
    y
    >>> Bye!

    You can use the list slicing syntax to extract a portion of a string.


    s = 'abcdefgh'
    print(s[2:])
    print(s[:5])
     → 

    cdefgh
    abcde

    The above technique can be used to extract the item description from an add command.

    import sys

    items = []


    def print_items():
    if len(items) == 0:
    print('>>> Nothing to list')
    else:
    for i, item in enumerate(items):
    # ...


    def add_item(user_input):
    # ...


    def terminate():
    # ...

    # ...

    def execute_command(command):
    if command == '':
    return
    elif command == 'exit':
    terminate()
    elif command == 'list':
    print_items()
    elif command.startswith('add '):
    add_item(command)
    else:
    print('>>> OOPS! Unknown command')


    def main():
    print_greeting()
    while True:
    command = read_command()
    execute_command(command)


    main()

    Week 5:

    Programming   Level 5. Mark Tasks as Done

    Level 5 Mark Tasks as Done

    Enhance the Monty Level 4 code in the following ways:

    • Add a done command so that the user can mark a task as done. e.g., done 2 marks the task at index 2 as 'done'.
    • Show appropriate error messages if the user gives an invalid index for the done command

    A sample output is given below.

    >>> Hello, my name is Monty
    >>> What can I do for you?

    add borrow book
    >>> What can I do for you?

    add read book
    >>> What can I do for you?

    add return book
    >>> What can I do for you?

    list
    >>> List of items:
    [✗] 1. borrow book
    [✗] 2. read book
    [✗] 3. return book
    >>> What can I do for you?

    done 1
    >>> What can I do for you?

    list
    >>> List of items:
    [✓] 1. borrow book
    [✗] 2. read book
    [✗] 3. return book
    >>> What can I do for you?

    done abc
    >>> SORRY, I could not perform that command. Problem: abc is not a number
    >>> What can I do for you?

    done 5
    >>> SORRY, I could not perform that command. Problem: No item at index 5
    >>> What can I do for you?

    done 0
    >>> SORRY, I could not perform that command. Problem: Index must be greater than 0
    >>> What can I do for you?

    garbage
    >>> SORRY, I could not perform that command. Problem: Command not recognized
    >>> What can I do for you?

    exit
    >>> Are you sure? y/n
    y
    >>> Bye!

    Each task has two data values: the description and the 'done' status. You can use a list to hold these two data items. That means your list of tasks will be a list containing lists. Example:

    tasks = []
    tasks.append(['read book', False])
    print('Description of the first task:', tasks[0][0])

    if tasks[0][1]:
    print('✓')
    else:
    print('✗')

    You can use exceptions to identify and handle errors in the command.

    def main():
    print_greeting()
    while True:
    try:
    command = read_command()
    execute_command(command)
    except Exception as e:
    print('>>> SORRY, I could not perform that command. Problem:', e)

    items = []

    # ...

    def get_item_for_index(index_as_string):
    try:
    index = int(index_as_string.strip())
    except Exception:
    raise ValueError(index_as_string + ' is not a number ')

    if index < 1:
    raise ValueError('Index must be greater than 0 ')

    try:
    return items[index - 1]
    except IndexError:
    raise ValueError('No item at index ' + index_as_string)


    def mark_item_as_done(user_input):
    index_as_string = user_input[5:]
    get_item_for_index(index_as_string)[1] = True


    def execute_command(command):
    if command == '':
    return
    elif command == 'exit':
    terminate()
    elif command == 'list':
    print_items()
    elif command.startswith('add '):
    add_item(command)
    elif command.startswith('done '):
    mark_item_as_done(command)
    else:
    raise Exception('Command not recognized')


    def main():
    print_greeting()
    while True:
    try:
    command = read_command()
    execute_command(command)
    except Exception as e:
    print('>>> SORRY, I could not perform that command. Problem:', e)


    main()
    Programming   Level 6. Give Help optional

    Level 6 Give Help

    Enhance the Monty Level 5 code in the following ways:

    • Add a help command so that the user can view how to use the app.
    • Improve the formatting of the text displayed to the user to make the user experience nicer.

    A sample output is given below.

    *******************************************************************************************
    * __ __ _ _ __ __ _ *
    * \ \ / / | | | | | \/ | | | *
    * \ \ /\ / /__| | ___ ___ _ __ ___ ___ | |_ ___ | \ / | ___ _ __ | |_ _ _ *
    * \ \/ \/ / _ \ |/ __/ _ \| '_ ' _ \ / _ \ | __/ _ \ | |\/| |/ _ \| '_ \| __| | | | *
    * \ /\ / __/ | (_| (_) | | | | | | __/ | || (_) | | | | | (_) | | | | |_| |_| | *
    * \/ \/ \___|_|\___\___/|_| |_| |_|\___| \__\___/ |_| |_|\___/|_| |_|\__|\__, | *
    * __/ | *
    * |___/ *
    *******************************************************************************************

    >>> What can I do for you?

    help
    >>> I'm glad you asked. Here it is:
    ==================================================
    Monty can understand the following commands:

    add DESCRIPTION
    Adds a task to the list
    Example: add read book
    done INDEX
    Marks the task at INDEX as 'done'
    Example: done 1
    exit
    Exits the application
    help
    Shows the help information
    list
    Lists the tasks in the list
    --------------------------------------------------

    >>> What can I do for you?

    add read book
    >>> Task added to the list
    >>> What can I do for you?

    add return book
    >>> Task added to the list
    >>> What can I do for you?

    done 1
    >>> Congrats on completing a task! :-)
    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ==================================================
    STATUS | INDEX | DESCRIPTION
    --------------------------------------------------
    ✓ | 1 | read book
    ✗ | 2 | return book
    --------------------------------------------------
    >>> What can I do for you?

    You can use triple quotes to define a long string such as the help text.

    help_text ='''
    long text
    more text
    '''

    You can generate ASCII art using online resources such as http://patorjk.com/software/taag

    def print_greeting():
    banner = '''
    *******************************************************************************************
    * __ __ _ _ __ __ _ *
    * \ \ / / | | | | | \/ | | | *
    * \ \ /\ / /__| | ___ ___ _ __ ___ ___ | |_ ___ | \ / | ___ _ __ | |_ _ _ *
    * \ \/ \/ / _ \ |/ __/ _ \| '_ ' _ \ / _ \ | __/ _ \ | |\/| |/ _ \| '_ \| __| | | | *
    * \ /\ / __/ | (_| (_) | | | | | | __/ | || (_) | | | | | (_) | | | | |_| |_| | *
    * \/ \/ \___|_|\___\___/|_| |_| |_|\___| \__\___/ |_| |_|\___/|_| |_|\__|\__, | *
    * __/ | *
    * |___/ *
    *******************************************************************************************
    '''
    print(banner.strip(), '\n')

    Week 6:

    Programming   Level 7. Save Tasks to Disk

    Level 7 Save Tasks to Disk

    Enhance the Monty Level 6 code in the following ways:

    • Monty saves tasks into a csv file, and loads data from the same file at the start.
    • Add a delete command that can delete a task at a specific index.

    A sample output is given below. Note the following:

    • Monty is able to show at the very start the three tasks loaded from the file.
    • When item 2 is deleted, the item previously at index 3 moves to position 2.
    *******************************************************************************************
    * __ __ _ _ __ __ _ *
    * \ \ / / | | | | | \/ | | | *
    * \ \ /\ / /__| | ___ ___ _ __ ___ ___ | |_ ___ | \ / | ___ _ __ | |_ _ _ *
    * \ \/ \/ / _ \ |/ __/ _ \| '_ ' _ \ / _ \ | __/ _ \ | |\/| |/ _ \| '_ \| __| | | | *
    * \ /\ / __/ | (_| (_) | | | | | | __/ | || (_) | | | | | (_) | | | | |_| |_| | *
    * \/ \/ \___|_|\___\___/|_| |_| |_|\___| \__\___/ |_| |_|\___/|_| |_|\__|\__, | *
    * __/ | *
    * |___/ *
    *******************************************************************************************

    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ==================================================
    STATUS | INDEX | DESCRIPTION
    --------------------------------------------------
    ✓ | 1 | borrow book
    ✗ | 2 | read book
    ✗ | 3 | return book
    --------------------------------------------------
    >>> What can I do for you?

    delete 2
    >>> Task deleted from the list
    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ==================================================
    STATUS | INDEX | DESCRIPTION
    --------------------------------------------------
    ✓ | 1 | borrow book
    ✗ | 2 | return book
    --------------------------------------------------

    here are some tips:

    • The filename can be specified in the code. e.g.,

      DATA_FILE = 'monty7.csv'
    • The following statement will create an empty data.csv file if the file doesn't exist, but will keep the file as it is if it already exists (it simply opens the file in append mode -- which creates the file it if it doesn't exist -- and close it right after).

      open('data.csv', 'a').close()
    • The format of the file is up to you. Here is an example:

      borrow book,done
      read book,pending
      return book,pending
    • The program can load the tasks from the file at the beginning. It can save the data after each command. For example, as follows:

       items = []
      DATA_FILE = 'monty7.csv'


      def main():
      create_file_if_missing(DATA_FILE)
      load_data(DATA_FILE) # load task data from the file
      print_greeting()
      while True:
      try:
      command = read_command()
      execute_command(command)
      save_data(DATA_FILE, items) # save all tasks in the file
      except Exception as e:
      print('>>> SORRY, I could not perform that command. Problem:', e)


      main()

    Here is the code for loading data from the file.

    def load_data(filename):
    data_file = open(filename)
    deliveries_reader = csv.reader(data_file)
    for row in deliveries_reader:
    if not row:
    continue
    add_item_from_csv_line(row)
    data_file.close()


    def add_item_from_csv_line(values):
    status = True if values[1] == 'done' else False
    items.append([values[0], status]) # items is a global variable

    Note that status = True if values[1] == 'done' else False is a shortcut syntax. It is equivalent to the code below:

    if values[1] == 'done':
    status = True
    else:
    status = False

    Given below are some more features you can consider adding at this point (it is optional to add them to Monty 7):

    • Remove the need for the user to confirm before exiting Monty. As data are saved to a file, such a confirmation is no longer necessary because an accidental exit will not cause any permanent damage.
      >>> What can I do for you?

      exit
      >>> Bye!
    • Add a pending command that can mark a task as pending (i.e., the opposite of the done command).
       >>> What can I do for you?

      list
      >>> Here is the list of tasks:
      ==================================================
      STATUS | INDEX | DESCRIPTION
      --------------------------------------------------
      ✓ | 1 | borrow book
      ✗ | 2 | read book
      ✗ | 3 | return book
      --------------------------------------------------
      >>> What can I do for you?

      pending 1
      >>> OK, I have marked that item as pending
      >>> What can I do for you?

      list
      >>> Here is the list of tasks:
      ==================================================
      STATUS | INDEX | DESCRIPTION
      --------------------------------------------------
      ✗ | 1 | borrow book
      ✗ | 2 | read book
      ✗ | 3 | return book
      --------------------------------------------------
      >>> What can I do for you?
    • Make commands case insensitive and immune to extra leading/trailing spaces. For example, all these commands should work the same way.
      add read book
      ADD read book
      Add read book
      add read book
      add read book

    Week 7:

    Programming   Level 8. Support Deadlines

    Level 8 Support Deadlines

    Enhance the Monty Level 7 code to add support for keeping track of deadlines as well as regular todo tasks

    Previous behavior:

    • add buy book: adds a task buy book

    Proposed change - replace the above command with the following two:

    • todo read book: adds a todo task read book
    • deadline return book by: May 3rd adds a deadline return book which is to be done by May 3d.
      Note: by: is a keyword. Anything that comes after it is considered a description of the deadline.

    A sample output is given below.

    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ============================================================
    STATUS | INDEX | DESCRIPTION | DEADLINE
    ------------------------------------------------------------
    ✓ | 1 | borrow book | -
    ✗ | 2 | read book | -
    ✗ | 3 | return book | Monday
    ------------------------------------------------------------
    >>> What can I do for you?

    todo watch movie
    >>> What can I do for you?

    deadline submit assignment by: end of May
    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ============================================================
    STATUS | INDEX | DESCRIPTION | DEADLINE
    ------------------------------------------------------------
    ✓ | 1 | borrow book | -
    ✗ | 2 | read book | -
    ✗ | 3 | return book | Monday
    ✗ | 4 | watch movie | -
    ✗ | 5 | submit assignment | end of May
    ------------------------------------------------------------
    >>> What can I do for you?

    here are some tips:

    • One option is to use a list of dictionary objects to store the tasks/deadlines. Given below is an example of such a data structure. In that data structure, T and D is used to indicate todo items and deadline items, respectively.
      [
      {'type': 'T', 'description': 'borrow book', 'is_done': True},
      {'type': 'T', 'description': 'read book', 'is_done': False},
      {'type': 'D', 'description': 'return book', 'is_done': False, 'by': 'Monday'}
      ]

    • The format of the csv file needs to be updated to store extra values too. Here is an example:
      T,borrow book,done
      T,read book,pending
      D,return book,pending,Monday

    Here is the code adding a todo item:


    command_parts = command.strip().split(' ', 1) # split the command into two: first word and the remainder
    if action == 'todo':
    items.append({'type': 'T', 'description': command_parts[1], 'is_done': False})
    elif ...


    Week 8:

    Programming   Level 9. Use Classes

    Level 9 Use Classes

    Enhance the Monty Level 8 code to use classes ToDo and Deadline (i.e., you need to define these two classes) to represent todo tasks and deadlines, respectively.

    Here is the code for an example ToDo class:

    class ToDo:

    def __init__(self, description, status):
    self.description = description
    self.is_done = status

    def mark_as_done(self):
    self.is_done = True

    def mark_as_pending(self):
    self.is_done = False

    def as_string(self):
    """ Return the details of todo object as a string"""
    status = '✓' if self.is_done else '✗'
    return status.center(6) + ' ' + ' -'.ljust(13) + self.description

    def as_csv(self):
    """ Return the details of todo object as a list,
    suitable to be stored in a csv file.
    """
    return ['T', self.description, 'done' if self.is_done else 'pending']

    Here are some sample functions that work with ToDo objects:

    def load_data(filename):
    data_file = open(filename)
    deliveries_reader = csv.reader(data_file)
    for row in deliveries_reader:
    if row[0] == 'T':
    items.append(ToDo(row[1], True if row[2] == 'done' else False))
    elif row[0] == 'D':
    items.append(Deadline(row[1], True if row[2] == 'done' else False, row[3]))
    data_file.close()


    def save_data(filename, items_to_save):
    output_file = open(filename, 'w', newline='')
    output_writer = csv.writer(output_file)
    for item in items_to_save:
    output_writer.writerow(item.as_csv())
    output_file.close()


    Week 9:

    Programming   Level 10. Use More Classes

    Level 10 Use More Classes

    Enhance the Monty Level 9 code to extract the following classes:

    • UserInterface: an object of this class can be used to handle reading input from the user and showing output back to the user.
    • StorageManager: an object of this class can be used to read data from the data file and write data back to the data file.
    • TaskManager: an object of this class will hold the list of Task/Deadline objects and will execute commands.

    Here's the main part of the code that illustrates how these objects can work together:

    def main():
    # create a UserInterface object and show the greeting
    ui = UserInterface()
    ui.show_greeting()

    # create a StorageManager object
    storage = StorageManager('data.csv')

    # create a TaskManager object and load data
    task_manager = TaskManager(storage)
    task_manager.load_data()

    while True:
    try:
    command = ui.read_command()
    execute_command(command, task_manager, ui)
    task_manager.save_data()
    except Exception as e:
    ui.display('SORRY, I could not perform that command. Problem:' + str(e))


    main()

    Here's a partial execute_command function:

    def execute_command(command_parts, task_manager, ui):
    if action == 'exit':
    ui.display('Bye!')
    sys.exit()
    elif action == 'list':
    message = task_manager.get_items_as_table()
    ui.display(message)
    elif action == 'todo':
    message = task_manager.add_item(ToDo(command_parts[1], False))
    ui.display(message)
    ...

    Optional feature to consider: add a progress command that shows how many tasks/deadlines were marked as done during a session so far. Here is an example output:

    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ============================================================
    STATUS | INDEX | DESCRIPTION | DEADLINE
    ------------------------------------------------------------
    ✓ | 1 | borrow book | -
    ✗ | 2 | read book | -
    ✗ | 3 | return book | Monday
    ------------------------------------------------------------
    >>> What can I do for you?

    progress
    >>> Progress for this session: todos 0 deadlines 0
    >>> What can I do for you?

    done 2
    >>> Congrats on completing a task! :-)
    >>> What can I do for you?

    progress
    >>> Progress for this session: todos 1 deadlines 0
    >>> What can I do for you?

    done 3
    >>> Congrats on completing a task! :-)
    >>> What can I do for you?

    progress
    >>> Progress for this session: todos 1 deadlines 1
    >>> What can I do for you?

    pending 2
    >>> OK, I have marked that item as pending
    >>> What can I do for you?

    progress
    >>> Progress for this session: todos 0 deadlines 1
    >>> What can I do for you?

    list
    >>> Here is the list of tasks:
    ============================================================
    STATUS | INDEX | DESCRIPTION | DEADLINE
    ------------------------------------------------------------
    ✓ | 1 | borrow book | -
    ✗ | 2 | read book | -
    ✓ | 3 | return book | Monday
    ------------------------------------------------------------
    >>> What can I do for you?

    A class-level variable in the ToDo class can be used to track the number of todo tasks marked as done in a session.

    class ToDo:

    progress = 0 # class-level variable

    def __init__(self, description, status):
    self.description = description
    self.is_done = status

    def mark_as_done(self):
    if not self.is_done: # increment progress if needed
    ToDo.progress = ToDo.progress + 1
    self.is_done = True

    • After submitting the above increment, there is no need to submit subsequent project increments (i.e., Level 11 onwards) on repl.it.
    Programming   Level 11. Use Multiple Code Files

    Level 11 Use Multiple Code Files

    Enhance the Monty Level 10 code to divide the source code into multiple files (e.g., todo.py, deadline.py, etc.).


    Week 10:

    Programming   Level 12. Use Inheritance

    Level 12 Use Inheritance

    Enhance the Monty Level 11 code to make the Deadline class inherit from the ToDo class:

    class ToDo:

    TYPE_KEY = 'T'

    def __init__(self, description, status):
    self.description = description
    self.is_done = status

    def mark_as_done(self):
    self.is_done = True

    def mark_as_pending(self):
    self.is_done = False

    def __status_as_icon(self):
    return '✓' if self.is_done else '✗'

    def __str__(self):
    return '(' + self.__status_as_icon() + ') ' + self.description

    # more code ...


    class Deadline (ToDo):

    TYPE_KEY = 'D'

    def __init__(self, description, status, by):
    super().__init__(description, status)
    self.by = by

    def __str__(self):
    return super().__str__() + ' [by: ' + self.by + ']'

    Note:

    • There no need for the Deadline class to implement methods such as mark_as_done because it inherits those methods from the parent class.
    • Note how the Deadline class overrides some methods (e.g., __init__) but uses the parent class method inside the overridden method (e.g., __init__ method of the Deadline class calls the super().__init__() method.
    Programming   Level 13. Add Unit Tests

    Level 13 Add Unit Tests

    Add some unit tests to Monty Level 12 code.


    Week 11:

    • Option 1: Add the following project increment.
    Programming   Level 14. Add a GUI

    Level 14 Add a GUI

    Enhance the Monty Level 13 code to integrate it with the skeletal GUI given below.

    Notes about the given version of the GUI:

    • The GUI shows the list of tasks all the time.
    • It initializes with some dummy data.
    • It only supports an add command and a help command.

    Here are some screenshots of the GUI:

    import datetime
    from tkinter import *

    import sys


    class GUI:

    def __init__(self, task_manager):
    self.task_manager = task_manager
    self.window = Tk()
    self.window.geometry('800x700') # set Window size
    self.window.title('Monty') # set Window title

    self.input_box = Entry(self.window) # create an input box
    self.input_box.pack(padx=5, pady=5, fill='x') # make the input box fill the width of the Window
    self.input_box.bind('<Return>', self.command_entered) # bind the command_entered function to the Enter key
    self.input_box.focus() # set focus to the input box

    # add a text area to show the chat history
    self.history_area = Text(self.window, width="50")
    self.history_area.pack(padx=5, pady=5, side=LEFT, fill="y")
    self.output_font = ('Courier New', 12)
    self.history_area.tag_configure('error_format', foreground='red', font=self.output_font)
    self.history_area.tag_configure('success_format', foreground='green', font=self.output_font)
    self.history_area.tag_configure('normal_format', font=self.output_font)

    # add a text area to show the list of tasks
    self.list_area = Text(self.window)
    self.list_area.pack(padx=5, pady=5, side=RIGHT, fill="both")
    self.list_area.tag_configure('normal_format', font=self.output_font)
    self.list_area.tag_configure('pending_format', foreground='red', font=self.output_font)
    self.list_area.tag_configure('done_format', foreground='green', font=self.output_font)

    # show the welcome message and the list of tasks
    self.update_chat_history('start', 'Welcome to Monty!', 'success_format')
    self.update_task_list(self.task_manager.items)

    def update_chat_history(self, command, response, status_format):
    """
    status_format: indicates which color to use for the status message
    can be 'error_format', 'success_format', or 'normal_format'
    """
    current_time = datetime.datetime.now().strftime("%H:%M:%S")
    self.history_area.insert(1.0, '-' * 40 + '\n', 'normal_format')
    self.history_area.insert(1.0, '>>> ' + response + '\n', status_format)
    self.history_area.insert(1.0, 'You said: ' + command + '\n', 'normal_format')
    self.history_area.insert(1.0, current_time + '\n', 'normal_format')

    def update_task_list(self, tasks):
    self.list_area.delete('1.0', END) # clear the list area
    for i, task in enumerate(tasks):
    if task[1]:
    icon = '✓'
    output_format = 'done_format'
    else:
    icon = '✗'
    output_format = 'pending_format'
    self.list_area.insert(END, icon + ' ' + str(i+1) + ' ' + task[0] + '\n', output_format)

    def clear_input_box(self):
    self.input_box.delete(0, END)

    def command_entered(self, event):
    command = None
    try:
    command = self.input_box.get()
    if command.strip().lower() == 'exit':
    sys.exit()
    output = self.task_manager.execute_command(command)
    self.update_chat_history(command, output, 'success_format')
    self.update_task_list(self.task_manager.items)
    self.clear_input_box()
    except Exception as e:
    self.update_chat_history(command, str(e) + '\n' + self.task_manager.get_help(), 'error_format')

    def start(self):
    self.window.mainloop()


    class TaskManager:
    def __init__(self):
    self.items = [
    ['task 1', True],
    ['task 2', False],
    ['task 3', True]
    ]

    def get_help(self):
    return 'help:\n...'

    def execute_command(self, command):
    if command == 'help':
    return self.get_help()
    elif command.startswith('add '):
    self.items.append([command[4:], False])
    return 'task added'
    else:
    raise Exception('Command not recognized')


    GUI(TaskManager()).start()

    • Option 2: Add the allocated individual feature. You will be given which feature to implement around week 10.
      • Note that a very minimal implementation of the feature is good enough.
      • Steps to find the feature you should implement:
        • First take the last digit of your student number. For example, if your student number is A0123456H, the last digit is 6.
        • Then, find the matching row in the table below. That row gives you three options.
        • You may implement any one of the three options. Click on the link to find details of the feature.
        • The expected amount of work for this option is about 1/4 to 1/3 of the amount of code you have written so far in the project.

    Week 12:

    1 Enhance previous week's feature

    • If you chose option 1 in the previous week, you can either continue to enhance the GUI or add an individual feature this week (from the three choices from option 2).
    • If you chose option 2 in the previous week, you can either continue to enhance that individual feature or add another individual feature from the three choices given to you.

    2 Start preparing for the final submission

    • Note that you can get prof's feedback for your project report before the final submission. See the panel below for more details.

    Week 13: Final Submission

    Submission Deadline: Sunday of week 13 (Apr 19th). Submissions later than the deadline are liable to a late submission penalty, to be fair to those who submitted on time. But given that you are part time students, the late submission penalty will be small (e.g., -1 per day).

    • The deadline for seeking feedback on the project report draft: week 13 lecture.
      • Preferred mode of feedback: in-person (reason: it is hard to give written feedback on diagrams) via email
      • Such feedback will be limited to high-level comments only (reason: the report is graded).

    Deliverables:

    1. Source code of the working program: zip (not rar) the code and submit to LumiNUS
      name: File name: {YourName}.zip e.g., JunHao.zip
    2. Documentation: a single .docx (preferred) or a pdf file that follows the template given (template file will be available in LumiNUS).
      Submission: Upload to LumiNUS. The file name should be your name e.g., JunHao.docx
    3. Demo video:
      • Record a demo video showcasing the features of your product.
      • Use the exact version of the code you submitted (i.e., the demo should match the submitted code exactly).
      • Recommended length 7 minutes, max length 10 minutes).
      • Audio narration is optional if the demo can be understood without the audio.
      • Ensure the video is in a format that can be played by any computer.
      • Submission: Name the file with your name (to match the zip and the report file) and upload to LumiNUS.


    Week 13:

    1 Submit the project

    Week 13: Final Submission

    Submission Deadline: Sunday of week 13 (Apr 19th). Submissions later than the deadline are liable to a late submission penalty, to be fair to those who submitted on time. But given that you are part time students, the late submission penalty will be small (e.g., -1 per day).

    • The deadline for seeking feedback on the project report draft: week 13 lecture.
      • Preferred mode of feedback: in-person (reason: it is hard to give written feedback on diagrams) via email
      • Such feedback will be limited to high-level comments only (reason: the report is graded).

    Deliverables:

    1. Source code of the working program: zip (not rar) the code and submit to LumiNUS
      name: File name: {YourName}.zip e.g., JunHao.zip
    2. Documentation: a single .docx (preferred) or a pdf file that follows the template given (template file will be available in LumiNUS).
      Submission: Upload to LumiNUS. The file name should be your name e.g., JunHao.docx
    3. Demo video:
      • Record a demo video showcasing the features of your product.
      • Use the exact version of the code you submitted (i.e., the demo should match the submitted code exactly).
      • Recommended length 7 minutes, max length 10 minutes).
      • Audio narration is optional if the demo can be understood without the audio.
      • Ensure the video is in a format that can be played by any computer.
      • Submission: Name the file with your name (to match the zip and the report file) and upload to LumiNUS.


    Week 13: Final Submission

    Submission Deadline: Sunday of week 13 (Apr 19th). Submissions later than the deadline are liable to a late submission penalty, to be fair to those who submitted on time. But given that you are part time students, the late submission penalty will be small (e.g., -1 per day).

    • The deadline for seeking feedback on the project report draft: week 13 lecture.
      • Preferred mode of feedback: in-person (reason: it is hard to give written feedback on diagrams) via email
      • Such feedback will be limited to high-level comments only (reason: the report is graded).

    Deliverables:

    1. Source code of the working program: zip (not rar) the code and submit to LumiNUS
      name: File name: {YourName}.zip e.g., JunHao.zip
    2. Documentation: a single .docx (preferred) or a pdf file that follows the template given (template file will be available in LumiNUS).
      Submission: Upload to LumiNUS. The file name should be your name e.g., JunHao.docx
    3. Demo video:
      • Record a demo video showcasing the features of your product.
      • Use the exact version of the code you submitted (i.e., the demo should match the submitted code exactly).
      • Recommended length 7 minutes, max length 10 minutes).
      • Audio narration is optional if the demo can be understood without the audio.
      • Ensure the video is in a format that can be played by any computer.
      • Submission: Name the file with your name (to match the zip and the report file) and upload to LumiNUS.

    Policies

    Deadlines

    • Deadline for weekly tasks:
      • If a specific deadline is given, adhere to that.
      • If no specific deadline is given,
        • Soft deadline: try to complete tasks allocated to a week by Tuesday 6.00pm of the following week (i.e., before the next lecture).
        • Hard deadline: In case you fail to meet the soft deadline, there will be no penalty if a task is done within one week after the soft deadline.

    Plagiarism

    • You may view/discuss others' work or get help from others. However, the work you submit should be your own. In case of similar submissions, marks will be divided among those submissions e.g., if your submission scored 8/10 and there is another submission that is similar to your work (beyond co-incidental similarity), each submission will get 4 marks.

    Tools

    repl.it

    • We'll be using Repl.it for coding exercises (compulsory).
    • Create an account on https://repl.it.
    • Make sure you set your display name in your repl.it user profile to match your real name (so that the prof can trace your repl.it submissions to you).
    • Join the repl.it classroom tic2002-2020 using this link https://repl.it/classroom/invite/jcXc9CX.

    PyCharm

    • PyCharm is the recommended Python editor. While using PyCharm is optional, there will be no help/instructions given for other editors.

    • In the initial weeks, repl.it online editor is good enough for writing Python code. As your project code gets bigger in later weeks, you can consider installing PyCharm on your computer. You may use the Community Edition (free) or the Professional Edition (free for students).


    Getting Help

    If you face difficulties/doubts while learning the weekly topics, doing weekly exercises/tasks

    • you can post in the module forum
    • email prof at damith[at]comp.nus.edu.sg
    • ask for prof's help during the following week’s tutorial hour

    Assessment

    • 10%: Participation -- To get full marks, submit weekly programming exercises and weekly project increments on time.
    • 30%: Project
      • 10%: Documentation
      • 20%: Functionality, code
    • 60%: Final Exam

    Deadlines

    • Deadline for weekly tasks:
      • If a specific deadline is given, adhere to that.
      • If no specific deadline is given,
        • Soft deadline: try to complete tasks allocated to a week by Tuesday 6.00pm of the following week (i.e., before the next lecture).
        • Hard deadline: In case you fail to meet the soft deadline, there will be no penalty if a task is done within one week after the soft deadline.

    Exam

    • The final exam will be on Wed 29th April, 1-3pm (as per normal exam schedule).
    • The exam will be done online. Tools used: LumiNUS, Zoom, Microsoft Teams.

    Early preparations

    • Set up Zoom: Follow the Zoom exam instructions provided by NUS (note the requirement for SSO login).
      • Update the name of your Zoom profile to match the exact name on your student card, including whether the family name is give first or last (reason: we need to manually locate your name in the attendance list, which is sorted by your name in LumiNUS). You will not be admitted to the Zoom meeting if you do not comply with the requirement.
      • Note the requirements for camera placement: Your Zoom video feed need to capture your upper body and the work area, including the computer screen (as explained in this example). That means the built-in camera of your computer is not suitable for this purpose. Use either a separate web cam (attached to your Computer) or use Zoom through your smart phone. If neither of those options are available to you, let the prof know ASAP (deadline: April 24).

    You will not be allowed into the Zoom meeting unless your Zoom name complies with the above requirement.
    Your exam submission will not be accepted if your Zoom video feed does not comply with the above requirement.

    As per NUS requirements, your Zoom video feed is recorded by us and will be shared with NUS administration. If you do not consent to that, please let us know ASAP (deadline: April 24) so that we can put you in touch with the NUS administration to sort it out.

    15 minutes before the exam

    • Ensure your computer and the phone (if applicable) are charged and within reach of a power supply.
    • In your computer, close all other apps and browser tabs other than the ones permitted to be use for the exam. Remember to exit other background apps that starts automatically such as telegram.
    • Launch MS-Teams, login to it, and close the app without exiting (which makes it run in the background).
    • Login to LumiNUS. The password to open the quiz will be broadcast via Zoom (audio announcement plus chat message) by the invigilator later.
    • Launch Zoom, login, ensure profile name and camera complies with our requirements, and join the meeting. Wait for the invigilator to take you into the meeting.
    • Do not use more than one Zoom device at a time.
      • If it is inconvenient to use the Zoom device for PM'ing the invigilator (e.g., if you are using Zoom through a smart phone mounted on a stand), use MS-Teams (via your computer) to PM the invigilator.
      • But, if you use a phone as your primary Zoom device but it not convenient to use it for audio (e.g., its speaker volume not high enough),
        1. Get our permission to use the PC as a second Zoom device.
        2. Install Zoom in the PC.
        3. Use the PC for audio only (i.e., switch off the video) and the phone of video only.
        4. Name your Zoom profile name in the PC as [PC] Your Name as in Student Card e.g., [PC] John Doe
    • Once you are inside the Zoom meeting, wait patiently until all students have been admitted and the exam is ready to start. This wait could be as long as 30 minutes.

    During the exam

    • Keep both the video and speaker switched-on (but microphone muted) in your Zoom during the entire exam.
    • Do not use MS-Teams during the exam unless the invigilator uses to contact you, you need to contact the invigilator, or you need to contact CIT for tech help.
    • Stay in the video frame for the entire exam duration, except during the toilet break.
    • Do not to use virtual backgrounds in Zoom. Do not use pre-recorded videos as your video feed.
    • As the exam is open-book, you can refer to any printed/written materials or use the computer to read any PDF/word documents that are in your computer. You may also access the online version of the textbook in the module website but strongly encouraged to use the PDF or printed version of the textbook instead.
      Do not visit any other websites, use any other apps, or online search engines during the exam.
    • Remain in the video frame until the invigilator ends the exam, even after you have submitted the quiz. Do not use the computer or other communication devices (not even Kindle) during that period (suggestion: have something in hard-copy form to ready to read during this time e.g., printed lecture notes of another module).
    • Do not communicate with any person other than the invigilator during the exam, as per normal exam rules.
    • When the invigilator asks you to do a face check, turn your face towards the camera, move closer to the camera, remove face mask (if any), and hold the pose until the invigilator tells you to go back to your working position.

    Troubleshooting exam problems

    • If you have a doubt/query about a question, or want to make an assumption about a question, please write it down in the 'justification' text box. Do not try to communicate those with the invigilator during the exam. We'll take your doubt/query/assumption into account when grading. For example, if many had queries about a specific question, we can conclude that the question is unclear and omit it from grading.
    • If you encounter a serious problem that prevents you from proceeding with the exam (e.g., the password to open the quiz doesn't work), contact the invigilator using Zoom chat or MS-Teams.
    • If your computer crashed/restarted during the exam, try to get it up again and resume the exam. LumiNUS will allow you to resume from where you stopped earlier. However, note that there is a deadline to finish the quiz and you will overrun that deadline if you lose more than 5 minutes due to the computer outage.

    Format

    • The exam will be given as quizzes in LumiNUS.
      For the ease of administration, the exam is split into two equal size quizzes: part 1, part 2.
    • Each quiz,
      • consists of 15 regular MCQ questions (plus one easy bonus question, and one dummy question to give comments)
      • is to be done in 35 minutes (2 minutes per question + 5 extra minutes)
    • All 30 questions have the same the weight and each question is expected to take a similar amount of time (around 2 minutes).
    • The questions will be presented in random order.
    • You are not allowed to go back to previous questions.
    • You are required to give a justification for your answer. The question will specify what should be included in the justification.
      Answers without the correct justification will not earn full marks. However, we'll give full marks up to two correct answers (per 15 questions) that do not have justifications (to cater for cases where you accidentally proceeded to the next question before adding the justification).
    • Here is an example question. The answer is a and the justification can be OOP is only one of the choices for an SE project.

    Choose the incorrect statement.

    [Justification: why is it incorrect?]

    • Almost all questions will ask you to choose the INCORRECT statement and justify why it is incorrect.