Пример #1
0
        public ActionResult LessonDetails(string id)
        {
            if (NeedLogin())
            {
                return(LoginRedir());
            }

            var lesson = LessonsCtrl.Get(id);

            if (lesson == null)
            {
                return(new HttpNotFoundResult());
            }

            if (!IsAdmin())
            {
                if (!AllowedLessons(CurrentUserEmail()).Contains(lesson.LessonID))
                {
                    return(RedirectToAction("Lessons"));
                }
            }

            var lessonTurns = LessonsCtrl.DBConn().FindTurns(lesson.LessonID, null);

            var modelObj  = new ExpandoObject();
            var modelDict = (IDictionary <string, object>)modelObj;

            modelDict["Lesson"] = lesson;
            modelDict["Turns"]  = lessonTurns;

            return(View("LessonDetail", modelObj));
        }
Пример #2
0
        public ActionResult Lessons()
        {
            if (NeedLogin())
            {
                return(LoginRedir());
            }

            var lessons = new List <Lesson>();

            //Only lessons we're allowed to see
            bool             admin          = IsAdmin();
            HashSet <string> allowedLessons = null;

            if (!admin)
            {
                //Only populate allowedLessons if we're not admin
                allowedLessons = AllowedLessons(CurrentUserEmail());
            }

            foreach (Lesson le in LessonsCtrl.Get())
            {
                if (admin || allowedLessons.Contains(le.LessonID))
                {
                    lessons.Add(le);
                }
            }

            var modelObj  = new ExpandoObject();
            var modelDict = (IDictionary <string, object>)modelObj;

            modelDict["Lessons"]    = lessons;
            modelDict["AnswerTots"] = LessonsCtrl.DBConn().FindLessonAnswerTots();

            return(View("Lessons", modelObj));
        }
Пример #3
0
        public ActionResult StudentLessonDevSelect()
        {
            if (NeedLogin())
            {
                return(LoginRedir());
            }
            if (!IsAdmin())
            {
                return(RedirectToAction("Lessons"));
            }

            var turns = new List <ExpandoObject>();

            foreach (var turn in LessonsCtrl.DBConn().FindTurnSummary())
            {
                turns.Add(new ExpandoObject());
                var turnDict = (IDictionary <string, object>)turns.Last();
                turnDict["LessonID"]  = turn.Item1;
                turnDict["UserID"]    = turn.Item2;
                turnDict["TurnCount"] = turn.Item3;
            }

            var modelObj  = new ExpandoObject();
            var modelDict = (IDictionary <string, object>)modelObj;

            modelDict["Turns"] = turns;

            return(View("StudentLessonDevSelect", modelObj));
        }
Пример #4
0
        public ActionResult StudentLessonDevView(string id, string id2)
        {
            if (NeedLogin())
            {
                return(LoginRedir());
            }

            string lessonID = Util.RenderHelp.URIDecode(id);
            string userID   = Util.RenderHelp.URIDecode(id2);

            if (!IsAdmin())
            {
                if (!AllowedLessons(CurrentUserEmail()).Contains(lessonID))
                {
                    return(RedirectToAction("StudentLessonDevSelect"));
                }
            }

            var lesson = LessonsCtrl.Get(lessonID);

            if (lesson == null)
            {
                return(RedirectToAction("StudentLessonDevSelect"));
            }

            var student = StudentsCtrl.Get(userID);

            if (student == null)
            {
                return(RedirectToAction("StudentLessonDevSelect"));
            }

            var turns = StudentsCtrl.DBConn().FindTurns(lessonID, userID);

            if (turns == null || turns.Count < 1)
            {
                return(RedirectToAction("StudentLessonDevSelect"));
            }

            var modelObj  = new ExpandoObject();
            var modelDict = (IDictionary <string, object>)modelObj;

            modelDict["ID"]         = id;
            modelDict["ID2"]        = id2;
            modelDict["LessonID"]   = lessonID;
            modelDict["LessonName"] = lesson.ShortName;
            modelDict["UserID"]     = userID;
            modelDict["Details"]    = turns[0];

            return(View("StudentLessonDevView", modelObj));
        }
Пример #5
0
        public ActionResult StudentLessonDrill(string id, string id2)
        {
            if (NeedLogin())
            {
                return(LoginRedir());
            }

            string lessonID = Util.RenderHelp.URIDecode(id);
            string userID   = Util.RenderHelp.URIDecode(id2);

            if (!IsAdmin())
            {
                if (!AllowedLessons(CurrentUserEmail()).Contains(lessonID))
                {
                    return(RedirectToAction("Lessons"));
                }
            }

            var lesson = LessonsCtrl.Get(lessonID);

            if (lesson == null)
            {
                return(RedirectToAction("Lessons"));
            }

            var student = StudentsCtrl.Get(userID);

            if (student == null)
            {
                return(RedirectToAction("Students"));
            }



            var turns     = StudentsCtrl.DBConn().FindTurns(lessonID, userID);
            var detailLog = new List <ExpandoObject>();

            if (turns == null || turns.Count < 1 || turns[0].Turns == null || turns[0].Turns.Count < 1)
            {
                detailLog.Add(DetailLogEntry(student, "No information"));
            }
            else
            {
                var    details      = turns[0];
                string lastQuestion = "???";
                string lastDiff     = "M";

                foreach (var turn in details.Turns)
                {
                    if (turn.TurnID == StudentLessonActs.TURN_ID_START)
                    {
                        detailLog.Add(DetailLogEntry(student, "Start of Lesson Attempt", "Attempt", entry: turn));
                    }

                    bool completion = false;

                    //The ignore-case comparison we use
                    const StringComparison CMP = StringComparison.InvariantCultureIgnoreCase;

                    foreach (var act in turn.AllValidActions())
                    {
                        if (String.Equals(act.Agent, "System", CMP))
                        {
                            if (String.Equals(act.Act, "Display", CMP) && !String.IsNullOrWhiteSpace(act.Data))
                            {
                                lastQuestion = act.Data;
                            }

                            if (String.Equals(act.Act, "End", CMP))
                            {
                                completion = true;
                            }
                        }
                    }

                    string evt       = null;
                    bool   correct   = false;
                    bool   incorrect = false;

                    if (turn.Input != null)
                    {
                        evt = turn.Input.Event;
                        if (evt != null)
                        {
                            evt = evt.Trim().ToLowerInvariant();
                            if (evt == "correct")
                            {
                                correct = true;
                            }
                            else if (evt.StartsWith("incorrect"))
                            {
                                incorrect = true;
                            }
                        }
                    }

                    if (correct)
                    {
                        detailLog.Add(DetailLogEntry(student, "CORRECT", "Answer", lastQuestion, turn));
                    }
                    else if (incorrect)
                    {
                        detailLog.Add(DetailLogEntry(student, "MISS", "Answer", lastQuestion, turn));
                    }

                    if (turn.Transitions != null && turn.Transitions.Count > 0)
                    {
                        foreach (var tran in turn.Transitions)
                        {
                            string ruleID = tran.RuleID;
                            if (String.IsNullOrWhiteSpace(ruleID))
                            {
                                continue;
                            }
                            ruleID = ruleID.Trim().ToLowerInvariant();

                            //lastDiff
                            string newState = null;

                            if (ruleID.EndsWith("easy"))
                            {
                                newState = "E";
                            }
                            else if (ruleID.EndsWith("medium"))
                            {
                                newState = "M";
                            }
                            else if (ruleID.EndsWith("hard"))
                            {
                                newState = "H";
                            }

                            if (newState != null && newState != lastDiff)
                            {
                                detailLog.Add(DetailLogEntry(student, lastDiff + " to " + newState, "PathChange", entry: turn));
                                lastDiff = newState;
                            }
                        }
                    }

                    if (completion)
                    {
                        detailLog.Add(DetailLogEntry(student, "Completed Lesson", "Completion", entry: turn));
                    }
                }
            }

            var modelObj  = new ExpandoObject();
            var modelDict = (IDictionary <string, object>)modelObj;

            modelDict["ID"]          = id;
            modelDict["ID2"]         = id2;
            modelDict["LessonID"]    = lessonID;
            modelDict["LessonName"]  = lesson.ShortName;
            modelDict["UserID"]      = userID;
            modelDict["DetailLog"]   = detailLog;
            modelDict["BlindTarget"] = student.FirstName;

            return(View("StudentLessonDrill", modelObj));
        }
Пример #6
0
        public ActionResult ClassDetails(string id)
        {
            if (NeedLogin())
            {
                return(LoginRedir());
            }
            var clazz = ClassesCtrl.Get(id);

            if (clazz == null)
            {
                return(new HttpNotFoundResult());
            }

            if (!IsAdmin())
            {
                if (!clazz.IsATeacher(CurrentUserEmail()))
                {
                    //Don't have rights to this class
                    return(RedirectToAction("Classes"));
                }
            }

            //Don't allow null lists
            if (clazz.Lessons == null)
            {
                clazz.Lessons = new List <string>();
            }
            if (clazz.Students == null)
            {
                clazz.Students = new List <string>();
            }

            //SPECIAL: if this is a memphis class with test in the name, we do some filtering
            if (clazz.Location.ToLower().Contains("memphis") && clazz.ClassID.ToLower().Contains("test"))
            {
                //No carl, test, or non-alpha students then...
                //Sort by len and take top 10
                var nonAlpha = new System.Text.RegularExpressions.Regex("[^A-Z,a-z]+");
                clazz.Students = clazz.Students
                                 .Where(s => !(s.Contains("carl") || s.Contains("test") || nonAlpha.IsMatch(s)))
                                 .OrderByDescending(s => s.Length)
                                 .Take(10)
                                 .ToList();

                //only lessons that match lessonN where N is a number
                var lessonMatch = new System.Text.RegularExpressions.Regex("lesson[0-9]+");
                clazz.Lessons = clazz.Lessons.Where(l => lessonMatch.IsMatch(l)).ToList();
            }

            //Sort info in the class for display purposes
            //Students are easy to sort, but we need a special sort for lessons
            clazz.Lessons = clazz.Lessons.OrderBy(x => Utils.LessonIDSort(x)).ToList();
            clazz.Students.Sort();

            var lessons  = new HashSet <String>(clazz.Lessons);
            var students = new HashSet <String>(clazz.Students);

            //Make dictionary of lesson:user
            var lookup = new Dictionary <Tuple <string, string>, StudentLessonActs>();

            if (lessons.Count > 0 && students.Count > 0)
            {
                foreach (var turns in LessonsCtrl.DBConn().FindTurnsForStudents(students))
                {
                    if (!students.Contains(turns.UserID) || !lessons.Contains(turns.LessonID))
                    {
                        continue; //Nope
                    }

                    var key = new Tuple <string, string>(turns.LessonID, turns.UserID);
                    lookup[key] = turns;
                }
            }

            //Calculate user and lessons average: first get totals and then
            //calculate the averages. This seemingly strange method means we
            //only need to perform lesson/student nested loop once
            var lessonTots = new Dictionary <string, Tuple <int, int> >();
            var userTots   = new Dictionary <string, Tuple <int, int> >();

            //Per-init student dict (since students are the inner loop)
            foreach (string userID in clazz.Students)
            {
                userTots[userID] = new Tuple <int, int>(0, 0);
            }

            //Find totals
            foreach (string lessonID in clazz.Lessons)
            {
                lessonTots[lessonID] = new Tuple <int, int>(0, 0);

                foreach (string userID in clazz.Students)
                {
                    var key = new Tuple <string, string>(lessonID, userID);
                    StudentLessonActs turns;
                    if (lookup.TryGetValue(key, out turns))
                    {
                        int ca = turns.CorrectAnswers;
                        int ia = turns.IncorrectAnswers;
                        if (ca + ia > 0)
                        {
                            lessonTots[lessonID] = TupleAdd(lessonTots[lessonID], ca, ia);
                            userTots[userID]     = TupleAdd(userTots[userID], ca, ia);
                        }
                    }
                }
            }

            //Set up model with all this data
            var modelObj  = new ExpandoObject();
            var modelDict = (IDictionary <string, object>)modelObj;

            modelDict["Class"]         = clazz;
            modelDict["LUTurns"]       = lookup;
            modelDict["LessonNames"]   = LessonsCtrl.DBConn().FindLessonNames();
            modelDict["LessonCounts"]  = lessonTots;
            modelDict["StudentCounts"] = userTots;

            return(View("ClassDetail", modelObj));
        }