多媒体测试系统
 
STUDENT
 
FACULTY
 
SCHOOL
 
SUPPORT
 
PUBLIC
 
SIGNUP
DAILY QUIZ
 
     
  B U L L E T I N    B O A R D

643 Week 12/15 Outline: Human-Computer Interaction and Collaboration Programming

(Subject: Systems Analysis/Authored by: Liping Liu on 4/25/2024 4:00:00 AM)/Views: 2478
Blog    News    Post   

UI Design Principles: Character, Control, and Cognition (Chapter11 of Liu)

Character refers to the goal of creating aesthetic characteristics of GUIs, i.e., they must look good. This principle embodies at least two sub-aspects. First, each form or report (or web page) must be neat and clean with appropriate grouping of related information. It does not waste valuable screen spaces but at the same time, it does not look crowded. Second, across forms or reports (or web pages), there shows consistency in size, look, and location of controls such as labels, textboxes, buttons, etc.

Control refers to the goal of giving users a sense of self control when using the system, i.e., the users feel that they are in control of the system. This principle implies many sub principles. For example, after each user action, the system must provide feedback through words and signs, and users must be given option to reverse their action to go back to the previous state.

Cognition refers to the goal of helping users to overcome their limited cognitive capabilities when using the system. For example, users do not want to memorize and do not want to think, and so we should not design GUIs that count on their short-term memory or mental math. For another example, making decision is hard, and so we should avoid too many user choices, and present a clear task flow for users to follow instead.  For still another example, people have perceptional or behavioral biases and so we should design GUIs to take advantage of their psychology to prevent errors and improve efficacies..  

 PowerPoint Presentation is based on the book Designing with the Mind in Mind 

 

Modeling and Coding Collaboration 

  1. Operations are capabilities: You are what you behave as. What does a printer do? Print. What does an airplane do? Fly. Can we ask an airplane to print? No. A book can hold pages and words. It is not supposed to know how to seat to stand. On the other hand, a bookshelf is supposed to hold books, and so it is capable of holding or support books. So should a book stand on a bookshelf or should a bookshelf holds a book? Each object has its own natural capabilities. CRC note card game can be simple starting point to understand the need for collaborations
  2. A hero needs helpers: An object should not attempt to do everything by itself. Rather, it should delegate a part of or a whole job to those who are most capable of. For example, an employee object may need an operation GoToWork(). While programming the operation, does the object need to know how to turn on a car, move the car, and stop the car? Which object is most capable of doing the later tasks? Of course, a car object. So the employee object should delegate those sub tasks to the car. By doing so, the employee object just needs to pick a car and send messages to the car object to do the rest.

Modeling Collaboration: Each hero function is performed by the hosting object with the help from one or more related objects. 

  1. Use Heuristic 1 and the data flow reduction principle to identify the hosting object for the hero function. 
  2. Use the activity diagrams or any other procedural models to understand what needs to be done to implement the hero function 
  3. Use Heuristics 2 to identify helper classes. Create new classes if not exist. Follow the navigation directions to identify the final responsible helpers. 

Example: Implement Compute GPA, Check Prerequisites, and Check Time Conflicts for Student Registration System

First, implement the class diagram as follows: 

 

Compute GPA: In order to compute GPA, we will need to have all the courses that a student has finished. Since Student class has a list of past enrollment records or transcript, which appear to be sufficient to do the calculation. GPA = total points / total credits. Each course grade is translated into points as follows: A => 4, B => 3, C => 2, D => 1, and F => 0. Multiplying the course point by the course credit obtains the points for each course. Adding the points of all courses obtains the total points. By this analysis, we identified some sub-tasks: get credits for each course, get grade for each course, and convert grades to points.

Check Prerequisites: In order to check prerequisites, we will need a list of courses that are designated as prerequisites and a list of courses that a student has finished. No class has both lists, so where should the operation be allocated? Course class has a list of designated prerequisites. However, it cannot obtain a list of finished courses from a Student object because it cannot send messages to Student according to navigability. CourseOffering class is one possible choice because it can ask Course class to tell the list of prerequisites and ask a Student object to tell a list of finished classes. The only parameter needed is a Student object or a student ID. Another choice is Student class because it has a list of finished courses and can also ask CourseOffering for help to get a list of prerequisites. 

Check Time Conflicts: When a student is about to enroll into a new class, we have to make sure the time for the class is not conflicting with ones that he or she already registered. To check for time conflicts, we need to know what courses that a student has registered and for each course offering, its class time. Thus, the best class to house the operation is Student class.

To implement the function, however, we face a major obstacle on how to represent class meeting times like 8-9A on Mondays and 1-3PM on Fridays, etc. A typical class time has three components: 1) each class is scheduled within a term or semester or year, which falls within a time period; 2) within the time period, the class will meet regularly every week in particular week days; 3) in each of the week days, the class meets in certain time intervals. 

 

Custom Data Type Design:

         Class = Data Type (= Structure) + Operations

Thus, any complex data type can be designed as a business class. We have dealt with one such a type before, i.e., Period, which consists of two points in time, designated by beginDate and endDate, which are two absolute points in time, including year, month, day, hour, minute, and second. For Period type, we can also program some customer operations such as "get the number of days in a period" or "check if a period is overlapping with another period":

 

public class Period

{

       private DateTime beginDate;

       private DateTime endDate;

       public int GetDays()

       {

           TimeSpan ts = endDate - beginDate;

           return ts.Days;

       }

 

       public bool Overlap(Period p)

       {

           if (this.endDate => p.beginDate && this.beginDate <= p.endDate)

               return true;

           else

               return false;

       }

}

 

For another example, what if we want a data type that represents one point in time in any calendar day, i.e., we don't want to specify any particular year, month, and day in this data type? The task we need such a type is everywhere, e.g., wakeup time, sleep time, dinner time, etc. For this type of time, the standard DateTime class will be inappropriate because DataTime specify one absolute point in time with a year, a month, a day, an hour, a minute, and a second. Thus we need to design a custom type that just include an hour, a minute, and a second only as follows. 

 

public class Time

{

       private int hour, minute, second;

       public int Hour

       {

           get { return hour;}

           set { hour = value;}

       }

       public int Minute

       {

           get { return minute;}

            set { minute = value;}

       }

       public int Second

       {

           get { return second;}

           set { second = value;}

       }

 

       public static bool operator <(Time a, Time b)

       {

           return (a.hour * 3600 + a.minute*60 + a.second <

                b.hour*3600 + b.minute * 60 + b.second);

       }

 

       public static bool operator >(Time a, Time b)

       {

           return (a.hour * 3600 + a.minute * 60 + a.second >

            b.hour * 3600 + b.minute * 60 + b.second);

       }

}

 

Note that with this new data type, we will need a way to compute two points in time to say which time is earlier than the other.  For that purpose, we create an operator < there so that we can compare if time is less than time b by using the operator a < b. The following the implementation of the Time class with the operator

With the custom Time type, we can now move one step further to define a new type which models one point in time a week as follows:

 

class TimeInWeek {

    Time t;

    int day;

...

}

 

Note that since a weekday takes values 0, 1, 2, …, 6, but the above type allows a day to be any integers, including those less than 0 or bigger than 7.  A better design should use a custom type for WeekDay or Day as follows 

public enum Day

{

       SUNDAY,

       MONDAY,

       TUESDAY,

       WEDNESDAY,

       THURSDAY,

       FRIDAY,

       SATURDAY

}

and then TimeInAWeek can be redefined as 

    class TimeInAWeek {

        Time t;

        Day d;

    }

 

Finally, let us see how can we model the time for a a meeting time of a course, which includes a specific day, and two points in Time. So we crate TimeSlot class with three attributes weekDay, beeginTime, endTime as follows.  

public class TimeSlot

{

       private Day weekDay;

       private Time beginTime;

       private Time endTime;

       public Day WeekDay

       {

           get { return weekDay; }

           set { weekDay = value; }

       }

 

       public Time BeginTime

       {

           get { return beginTime; }

           set { beginTime = value; }

       }

       public Time EndTime

       {

           get { return endTime; }

           set { endTime = value; }

       }

 

       public bool Overlap(TimeSlot ts)

       {

           bool result = false;

           if (ts.WeekDay != this.WeekDay)

               result = false;

           else

           {

               if (ts.beginTime <= this.endTime &&

                    ts.endTime <= this.beginTime)

               {

                   result = true;

               }

               else

                   result = false;

           }

           return result;

 

       }

}

 

Note that we can also include custom operations for the new TimeSlot to check if a time slot is overlapping with another. If two time slots are on different weekdays, they will not be overlapping. If they are on the day weekday, then we check if the end time of one slot is smaller than the begin time of another time slot.  

 

Programming Collaboration for Check Time Conflicts

 

The logic of the operation: First we need each course offering or section to tell its class time. Then we need to compare the class time of the course to be enrolled with that of each of enrolled classes to see if there is an overlap.

 

Note that the time for a course section is usually stated like Mondays and Wednesdays between 1:30-2:55 PM during a period between January 15, 2015 and May 5, 2015. Usually we use s text field to record the class time. That will be prone to mistakes and difficult to implement CheckTimeConflicts operation. To better model the class time type, we will need to have Period class with attributes beginDate and endDate with values like “between January 15, 2015 and May 5, 2015.” Then we need a new Time class with data members hour, minute, and second. Then we can use the Time class to create TimeSlot class with data members, day (for week day 1, 2, 7), beginTime, and endTime. The later two are of Time type. Then the class time for each course offering will be better specified by a time period like between January 15, 2015 and May 5, 2015 and one or more time slots like Monday 1:30-2:55PM, Wednesday 1:30-2:55PM. With these helper classes, we can now update the class diagram accordingly as follows. 

 

 

In order to check if two class times are overlapping, we can delegate the task to CourseOffering and so create a method Overlap(CourseOffering c) in there. But in order to check if one course offering has time conflicts with another course offering, we need to check if two periods are overlapping and if two times slots are overlapping. So CourseOffering class is going to delegate the sub-tasks to Period and TimeSlot classes and so we create helper methods accordingly in there (see Figure 2).

 

Now we can check if one course offering has overlapping time with another. First check if they have overlapping periods. If they do, check for all possible overlapping time slots.

 

public class CourseOffering

{

       private Course course;

       private Period period;

       private int cap;

       private TimeSlot[] timeslots;

 

       private Dictionary<string, Student> roster;

       private Dictionary<Student, Enrollment> gradeBook;

      …

      

       public bool Overlap(CourseOffering co)

       {

           if (this.period.Overlap(co.period) == false)

             return false;

           else

           {

               foreach (TimeSlot ts1 in this.timeslots)

               {

                   foreach (TimeSlot ts2 in co.timeslots)

                   {

                       if (ts1.Overlap(ts2))

                           return true;

                   }

               }

               return false;

           }

       }

}

 

Finally, let us implement CheckTimeConflicts(CourseOffering c) in Student class. One would think Student class is a hero here; it does the most important jobs in the registration system. Yet, see how little it does. It delegates most of the job to other classes. The hero becomes a hero with a lot of helpers.

 

public class Student

{

       private string id;

       private string sname;

       private List classes;

       private Dictionary<CourseOffering,Enrollment> transcript;

            …

       public bool CheckTimeConflicts(CourseOffering c)

       {

           foreach (CourseOffering s in this.classes)

           {

               if (s.Overlap(c))

                   return true;

           }

           return false;

       }

}

 

Don’t forget to call these methods before we enroll students. So we change AddClass(CourseOffering c) in Student class and EnrollStudent(Student s) in CourseOffering class. Also add a method in CourseOffering class to check if it is currently available.

 

public class Student

{

       private string id;

       private string sname;

       private List classes;

       private Dictionary<CourseOffering,Enrollment> transcript;

            …

       public void AddClass(CourseOffering c)

       {

           if (this.CheckPrerequisite(c) == true && this.CheckTimeConflicts(c) == false && c.IsAvailable())

           {

               classes.Add(c);

               transcript.Add(c, new Enrollment(this, c));

           }

       }

}

 

public class CourseOffering

{

       private Course course;

       private Period period;

       private int cap;

       private TimeSlot[] timeslots;

 

       private Dictionary<string, Student> roster;

       private Dictionary<Student, Enrollment> gradeBook;

            …

       public void Enroll(Student s)

       {

           if (s.CheckPrerequisite(this) &&

   s.CheckTimeConflicts(this) == false &&

   this.IsAvailable())

           {

               roster.Add(s.ID, s);

               gradeBook.Add(s, new Enrollment(s, this));

               s.AddClass(this);

           }

       }

 

       public bool IsAvailable()

       {

          return (cap > roster.Count);

       }

 Homework:

  • Reading: Chapter 14 of LIU (2020)
  • Exercises: Closeness (Question 6 of Chapter 14)

           Register

Blog    News    Post
 
     
 
Blog Posts    News Digest    Contact Us    About Developer    Privacy Policy

©1997-2024 ecourse.org. All rights reserved.