CS2113/T 2018
  • Flat (current format)
  •     Nested
  • Schedule
  • Textbook
  • Admin Info
  • Report Bugs
  • Slack
  • Forum
  • Instructors
  • IVLE Announcements
  • IVLE File Submissions
  • Tutorial Schedule
  • Team IDs
  • Java Coding Standard
  • samplerepo-things
  • Addressbook-level1
  • Addressbook-level2
  • Addressbook-level3
  • Addressbook-level4
  • Projects List
  • Week 4 [Sep 3]

    Todo

    Admin info to read:

    Admin Appendix B (Policies) → Policy on plagiarism

    Policy on plagiarism

    We encourage sharing, but you should share with everyone in the class, not just a selected group. That is,

    • You are not allowed to share individual assignments with classmates directly.
    • You are not allowed to share project-related things with other teams directly.

    You can even reuse each other's work subject to the 'reuse policy' given below.

    If you submit code (or adopt ideas) taken from elsewhere, you need to comply with our reuse policy.

    Detection:

    • Detecting plagiarism in code is quite easy. You are not fooling anyone by reordering code or renaming methods/variables.
    • As all your work is publicly visible on GitHub, sooner or later somebody will notice the plagiarism.

    Penalties:

    • For submissions not affecting marks: We make a record of cases of plagiarism but we do not take further action. Such plagiarism does not disadvantage other students. Therefore, we prefer to spend all available resources on helping honest students to do better rather than to chase after dishonest students. If you think you gain something by plagiarizing, go ahead and do it. It's your choice and it's your loss.
    • For the final project/exam: Any case of claiming others' work as yours will be reported to the university for disciplinary action.

    Admin Appendix B (Policies) → Policy on reuse

    Policy on reuse

    Reuse is encouraged. However, note that reuse has its own costs (such as the learning curve, additional complexity, usage restrictions, and unknown bugs). Furthermore, you will not be given credit for work done by others. Rather, you will be given credit for using work done by others.

    • You are allowed to reuse work from your classmates, subject to following conditions:
      • The work has been published by us or the authors.
      • You clearly give credit to the original author(s).
    • You are allowed to reuse work from external sources, subject to following conditions:
      • The work comes from a source of 'good standing' (such as an established open source project). This means you cannot reuse code written by an outside 'friend'.
      • You clearly give credit to the original author. Acknowledge use of third party resources clearly e.g. in the welcome message, splash screen (if any) or under the 'about' menu. If you are open about reuse, you are less likely to get into trouble if you unintentionally reused something copyrighted.
      • You do not violate the license under which the work has been released. Please  do not use 3rd-party images/audio in your software unless they have been specifically released to be used freely. Just because you found it in the Internet does not mean it is free for reuse.
      • Always get permission from us before you reuse third-party libraries. Please post your 'request to use 3rd party library' in our GitHub forum. That way, the whole class get to see what libraries are being used by others.

    Giving credit for reused work

    Given below are how to give credit for things you reuse from elsewhere. These requirements are specific to this module  i.e., not applicable outside the module (outside the module you should follow the rules specified by your employer and the license of the reused work)

    If you used a third party library:

    • Mention in the README.adoc (under the Acknowledgements section)
    • mention in the Project Portfolio Page if the library has a significant relevance to the features you implemented

    If you reused code snippets found on the Internet  e.g. from StackOverflow answers or
    referred code in another software or
    referred project code by current/past student:

    • If you read the code to understand the approach and implemented it yourself, mention it as a comment
      Example:
      //Solution below adapted from https://stackoverflow.com/a/16252290
      {Your implmentation of the reused solution here ...}
      
    • If you copy-pasted a non-trivial code block (possibly with minor modifications  renaming, layout changes, changes to comments, etc.), also mark the code block as reused code (using @@author tags)
      Format:
      //@@author {yourGithubUsername}-reused
      //{Info about the source...}
      
      {Reused code (possibly with minor modifications) here ...}
      
      //@@author
      
      Example of reusing a code snippet (with minor modifications):
      persons = getList()
      //@@author johndoe-reused
      //Reused from https://stackoverflow.com/a/34646172 with minor modifications
      Collections.sort(persons, new Comparator<CustomData>() {
          @Override
          public int compare(CustomData lhs, CustomData rhs) {
              return lhs.customInt > rhs.customInt ? -1 : (lhs.customInt < rhs.customInt) ? 1 : 0;
          }
      });
      //@@author
      return persons;
      

    Adding @@author tags indicate authorship

    • Mark your code with a //@@author {yourGithubUsername}. Note the double @.
      The //@@author tag should indicates the beginning of the code you wrote. The code up to the next //@@author tag or the end of the file (whichever comes first) will be considered as was written by that author. Here is a sample code file:

      //@@author johndoe
      method 1 ...
      method 2 ...
      //@@author sarahkhoo
      method 3 ...
      //@@author johndoe
      method 4 ...
      
    • If you don't know who wrote the code segment below yours, you may put an empty //@@author (i.e. no GitHub username) to indicate the end of the code segment you wrote. The author of code below yours can add the GitHub username to the empty tag later. Here is a sample code with an empty author tag:

      method 0 ...
      //@@author johndoe
      method 1 ...
      method 2 ...
      //@@author
      method 3 ...
      method 4 ...
      
    • The author tag syntax varies based on file type e.g. for java, css, fxml. Use the corresponding comment syntax for non-Java files.
      Here is an example code from an xml/fxml file.

      <!-- @@author sereneWong -->
      <textbox>
        <label>...</label>
        <input>...</input>
      </textbox>
      ...
      
    • Do not put the //@@author inside java header comments.
      👎

      /**
        * Returns true if ...
        * @@author johndoe
        */
      

      👍

      //@@author johndoe
      /**
        * Returns true if ...
        */
      

    What to and what not to annotate

    • Annotate both functional and test code There is no need to annotate documentation files.

    • Annotate only significant size code blocks that can be reviewed on its own  e.g., a class, a sequence of methods, a method.
      Claiming credit for code blocks smaller than a method is discouraged but allowed. If you do, do it sparingly and only claim meaningful blocks of code such as a block of statements, a loop, or an if-else statement.

      • If an enhancement required you to do tiny changes in many places, there is no need to annotate all those tiny changes; you can describe those changes in the Project Portfolio page instead.
      • If a code block was touched by more than one person, either let the person who wrote most of it (e.g. more than 80%) take credit for the entire block, or leave it as 'unclaimed' (i.e., no author tags).
      • Related to the above point, if you claim a code block as your own, more than 80% of the code in that block should have been written by yourself. For example, no more than 20% of it can be code you reused from somewhere.
      • 💡 GitHub has a blame feature and a history feature that can help you determine who wrote a piece of code.
    • Do not try to boost the quantity of your contribution using unethical means such as duplicating the same code in multiple places. In particular, do not copy-paste test cases to create redundant tests. Even repetitive code blocks within test methods should be extracted out as utility methods to reduce code duplication. Individual members are responsible for making sure code attributed to them are correct. If you notice a team member claiming credit for code that he/she did not write or use other questionable tactics, you can email us (after the final submission) to let us know.

    • If you wrote a significant amount of code that was not used in the final product,

      • Create a folder called {project root}/unused
      • Move unused files (or copies of files containing unused code) to that folder
      • use //@@author {yourGithubUsername}-unused to mark unused code in those files (note the suffix unused) e.g.
      //@@author johndoe-unused
      method 1 ...
      method 2 ...
      

      Please put a comment in the code to explain why it was not used.

    • If you reused code from elsewhere, mark such code as //@@author {yourGithubUsername}-reused (note the suffix reused) e.g.

      //@@author johndoe-reused
      method 1 ...
      method 2 ...
      
    • You can use empty @@author tags to mark code as not yours when RepoSense attribute the to you incorrectly.

      • Code generated by the IDE/framework, should not be annotated as your own.

      • Code you modified in minor ways e.g. adding a parameter. These should not be claimed as yours but you can mention these additional contributions in the Project Portfolio page if you want to claim credit for them.

    At the end of the project each student is required to submit a Project Portfolio Page.

    • Objective:

      • For you to use  (e.g. in your resume) as a well-documented data point of your SE experience
      • For us to use as a data point to evaluate your,
        • contributions to the project
        • your documentation skills
    • Sections to include:

      • Overview: A short overview of your product to provide some context to the reader.

      • Summary of Contributions:

        • Code contributed: Give a link to your code on Project Code Dashboard, which should be https://nuscs2113-ay1819s1.github.io/dashboard/#=undefined&search=githbub_username_in_lower_case (replace githbub_username_in_lower_case with your actual username in lower case e.g., johndoe). This link is also available in the Project List Page -- linked to the icon under your photo.
        • Main feature implemented: A summary of the main feature you implemented
        • Other contributions:
          • Contributions to project management e.g., setting up project tools, managing releases, managing issue tracker etc.
          • Evidence of helping others e.g. responses you posted in our forum, bugs you reported in other team's products,
          • Evidence of technical leadership e.g. sharing useful information in the forum
        • [Optional] Other minor enhancements: If you have other enhancements that you implemented, which are not related to your main feature, you can include it here. If you have written a significant amount of code that can be advertised as a feature by itself, but does not belong to your main feature, you can choose to include it as a part of the optional enhancements.
      • Contributions to the User Guide: Reproduce the parts in the User Guide that you wrote. This can include features you implemented as well as features you propose to implement.
        The purpose of allowing you to include proposed features is to provide you more flexibility to show your documentation skills. e.g. you can bring in a proposed feature just to give you an opportunity to use a UML diagram type not used by the actual features.

      • Contributions to the Developer Guide: Reproduce the parts in the Developer Guide that you wrote. Ensure there is enough content to evaluate your technical documentation skills and UML modelling skills. You can include descriptions of your design/implementations, possible alternatives, pros and cons of alternatives, etc.

      • If you plan to use the PPP in your Resume, you can also include your SE work outside of the module (will not be graded)

    • Format:

      • File name: docs/team/githbub_username_in_lower_case.adoc e.g., docs/team/johndoe.adoc

      • Follow the example in the AddressBook-Level4, but ignore the following two lines in it.

        • Minor enhancement: added a history command that allows the user to navigate to previous commands using up/down keys.
        • Code contributed: [Functional code] [Test code] {give links to collated code files}
      • 💡 You can use the Asciidoc's include feature to include sections from the developer guide or the user guide in your PPP. Follow the example in the sample.

      • It is assumed that all contents in the PPP were written primarily by you. If any section is written by someone else  e.g. someone else wrote described the feature in the User Guide but you implemented the feature, clearly state that the section was written by someone else  (e.g. Start of Extract [from: User Guide] written by Jane Doe).  Reason: Your writing skills will be evaluated based on the PPP

      • Page limit: If you have more content than the limit given below, shorten (or omit some content) so that you do not exceed the page limit. Having too much content in the PPP will be viewed unfavorably during grading. Note: the page limits given below are after converting to PDF format. The actual amount of content you require is actually less than what these numbers suggest because the HTML → PDF conversion adds a lot of spacing around content.

        Content Limit
        Overview + Summary of contributions 0.5-1
        Contributions to the User Guide 1-3
        Contributions to the Developer Guide 3-6
        Total 5-10

    Admin Appendix B (Policies) → Policy on help from outsiders

    Policy on help from outsiders

    In general, you are not allowed to involve outsiders in your project except your team members and the teaching team. However, It is OK to give your product to others for the purpose of getting voluntary user feedback. It is also OK to learn from others as long as they don't do your project work themselves.

    Admin Exams

    There is no midterm.

    The final exam has two parts:

    • Part 1: MCQ questions (30 minutes, 25 marks)
    • Part 2: Essay questions (1 hour 30 min, 30 marks)

    Both papers will be given to you at the start but you need to answer Part 1 first (i.e. MCQ paper). It will be collected 30 min after the exam start time (even if arrived late for the exam). You are free to start part 2 early if you finish Part 1 early.

    Final Exam: Part 1 (MCQ)

    Each MCQ question gives you a statement to evaluate.

    An example statement

    Testing is a Q&A activity

    Unless stated otherwise, the meaning of answer options are
    A. True
    B. False

    The exam paper has 50 questions. All questions carry equal marks.

    The weightage of the Part 1 of the final exam is 25 marks out of the total score of 100.

    Note that you have slightly more than ½ minute for each question, which means you need to go through the questions fairly quickly.

    Given the fast pace required by the paper, to be fair to all students, you will not be allowed to clarify doubts about questions (in Part 1) by talking to invigilators.

    Questions in Part 1 are confidential. You are not allowed to reveal Part 1 content to anyone after the exam. All pages of the assessment paper are to be returned at the end of the exam.

    You will be given OCR forms to indicate your answers for Part 1.

    The paper is open-book: you may bring any printed or written materials to the exam in hard copy format. However, given the fast pace required by Part 1, you will not have time left to refer notes during that part of the exam.

    💡 Mark the OCR form as you go, rather than planning to transfer your answers to the OCR form near the end.  Reason: Given there are 50 questions and only 30 mins, it will be hard to estimate how much time you need to mass-transfer all answers to OCR forms.

    💡 Write the answer in the exam paper as well as marking it in the OCR form.  Reason: It will reduce the chance of missing a question. Furthermore, in case you missed a question, it will help you correct the OCR form quickly.

    💡 We have tried to avoid deliberately misleading/tricky questions. If a question seems to take a very long time to figure out, you are probably over-thinking it.

    Final Exam: Part 2 (Essay)

    Unlike in part 1, you can ask invigilators for clarifications if you found a question to be unclear in part 2.

    Yes, you may use pencils when answering part 2.

    The weightage of the Part 2 of the final exam is 15 marks out of the total score of 100.

    Resources

    Past exam papers uploaded on IVLE

    Admin Appendix C (FAQs) → What if I don’t carry around a laptop?

    What if I don’t carry around a laptop?

    If you do not have a laptop or prefer not to bring the laptop, it is up to you to show your work to the tutor in some way (e.g. by connecting to your home PC remotely), without requiring extra time/effort from the tutor or team members.

    Reason: As you enjoy the benefits of not bring the laptop; you (not others) should bear the cost too.

    Admin Appendix B (Policies) → Policy on publishing submissions

    Policy on publishing submissions

    The source code are publicly available and are available for reuse by others without any restrictions. 
    Is publishing submissions unfair to the team? We don't think so. If you were the first to think of something your peers are willing to adopt later, that means you are already ahead of them and they are unlikely to earn more marks by adopting your ideas.

    Outcomes

    Testing

    W4.1 Can automate simple regression testing of text UIs W4.1a Can explain testing

    Quality Assurance → Testing → Introduction →

    What

    Testing: Testing is operating a system or component under specified conditions, observing or recording the results, and making an evaluation of some aspect of the system or component. –- source: IEEE

    When testing, we execute a set of test cases. A test case specifies how to perform a test. At a minimum, it specifies the input to the software under test (SUT) and the expected behavior.

    Example: A minimal test case for testing a browser:

    • Input – Start the browser using a blank page (vertical scrollbar disabled). Then, load longfile.html located in the test data folder.
    • Expected behavior – The scrollbar should be automatically enabled upon loading longfile.html.

    Test cases can be determined based on the specification, reviewing similar existing systems, or comparing to the past behavior of the SUT.

    A more elaborate test case can have other details such as those given below.

    • A unique identifier : e.g. TC0034-a
    • A descriptive name: e.g. vertical scrollbar activation for long web pages
    • Objectives: e.g. to check whether the vertical scrollbar is correctly activated when a long web page is loaded to the browser
    • Classification information: e.g. priority - medium, category - UI features
    • Cleanup, if any: e.g. empty the browser cache.

    For each test case we do the following:

    1. Feed the input to the SUT
    2. Observe the actual output
    3. Compare actual output with the expected output

    A test case failure is a mismatch between the expected behavior and the actual behavior. A failure is caused by a defect (or a bug).

    Example: In the browser example above, a test case failure is implied if the scrollbar remains disabled after loading longfile.html. The defect/bug causing that failure could be an uninitialized variable.

    Here is another definition of testing:

    Software testing consists of the dynamic verification that a program provides expected behaviors on a finite set of test cases, suitably selected from the usually infinite execution domain. -– source: Software Engineering Book of Knowledge V3

    Some things to note (indicated by keywords in the above definition):

    • Dynamic: Testing involves executing the software. It is not by examining the code statically.
    • Finite: In most non-trivial cases there are potentially infinite test scenarios but resource constraints dictate that we can test only a finite number of scenarios.
    • Selected: In most cases it is not possible to test all scenarios. That means we need to select what scenarios to test.
    • Expected: Testing requires some knowledge of how the software is expected to behave.

    Explain how the concepts of testing, test case, test failure, and defect are related to each other.


    Evidence:

    Explain how the concepts of testing, test case, test failure, and defect are related to each other.

    W4.1b Can explain regression testing

    Quality Assurance → Testing → Regression Testing →

    What

    When we modify a system, the modification may result in some unintended and undesirable effects on the system. Such an effect is called a regression.

    Regression testing is re-testing the software to detect regressions. Note that to detect regressions, we need to retest all related components, even if they were tested before.

    Regression testing is more effective when it is done frequently, after each small change. However, doing so can be prohibitively expensive if testing is done manually. Hence, regression testing is more practical when it is automated.

    Regression testing is the automated re-testing of a software after it has been modified.

    c.

    Explanation: Regression testing need not be automated but automation is highly recommended.

    Explain why and when you would do regression testing in a software project.


    Evidence:

    Explain why and when you would do regression testing in a software project.

    W4.1c Can explain test automation

    Quality Assurance → Testing → Test Automation →

    What

    An automated test case can be run programmatically and the result of the test case (pass or fail) is determined programmatically. Compared to manual testing, automated testing reduces the effort required to run tests repeatedly and increases precision of testing (because manual testing is susceptible to human errors).



    W4.1d Can semi-automate testing of CLIs

    Quality Assurance → Testing → Test Automation →

    Automated Testing of CLI Apps

    A simple way to semi-automate testing of a CLI(Command Line Interface) app is by using input/output re-direction.

    • First, we feed the app with a sequence of test inputs that is stored in a file while redirecting the output to another file.
    • Next, we compare the actual output file with another file containing the expected output.

    Let us assume we are testing a CLI app called AddressBook. Here are the detailed steps:

    1. Store the test input in the text file input.txt.

      add Valid Name p/12345 valid@email.butNoPrefix
      add Valid Name 12345 e/valid@email.butPhonePrefixMissing
      
    2. Store the output we expect from the SUT in another text file expected.txt.

      Command: || [add Valid Name p/12345 valid@email.butNoPrefix]
      Invalid command format: add 
      
      Command: || [add Valid Name 12345 e/valid@email.butPhonePrefixMissing]
      Invalid command format: add 
      
    3. Run the program as given below, which will redirect the text in input.txt as the input to AddressBook and similarly, will redirect the output of AddressBook to a text file output.txt. Note that this does not require any code changes to AddressBook.

      java AddressBook < input.txt > output.txt
      
      • 💡 The way to run a CLI program differs based on the language.
        e.g., In Python, assuming the code is in AddressBook.py file, use the command
        python AddressBook.py < input.txt > output.txt

      • 💡 If you are using Windows, use a normal command window to run the app, not a Power Shell window.

      More on the > operator and the < operator. tangential

      A CLI program takes input from the keyboard and outputs to the console. That is because those two are default input and output streams, respectively. But you can change that behavior using < and > operators. For example, if you run AddressBook in a command window, the output will be shown in the console, but if you run it like this,

      java AddressBook > output.txt 
      

      the Operating System then creates a file output.txt and stores the output in that file instead of displaying it in the console. No file I/O coding is required. Similarly, adding < input.txt (or any other filename) makes the OS redirect the contents of the file as input to the program, as if the user typed the content of the file one line at a time.

      Resources:

    4. Next, we compare output.txt with the expected.txt. This can be done using a utility such as Windows FC (i.e. File Compare) command, Unix diff command, or a GUI tool such as WinMerge.

      FC output.txt expected.txt
      

    Note that the above technique is only suitable when testing CLI apps, and only if the exact output can be predetermined. If the output varies from one run to the other (e.g. it contains a time stamp), this technique will not work. In those cases we need more sophisticated ways of automating tests.

    CLI App: An application that has a Command Line Interface. i.e. user interacts with the app by typing in commands.


    Evidence:

    Acceptable: Any project where you use the I/O redirection method to test a CLI.

    Suggested: Do the exercise given in AddressBook - Level1 : LO-AutomatedCliTesting

    Submission: Demo the test during the tutorial.

    Requirements

    W4.2 Can explain requirements W4.2a Can explain requirements

    Requirements → Requirements →

    Introduction

    A software requirement specifies a need to be fulfilled by the software product.

    A software project may be,

    • a brown-field project i.e., develop a product to replace/update an existing software product
    • a green-field project i.e., develop a totally new system with no precedent

    In either case, requirements need to be gathered, analyzed, specified, and managed.

    Requirements come from stakeholders.

    Stakeholder: A party that is potentially affected by the software project. e.g. users, sponsors, developers, interest groups, government agencies, etc.

    Identifying requirements is often not easy. For example, stakeholders may not be aware of their precise needs, may not know how to communicate their requirements correctly, may not be willing to spend effort in identifying requirements, etc.

    W4.2b Can explain non-functional requirements

    Requirements → Requirements →

    Non-Functional Requirements

    There are two kinds of requirements:

    1. Functional requirements specify what the system should do.
    2. Non-functional requirements specify the constraints under which system is developed and operated.

    Some examples of non-functional requirement categories:

    • Data requirements e.g. size, volatility, persistency etc.,
    • Environment requirements e.g. technical environment in which system would operate or need to be compatible with.
    • Accessibility, Capacity, Compliance with regulations, Documentation, Disaster recovery, Efficiency, Extensibility, Fault tolerance, Interoperability, Maintainability, Privacy, Portability, Quality, Reliability, Response time, Robustness, Scalability, Security, Stability, Testability, and more ...
    • Business/domain rules: e.g. the size of the minefield cannot be smaller than five.
    • Constraints: e.g. the system should be backward compatible with data produced by earlier versions of the system; system testers are available only during the last month of the project; the total project cost should not exceed $1.5 million.
    • Technical requirements: e.g. the system should work on both 32-bit and 64-bit environments.
    • Performance requirements: e.g. the system should respond within two seconds.
    • Quality requirements: e.g. the system should be usable by a novice who has never carried out an online purchase.
    • Process requirements: e.g. the project is expected to adhere to a schedule that delivers a feature set every one month.
    • Notes about project scope: e.g. the product is not required to handle the printing of reports.
    • Any other noteworthy points: e.g. the game should not use images deemed offensive to those injured in real mine clearing activities.

    We may have to spend an extra effort in digging NFRs out as early as possible because,

    1. NFRs are easier to miss  e.g., stakeholders tend to think of functional requirements first
    2. sometimes NFRs are critical to the success of the software.  E.g. A web application that is too slow or that has low security is unlikely to succeed even if it has all the right functionality.

    Given below are some requirements of TEAMMATES (an online peer evaluation system for education). Which one of these are non-functional requirements?

    • a. The response to any use action should become visible within 5 seconds.
    • b. The application admin should be able to view a log of user activities.
    • c. The source code should be open source.
    • d. A course should be able to have up to 2000 students.
    • e. As a student user, I can view details of my team members so that I can know who they are.
    • f. The user interface should be intuitive enough for users who are not IT-savvy.
    • g. The product is offered as a free online service.

    (a)(c)(d)(f)(g)

    Explanation: (b) are (e) are functions available for a specific user types. Therefore, they are functional requirements. (a), (c), (d), (f) and (g) are either constraints on functionality or constraints on how the project is done, both of which are considered non-functional requirements.

    W4.2c Can explain prioritizing requirements

    Requirements → Requirements →

    Prioritizing Requirements

    Requirements can be prioritized based the importance and urgency, while keeping in mind the constraints of schedule, budget, staff resources, quality goals, and other constraints.

    A common approach is to group requirements into priority categories. Note that all such scales are subjective, and stakeholders define the meaning of each level in the scale for the project at hand.

    An example scheme for categorizing requirements:

    • Essential: The product must have this requirement fulfilled or else it does not get user acceptance
    • Typical: Most similar systems have this feature although the product can survive without it.
    • Novel: New features that could differentiate this product from the rest.

    Other schemes:

    • High, Medium, Low
    • Must-have, Nice-to-have, Unlikely-to-have
    • Level 0, Level 1, Level 2, ...

    Some requirements can be discarded if they are considered ‘out of scope’.

    The requirement given below is for a Calendar application. Stakeholder of the software (e.g. product designers) might decide the following requirement is not in the scope of the software.

    The software records the actual time taken by each task and show the difference between the actual and scheduled time for the task.

    W4.2d Can explain quality of requirements

    Requirements → Requirements →

    Quality of Requirements

    Here are some characteristics of well-defined requirements [📖 zielczynski]:

    • Unambiguous
    • Testable (verifiable)
    • Clear (concise, terse, simple, precise)
    • Correct
    • Understandable
    • Feasible (realistic, possible)
    • Independent
    • Atomic
    • Necessary
    • Implementation-free (i.e. abstract)

    Besides these criteria for individual requirements, the set of requirements as a whole should be

    • Consistent
    • Non-redundant
    • Complete

    Peter Zielczynski, Requirements Management Using IBM Rational RequisitePro, IBM Press, 2008

    W4.3 Can explain some techniques for gathering requirements W4.3a Can explain brainstorming

    Requirements → Gathering Requirements →

    Brainstorming

    Brainstorming: A group activity designed to generate a large number of diverse and creative ideas for the solution of a problem.

    In a brainstorming session there are no "bad" ideas. The aim is to generate ideas; not to validate them. Brainstorming encourages you to "think outside the box" and put "crazy" ideas on the table without fear of rejection.

    What is the key characteristic about brainstorming?

    (b)

    W4.3b Can explain product surveys

    Requirements → Gathering Requirements →

    Product Surveys

    Studying existing products can unearth shortcomings of existing solutions that can be addressed by a new product. Product manuals and other forms of technical documentation of an existing system can be a good way to learn about how the existing solutions work.

    When developing a game for a mobile device, a look at a similar PC game can give insight into the kind of features and interactions the mobile game can offer.

    W4.3c Can explain observation

    Requirements → Gathering Requirements →

    Observation

    Observing users in their natural work environment can uncover product requirements. Usage data of an existing system can also be used to gather information about how an existing system is being used, which can help in building a better replacement  e.g. to find the situations where the user makes mistakes when using the current system.

    W4.3d Can explain user surveys

    Requirements → Gathering Requirements →

    User Surveys

    Surveys can be used to solicit responses and opinions from a large number of stakeholders regarding a current product or a new product.

    W4.3e Can explain interviews

    Requirements → Gathering Requirements →

    Interviews

    Interviewing stakeholders and domain experts can produce useful information that project requirements.

    Domain Expert : An expert of a discipline to which the product is connected  e.g., for a software used for Accounting, a domain expert is someone who is an expert of Accounting.

    W4.3f Can explain focus groups

    Requirements → Gathering Requirements →

    Focus Groups


    [source]

    Focus groups are a kind of informal interview within an interactive group setting. A group of people (e.g. potential users, beta testers) are asked about their understanding of a specific issue, process, product, advertisement, etc.

    : How do focus groups work? - Hector Lanz tangential
    W4.4 Can use some techniques for specifying requirements

    Prose

    W4.4a Can explain prose

    Requirements → Specifying Requirements → Prose →

    What

    A textual description (i.e. prose) can be used to describe requirements. Prose is especially useful when describing abstract ideas such as the vision of a product.

    The product vision of the TEAMMATES Project given below is described using prose.

    TEAMMATES aims to become the biggest student project in the world (biggest here refers to 'many contributors, many users, large code base, evolving over a long period'). Furthermore, it aims to serve as a training tool for Software Engineering students who want to learn SE skills in the context of a non-trivial real software product.

    Avoid using lengthy prose to describe requirements; they can be hard to follow.


    Feature Lists

    W4.4b Can explain feature list

    Requirements → Specifying Requirements → Feature Lists →

    What

    Feature List: A list of features of a product grouped according to some criteria such as aspect, priority, order of delivery, etc.

    A sample feature list from a simple Minesweeper game  (only a brief description has been provided to save space):

    1. Basic play – Single player play.
    2. Difficulty levels
      • Medium-levels
      • Advanced levels
    3. Versus play – Two players can play against each other.
    4. Timer – Additional fixed time restriction on the player.
    5. ...

    User Stories

    W4.4c Can write simple user stories

    Requirements → Specifying Requirements → User Stories →

    Introduction

    User story: User stories are short, simple descriptions of a feature told from the perspective of the person who desires the new capability, usually a user or customer of the system. [Mike Cohn]

    A common format for writing user stories is:

    User story format: As a {user type/role} I can {function} so that {benefit}

    Examples (from a Learning Management System):

    1. As a student, I can download files uploaded by lecturers, so that I can get my own copy of the files
    2. As a lecturer, I can create discussion forums, so that students can discuss things online
    3. As a tutor, I can print attendance sheets, so that I can take attendance during the class

    We can write user stories on index cards or sticky notes, and arrange on walls or tables, to facilitate planning and discussion. Alternatively, we can use a software (e.g., GitHub Project Boards, Trello, Google Docs, ...) to manage user stories digitally.

    [credit: https://www.flickr.com/photos/jakuza/2682466984/]

    [credit: https://www.flickr.com/photos/jakuza/with/2726048607/]

    [credit: https://commons.wikimedia.org/wiki/File:User_Story_Map_in_Action.png]

    • a. They are based on stories users tell about similar systems
    • b. They are written from the user/customer perspective
    • c. They are always written in some physical medium such as index cards or sticky notes
    • a. Reason: Despite the name, user stories are not related to 'stories' about the software.
    • b.
    • c. Reason: It is possible to use software to record user stories. When the team members are not co-located this may be the only option.

    Critique the following user story taken from a software project to build an e-commerce website.

    As a developer, I want to use Python to implement the software, so that we can resue existing Python modules.

    Refer to the definition of a user story.

    User story: User stories are short, simple descriptions of a feature told from the perspective of the person who desires the new capability, usually a user or customer of the system. [Mike Cohn]

    This user story is not written from the perspective of the user/customer.

    Bill wants you to build a Human Resource Management (HRM) system. He mentions that the system will help employees to view their own leave balance. What are the user stories you can extract from that statement?

    Remember to follow the correct format when writing user stories.

    User story format: As a {user type/role} I can {function} so that {benefit}

    As an employee, I can view my leave balance, so that I can know how many leave days I have left.

    Note: the {benefit} part may vary as it is not specifically mentioned in the question.


    Evidence:

    Acceptable: Using user stories in any past project.

    Suggested: Do the exercise in [Addressbook-Level3: LO-UesrStories]

    Submission: Create a PR against Addressbook-Level3. Remember to use team ID (e.g. W09-2) in your PR name.

    W4.4d Can write more detailed user stories

    Requirements → Specifying Requirements → User Stories →

    Details

    The {benefit} can be omitted if it is obvious.

    As a user, I can login to the system so that I can access my data

    💡 It is recommended to confirm there is a concrete benefit even if you omit it from the user story. If not, you could end up adding features that have no real benefit.

    You can add more characteristics to the {user role} to provide more context to the user story.

    • As a forgetful user, I can view a password hint, so that I can recall my password.
    • As an expert user, I can tweak the underlying formatting tags of the document, so that I can format the document exactly as I need.

    You can write user stories at various levels. High-level user stories, called epics (or themes) cover bigger functionality. You can then break down these epics to multiple user stories of normal size.

    [Epic] As a lecturer, I can monitor student participation levels

    • As a lecturer, I can view the forum post count of each student so that I can identify the activity level of students in the forum
    • As a lecturer, I can view webcast view records of each student so that I can identify the students who did not view webcasts
    • As a lecturer, I can view file download statistics of each student so that I can identify the students who do not download lecture materials

    You can add conditions of satisfaction to a user story to specify things that need to be true for the user story implementation to be accepted as ‘done’.

    • As a lecturer, I can view the forum post count of each student so that I can identify the activity level of students in the forum.

    Conditions:

    • Separate post count for each forum should be shown
    • Total post count of a student should be shown
    • The list should be sortable by student name and post count

    Other useful info that can be added to a user story includes (but not limited to)

    • Priority: how important the user story is
    • Size: the estimated effort to implement the user story
    • Urgency: how soon the feature is needed
    More examples tangential

    User stories for a travel website (credit: Mike Cohen)

    • As a registered user, I am required to log in so that I can access the system
    • As a forgetful user, I can request a password reminder so that I can log in if I forget mine
    • [Epic] As a user, I can cancel a reservation
      • As a premium site member, I can cancel a reservation up to the last minute
      • As a non-premium member, I can cancel up to 24 hours in advance
      • As a member, I am emailed a confirmation of any cancelled reservation
    • [Epic] As a frequent flyer, I want to book a trip
      • As a frequent flyer, I want to book a trip using miles
      • As a frequent flyer, I want to rebook a trip I take often
      • As a frequent flyer, I want to request an upgrade
      • As a frequent flyer, I want to see if my upgrade cleared

    Choose the correct statements

    • a. User stories are short and written in a formal notation.
    • b. User stories is another name for use cases.
    • c. User stories describes past experiences users had with similar systems. These are helpful in developing the new system.
    • d. User stories are not detailed enough to tell us exact details of the product.
    • a.
    • b.
    • c.
    • d.

    Explanation: User stories are short and written in natural language, NOT in a formal language. They are used for estimation and scheduling purposes but do not contain enough details to form a complete system specification.

    W4.4e Can use user stories to manage requirements of project

    Requirements → Specifying Requirements → User Stories →

    Usage

    User stories capture user requirements in a way that is convenient for scoping, estimation and scheduling.

    [User stories] strongly shift the focus from writing about features to discussing them. In fact, these discussions are more important than whatever text is written. [Mike Cohn, MountainGoat Software 🔗]

    User stories differ from traditional requirements specifications mainly in the level of detail. User stories should only provide enough details to make a reasonably low risk estimate of how long the user story will take to implement. When the time comes to implement the user story, the developers will meet with the customer face-to-face to work out a more detailed description of the requirements. [more...]

    User stories can capture non-functional requirements too because even NFRs must benefit some stakeholder.

    An example of a NFR captured as a user story:

    As a I want to so that
    impatient user to be able experience reasonable response time from the website while up to 1000 concurrent users are using it I can use the app even when the traffic is at the maximum expected level

    Given their lightweight nature, user stories are quite handy for recording requirements during early stages of requirements gathering.

    💡 Here are some tips for using user stories for early stages of requirement gathering:

    • Define the target user:
      Decide your target user's profile (e.g. a student, office worker, programmer, sales person) and work patterns (e.g. Does he work in groups or alone? Does he share his computer with others?). A clear understanding of the target user will help when deciding the importance of a user story. You can even give this user a name.  e.g. Target user Jean is a university student studying in a non-IT field. She interacts with a lot of people due to her involvement in university clubs/societies. ...
    • Define the problem scope: Decide that exact problem you are going to solve for the target user.  e.g. Help Jean keep track of all her school contacts
    • Don't be too hasty to discard 'unusual' user stories:
      Those might make your product unique and stand out from the rest, at least for the target users.
    • Don't go into too much details:
      For example, consider this user story: As a user, I want to see a list of tasks that needs my attention most at the present time, so that I pay attention to them first.
      When discussing this user story, don't worry about what tasks should be considered needs my attention most at the present time. Those details can be worked out later.
    • Don't be biased by preconceived product ideas:
      When you are at the stage of identifying user needs, clear your mind of ideas you have about what your end product will look like.
    • Don't discuss implementation details or whether you are actually going to implement it:
      When gathering requirements, your decision is whether the user's need is important enough for you to want to fulfil it. Implementation details can be discussed later. If a user story turns out to be too difficult to implement later, you can always omit it from the implementation plan.

    While use cases can be recorded on physical paper in the initial stages, an online tool is more suitable for longer-term management of user stories, especially if the team is not co-located.

    You can create issues for each of the user stories and use a GitHub Project Board to sort them into categories.

    Example Project Board:

    Example Issue to represent a user story:

    A video on GitHub Project Boards:


    Example Google Sheet for recording user stories:


    Example Trello Board for recording user stories:


    eXtreme Programming (XP)

    Extreme programming (XP) is a software development methodology which is intended to improve software quality and responsiveness to changing customer requirements. As a type of agile software development, it advocates frequent "releases" in short development cycles, which is intended to improve productivity and introduce checkpoints at which new customer requirements can be adopted. [wikipedia, 2017.05.01]

    uses User stories to capture requirements.

    This page in their website explains the difference between user stories and traditional requirements.

    One of the biggest misunderstandings with user stories is how they differ from traditional requirements specifications. The biggest difference is in the level of detail. User stories should only provide enough detail to make a reasonably low risk estimate of how long the story will take to implement. When the time comes to implement the story developers will go to the customer and receive a detailed description of the requirements face to face.


    Evidence:

    Covered by the final project.


    Use Cases

    W4.4f Can explain use cases

    Requirements → Specifying Requirements → Use Cases →

    Introduction

    Use Case: A description of a set of sequences of actions, including variants, that a system performs to yield an observable result of value to an actor.[ 📖 : uml-user-guideThe Unified Modeling Language User Guide, 2e, G Booch, J Rumbaugh, and I Jacobson ]

    Actor: An actor (in a use case) is a role played by a user. An actor can be a human or another system. Actors are not part of the system; they reside outside the system.

    A use case describes an interaction between the user and the system for a specific functionality of the system.

    • System: ATM
    • Actor: Customer
    • Use Case: Check account balance
      1. User inserts an ATM card
      2. ATM prompts for PIN
      3. User enters PIN
      4. ATM prompts for withdrawal amount
      5. User enters the amount
      6. ATM ejects the ATM card and issues cash
      7. User collects the card and the cash.
    • System: A Learning Management System (LMS)
    • Actor: Student
    • Use Case: Upload file
      1. Student requests to upload file
      2. LMS requests for the file location
      3. Student specifies the file location
      4. LMS uploads the file

    UML includes a diagram type called use case diagrams that can illustrate use cases of a system visually, providing a visual ‘table of contents’ of the use cases of a system. In the example below, note how use cases are shown as ovals and user roles relevant to each use case are shown as stick figures connected to the corresponding ovals.

    Unified Modeling Language (UML) is a graphical notation to describe various aspects of a software system. UML is the brainchild of three software modeling specialists James Rumbaugh, Grady Booch and Ivar Jacobson (also known as the Three Amigos). Each of them has developed their own notation for modeling software systems before joining force to create a unified modeling language (hence, the term ‘Unified’ in UML). UML is currently the de facto modeling notation used in the software industry.

    Use cases capture the functional requirements of a system.

    W4.4g Can use use cases to list functional requirements of a simple system

    Requirements → Specifying Requirements → Use Cases →

    Identifying

    A use case is an interaction between a system and its actors.

    Actors in Use Cases

    Actor: An actor (in a use case) is a role played by a user. An actor can be a human or another system. Actors are not part of the system; they reside outside the system.

    Some example actors for a Learning Management System

    • Actors: Guest, Student, Staff, Admin, ExamSys, LibSys.

    A use case can involve multiple actors.

    • Software System: LearnSys
    • Use case: UC01 conduct survey
    • Actors: Staff, Student

    An actor can be involved in many use cases.

    • Software System: LearnSys
    • Actor: Staff
    • Use cases: UC01 conduct survey, UC02 Set Up Course Schedule, UC03 Email Class, ...

    A single person/system can play many roles.

    • Software System: LearnSys
    • Person: a student
    • Actors (or Roles): Student, Guest, Tutor

    Many persons/systems can play a single role.

    • Software System: LearnSys
    • Actor(or role) : Student
    • Persons that can play this role : undergraduate student, graduate student, a staff member doing a part-time course, exchange student

    Use cases can be specified at various levels of detail.

    Consider the three use cases given below. Clearly, (a) is at a higher level than (b) and (b) is at a higher level than (c).

    • System: LearnSys
    • Use cases:
      a. Conduct a survey
      b. Take the survey
      c. Answer survey question

    💡 While modeling user-system interactions,

    • Start with high level use cases and progressively work toward lower level use cases.
    • Be mindful at which level of details you are working on and not to mix use cases of different levels.

    Consider a simple movie ticket vending machine application. Every week, the theatre staff will enter the weekly schedule as well as ticket price for each show. A customer sees the schedule and the ticket price displayed at the machine. There is a slot to insert money, a keypad to enter a code for a movie, a code for the show time, and the number of tickets. A display shows the customer's balance inside the machine. A customer may choose to cancel a transaction before pressing the “buy” button. Printed tickets can be collected from a slot at the bottom of the machine. The machine also displays messages such as "Please enter more money”, “Request fewer tickets" or "SOLD OUT!”. Finally, a "Return Change" button allows the customer to get back his unspent money.

    Draw a use case diagram for the above requirements.

    Note that most of the details in the description are better given as part of the use case description rather than as low-level use cases in the diagram.

    A software house wishes to automate its Quality Assurance division.

    The system is to be used by Testers, Programmers and System Administrators. Only an administrator can create new users and assign tasks to programmers. Any tester can create a bug report, as well as set the status of a bug report as ‘closed’. Only a programmer can set the state of a bug report to ‘fixed’, but a programmer cannot set the status of a bug report to ‘closed’. Each tester is assigned just one task at a time. A task involves testing of a particular component for a particular customer. Tester must document the bugs they find. Each bug is given a unique identifier. Other information recorded about the bug is component id, severity, date and time reported, programmer who is assigned to fix it, date fixed, date retested and date closed. The system keeps track of which bugs are assigned to which programmer at any given time. It should be able to generate reports on the number of bugs found, fixed and closed e.g. number of bugs per component and per customer; number of bugs found by a particular tester ; number of bugs awaiting to be fixed; number of bugs awaiting to be retested; number of bugs awaiting to be assigned to programmers etc.

    Develop a use case diagram to capture their requirements given below.

    Explanation: The given description contains information not relevant to use case modeling. Furthermore, the description is not enough to complete the use case diagram All these are realities of real projects. However, the process of trying to create this use case diagram prompts us to investigate issues such as:

    • Is ‘edit bug report’ a use case or editing the bug report is covered by other use cases such as those for setting the status of bug reports? If it is indeed a separate use case, who are the actors of that use case?
    • Does ‘assign task’ simply means ‘assign bug report’ or is there any other type of tasks?
    • There was some mention about Customers and Components. Does the system have to support use cases for creating and maintaining details about those entities? For example, should we have a ‘create customer record’ use case?
    • Which actors can perform the ‘generate report’ use case? Are reports generated automatically by the system at a specific time or generated ‘on demand’ when users request to view them? Do we have to treat different types of reports as different use cases (in case some types of reports are restricted to some types of users)? The above diagram assumes (just for illustration) that the report is generated on demand and only the system admin can generate any report.
    W4.4h Can specify details of a use case in a structured format

    Requirements → Specifying Requirements → Use Cases →

    Details

    Writing use case steps

    The main body of the use case is the sequence of steps that describes the interaction between the system and the actors. Each step is given as a simple statement describing who does what.

    An example of the main body of a use case.

    1. Student requests to upload file
    2. LMS requests for the file location
    3. Student specifies the file location
    4. LMS uploads the file

    A use case describes only the externally visible behavior, not internal details, of a system i.e. should not mention give details that are not part of the interaction between the user and the system.

    This example use case step refers to behaviors not externally visible .

    1. LMS saves the file into the cache and indicates success.

    A step gives the intention of the actor (not the mechanics). That means UI details are usually omitted. The idea is to leave as much flexibility to the UI designer as possible. That is, the use case specification should be as general as possible (less specific) about the UI.

    The first example below is not a good use case step because contains UI-specific details. The second one is better because it omits UI-specific details.

    Bad : User right-clicks the text box and chooses ‘clear’

    Good : User clears the input

    A use case description can show loops too.

    An example of how you can show a loop:

    Software System: Square game Use case: UC02 - Play a Game Actors: Player (multiple players)

    1. A Player starts the game.
    2. SquareGame asks for player names.
    3. Each Player enters his own name.
    4. SquareGame shows the order of play.
    5. SquareGame prompts for the current Player to throw die.
    6. Current Player adjusts the throw speed.
    7. Current Player triggers the die throw.
    8. Square Game shows the face value of the die.
    9. Square Game moves the Player's piece accordingly.
      Steps 5-9 are repeated for each Player, and for as many rounds as required until a Player reaches the 100th square.
    10. Square Game shows the Winner.

      Use case ends.

    The Main Success Scenario (MSS) describes the most straightforward interaction for a given use case, which assumes that nothing goes wrong. This is also called the Basic Course of Action or the Main Flow of Events of a use case.

    • System: Online Banking System (OBS)
    • Use case: UC23 - Transfer Money
    • Actor: User
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details of the transfer.
      3. User enters the requested details.
      4. OBS requests for confirmation.
      5. OBS transfers the money and displays the new account balance.
      6. Use case ends.

    Note how the MSS assumes that all entered details are correct and ignores problems such as timeouts, network outages etc. Fro example, MSS does not tell us what happens if the user enters an incorrect data.

    Extensions are "add-on"s to the MSS that describe exceptional/alternative flow of events. They describe variations of the scenario that can happen if certain things are not as expected by the MSS. Extensions appear below the MSS.

    This example adds some extensions to the use case in the previous example.

    • System: Online Banking System (OBS)
    • Use case: UC23 - Transfer Money
    • Actor: User
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details of the transfer.
      3. User enters the requested details.
      4. OBS requests for confirmation.
      5. OBS transfers the money and displays the new account balance.
      6. Use case ends.

    • Extensions:
      1. 3a. OBS detects an error in the entered data.
        1. 3a1. OBS requests for the correct data.
        2. 3a2. User enters new data.
        3. Steps 3a1-3a2 are repeated until the data entered are correct.
        4. Use case resumes from step 4.

      2. 3b. User requests to effect the transfer in a future date.
        1. 3b1. OBS requests for confirmation.
        2. 3b2. User confirms future transfer.
        3. Use case ends.

      3. *a. At any time, User chooses to cancel the transfer.
        1. *a1. OBS requests to confirm the cancellation.
        2. *a2. User confirms the cancellation.
        3. Use case ends.

      4. *b. At any time, 120 seconds lapse without any input from the User.
        1. *b1. OBS cancels the transfer.
        2. *b2. OBS informs the User of the cancellation.
        3. Use case ends.

    Note that the numbering style is not a universal rule but a widely used convention. Based on that convention,

    • either of the extensions marked 3a. and 3b. can happen just after step 3 of the MSS.
    • the extension marked as *a. can happen at any step (hence, the *).

    When separating extensions from the MSS, keep in mind that the MSS should be self-contained. That is, the MSS should give us a complete usage scenario.

    Also note that it is not useful to mention events such as power failures or system crashes as extensions because the system cannot function beyond such catastrophic failures.

    In use case diagrams you can use the <<extend>> arrows to show extensions. Note the direction of the arrow is from the extension to the use case it extends and the arrow uses a dashed line.

    A use case can include another use case. Underlined text is commonly used to show an inclusion of a use case.

    This use case includes two other use cases, one in step 1 and one in step 2.

    • Software System: LearnSys
    • Use case: UC01 - Conduct Survey
    • Actors: Staff, Student
    • MSS:
      1. Staff creates the survey (UC44).
      2. Student completes the survey (UC50).
      3. Staff views the survey results.
        Use case ends.

    Inclusions are useful,

    • when you don't want to clutter a use case with too many low-level steps.
    • when a set of steps is repeated in multiple use cases.

    We use a dotted arrow and a <<include>> annotation to show use case inclusions in a use case diagram. Note how the arrow direction is different from the <<extend>> arrows.

    Preconditions specify the specific state we expect the system to be in before the use case starts.

    • Software System: Online Banking System
    • Use case: UC23 - Transfer Money
    • Actor: User
    • Preconditions: User is logged in.
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details for the transfer.
      3. ...

    Guarantees specify what the use case promises to give us at the end of its operation.

    • Software System: Online Banking System
    • Use case: UC23 - Transfer Money
    • Actor: User
    • Preconditions: User is logged in.
    • Guarantees:
      • Money will be deducted from the source account only if the transfer to the destination account is successful
      • The transfer will not result in the account balance going below the minimum balance required.
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details for the transfer.
      3. ...

    Complete the following use case (MSS, extensions, etc.). Note that you should not blindly follow how the existing EZ-Link machine operates because it will prevent you from designing a better system. You should consider all possible extensions without complicating the use case too much.

    • System: EZ-Link machine
    • Use case: UC2 top-up EZ-Link card
    • Actor: EZ-Link card user
    • System: EZ-Link machine (those found at MRTs)
    • Use case: UC2 top-up EZ-Link card
    • Actor: EZ-Link card user
    • Preconditions: All hardware in working order.
    • Guarantees: MSS → the card will be topped-up.
    • MSS:
      1. User places the card on the reader.
      2. System displays card details and prompts for desired action.
      3. User selects top-up.
      4. System requests for top-up details (amount, payment option, receipt required?).
      5. User enters details.
      6. System processes cash payment (UC02) or NETS payment (UC03).
      7. System updates the card value.
      8. System indicates transaction as completed.
      9. If requested in step 5, system prints receipt.
      10. User removes the card.
      11. Use case ends.
    • Extensions:
      1. *a. User removed card or other hardware error detected.
        1. *a1. System indicates the transaction has been aborted.
        2. Use case ends.

    Notes:

    • We assume that the only way to cancel a transaction is by removing the card.
    • By not breaking step 4 into further steps, we avoid committing to a particular mechanism to enter data. For example, we are free to accept all data in one screen.
    • In step 5, we assume that the input mechanism does not allow any incorrect data.
    • System: EZ-Link machine
    • Use case: UC03 process NETS payment
    • Actor: EZ-Link card user
    • Preconditions: A transaction requiring payment is underway.
    • Guarantees: MSS → Transaction amount is transferred from user account to EZ-Link company account.
    • MSS:
      1. System requests to insert ATM card.
      2. User inserts the ATM card.
      3. System requests for PIN.
      4. User enters PIN.
      5. System reports success.
      6. Use case ends.
    • Extensions:
      1. 2a. Unacceptable ATM card (damaged or inserted wrong side up).
        1. ...
      2. 4a. Wrong PIN.
        1. ...
      3. 4b. Insufficient funds.
        1. ...
      4. *a. Connection to the NETS gateway is disrupted.
        1. ...

    Note: UC02 can be written along similar lines.

    Complete the following use case (MSS, extensions, etc.).

    • System: LearnSys (an online Learning Management System)
    • Use case: UC01 reply to post in the forum
    • Actor: Student
    • System: LearnSys
    • Use case: UC01 reply to post in the forum
    • Actor: Student
    • Preconditions: Student is logged in and has permission to post in the forum. The post to which the Student replies already exists.
    • MSS:
      1. Student chooses to reply to an existing post.
      2. LearnSys requests the user to enter post details.
      3. Student enters post details.
      4. Student submits the post.
      5. LearnSys displays the post.
      6. Use case ends.
    • Extensions:
      1. *a. Internet connection goes down.
        1. ...
      2. *b. LearnSys times out
        1. ...
      3. 3a. Student chooses to ‘preview’ the post.
        1. 3a1. LearnSys shows a preview.
        2. 3a2. User chooses to go back to editing.
        3. Use case resumes at step 3.
      4. 3b. Student chooses to attach picture/file
        1. ...
      5. 3c. Student chooses to save the post as a draft.
        1. 3c1. LearnSys confirms draft has been saved.
        2. Use case ends.
      6. 3d. Student chooses to abort the operation.
        1. ...
      7. 4a. The post being replied to is deleted by the owner while the reply is being entered.
        1. ...
      8. 4b. Unacceptable data entered.
        1. ...

    Which of these cannot appear as part of a use case description?

    • a. Use case identifier
    • b. Preconditions
    • c. Guarantees
    • d. References to another use case
    • e. Main Success Scenario
    • f. Performance requirements
    • g. Extensions
    • h. Inclusions

    (f)

    Explanation: Performance requirements are non-functional requirements. They are not captured in use cases.

    Identify problems with this use case description.

    • System: EZ-Link machine (those found at MRTs)
    • Use case: UC2 top-up EZ-Link card
    • Actor: EZ-Link card user
    • Preconditions: All hardware in working order.
    • Guarantees: If MSS completes at least until step 7, the card will be topped-up.
    • MSS:
      1. User places the card on the reader.
      2. System displays card details and prompts for desired action.
      3. User selects top-up.
      4. System requests for top-up details (amount, payment option, receipt required?).
      5. User enters details.
      6. System processes cash payment (UC02) or NETS payment (UC03).
      7. System updates the card value.
      8. System indicates transaction as completed.
      9. If requested in step 5, system prints receipt.
      10. User removes the card.
      11. Use case ends.
    • Extensions:
      1. *a. User removed card or other hardware error detected.
        1. *a1. System indicates the transaction has been aborted.
        2. Use case ends.
    • a. It does not consider ‘system crash’ scenario.
    • b. It does not contain enough UI details.
    • c. The extension given is in fact an inclusion.
    • d. No post conditions are given.
    • e. ‘Use case ends’ is duplicated.

    None.

    Explanation: Catastrophic failures such as ‘system crash’ need not be included in a use case. A use case is not supposed to contain UI details. Post conditions are optional. It is not a problem to have multiple exit points for a use case.


    Evidence:

    Suggested: Do the exercise in [Addressbook-Level3: LO-UseCases]

    Submission: Create a PR against Addressbook-Level3. Remember to use team ID (e.g. W09-2) in your PR name.

    W4.4i Can optimize the use of use cases

    Requirements → Specifying Requirements → Use Cases →

    Usage

    You can use actor generalization in use case diagrams using a symbol similar to that of UML notation for inheritance.

    In this example, actor Blogger can do all the use cases the actor Guest can do, as a result of the actor generalization relationship given in the diagram.

    💡 Do not over-complicate use case diagrams by trying to include everything possible. A use case diagram is a brief summary of the use cases that is used as a starting point. Details of the use cases can be given in the use case descriptions.

    Some include ‘System’ as an actor to indicate that something is done by the system itself without being initiated by a user or an external system.

    The diagram below can be used to indicate that the system generates daily reports at midnight.

    However, others argue that only use cases providing value to an external user/system should be shown in the use case diagram. For example, they argue that ‘view daily report’ should be the use case and generate daily report is not to be shown in the use case diagram because it is simply something the system has to do to support the view daily report use case.

    We recommend that you follow the latter view (i.e. not to use System as a user). Limit use cases for modeling behaviors that involve an external actor.

    UML is not very specific about the text contents of a use case. Hence, there are many styles for writing use cases. For example, the steps can be written as a continuous paragraph. Use cases should be easy to read. Note that there is no strict rule about writing all details of all steps or a need to use all the elements of a use case.

    There are some advantages of documenting system requirements as use cases:

    • Because they use a simple notation and plain English descriptions, they are easy for users to understand and give feedback.
    • They decouple user intention from mechanism (note that use cases should not include UI-specific details), allowing the system designers more freedom to optimize how a functionality is provided to a user.
    • Identifying all possible extensions encourages us to consider all situations that a software product might face during its operation.
    • Separating typical scenarios from special cases encourages us to optimize the typical scenarios.

    One of the main disadvantages of use cases is that they are not good for capturing requirements that does not involve a user interacting with the system. Hence, they should not be used as the sole means to specify requirements.

    What are the advantages of using use cases (the textual form) for requirements modelling?

    • a. They can be fairly detailed but still natural enough for users for users to understand and give feedback.
    • b. The UI-independent nature of use case specification allows the system designers more freedom to decide how a functionality is provided to a user.
    • c. Extensions encourage us to consider all situations a software product might face during its operations.
    • d. They encourage us to identify and optimize the typical scenario of usage over exceptional usage scenarios.

    (a) (b) (c) (d)

    Which of these are correct?

    • a. Use case are not very suitable for capturing non-functional requirements.
    • b. Use case diagrams are less detailed than textual use cases.
    • c. Use cases are better than user stories.
    • d. Use cases can be expressed at different levels of abstraction.

    (a)(b)(d)

    Explanation: It is not correct to say one format is better than the other. It depends on the context.


    Glossary

    W4.4j Can explain glossary

    Requirements → Specifying Requirements → Glossary →

    What

    Glossary: A glossary serves to ensure that all stakeholders have a common understanding of the noteworthy terms, abbreviation, acronyms etc.

    Here is a partial glossary from a variant of the Snakes and Ladders game:

    • Conditional square: A square that specifies a specific face value which a player has to throw before his/her piece can leave the square.
    • Normal square: a normal square does not have any conditions, snakes, or ladders in it.

    Supplementary Requirements

    W4.4k Can explain supplementary requirements

    Requirements → Specifying Requirements → Supplementary Requirements →

    What

    A supplementary requirements section can be used to capture requirements that do not fit elsewhere. Typically, this is where most Non Functional Requirements will be listed.

    Requirements → Requirements →

    Non-Functional Requirements

    There are two kinds of requirements:

    1. Functional requirements specify what the system should do.
    2. Non-functional requirements specify the constraints under which system is developed and operated.

    Some examples of non-functional requirement categories:

    • Data requirements e.g. size, volatility, persistency etc.,
    • Environment requirements e.g. technical environment in which system would operate or need to be compatible with.
    • Accessibility, Capacity, Compliance with regulations, Documentation, Disaster recovery, Efficiency, Extensibility, Fault tolerance, Interoperability, Maintainability, Privacy, Portability, Quality, Reliability, Response time, Robustness, Scalability, Security, Stability, Testability, and more ...
    • Business/domain rules: e.g. the size of the minefield cannot be smaller than five.
    • Constraints: e.g. the system should be backward compatible with data produced by earlier versions of the system; system testers are available only during the last month of the project; the total project cost should not exceed $1.5 million.
    • Technical requirements: e.g. the system should work on both 32-bit and 64-bit environments.
    • Performance requirements: e.g. the system should respond within two seconds.
    • Quality requirements: e.g. the system should be usable by a novice who has never carried out an online purchase.
    • Process requirements: e.g. the project is expected to adhere to a schedule that delivers a feature set every one month.
    • Notes about project scope: e.g. the product is not required to handle the printing of reports.
    • Any other noteworthy points: e.g. the game should not use images deemed offensive to those injured in real mine clearing activities.

    We may have to spend an extra effort in digging NFRs out as early as possible because,

    1. NFRs are easier to miss  e.g., stakeholders tend to think of functional requirements first
    2. sometimes NFRs are critical to the success of the software.  E.g. A web application that is too slow or that has low security is unlikely to succeed even if it has all the right functionality.

    Given below are some requirements of TEAMMATES (an online peer evaluation system for education). Which one of these are non-functional requirements?

    • a. The response to any use action should become visible within 5 seconds.
    • b. The application admin should be able to view a log of user activities.
    • c. The source code should be open source.
    • d. A course should be able to have up to 2000 students.
    • e. As a student user, I can view details of my team members so that I can know who they are.
    • f. The user interface should be intuitive enough for users who are not IT-savvy.
    • g. The product is offered as a free online service.

    (a)(c)(d)(f)(g)

    Explanation: (b) are (e) are functions available for a specific user types. Therefore, they are functional requirements. (a), (c), (d), (f) and (g) are either constraints on functionality or constraints on how the project is done, both of which are considered non-functional requirements.


    Prototyping

    W4.4l Can explain prototyping

    Requirements → Gathering Requirements →

    Prototyping

    Prototype: A prototype is a mock up, a scaled down version, or a partial system constructed

    • to get users’ feedback.
    • to validate a technical concept (a "proof-of-concept" prototype).
    • to give a preview of what is to come, or to compare multiple alternatives on a small scale before committing fully to one alternative.
    • for early field-testing under controlled conditions.

    Prototyping can uncover requirements, in particular, those related to how users interact with the system. UI prototypes are often used in brainstorming sessions, or in meetings with the users to get quick feedback from them.

    [source: http://balsamiq.com/products/mockups]

    💡 Prototyping can be used for discovering as well as specifying requirements  e.g. a UI prototype can serve as a specification of what to build.

    Documentation

    W4.5 Can use some common documentation tools

    Javadoc

    W4.5a Can explain JavaDoc

    Implementation → Documentation → Tools → JavaDoc

    What

    Javadoc is a tool for generating API documentation in HTML format from doc comments in source. In addition, modern IDEs use JavaDoc comments to generate explanatory tool tips.

    An example method header comment in JavaDoc format (adapted from Oracle's Java documentation)

    /**
     * Returns an Image object that can then be painted on the screen. 
     * The url argument must specify an absolute {@link URL}. The name
     * argument is a specifier that is relative to the url argument. 
     * <p>
     * This method always returns immediately, whether or not the 
     * image exists. When this applet attempts to draw the image on
     * the screen, the data will be loaded. The graphics primitives 
     * that draw the image will incrementally paint on the screen. 
     *
     * @param url an absolute URL giving the base location of the image
     * @param name the location of the image, relative to the url argument
     * @return the image at the specified URL
     * @see Image
     */
     public Image getImage(URL url, String name) {
            try {
                return getImage(new URL(url, name));
            } catch (MalformedURLException e) {
                return null;
            }
     }
    

    Generated HTML documentation:

    Tooltip generated by Intellij IDE:

    W4.5b Can write Javadoc comments

    Implementation → Documentation → Tools → JavaDoc


    Markdown

    W4.5c Can explain Markdown

    Implementation → Documentation → Tools → Markdown

    What

    Markdown is a lightweight markup language with plain text formatting syntax.

    W4.5d Can write documents in Markdown format

    Implementation → Documentation → Tools → Markdown


    AsciiDoc

    W4.5e Can explain AsciiDoc

    Implementation → Documentation → Tools → AsciiDoc

    What

    AsciiDoc is similar to Markdown but has more powerful (but also more complex) syntax.

    Implementation

    W4.6 Can use Generics in Java W4.6a Can explain Java Generics

    C++ to Java → Generics →

    What are Generics?

    Given below is an extract from the -- Java Tutorial, with some adaptations.

    You can use polymorphism to write code that can work with multiple types, but that approach has some shortcomings.

    Consider the following Box class. It can be used only for storing Integer objects.

    public class BoxForIntegers {
        private Integer x;
    
        public void set(Integer x) {
            this.x = x;
        }
        public Integer get() {
            return x;
        }
    }
    

    To store String objects, another similar class is needed, resulting in the duplication of the entire class. As you can see, if you need to store many different types of objects, you could end up writing many similar classes.

    public class BoxForString {
        private String x;
    
        public void set(String x) {
            this.x = x;
        }
        public String get() {
            return x;
        }
    }
    

    One solution for this problem is to use polymorphism i.e., write the Box class to store Object objects.

    public class Box {
        private Object x;
    
        public void set(Object x) {
            this.x = x;
        }
        public Object get() {
            return x;
        }
    }
    

    The problem with this solution is, since its methods accept or return an Object, you are free to pass in whatever you want, provided that it is not one of the primitive types. There is no way to verify, at compile time, how the class is used. One part of the code may place an Integer in the box and expect to get Integers out of it, while another part of the code may mistakenly pass in a String, resulting in a runtime error.

    Generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types.

    A generic Box class allows you to define what type of elements will be put in the Box. For example, you can instantiate a Box object to keep Integer elements so that any attempt to put a non-Integer object in that Box object will result in a compile error.

    W4.6b Can use Java Generics

    C++ to Java → Generics →

    How to use Generics

    This section includes extract from the -- Java Tutorial, with some adaptations.

    The definition of a generic class includes a type parameter section, delimited by angle brackets (<>). It specifies the type parameters (also called type variables) T1, T2, ..., and Tn. A generic class is defined with the following format:

    class name<T1, T2, ..., Tn> { /* ... */ }
    

    Here is a generic Box class. The class declaration Box<T> introduces the type variable, T, which is also used inside the class to refer to the same type.

    Using Object as the type:

    public class Box {
        private Object x;
    
        public void set(Object x) {
            this.x = x;
        }
    
        public Object get() {
            return x;
        }
    }
    

    A generic Box using type parameter T:

    public class Box<T> {
        private T x;
    
        public void set(T x) {
            this.x = x;
        }
    
        public T get() {
            return x;
        }
    }
    

    As you can see, all occurrences of Object are replaced by T.

    To reference the generic Box class from within your code, you must perform a generic type invocation, which replaces T with some concrete value, such as Integer. It is similar to an ordinary method invocation, but instead of passing an argument to a method, you are passing a type argument enclosed within angle brackets — e.g., <Integer> or <String, Integer> — to the generic class itself. Note that in some cases you can omit the type parameter i.e., <> if the type parameter can be inferred from the context.

    Using the generic Box class to store Integer objects:

    Box<Integer> integerBox;
    integerBox = new Box<>(); // type parameter omitted as it can be inferred
    integerBox.set(Integer.valueOf(4));
    Integer i = integerBox.get(); // returns an Integer
    
    • Box<Integer> integerBox; simply declares that integerBox will hold a reference to a "Box of Integer", which is how Box<Integer> is read.
    • integerBox = new Box<>(); instantiates a Box<Integer> class. Note the <> (an empty pair of angle brackets, also called the diamond operator) between the class name and the parenthesis.

    The compiler is able to check for type errors when using generic code.

    The code below will fail because it creates a Box<String> and then tries to pass Double objects into it.

    Box<String> stringBox = new Box<>();
    stringBox.set(Double.valueOf(5.0)); //compile error!
    

    A generic class can have multiple type parameters.

    The generic OrderedPair class, which implements the generic Pair interface:

    public interface Pair<K, V> {
        public K getKey();
        public V getValue();
    }
    
    public class OrderedPair<K, V> implements Pair<K, V> {
    
        private K key;
        private V value;
    
        public OrderedPair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    
        public K getKey()	{ return key; }
        public V getValue() { return value; }
    }
    

    The following statements create two instantiations of the OrderedPair class:

    Pair<String, Integer> p1 = new OrderedPair<>("Even", 8);
    Pair<String, String>  p2 = new OrderedPair<>("hello", "world");
    

    The code, new OrderedPair<String, Integer>, instantiates K as a String and V as an Integer. Therefore, the parameter types of OrderedPair's constructor are String and Integer, respectively.

    A type variable can be any non-primitive type you specify: any class type, any interface type, any array type, or even another type variable.

    By convention, type parameter names are single, uppercase letters. The most commonly used type parameter names are:

    • E - Element (used extensively by the Java Collections Framework)
    • K - Key
    • N - Number
    • T - Type
    • V - Value
    • S, U, V etc. - 2nd, 3rd, 4th types
    W4.7 Can use Java Collections W4.7a Can explain the Collections framework

    C++ to Java → Collections →

    The Collections Framework

    This section uses extracts from the -- Java Tutorial, with some adaptations.

    A collection — sometimes called a container — is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data.

    Typically, collections represent data items that form a natural group, such as a poker hand (a collection of cards), a mail folder (a collection of letters), or a telephone directory (a mapping of names to phone numbers).

    The collections framework is a unified architecture for representing and manipulating collections. It contains the following:

    • Interfaces: These are abstract data types that represent collections. Interfaces allow collections to be manipulated independently of the details of their representation.
      Example: the List<E> interface can be used to manipulate list-like collections which may be implemented in different ways such as ArrayList<E> or LinkedList<E>.

    • Implementations: These are the concrete implementations of the collection interfaces. In essence, they are reusable data structures.
      Example: the ArrayList<E> class implements the List<E> interface while the HashMap<K, V> class implements the Map<K, V> interface.

    • Algorithms: These are the methods that perform useful computations, such as searching and sorting, on objects that implement collection interfaces. The algorithms are said to be polymorphic: that is, the same method can be used on many different implementations of the appropriate collection interface.
      Example: the sort(List<E>) method can sort a collection that implements the List<E> interface.

    A well-known example of collections frameworks is the C++ Standard Template Library (STL). Although both are collections frameworks and the syntax look similar, note that there are important philosophical and implementation differences between the two.

    The following list describes the core collection interfaces:

    • Collection — the root of the collection hierarchy. A collection represents a group of objects known as its elements. The Collection interface is the least common denominator that all collections implement and is used to pass collections around and to manipulate them when maximum generality is desired. Some types of collections allow duplicate elements, and others do not. Some are ordered and others are unordered. The Java platform doesn't provide any direct implementations of this interface but provides implementations of more specific subinterfaces, such as Set and List. Also see the Collection API.

    • Set — a collection that cannot contain duplicate elements. This interface models the mathematical set abstraction and is used to represent sets, such as the cards comprising a poker hand, the courses making up a student's schedule, or the processes running on a machine. Also see the Set API.

    • List — an ordered collection (sometimes called a sequence). Lists can contain duplicate elements. The user of a List generally has precise control over where in the list each element is inserted and can access elements by their integer index (position). Also see the List API.

    • Queue — a collection used to hold multiple elements prior to processing. Besides basic Collection operations, a Queue provides additional insertion, extraction, and inspection operations. Also see the Queue API.

    • Map — an object that maps keys to values. A Map cannot contain duplicate keys; each key can map to at most one value. Also see the Map API.

    • Others: Deque, SortedSet, SortedMap


    Evidence:

    Acceptable: Some code that you have written that uses some Java Collection classes.

    Suggested: Do the exercise given in AddressBook - Level1 : LO-Collections

    Submission: Show your code to the tutor during the tutorial.

    W4.7b Can use the ArrayList class

    C++ to Java → Collections →

    The ArrayList Class

    The ArrayList class is a resizable-array implementation of the List interface. Unlike a normal array, an ArrayList can grow in size as you add more items to it. The example below illustrate some of the useful methods of the ArrayList class using an ArrayList of String objects.

    import java.util.ArrayList;
    
    public class ArrayListDemo {
    
        public static void main(String args[]) {
            ArrayList<String> items = new ArrayList<>();
    
            System.out.println("Before adding any items:" + items);
    
            items.add("Apple");
            items.add("Box");
            items.add("Cup");
            items.add("Dart");
            print("After adding four items: " + items);
    
            items.remove("Box"); // remove item "Box"
            print("After removing Box: " + items);
    
            items.add(1, "Banana"); // add "Banana" at index 1
            print("After adding Banana: " + items);
    
            items.add("Egg"); // add "Egg", will be added to the end
            items.add("Cup"); // add another "Cup"
            print("After adding Egg: " + items);
    
            print("Number of items: " + items.size());
    
            print("Index of Cup: " + items.indexOf("Cup"));
            print("Index of Zebra: " + items.indexOf("Zebra"));
    
            print("Item at index 3 is: " + items.get(2));
    
            print("Do we have a Box?: " + items.contains("Box"));
            print("Do we have an Apple?: " + items.contains("Apple"));
    
            items.clear();
            print("After clearing: " + items);
        }
    
        private static void print(String text) {
            System.out.println(text);
        }
    }
    

    Before adding any items:[]
    After adding four items: [Apple, Box, Cup, Dart]
    After removing Box: [Apple, Cup, Dart]
    After adding Banana: [Apple, Banana, Cup, Dart]
    After adding Egg: [Apple, Banana, Cup, Dart, Egg, Cup]
    Number of items: 6
    Index of Cup: 2
    Index of Zebra: -1
    Item at index 3 is: Cup
    Do we have a Box?: false
    Do we have an Apple?: true
    After clearing: []
    

    [Try the above code on Repl.it]

    Add the missing methods to the class given below so that it produces the output given.

    💡 Use an ArrayList to store the numbers.

    public class Main {
    
        //TODO: add your methods here
    
        public static void main(String[] args) {
            System.out.println("Adding numbers to the list");
            addNumber(3);
            addNumber(8);
            addNumber(24);
            System.out.println("The total is: " + getTotal());
            System.out.println("8 in the list : " + isFound(8) );
            System.out.println("5 in the list : " + isFound(5) );
            removeNumber(8);
            System.out.println("The total is: " + getTotal());
        }
    
    }
    

    Adding numbers to the list
    [3]
    [3, 8]
    [3, 8, 24]
    The total is: 35
    8 in the list : true
    5 in the list : false
    [3, 24]
    The total is: 27
    

    Partial solution:

    import java.util.ArrayList;
    
    public class Main {
        private static ArrayList<Integer> numbers = new ArrayList<>();
    
        private static void addNumber(int i) {
            numbers.add(Integer.valueOf(i));
            System.out.println(numbers);
        }
    
        // ...
    
    }
    

    This exercise continues from the TaskManager Level 1-3 exercises quoted above.

    Enhance the TaskManager in the following ways:

    1. Use a suitable Collection class to store tasks, instead of using an array.
    2. Introduce a done n command to mark the task at index n as done.

    Here is an example output:

    Welcome to TaskManager-Level4!
    Your task? todo read book
    Tasks in the list: 1
    Your task? deadline return book /by Friday
    Tasks in the list: 2
    Your task? print
    Tasks:
    [1] description: read book
    is done? No
    [2] description: return book
    is done? No
    do by: Friday
    Your task? done 1
    Tasks in the list: 2
    Your task? print
    Tasks:
    [1] description: read book
    is done? Yes
    [2] description: return book
    is done? No
    do by: Friday
    Your task?

    Suggestions:

    • Move the isDone variable to the Task class and provide a setDone(boolean) method.
    public class Task {
        protected String description;
        protected boolean isDone;
    
        // ...
    
        public void setDone(boolean isDone){
            this.isDone = isDone;
        }
    }
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Main {
        static Scanner in = new Scanner(System.in);
        static List<Task> tasks = new ArrayList<>();
    
        public static void main(String[] args) {
            // ...
        }
    
        private static void addTodo(String line) throws TaskManagerException {
            //...
            tasks.add(new Todo(description));
            //...
        }
    
        private static void markAsDone(String line) {
            int index = Integer.parseInt(line.substring("done".length()).trim());
            tasks.get(index - 1).setDone(true);
            System.out.println("Tasks in the list: " + tasks.size());
        }
    
        private static void printTasks() {
            // ...
            for (int i = 0; i < tasks.size(); i++) {
                System.out.println("[" + (i + 1) + "] " + tasks.get(i));
            }
        }
    }
    
    W4.7c Can use the HashMap class

    C++ to Java → Collections →

    The HashMap Class

    HashMap is an implementation of the Map interface. It allows you to store a collection of key-value pairs. The example below illustrates how to use a HashMap<String, Point> to maintain a list of coordinates and their identifiers e.g., the identifier x1 is used to identify the point 0,0 where x1 is the key and 0,0 is the value.

    import java.awt.Point;
    import java.util.HashMap;
    import java.util.Map;
    
    public class HashMapDemo {
        public static void main(String[] args) {
            HashMap<String, Point> points = new HashMap<>();
    
            // put the key-value pairs in the HashMap
            points.put("x1", new Point(0, 0));
            points.put("x2", new Point(0, 5));
            points.put("x3", new Point(5, 5));
            points.put("x4", new Point(5, 0));
    
            // retrieve a value for a key using the get method
            print("Coordinates of x1: " + pointAsString(points.get("x1")));
    
            // check if a key or a value exists
            print("Key x1 exists? " + points.containsKey("x1"));
            print("Key x1 exists? " + points.containsKey("y1"));
            print("Value (0,0) exists? " + points.containsValue(new Point(0, 0)));
            print("Value (1,2) exists? " + points.containsValue(new Point(1, 2)));
    
            // update the value of a key to a new value
            points.put("x1", new Point(-1,-1));
    
            // iterate over the entries
            for (Map.Entry<String, Point> entry : points.entrySet()) {
                print(entry.getKey() + " = " + pointAsString(entry.getValue()));
            }
    
            print("Number of keys: " + points.size());
            points.clear();
            print("Number of keys after clearing: " + points.size());
    
        }
    
        public static String pointAsString(Point p) {
            return "[" + p.x + "," + p.y + "]";
        }
    
        public static void print(String s) {
            System.out.println(s);
        }
    }
    

    Coordinates of x1: [0,0]
    Key x1 exists? true
    Key x1 exists? false
    Value (0,0) exists? true
    Value (1,2) exists? false
    x1 = [-1,-1]
    x2 = [0,5]
    x3 = [5,5]
    x4 = [5,0]
    Number of keys: 4
    Number of keys after clearing: 0
    

    [Try the above code on Repl.it]

    The class given below keeps track of how many people signup to attend an event on each day of the week. Add the missing methods so that it produces the output given.

    💡 Use an HashMap to store the number of entries for each day.

    public class Main {
        private static HashMap<String, Integer> roster = new HashMap<>();
    
        //TODO: add your methods here
    
        public static void main(String[] args) {
            addToRoster("Monday"); // i.e., one person signed up for Monday
            addToRoster("Wednesday"); // i.e., one person signed up for Wednesday
            addToRoster("Wednesday"); // i.e., another person signed up for Wednesday
            addToRoster("Friday");
            addToRoster("Monday");
            printRoster();
        }
    
    }
    

    Monday => 2
    Friday => 1
    Wednesday => 2
    

    Partial solution:

    import java.util.HashMap;
    import java.util.Map;
    
    public class Main {
        private static HashMap<String, Integer> roster = new HashMap<>();
    
        private static void addToRoster(String day) {
            if (roster.containsKey(day)){
                Integer newValue = Integer.valueOf(roster.get(day).intValue() + 1);
                roster.put(day, newValue);
            } else {
                roster.put(day, Integer.valueOf(1));
            }
        }
    
        // ...
    }
    
    W4.8 Can use Java enumerations W4.8a Can explain the meaning of enumerations

    Paradigms → Object Oriented Programming → Classes →

    Enumerations

    An Enumeration is a fixed set of values that can be considered as a data type. An enumeration is often useful when using a regular data type such as int or String would allow invalid values to be assigned to a variable. You are recommended to enumeration types any time you need to represent a fixed set of constants.

    Suppose you want a variable to store the priority of something. There are only three priority levels: high, medium, and low. You can declare the variable as of type int and use only values 2, 1, and 0 to indication the three priority levels. However, this opens the possibility of an invalid values such as 9 to be assigned to it. But if you define an enumeration type called Priority that has three values HIGH, MEDIUM, LOW only, a variable of type Priority will never be assigned an invalid value because the compiler is able to catch such an error.

    Priority: HIGH, MEDIUM, LOW


    Evidence:

    Show (in UML notation) an enumeration called WeekDay to use when the value can only be Monday ... Friday.

    W4.8b Can use Java enumerations

    Tools → Java →

    Enums

    You can define an enum type by using the enum keyword. Because they are constants, the names of an enum type's fields are in uppercase letters e.g., FLAG_SUCCESS.

    Defining an enumeration to represent days of a week (code to be put in the Day.java file):

    public enum Day {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
        THURSDAY, FRIDAY, SATURDAY
    }
    

    Some examples of using the Day enumeration defined above:

    Day today = Day.MONDAY;
    Day[] holidays = new Day[]{Day.SATURDAY, Day.SUNDAY};
    
    switch (today) {
    case SATURDAY:
    case SUNDAY:
        System.out.println("It's the weekend");
        break;
    default:
        System.out.println("It's a week day");
    }
    

    Note that while enumerations are usually a simple set of fixed values, Java enumerations can have behaviors too, as explained in this tutorial from -- Java Tutorial

    Define an enumeration named Priority. Add the missing describe method to the code below so that it produces the output given.

    public class Main {
    
        // Add your method here
    
        public static void main(String[] args) {
            describe("Red", Priority.HIGH);
            describe("Orange", Priority.MEDIUM);
            describe("Blue", Priority.MEDIUM);
            describe("Green", Priority.LOW);
        }
    }
    

    Red indicates high priority
    Orange indicates medium priority
    Blue indicates medium priority
    Green indicates low priority
    

    Use a switch statement to select between possible values for Priority.

        public static void describe(String color, Priority p) {
            switch (p) {
                case LOW:
                    System.out.println(color + " indicates low priority");
                    break;
                // ...
            }
        }
    

    Code for the enumeration is given below:

    public enum Priority {
        HIGH, MEDIUM, LOW
    }
    

    Evidence:

    Acceptable: Any code you have written that uses Java enumerations.

    Suggested: The exercise in AddressBook-Level1: LO-Enums

    Submission: Show your code during tutorial

    Project Management

    W4.9 Can create PRs on GitHub W4.9a Can explain branching

    Project Management → Revision Control →

    Branching

    Branching is the process of evolving multiple versions of the software in parallel. For example, one team member can create a new branch and add an experimental feature to it while the rest of the team keeps working on another branch. Branches can be given names e.g. master, release, dev.

    A branch can be merged into another branch. Merging usually result in a new commit that represents the changes done in the branch being merged.

    Branching and merging

    Merge conflicts happen when you try to merge two branches that had changed the same part of the code and the RCS software cannot decide which changes to keep. In those cases we have to ‘resolve’ those conflicts manually.

    In the context of RCS, what is the branching? What is the need for branching?.

    In the context of RCS, what is the merging branches? How can it lead to merge conflicts?.


    Evidence:

    In the context of RCS, what is the branching? What is the need for branching?.

    In the context of RCS, what is the merging branches? How can it lead to merge conflicts?.

    W4.9b Can use Git branching

    Tools → Git and GitHub →

    Branch

    0. Observe that you are normally in the branch called master. For this, you can take any repo you have on your computer (e.g. a clone of the samplerepo-things).


    git status
    

    on branch master
    

    1. Start a branch named feature1 and switch to the new branch.

    Click on the Branch button on the main menu. In the next dialog, enter the branch name and click Create Branch

    Note how the feature1 is indicated as the current branch.


    You can use the branch command to create a new branch and the checkout command to switch to a specific branch.

    git branch feature1
    git checkout feature1
    

    One-step shortcut to create a branch and switch to it at the same time:

    git checkout –b feature1
    

    2. Create some commits in the new branch. Just commit as per normal. Commits you add while on a certain branch will become part of that branch.

    3. Switch to the master branch. Note how the changes you did in the feature1 branch are no longer in the working directory.

    Double-click the master branch


    git checkout master
    

    4. Add a commit to the master branch. Let’s imagine it’s a bug fix.

    5. Switch back to the feature1 branch (similar to step 3).

    6. Merge the master branch to the feature1 branch, giving an end-result like the below. Also note how Git has created a merge commit.

    Right-click on the master branch and choose merge master into the current branch. Click OK in the next dialog.


    git merge master
    

    Observe how the changes you did in the master branch (i.e. the imaginary bug fix) is now available even when you are in the feature1 branch.

    7. Add another commit to the feature1 branch.

    8. Switch to the master branch and add one more commit.

    9. Merge feature1 to the master branch, giving and end-result like this:

    Right-click on the feature1 branch and choose Merge....


    git merge feature1
    

    10. Create a new branch called add-countries, switch to it, and add some commits to it (similar to steps 1-2 above). You should have something like this now:

    11. Go back to the master branch and merge the add-countries branch onto the master branch (similar to steps 8-9 above). While you might expect to see something like the below,

    ... you are likely to see something like this instead:

    That is because Git does a fast forward merge if possible. Seeing that the master branch has not changed since you started the add-countries branch, Git has decided it is simpler to just put the commits of the add-countries branch in front of the master branch, without going into the trouble of creating an extra merge commit.

    It is possible to force Git to create a merge commit even if fast forwarding is possible.

    Tick the box shown below when you merge a branch:


    Use the --no-ff switch (short for no fast forward):

    git merge --no-ff add-countries
    


    Evidence:

    Acceptable: Git branches you have created in any repo.

    Suggested: Results of following the steps in the LO.

    Submission: Show your branches during the tutorial.

    W4.9c Can create PRs on GitHub

    Tools → Git and GitHub →

    Create PRs

    1. Fork the samplerepo-pr-practice onto your GitHub account. Clone it onto your computer.

    2. Create a branch named add-intro in your clone. Add a couple of commits which adds/modifies an Introduction section to the README.md. Example:

    
    # Introduction
    Creating Pull Requsts (PRs) is needed when using RCS in a multi-person projects.
    This repo can be used to practice creating PRs.
    
    

    3. Push the add-intro branch to your fork.


    git push origin add-intro
    

    4. Create a Pull Request from the add-intro branch in your fork to the master branch of the same fork (i.e. your-user-name/samplerepo-pr-practice, not se-edu/samplerepo-pr-practice), as described below.

    4a. Go to the GitHub page of your fork (i.e. https://github.com/{your_username}/samplerepo-pr-practice), click on the Pull Requests tab, and then click on New Pull Request button.

    4b. Select base fork and head fork as follows:

    • base fork: your own fork (i.e. {your user name}/samplerepo-pr-practice, NOT se-edu/samplerepo-pr-practice)
    • head fork: your own fork.

    The base fork is where changes should be applied. The head fork contains the changes you would like to be applied.

    4c. (1) Set the base branch to master and head branch to add-intro, (2) confirm the diff contains the changes you propose to merge in this PR (i.e. confirm that you did not accidentally include extra commits in the branch), and (3) click the Create pull request button.

    4d. (1) Set PR name, (2) set PR description, and (3) Click the Create pull request button.

    A common newbie mistake when creating branch-based PRs is to mix commits of one PR with another. To learn how to avoid that mistake, you are encouraged to continue and create another PR as explained below.

    5. In your local repo, create a new branch add-summary off the master branch.

    When creating the new branch, it is very important that you switch back to the master branch first. If not, the new branch will be created off the current branch add-intro. And that is how you end up having commits of the first PR in the second PR as well.

    6. Add a commit in the add-summary branch that adds a Summary section to the README.md, in exactly the same place you added the Introduction section earlier.

    7. Push the add-summary to your fork and create a new PR similar to before.


    Evidence:

    Acceptable: PRs created in any repo.

    Suggested: PRs created by following the steps in the LO.

    Submission: Show your PRs during the tutorial.

    🅿️ Project

    W4.10 Can define requirements of a product

    Covered by:

    Tutorial 4

    In this week's tutorial we would like to ensure that,

    1. All students are able to create branch-based PRs without accidentally mixing commits between PRs (a common mistake)
    2. At least some members of the team are able to resolve merge conflicts and merge PRs

    Reason: These two skills are going to be essential for you in future weeks because most of your work will require creating PRs.

    Therefore, we strongly encourage you to achieve the Can create PRs on GitHub before coming to the tutorial. If not, you'll have to do it during the tutorial and then there will be less time for you to do the other activities we have planned for this tutorial

    Within your team

    • Discuss the product(s) you surveyed and its shortcomings with reference to your targeted user group (if you haven't already done that)

    Explain to the other team

    • What is the user profile your team has chosen?

    • This week we don't join teams during the initial discussions; work with your own team members and prepare for the upcoming peer review in week 6. (Be mindful of the interaction within and outside the team.)


    As before, discuss evidence of achieving LOs as directed by the tutor.
    For W4.1a Can explain testing
    Details of the LO

    Quality Assurance → Testing → Introduction →

    What

    Testing: Testing is operating a system or component under specified conditions, observing or recording the results, and making an evaluation of some aspect of the system or component. –- source: IEEE

    When testing, we execute a set of test cases. A test case specifies how to perform a test. At a minimum, it specifies the input to the software under test (SUT) and the expected behavior.

    Example: A minimal test case for testing a browser:

    • Input – Start the browser using a blank page (vertical scrollbar disabled). Then, load longfile.html located in the test data folder.
    • Expected behavior – The scrollbar should be automatically enabled upon loading longfile.html.

    Test cases can be determined based on the specification, reviewing similar existing systems, or comparing to the past behavior of the SUT.

    A more elaborate test case can have other details such as those given below.

    • A unique identifier : e.g. TC0034-a
    • A descriptive name: e.g. vertical scrollbar activation for long web pages
    • Objectives: e.g. to check whether the vertical scrollbar is correctly activated when a long web page is loaded to the browser
    • Classification information: e.g. priority - medium, category - UI features
    • Cleanup, if any: e.g. empty the browser cache.

    For each test case we do the following:

    1. Feed the input to the SUT
    2. Observe the actual output
    3. Compare actual output with the expected output

    A test case failure is a mismatch between the expected behavior and the actual behavior. A failure is caused by a defect (or a bug).

    Example: In the browser example above, a test case failure is implied if the scrollbar remains disabled after loading longfile.html. The defect/bug causing that failure could be an uninitialized variable.

    Here is another definition of testing:

    Software testing consists of the dynamic verification that a program provides expected behaviors on a finite set of test cases, suitably selected from the usually infinite execution domain. -– source: Software Engineering Book of Knowledge V3

    Some things to note (indicated by keywords in the above definition):

    • Dynamic: Testing involves executing the software. It is not by examining the code statically.
    • Finite: In most non-trivial cases there are potentially infinite test scenarios but resource constraints dictate that we can test only a finite number of scenarios.
    • Selected: In most cases it is not possible to test all scenarios. That means we need to select what scenarios to test.
    • Expected: Testing requires some knowledge of how the software is expected to behave.

    Explain how the concepts of testing, test case, test failure, and defect are related to each other.



    Evidence:

    Explain how the concepts of testing, test case, test failure, and defect are related to each other.

    For W4.1b Can explain regression testing
    Details of the LO

    Quality Assurance → Testing → Regression Testing →

    What

    When we modify a system, the modification may result in some unintended and undesirable effects on the system. Such an effect is called a regression.

    Regression testing is re-testing the software to detect regressions. Note that to detect regressions, we need to retest all related components, even if they were tested before.

    Regression testing is more effective when it is done frequently, after each small change. However, doing so can be prohibitively expensive if testing is done manually. Hence, regression testing is more practical when it is automated.

    Regression testing is the automated re-testing of a software after it has been modified.

    c.

    Explanation: Regression testing need not be automated but automation is highly recommended.

    Explain why and when you would do regression testing in a software project.



    Evidence:

    Explain why and when you would do regression testing in a software project.

    For W4.1d Can semi-automate testing of CLIs
    Details of the LO

    Quality Assurance → Testing → Test Automation →

    Automated Testing of CLI Apps

    A simple way to semi-automate testing of a CLI(Command Line Interface) app is by using input/output re-direction.

    • First, we feed the app with a sequence of test inputs that is stored in a file while redirecting the output to another file.
    • Next, we compare the actual output file with another file containing the expected output.

    Let us assume we are testing a CLI app called AddressBook. Here are the detailed steps:

    1. Store the test input in the text file input.txt.

      add Valid Name p/12345 valid@email.butNoPrefix
      add Valid Name 12345 e/valid@email.butPhonePrefixMissing
      
    2. Store the output we expect from the SUT in another text file expected.txt.

      Command: || [add Valid Name p/12345 valid@email.butNoPrefix]
      Invalid command format: add 
      
      Command: || [add Valid Name 12345 e/valid@email.butPhonePrefixMissing]
      Invalid command format: add 
      
    3. Run the program as given below, which will redirect the text in input.txt as the input to AddressBook and similarly, will redirect the output of AddressBook to a text file output.txt. Note that this does not require any code changes to AddressBook.

      java AddressBook < input.txt > output.txt
      
      • 💡 The way to run a CLI program differs based on the language.
        e.g., In Python, assuming the code is in AddressBook.py file, use the command
        python AddressBook.py < input.txt > output.txt

      • 💡 If you are using Windows, use a normal command window to run the app, not a Power Shell window.

      More on the > operator and the < operator. tangential

      A CLI program takes input from the keyboard and outputs to the console. That is because those two are default input and output streams, respectively. But you can change that behavior using < and > operators. For example, if you run AddressBook in a command window, the output will be shown in the console, but if you run it like this,

      java AddressBook > output.txt 
      

      the Operating System then creates a file output.txt and stores the output in that file instead of displaying it in the console. No file I/O coding is required. Similarly, adding < input.txt (or any other filename) makes the OS redirect the contents of the file as input to the program, as if the user typed the content of the file one line at a time.

      Resources:

    4. Next, we compare output.txt with the expected.txt. This can be done using a utility such as Windows FC (i.e. File Compare) command, Unix diff command, or a GUI tool such as WinMerge.

      FC output.txt expected.txt
      

    Note that the above technique is only suitable when testing CLI apps, and only if the exact output can be predetermined. If the output varies from one run to the other (e.g. it contains a time stamp), this technique will not work. In those cases we need more sophisticated ways of automating tests.

    CLI App: An application that has a Command Line Interface. i.e. user interacts with the app by typing in commands.



    Evidence:

    Acceptable: Any project where you use the I/O redirection method to test a CLI.

    Suggested: Do the exercise given in AddressBook - Level1 : LO-AutomatedCliTesting

    Submission: Demo the test during the tutorial.

    For W4.4c Can write simple user stories
    Details of the LO

    Requirements → Specifying Requirements → User Stories →

    Introduction

    User story: User stories are short, simple descriptions of a feature told from the perspective of the person who desires the new capability, usually a user or customer of the system. [Mike Cohn]

    A common format for writing user stories is:

    User story format: As a {user type/role} I can {function} so that {benefit}

    Examples (from a Learning Management System):

    1. As a student, I can download files uploaded by lecturers, so that I can get my own copy of the files
    2. As a lecturer, I can create discussion forums, so that students can discuss things online
    3. As a tutor, I can print attendance sheets, so that I can take attendance during the class

    We can write user stories on index cards or sticky notes, and arrange on walls or tables, to facilitate planning and discussion. Alternatively, we can use a software (e.g., GitHub Project Boards, Trello, Google Docs, ...) to manage user stories digitally.

    [credit: https://www.flickr.com/photos/jakuza/2682466984/]

    [credit: https://www.flickr.com/photos/jakuza/with/2726048607/]

    [credit: https://commons.wikimedia.org/wiki/File:User_Story_Map_in_Action.png]

    • a. They are based on stories users tell about similar systems
    • b. They are written from the user/customer perspective
    • c. They are always written in some physical medium such as index cards or sticky notes
    • a. Reason: Despite the name, user stories are not related to 'stories' about the software.
    • b.
    • c. Reason: It is possible to use software to record user stories. When the team members are not co-located this may be the only option.

    Critique the following user story taken from a software project to build an e-commerce website.

    As a developer, I want to use Python to implement the software, so that we can resue existing Python modules.

    Refer to the definition of a user story.

    User story: User stories are short, simple descriptions of a feature told from the perspective of the person who desires the new capability, usually a user or customer of the system. [Mike Cohn]

    This user story is not written from the perspective of the user/customer.

    Bill wants you to build a Human Resource Management (HRM) system. He mentions that the system will help employees to view their own leave balance. What are the user stories you can extract from that statement?

    Remember to follow the correct format when writing user stories.

    User story format: As a {user type/role} I can {function} so that {benefit}

    As an employee, I can view my leave balance, so that I can know how many leave days I have left.

    Note: the {benefit} part may vary as it is not specifically mentioned in the question.



    Evidence:

    Acceptable: Using user stories in any past project.

    Suggested: Do the exercise in [Addressbook-Level3: LO-UesrStories]

    Submission: Create a PR against Addressbook-Level3. Remember to use team ID (e.g. W09-2) in your PR name.

    For W4.4e Can use user stories to manage requirements of project
    Details of the LO

    Requirements → Specifying Requirements → User Stories →

    Usage

    User stories capture user requirements in a way that is convenient for scoping, estimation and scheduling.

    [User stories] strongly shift the focus from writing about features to discussing them. In fact, these discussions are more important than whatever text is written. [Mike Cohn, MountainGoat Software 🔗]

    User stories differ from traditional requirements specifications mainly in the level of detail. User stories should only provide enough details to make a reasonably low risk estimate of how long the user story will take to implement. When the time comes to implement the user story, the developers will meet with the customer face-to-face to work out a more detailed description of the requirements. [more...]

    User stories can capture non-functional requirements too because even NFRs must benefit some stakeholder.

    An example of a NFR captured as a user story:

    As a I want to so that
    impatient user to be able experience reasonable response time from the website while up to 1000 concurrent users are using it I can use the app even when the traffic is at the maximum expected level

    Given their lightweight nature, user stories are quite handy for recording requirements during early stages of requirements gathering.

    💡 Here are some tips for using user stories for early stages of requirement gathering:

    • Define the target user:
      Decide your target user's profile (e.g. a student, office worker, programmer, sales person) and work patterns (e.g. Does he work in groups or alone? Does he share his computer with others?). A clear understanding of the target user will help when deciding the importance of a user story. You can even give this user a name.  e.g. Target user Jean is a university student studying in a non-IT field. She interacts with a lot of people due to her involvement in university clubs/societies. ...
    • Define the problem scope: Decide that exact problem you are going to solve for the target user.  e.g. Help Jean keep track of all her school contacts
    • Don't be too hasty to discard 'unusual' user stories:
      Those might make your product unique and stand out from the rest, at least for the target users.
    • Don't go into too much details:
      For example, consider this user story: As a user, I want to see a list of tasks that needs my attention most at the present time, so that I pay attention to them first.
      When discussing this user story, don't worry about what tasks should be considered needs my attention most at the present time. Those details can be worked out later.
    • Don't be biased by preconceived product ideas:
      When you are at the stage of identifying user needs, clear your mind of ideas you have about what your end product will look like.
    • Don't discuss implementation details or whether you are actually going to implement it:
      When gathering requirements, your decision is whether the user's need is important enough for you to want to fulfil it. Implementation details can be discussed later. If a user story turns out to be too difficult to implement later, you can always omit it from the implementation plan.

    While use cases can be recorded on physical paper in the initial stages, an online tool is more suitable for longer-term management of user stories, especially if the team is not co-located.

    You can create issues for each of the user stories and use a GitHub Project Board to sort them into categories.

    Example Project Board:

    Example Issue to represent a user story:

    A video on GitHub Project Boards:


    Example Google Sheet for recording user stories:


    Example Trello Board for recording user stories:


    eXtreme Programming (XP)

    Extreme programming (XP) is a software development methodology which is intended to improve software quality and responsiveness to changing customer requirements. As a type of agile software development, it advocates frequent "releases" in short development cycles, which is intended to improve productivity and introduce checkpoints at which new customer requirements can be adopted. [wikipedia, 2017.05.01]

    uses User stories to capture requirements.

    This page in their website explains the difference between user stories and traditional requirements.

    One of the biggest misunderstandings with user stories is how they differ from traditional requirements specifications. The biggest difference is in the level of detail. User stories should only provide enough detail to make a reasonably low risk estimate of how long the story will take to implement. When the time comes to implement the story developers will go to the customer and receive a detailed description of the requirements face to face.



    Evidence:

    Covered by the final project.

    For W4.4h Can specify details of a use case in a structured format
    Details of the LO

    Requirements → Specifying Requirements → Use Cases →

    Details

    Writing use case steps

    The main body of the use case is the sequence of steps that describes the interaction between the system and the actors. Each step is given as a simple statement describing who does what.

    An example of the main body of a use case.

    1. Student requests to upload file
    2. LMS requests for the file location
    3. Student specifies the file location
    4. LMS uploads the file

    A use case describes only the externally visible behavior, not internal details, of a system i.e. should not mention give details that are not part of the interaction between the user and the system.

    This example use case step refers to behaviors not externally visible .

    1. LMS saves the file into the cache and indicates success.

    A step gives the intention of the actor (not the mechanics). That means UI details are usually omitted. The idea is to leave as much flexibility to the UI designer as possible. That is, the use case specification should be as general as possible (less specific) about the UI.

    The first example below is not a good use case step because contains UI-specific details. The second one is better because it omits UI-specific details.

    Bad : User right-clicks the text box and chooses ‘clear’

    Good : User clears the input

    A use case description can show loops too.

    An example of how you can show a loop:

    Software System: Square game Use case: UC02 - Play a Game Actors: Player (multiple players)

    1. A Player starts the game.
    2. SquareGame asks for player names.
    3. Each Player enters his own name.
    4. SquareGame shows the order of play.
    5. SquareGame prompts for the current Player to throw die.
    6. Current Player adjusts the throw speed.
    7. Current Player triggers the die throw.
    8. Square Game shows the face value of the die.
    9. Square Game moves the Player's piece accordingly.
      Steps 5-9 are repeated for each Player, and for as many rounds as required until a Player reaches the 100th square.
    10. Square Game shows the Winner.

      Use case ends.

    The Main Success Scenario (MSS) describes the most straightforward interaction for a given use case, which assumes that nothing goes wrong. This is also called the Basic Course of Action or the Main Flow of Events of a use case.

    • System: Online Banking System (OBS)
    • Use case: UC23 - Transfer Money
    • Actor: User
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details of the transfer.
      3. User enters the requested details.
      4. OBS requests for confirmation.
      5. OBS transfers the money and displays the new account balance.
      6. Use case ends.

    Note how the MSS assumes that all entered details are correct and ignores problems such as timeouts, network outages etc. Fro example, MSS does not tell us what happens if the user enters an incorrect data.

    Extensions are "add-on"s to the MSS that describe exceptional/alternative flow of events. They describe variations of the scenario that can happen if certain things are not as expected by the MSS. Extensions appear below the MSS.

    This example adds some extensions to the use case in the previous example.

    • System: Online Banking System (OBS)
    • Use case: UC23 - Transfer Money
    • Actor: User
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details of the transfer.
      3. User enters the requested details.
      4. OBS requests for confirmation.
      5. OBS transfers the money and displays the new account balance.
      6. Use case ends.

    • Extensions:
      1. 3a. OBS detects an error in the entered data.
        1. 3a1. OBS requests for the correct data.
        2. 3a2. User enters new data.
        3. Steps 3a1-3a2 are repeated until the data entered are correct.
        4. Use case resumes from step 4.

      2. 3b. User requests to effect the transfer in a future date.
        1. 3b1. OBS requests for confirmation.
        2. 3b2. User confirms future transfer.
        3. Use case ends.

      3. *a. At any time, User chooses to cancel the transfer.
        1. *a1. OBS requests to confirm the cancellation.
        2. *a2. User confirms the cancellation.
        3. Use case ends.

      4. *b. At any time, 120 seconds lapse without any input from the User.
        1. *b1. OBS cancels the transfer.
        2. *b2. OBS informs the User of the cancellation.
        3. Use case ends.

    Note that the numbering style is not a universal rule but a widely used convention. Based on that convention,

    • either of the extensions marked 3a. and 3b. can happen just after step 3 of the MSS.
    • the extension marked as *a. can happen at any step (hence, the *).

    When separating extensions from the MSS, keep in mind that the MSS should be self-contained. That is, the MSS should give us a complete usage scenario.

    Also note that it is not useful to mention events such as power failures or system crashes as extensions because the system cannot function beyond such catastrophic failures.

    In use case diagrams you can use the <<extend>> arrows to show extensions. Note the direction of the arrow is from the extension to the use case it extends and the arrow uses a dashed line.

    A use case can include another use case. Underlined text is commonly used to show an inclusion of a use case.

    This use case includes two other use cases, one in step 1 and one in step 2.

    • Software System: LearnSys
    • Use case: UC01 - Conduct Survey
    • Actors: Staff, Student
    • MSS:
      1. Staff creates the survey (UC44).
      2. Student completes the survey (UC50).
      3. Staff views the survey results.
        Use case ends.

    Inclusions are useful,

    • when you don't want to clutter a use case with too many low-level steps.
    • when a set of steps is repeated in multiple use cases.

    We use a dotted arrow and a <<include>> annotation to show use case inclusions in a use case diagram. Note how the arrow direction is different from the <<extend>> arrows.

    Preconditions specify the specific state we expect the system to be in before the use case starts.

    • Software System: Online Banking System
    • Use case: UC23 - Transfer Money
    • Actor: User
    • Preconditions: User is logged in.
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details for the transfer.
      3. ...

    Guarantees specify what the use case promises to give us at the end of its operation.

    • Software System: Online Banking System
    • Use case: UC23 - Transfer Money
    • Actor: User
    • Preconditions: User is logged in.
    • Guarantees:
      • Money will be deducted from the source account only if the transfer to the destination account is successful
      • The transfer will not result in the account balance going below the minimum balance required.
    • MSS:
      1. User chooses to transfer money.
      2. OBS requests for details for the transfer.
      3. ...

    Complete the following use case (MSS, extensions, etc.). Note that you should not blindly follow how the existing EZ-Link machine operates because it will prevent you from designing a better system. You should consider all possible extensions without complicating the use case too much.

    • System: EZ-Link machine
    • Use case: UC2 top-up EZ-Link card
    • Actor: EZ-Link card user
    • System: EZ-Link machine (those found at MRTs)
    • Use case: UC2 top-up EZ-Link card
    • Actor: EZ-Link card user
    • Preconditions: All hardware in working order.
    • Guarantees: MSS → the card will be topped-up.
    • MSS:
      1. User places the card on the reader.
      2. System displays card details and prompts for desired action.
      3. User selects top-up.
      4. System requests for top-up details (amount, payment option, receipt required?).
      5. User enters details.
      6. System processes cash payment (UC02) or NETS payment (UC03).
      7. System updates the card value.
      8. System indicates transaction as completed.
      9. If requested in step 5, system prints receipt.
      10. User removes the card.
      11. Use case ends.
    • Extensions:
      1. *a. User removed card or other hardware error detected.
        1. *a1. System indicates the transaction has been aborted.
        2. Use case ends.

    Notes:

    • We assume that the only way to cancel a transaction is by removing the card.
    • By not breaking step 4 into further steps, we avoid committing to a particular mechanism to enter data. For example, we are free to accept all data in one screen.
    • In step 5, we assume that the input mechanism does not allow any incorrect data.
    • System: EZ-Link machine
    • Use case: UC03 process NETS payment
    • Actor: EZ-Link card user
    • Preconditions: A transaction requiring payment is underway.
    • Guarantees: MSS → Transaction amount is transferred from user account to EZ-Link company account.
    • MSS:
      1. System requests to insert ATM card.
      2. User inserts the ATM card.
      3. System requests for PIN.
      4. User enters PIN.
      5. System reports success.
      6. Use case ends.
    • Extensions:
      1. 2a. Unacceptable ATM card (damaged or inserted wrong side up).
        1. ...
      2. 4a. Wrong PIN.
        1. ...
      3. 4b. Insufficient funds.
        1. ...
      4. *a. Connection to the NETS gateway is disrupted.
        1. ...

    Note: UC02 can be written along similar lines.

    Complete the following use case (MSS, extensions, etc.).

    • System: LearnSys (an online Learning Management System)
    • Use case: UC01 reply to post in the forum
    • Actor: Student
    • System: LearnSys
    • Use case: UC01 reply to post in the forum
    • Actor: Student
    • Preconditions: Student is logged in and has permission to post in the forum. The post to which the Student replies already exists.
    • MSS:
      1. Student chooses to reply to an existing post.
      2. LearnSys requests the user to enter post details.
      3. Student enters post details.
      4. Student submits the post.
      5. LearnSys displays the post.
      6. Use case ends.
    • Extensions:
      1. *a. Internet connection goes down.
        1. ...
      2. *b. LearnSys times out
        1. ...
      3. 3a. Student chooses to ‘preview’ the post.
        1. 3a1. LearnSys shows a preview.
        2. 3a2. User chooses to go back to editing.
        3. Use case resumes at step 3.
      4. 3b. Student chooses to attach picture/file
        1. ...
      5. 3c. Student chooses to save the post as a draft.
        1. 3c1. LearnSys confirms draft has been saved.
        2. Use case ends.
      6. 3d. Student chooses to abort the operation.
        1. ...
      7. 4a. The post being replied to is deleted by the owner while the reply is being entered.
        1. ...
      8. 4b. Unacceptable data entered.
        1. ...

    Which of these cannot appear as part of a use case description?

    • a. Use case identifier
    • b. Preconditions
    • c. Guarantees
    • d. References to another use case
    • e. Main Success Scenario
    • f. Performance requirements
    • g. Extensions
    • h. Inclusions

    (f)

    Explanation: Performance requirements are non-functional requirements. They are not captured in use cases.

    Identify problems with this use case description.

    • System: EZ-Link machine (those found at MRTs)
    • Use case: UC2 top-up EZ-Link card
    • Actor: EZ-Link card user
    • Preconditions: All hardware in working order.
    • Guarantees: If MSS completes at least until step 7, the card will be topped-up.
    • MSS:
      1. User places the card on the reader.
      2. System displays card details and prompts for desired action.
      3. User selects top-up.
      4. System requests for top-up details (amount, payment option, receipt required?).
      5. User enters details.
      6. System processes cash payment (UC02) or NETS payment (UC03).
      7. System updates the card value.
      8. System indicates transaction as completed.
      9. If requested in step 5, system prints receipt.
      10. User removes the card.
      11. Use case ends.
    • Extensions:
      1. *a. User removed card or other hardware error detected.
        1. *a1. System indicates the transaction has been aborted.
        2. Use case ends.
    • a. It does not consider ‘system crash’ scenario.
    • b. It does not contain enough UI details.
    • c. The extension given is in fact an inclusion.
    • d. No post conditions are given.
    • e. ‘Use case ends’ is duplicated.

    None.

    Explanation: Catastrophic failures such as ‘system crash’ need not be included in a use case. A use case is not supposed to contain UI details. Post conditions are optional. It is not a problem to have multiple exit points for a use case.



    Evidence:

    Suggested: Do the exercise in [Addressbook-Level3: LO-UseCases]

    Submission: Create a PR against Addressbook-Level3. Remember to use team ID (e.g. W09-2) in your PR name.

    For W4.7a Can explain the Collections framework
    Details of the LO

    C++ to Java → Collections →

    The Collections Framework

    This section uses extracts from the -- Java Tutorial, with some adaptations.

    A collection — sometimes called a container — is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data.

    Typically, collections represent data items that form a natural group, such as a poker hand (a collection of cards), a mail folder (a collection of letters), or a telephone directory (a mapping of names to phone numbers).

    The collections framework is a unified architecture for representing and manipulating collections. It contains the following:

    • Interfaces: These are abstract data types that represent collections. Interfaces allow collections to be manipulated independently of the details of their representation.
      Example: the List<E> interface can be used to manipulate list-like collections which may be implemented in different ways such as ArrayList<E> or LinkedList<E>.

    • Implementations: These are the concrete implementations of the collection interfaces. In essence, they are reusable data structures.
      Example: the ArrayList<E> class implements the List<E> interface while the HashMap<K, V> class implements the Map<K, V> interface.

    • Algorithms: These are the methods that perform useful computations, such as searching and sorting, on objects that implement collection interfaces. The algorithms are said to be polymorphic: that is, the same method can be used on many different implementations of the appropriate collection interface.
      Example: the sort(List<E>) method can sort a collection that implements the List<E> interface.

    A well-known example of collections frameworks is the C++ Standard Template Library (STL). Although both are collections frameworks and the syntax look similar, note that there are important philosophical and implementation differences between the two.

    The following list describes the core collection interfaces:

    • Collection — the root of the collection hierarchy. A collection represents a group of objects known as its elements. The Collection interface is the least common denominator that all collections implement and is used to pass collections around and to manipulate them when maximum generality is desired. Some types of collections allow duplicate elements, and others do not. Some are ordered and others are unordered. The Java platform doesn't provide any direct implementations of this interface but provides implementations of more specific subinterfaces, such as Set and List. Also see the Collection API.

    • Set — a collection that cannot contain duplicate elements. This interface models the mathematical set abstraction and is used to represent sets, such as the cards comprising a poker hand, the courses making up a student's schedule, or the processes running on a machine. Also see the Set API.

    • List — an ordered collection (sometimes called a sequence). Lists can contain duplicate elements. The user of a List generally has precise control over where in the list each element is inserted and can access elements by their integer index (position). Also see the List API.

    • Queue — a collection used to hold multiple elements prior to processing. Besides basic Collection operations, a Queue provides additional insertion, extraction, and inspection operations. Also see the Queue API.

    • Map — an object that maps keys to values. A Map cannot contain duplicate keys; each key can map to at most one value. Also see the Map API.

    • Others: Deque, SortedSet, SortedMap



    Evidence:

    Acceptable: Some code that you have written that uses some Java Collection classes.

    Suggested: Do the exercise given in AddressBook - Level1 : LO-Collections

    Submission: Show your code to the tutor during the tutorial.

    For W4.8a Can explain the meaning of enumerations
    Details of the LO

    Paradigms → Object Oriented Programming → Classes →

    Enumerations

    An Enumeration is a fixed set of values that can be considered as a data type. An enumeration is often useful when using a regular data type such as int or String would allow invalid values to be assigned to a variable. You are recommended to enumeration types any time you need to represent a fixed set of constants.

    Suppose you want a variable to store the priority of something. There are only three priority levels: high, medium, and low. You can declare the variable as of type int and use only values 2, 1, and 0 to indication the three priority levels. However, this opens the possibility of an invalid values such as 9 to be assigned to it. But if you define an enumeration type called Priority that has three values HIGH, MEDIUM, LOW only, a variable of type Priority will never be assigned an invalid value because the compiler is able to catch such an error.

    Priority: HIGH, MEDIUM, LOW



    Evidence:

    Show (in UML notation) an enumeration called WeekDay to use when the value can only be Monday ... Friday.

    For W4.8b Can use Java enumerations
    Details of the LO

    Tools → Java →

    Enums

    You can define an enum type by using the enum keyword. Because they are constants, the names of an enum type's fields are in uppercase letters e.g., FLAG_SUCCESS.

    Defining an enumeration to represent days of a week (code to be put in the Day.java file):

    public enum Day {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
        THURSDAY, FRIDAY, SATURDAY
    }
    

    Some examples of using the Day enumeration defined above:

    Day today = Day.MONDAY;
    Day[] holidays = new Day[]{Day.SATURDAY, Day.SUNDAY};
    
    switch (today) {
    case SATURDAY:
    case SUNDAY:
        System.out.println("It's the weekend");
        break;
    default:
        System.out.println("It's a week day");
    }
    

    Note that while enumerations are usually a simple set of fixed values, Java enumerations can have behaviors too, as explained in this tutorial from -- Java Tutorial

    Define an enumeration named Priority. Add the missing describe method to the code below so that it produces the output given.

    public class Main {
    
        // Add your method here
    
        public static void main(String[] args) {
            describe("Red", Priority.HIGH);
            describe("Orange", Priority.MEDIUM);
            describe("Blue", Priority.MEDIUM);
            describe("Green", Priority.LOW);
        }
    }
    

    Red indicates high priority
    Orange indicates medium priority
    Blue indicates medium priority
    Green indicates low priority
    

    Use a switch statement to select between possible values for Priority.

        public static void describe(String color, Priority p) {
            switch (p) {
                case LOW:
                    System.out.println(color + " indicates low priority");
                    break;
                // ...
            }
        }
    

    Code for the enumeration is given below:

    public enum Priority {
        HIGH, MEDIUM, LOW
    }
    


    Evidence:

    Acceptable: Any code you have written that uses Java enumerations.

    Suggested: The exercise in AddressBook-Level1: LO-Enums

    Submission: Show your code during tutorial

    For W4.9a Can explain branching
    Details of the LO

    Project Management → Revision Control →

    Branching

    Branching is the process of evolving multiple versions of the software in parallel. For example, one team member can create a new branch and add an experimental feature to it while the rest of the team keeps working on another branch. Branches can be given names e.g. master, release, dev.

    A branch can be merged into another branch. Merging usually result in a new commit that represents the changes done in the branch being merged.

    Branching and merging

    Merge conflicts happen when you try to merge two branches that had changed the same part of the code and the RCS software cannot decide which changes to keep. In those cases we have to ‘resolve’ those conflicts manually.

    In the context of RCS, what is the branching? What is the need for branching?.

    In the context of RCS, what is the merging branches? How can it lead to merge conflicts?.



    Evidence:

    In the context of RCS, what is the branching? What is the need for branching?.

    In the context of RCS, what is the merging branches? How can it lead to merge conflicts?.

    For W4.9b Can use Git branching
    Details of the LO

    Tools → Git and GitHub →

    Branch

    0. Observe that you are normally in the branch called master. For this, you can take any repo you have on your computer (e.g. a clone of the samplerepo-things).


    git status
    

    on branch master
    

    1. Start a branch named feature1 and switch to the new branch.

    Click on the Branch button on the main menu. In the next dialog, enter the branch name and click Create Branch

    Note how the feature1 is indicated as the current branch.


    You can use the branch command to create a new branch and the checkout command to switch to a specific branch.

    git branch feature1
    git checkout feature1
    

    One-step shortcut to create a branch and switch to it at the same time:

    git checkout –b feature1
    

    2. Create some commits in the new branch. Just commit as per normal. Commits you add while on a certain branch will become part of that branch.

    3. Switch to the master branch. Note how the changes you did in the feature1 branch are no longer in the working directory.

    Double-click the master branch


    git checkout master
    

    4. Add a commit to the master branch. Let’s imagine it’s a bug fix.

    5. Switch back to the feature1 branch (similar to step 3).

    6. Merge the master branch to the feature1 branch, giving an end-result like the below. Also note how Git has created a merge commit.

    Right-click on the master branch and choose merge master into the current branch. Click OK in the next dialog.


    git merge master
    

    Observe how the changes you did in the master branch (i.e. the imaginary bug fix) is now available even when you are in the feature1 branch.

    7. Add another commit to the feature1 branch.

    8. Switch to the master branch and add one more commit.

    9. Merge feature1 to the master branch, giving and end-result like this:

    Right-click on the feature1 branch and choose Merge....


    git merge feature1
    

    10. Create a new branch called add-countries, switch to it, and add some commits to it (similar to steps 1-2 above). You should have something like this now:

    11. Go back to the master branch and merge the add-countries branch onto the master branch (similar to steps 8-9 above). While you might expect to see something like the below,

    ... you are likely to see something like this instead:

    That is because Git does a fast forward merge if possible. Seeing that the master branch has not changed since you started the add-countries branch, Git has decided it is simpler to just put the commits of the add-countries branch in front of the master branch, without going into the trouble of creating an extra merge commit.

    It is possible to force Git to create a merge commit even if fast forwarding is possible.

    Tick the box shown below when you merge a branch:


    Use the --no-ff switch (short for no fast forward):

    git merge --no-ff add-countries
    



    Evidence:

    Acceptable: Git branches you have created in any repo.

    Suggested: Results of following the steps in the LO.

    Submission: Show your branches during the tutorial.

    For W4.9c Can create PRs on GitHub
    Details of the LO

    Tools → Git and GitHub →

    Create PRs

    1. Fork the samplerepo-pr-practice onto your GitHub account. Clone it onto your computer.

    2. Create a branch named add-intro in your clone. Add a couple of commits which adds/modifies an Introduction section to the README.md. Example:

    
    # Introduction
    Creating Pull Requsts (PRs) is needed when using RCS in a multi-person projects.
    This repo can be used to practice creating PRs.
    
    

    3. Push the add-intro branch to your fork.


    git push origin add-intro
    

    4. Create a Pull Request from the add-intro branch in your fork to the master branch of the same fork (i.e. your-user-name/samplerepo-pr-practice, not se-edu/samplerepo-pr-practice), as described below.

    4a. Go to the GitHub page of your fork (i.e. https://github.com/{your_username}/samplerepo-pr-practice), click on the Pull Requests tab, and then click on New Pull Request button.

    4b. Select base fork and head fork as follows:

    • base fork: your own fork (i.e. {your user name}/samplerepo-pr-practice, NOT se-edu/samplerepo-pr-practice)
    • head fork: your own fork.

    The base fork is where changes should be applied. The head fork contains the changes you would like to be applied.

    4c. (1) Set the base branch to master and head branch to add-intro, (2) confirm the diff contains the changes you propose to merge in this PR (i.e. confirm that you did not accidentally include extra commits in the branch), and (3) click the Create pull request button.

    4d. (1) Set PR name, (2) set PR description, and (3) Click the Create pull request button.

    A common newbie mistake when creating branch-based PRs is to mix commits of one PR with another. To learn how to avoid that mistake, you are encouraged to continue and create another PR as explained below.

    5. In your local repo, create a new branch add-summary off the master branch.

    When creating the new branch, it is very important that you switch back to the master branch first. If not, the new branch will be created off the current branch add-intro. And that is how you end up having commits of the first PR in the second PR as well.

    6. Add a commit in the add-summary branch that adds a Summary section to the README.md, in exactly the same place you added the Introduction section earlier.

    7. Push the add-summary to your fork and create a new PR similar to before.



    Evidence:

    Acceptable: PRs created in any repo.

    Suggested: PRs created by following the steps in the LO.

    Submission: Show your PRs during the tutorial.

    For W4.10 Can define requirements of a product

    Covered by:

    Lecture 4

    Slides: Uploaded on IVLE.