// returns basically the fraction of the user's time that was spent performing that Doable recently at that date public ProgressionValue GetValueAt(DateTime when, bool strictlyEarlier) { // find the most recent Participation ListItemStats <DateTime, Participation> previousStats = this.searchHelper.FindPreviousItem(when, strictlyEarlier); DateTime previousEnd; // make sure that we have enough data if (previousStats == null) { previousEnd = this.Owner.DiscoveryDate; } else { // figure out whether we're in the middle of a participation or not Participation previousParticipation = previousStats.Value; previousEnd = previousParticipation.EndDate; } //int index = 2 * this.searchHelper.CountBeforeKey(when, !strictlyEarlier); if (previousEnd.CompareTo(when) > 0) { // we're in the middle of a participation, so the value is zero return(new ProgressionValue(when, new Distribution(0, 0, 1))); } // we're not in the middle of a participation, so the value is the amount of time since the last one ended TimeSpan duration = when.Subtract(previousEnd); Distribution currentValue = Distribution.MakeDistribution(duration.TotalSeconds, 0, 1); ProgressionValue result = new ProgressionValue(when, currentValue); return(result); }
ParticipationAndSummary Summarize(Participation participation) { ParticipationAndSummary result = new ParticipationAndSummary(); result.Participation = participation; ParticipationsSummary summary = new ParticipationsSummary(); Correlator correlator = new Correlator(); double x = this.GetWeight(participation.Duration); double weight = x / 2; correlator.Add(0, 0, weight); correlator.Add(x, x, weight); summary.Trend = correlator; Distribution logActiveTime = Distribution.MakeDistribution(Math.Log(participation.Duration.TotalSeconds), 0, 1); summary.LogActiveTime = logActiveTime; summary.Start = participation.StartDate; summary.End = participation.EndDate; summary.CumulativeIntensity = participation.Duration; result.Summary = summary; return(result); }
public static RatingSource FromParticipation(Participation source) { RatingSource cause = new RatingSource("Participation"); cause.Converted = source; return(cause); }
} // the suggestion that caused this Consideration public void FillInFromParticipation(Participation source) { if (this.ActivityDescriptor == null) { this.ActivityDescriptor = source.ActivityDescriptor; } }
public override void PreviewParticipation(Participation newParticipation) { if (this.LatestParticipation == null || newParticipation.EndDate.CompareTo(this.LatestParticipation.EndDate) > 0) { this.LatestParticipation = newParticipation; } }
public void RemoveParticipation(Participation participationToRemove) { // make sure that we had included it in the first place if (this.ShouldIncludeParticipation(participationToRemove)) { this.searchHelper.Remove(participationToRemove.StartDate); } }
public void AddParticipation(Participation newParticipation) { if (this.ShouldIncludeParticipation(newParticipation)) { // Eventually, the StatList should be improved to allow intervals as keys // For now we allow searching for participation by start date this.searchHelper.Add(newParticipation.StartDate, newParticipation); //this.searchHelper.Add(newParticipation.EndDate, newParticipation); } }
public void RemoveParticipation(Participation participation) { // make sure that we actually added it in the first place if (this.ShouldIncludeParticipation(participation)) { // for now, the searchHelper identifies the item solely based on key, but it's okay, because ties are broken in a last-in-first-out manner DateTime startDate = participation.StartDate; this.searchHelper.Remove(startDate); } }
public void AddParticipation(Participation newParticipation) { if (this.ShouldIncludeParticipation(newParticipation)) { // for now, we add the participation as a single datapoint, where the key knows the start date but not the end date // Eventually, the StatList should be improved to allow intervals as keys DateTime startDate = newParticipation.StartDate; this.searchHelper.Add(startDate, this.Summarize(newParticipation)); } }
public override void AttemptToMatch(Participation participation) { // check whether this rating might describe this participation if (!this.CanMatch(participation)) { return; } // This rating seems to describe this participation, so fill in the corresponding data this.ActivityDescriptor = participation.ActivityDescriptor; this.Date = participation.StartDate; base.AttemptToMatch(participation); }
public override void AddParticipation(Participation newParticipation) { if (newParticipation.DismissedActivity) { this.complete = true; } if (newParticipation.CompletedMetric) { this.completedSuccessfully = true; } base.AddParticipation(newParticipation); }
public New_ParticipationComment_Layout(Participation participation, LayoutStack layoutStack) { this.participation = participation; this.textBox = new Editor(); this.layoutStack = layoutStack; Button saveButton = new Button(); saveButton.Clicked += SaveButton_Clicked; GridLayout_Builder builder = new Vertical_GridLayout_Builder() .AddLayout(new TextblockLayout("Comment")) .AddLayout(new TextboxLayout(textBox)) .AddLayout(new ButtonLayout(saveButton, "Save")); this.SubLayout = builder.BuildAnyLayout(); }
public void AddParticipation(Participation newParticipation) { if (this.ShouldIncludeParticipation(newParticipation)) { WillingnessSummary willingness; if (newParticipation.Suggested) { willingness = WillingnessSummary.Prompted; } else { willingness = WillingnessSummary.Unprompted; } this.AddValue(newParticipation.StartDate, willingness); } }
public override void PreviewParticipation(Participation newParticipation) { if (this.recomputeRatings) { if (newParticipation.Rating == null) { newParticipation.Rating = this.engine.MakeEstimatedRating(newParticipation); } } if (this.recomputeEfficiencies) { if (newParticipation.RelativeEfficiencyMeasurement != null) { newParticipation.setRelativeEfficiencyMeasurement(this.engine.Make_CompletionEfficiencyMeasurement(newParticipation), newParticipation.EffectivenessMeasurement.Metric); } } }
public override void AttemptToMatch(Participation participation) { bool betterCanMatch = this.BetterRating.CanMatch(participation); bool worseCanMatch = this.WorseRating.CanMatch(participation); // figure out whether the better activity or the worse activity is the one that generated this rating if (betterCanMatch && !worseCanMatch) { // if we get here, the better participation generated this RelativeRating this.BetterRating.AttemptToMatch(participation); } if (worseCanMatch && !betterCanMatch) { // if we get here, the worse participation generated this RelativeRating this.WorseRating.AttemptToMatch(participation); } }
public void AddParticipation(Participation newParticipation) { if (!this.updatedAfterInheritances) { this.engine.FullUpdate(); this.updatedAfterInheritances = true; } RelativeRating newRelativeRating = newParticipation.Rating as RelativeRating; if (newRelativeRating != null) { RelativeRating newRating = this.AddRating(newRelativeRating); newParticipation.Rating = newRating; } this.PreviewParticipation(newParticipation); this.engine.PutParticipationInMemory(newParticipation); this.PostParticipation(newParticipation); }
// creates the rating to assign to the given Participation public Rating GetRelativeRating(Engine engine, Participation participation) { // abort if null input double?maybeScale = this.GetRatio(); if (maybeScale == null) { return(engine.MakeEstimatedRating(participation)); } double scale = maybeScale.Value; if (this.latestParticipation == null) { return(null); } RelativeRating rating = engine.MakeRelativeRating(participation.ActivityDescriptor, participation.StartDate, scale, this.latestParticipation); return(rating); }
public bool CanMatch(Participation participation) { if (participation == null) { return(false); } if (this.ActivityDescriptor != null) { if (!this.ActivityDescriptor.CanMatch(participation.ActivityDescriptor)) { return(false); } } if (this.Date != null) { if (!this.Date.Value.Equals(participation.StartDate)) { return(false); } } return(true); }
public override void PreviewParticipation(Participation newParticipation) { logCounter++; // resolve some parameters Activity activity = this.activityDatabase.ResolveDescriptor(newParticipation.ActivityDescriptor); DateTime when = newParticipation.StartDate; if (logCounter % 1000 == 0) { this.log("Processing participation at " + when + " for " + activity.Name); } ParticipationFeedback feedbackObject = this.engine.computeStandardParticipationFeedback(activity, when, newParticipation.EndDate); if (feedbackObject != null) { // remove the number string fullFeedback = feedbackObject.Summary; string feedback = this.stripLeadingNumbers(fullFeedback); // save into this.feedbacks string prefix = "Feedback at " + when + " for " + activity + ":"; //this.log(this.padColumn(prefix) + " " + fullFeedback); if (!this.feedbacks.ContainsKey(feedback)) { this.feedbacks[feedback] = new Dictionary <Activity, int>(); } Dictionary <Activity, int> counts = feedbacks[feedback]; if (!counts.ContainsKey(activity)) { counts[activity] = 0; } counts[activity]++; } // call parent class base.PreviewParticipation(newParticipation); }
public override RelativeRating ProcessRating(RelativeRating newRating) { if (!this.recomputeRatings) { return(newRating); } System.Diagnostics.Debug.WriteLine("Adding rating with date " + ((DateTime)newRating.FirstRating.Date).ToString()); AbsoluteRating otherRating = newRating.FirstRating; AbsoluteRating thisRating = newRating.SecondRating; if (newRating.Source != null) { Participation participation = newRating.Source.ConvertedAsParticipation; RelativeRating rawRating = participation.Rating as RelativeRating; if (rawRating.BetterRating.Date == null && rawRating.WorseRating.Date != null) { // This one is BetterRating thisRating = newRating.BetterRating; otherRating = newRating.WorseRating; } else { // This one is WorseRating thisRating = newRating.WorseRating; otherRating = newRating.BetterRating; } } if (newRating.RawScoreScale == null) { // The relative rating simply said "activity X is better than Y" // We might as well assign the same scale that the previous algorithm had computed double scale = thisRating.Score / otherRating.Score; newRating.RawScoreScale = scale; } Participation otherParticipation = null; if (otherRating.Source != null) { otherParticipation = otherRating.Source.ConvertedAsParticipation; } Participation thisParticipation = null; if (thisRating.Source != null) { thisParticipation = thisRating.Source.ConvertedAsParticipation; } if (otherParticipation != null && thisParticipation != null) { RelativeRating modifiedRating = this.engine.MakeRelativeRating(thisParticipation.ActivityDescriptor, thisParticipation.StartDate, newRating.RawScoreScale.Value, otherParticipation); if (modifiedRating.BetterRating.ActivityDescriptor != null) { if (!modifiedRating.BetterRating.ActivityDescriptor.CanMatch(newRating.BetterRating.ActivityDescriptor)) { throw new Exception("Internal error: RatingRenormalizer swapped ratings while rewriting them"); } } if (modifiedRating.WorseRating.ActivityDescriptor != null) { if (!modifiedRating.WorseRating.ActivityDescriptor.CanMatch(newRating.WorseRating.ActivityDescriptor)) { throw new Exception("Internal error: RatingRenormalizer swapped ratings while rewriting them"); } } if (modifiedRating.BetterRating.ActivityDescriptor == null && modifiedRating.WorseRating.ActivityDescriptor == null) { throw new Exception("Internal error: RatingRenormalizer created rating that does not specify an activity"); } return(modifiedRating); } return(newRating); }
public Participation Combine(Participation participation1, Participation participation2) { // we don't actually care about conglomerations of Participations so this function can return anything return(this.Default()); }
public virtual void PostParticipation(Participation newParticipation) { }
public virtual void PreviewParticipation(Participation newParticipation) { }
// tells whether we care about this participation at all public bool ShouldIncludeParticipation(Participation newParticipation) { return(true); }
public override void PostParticipation(Participation newParticipation) { string text = this.textConverter.ConvertToString(newParticipation); this.addText(text); }
// checks whether it's possible that this rating was generated by this participation, and if so, fills in some data for it public virtual void AttemptToMatch(Participation participation) { this.Source = RatingSource.FromParticipation(participation); }
public Participation GetParticipation(Engine engine) { Activity activity = this.nameBox.Activity; if (activity == null) { return(null); } ActivityDescriptor descriptor = activity.MakeDescriptor(); if (descriptor.ActivityName == null || descriptor.ActivityName.Length == 0) { return(null); } if (!this.startDateBox.IsDateValid()) { return(null); } if (!this.endDateBox.IsDateValid()) { return(null); } // If the user is trying to submit a participation with misordered dates, then point the out to them // Although we could've highlighted this to the user sooner, in most cases this would just distract them and they wouldn't want to think about it if (this.EndDate.CompareTo(this.StartDate) <= 0) { this.startDateBox.appearInvalid(); this.endDateBox.appearInvalid(); return(null); } // If the user tries to record having done someting in the future, that's a mistake because it hasn't happened yet DateTime now = DateTime.Now; if (this.StartDate.CompareTo(now) > 0 || this.EndDate.CompareTo(now) > 0) { return(null); } Participation participation = new Participation(this.StartDate, this.EndDate, descriptor); if (this.CommentText != "" && this.CommentText != null) { participation.Comment = this.CommentText; } try { Rating rating = this.ratingBox.GetRelativeRating(engine, participation); participation.Rating = rating; } catch (Exception) { // If the rating is invalid, then we can ignore that } Metric metric = this.Metric; if (metric != null) { // Record the success/failure status of the participation string status = this.todoCompletionStatusPicker.SelectedItem.ToString(); bool successful = (status == this.TaskCompleted_Text || status == this.ProblemComplete_Text); bool closed = (status != this.TaskIncomplete_Text && status != this.ProblemIncomplete_Text); double helpFraction = this.helpStatusPicker.GetHelpFraction(participation.Duration); participation.EffectivenessMeasurement = new CompletionEfficiencyMeasurement(metric, successful, helpFraction); participation.EffectivenessMeasurement.DismissedActivity = closed; // Notice that the Engine doesn't need us to pass in a Metric for computing the efficiency of this participation, because computing efficiency requires an experiment, and the // experiment already knows which metric we're using RelativeEfficiencyMeasurement measurement = engine.Make_CompletionEfficiencyMeasurement(participation); participation.EffectivenessMeasurement.Computation = measurement; } participation.Suggested = this.get_wasSuggested(participation.ActivityDescriptor); return(participation); }
private void Update_FeedbackBlock_Text() { ParticipationFeedback participationFeedback = null; Activity activity = this.nameBox.Activity; if (activity != null && this.startDateBox.IsDateValid() && this.endDateBox.IsDateValid()) { // We have a valid activity and valid dates, so give feedback about the participation DateTime startDate = this.startDateBox.GetDate(); DateTime endDate = this.endDateBox.GetDate(); participationFeedback = this.computeFeedback(activity, startDate, endDate); if (participationFeedback != null) { this.participationFeedbackButtonLayout.setText(participationFeedback.Summary); bool?happySummary = participationFeedback.happySummary; if (happySummary != null) { if (happySummary.Value == true) { this.participationFeedbackButtonLayout.setTextColor(Color.Green); } else { this.participationFeedbackButtonLayout.setTextColor(Color.Red); } } else { this.participationFeedbackButtonLayout.resetTextColor(); } this.promptHolder.SubLayout = this.participationFeedbackButtonLayout; } else { this.promptHolder.SubLayout = null; } } else { if (this.nameBox.NameText == null || this.nameBox.NameText == "") { // If we have no text in the activity name box, then we do have space for a response and there isn't a current activity to give feedback on Participation latestParticipation = this.LatestParticipation; if (latestParticipation != null && latestParticipation.RelativeEfficiencyMeasurement != null) { this.promptHolder.SubLayout = this.experimentFeedbackLayout; } else { // If the user has submitted a participation before, it should be fast to get a suggestion, so we do that now if (this.wasEverCleared) { this.updateSuggestion(); if (this.suggestedActivityName != null) { this.promptHolder.SubLayout = this.suggestionsLayout; this.suggestionLayout.setText("How about " + this.suggestedActivityName + "?"); } else { this.promptHolder.SubLayout = null; } } else { // If the user hasn't submitted a participation during this usage of ActivityRecommender yet, then it will probably be slow to get a suggestion, so we'll wait until later before showing a suggestion this.promptHolder.SubLayout = null; } } } else { // If we have no valid activity name but we do have some text in the name box, then we don't need to say anything // The name entry box will offer autocomplete suggestions and/or help this.promptHolder.SubLayout = null; } } // Note that this is the only method that modifies either participationFeedback or responseButtonLayout.text, // so we can ensure that they match this.participationFeedback = participationFeedback; this.feedbackIsUpToDate = true; }