Streaks don't count skip days in their length

pull/610/head
KristianTashkov 5 years ago
parent 4d282c7a88
commit 2bb2c25fd3

@ -99,12 +99,14 @@ public class StreakChart extends View
{
Timestamp start = DateUtils.getToday();
LinkedList<Streak> streaks = new LinkedList<>();
Random random = new Random();
for (int i = 0; i < 10; i++)
{
int length = new Random().nextInt(100);
int length = random.nextInt(100);
int skipDays = random.nextInt(Math.max(0, length - 2));
Timestamp end = start.plus(length);
streaks.add(new Streak(start, end));
streaks.add(new Streak(start, end, skipDays));
start = end.plus(1);
}

@ -29,10 +29,13 @@ public final class Streak
private final Timestamp end;
public Streak(Timestamp start, Timestamp end)
private final int skipDays;
public Streak(Timestamp start, Timestamp end, int skipDays)
{
this.start = start;
this.end = end;
this.skipDays = skipDays;
}
public int compareLonger(Streak other)
@ -55,7 +58,7 @@ public final class Streak
public int getLength()
{
return start.daysUntil(end) + 1;
return start.daysUntil(end) + 1 - skipDays;
}
public Timestamp getStart()
@ -69,6 +72,7 @@ public final class Streak
return new ToStringBuilder(this, defaultToStringStyle())
.append("start", start)
.append("end", end)
.append("skipDays", skipDays)
.toString();
}
@ -84,6 +88,7 @@ public final class Streak
return new EqualsBuilder()
.append(start, streak.start)
.append(end, streak.end)
.append(skipDays, streak.skipDays)
.isEquals();
}
@ -93,6 +98,7 @@ public final class Streak
return new HashCodeBuilder(17, 37)
.append(start)
.append(end)
.append(skipDays)
.toHashCode();
}
}

@ -89,84 +89,69 @@ public abstract class StreakList
@NonNull
protected List<Streak> checkmarksToStreaks(Timestamp beginning, int[] checks)
{
ArrayList<Timestamp> transitions = getTransitions(beginning, checks);
List<Streak> streaks = new LinkedList<>();
for (int i = 0; i < transitions.size(); i += 2)
{
Timestamp start = transitions.get(i);
Timestamp end = transitions.get(i + 1);
streaks.add(new Streak(start, end));
}
return streaks;
}
/**
* Finds the place where we should start when recomputing the streaks.
*
* @return
*/
@Nullable
protected Timestamp findBeginning()
{
Streak newestStreak = getNewestComputed();
if (newestStreak != null) return newestStreak.getStart();
Repetition oldestRep = habit.getRepetitions().getOldestSuccessful();
if (oldestRep != null) return oldestRep.getTimestamp();
return null;
}
/**
* Returns the timestamps where there was a transition from performing a
* habit to not performing a habit, and vice-versa.
*
* @param beginning the timestamp for the first checkmark
* @param checks the checkmarks, ordered by decreasing timestamp
* @return the list of transitions
*/
@NonNull
protected ArrayList<Timestamp> getTransitions(Timestamp beginning, int[] checks)
{
ArrayList<Timestamp> list = new ArrayList<>();
Timestamp current = beginning;
Timestamp lastChecked = beginning;
Timestamp streakStart = beginning;
boolean isInStreak = false;
int skipDaysInStreak = 0;
for (int i = checks.length - 1; i >= 0; --i)
{
boolean isCurrentChecked = (
checks[i] == Checkmark.CHECKED_EXPLICITLY ||
checks[i] == Checkmark.CHECKED_IMPLICITLY ||
checks[i] == Checkmark.UNCHECKED_EXPLICITLY_UNNECESSARY
checks[i] == Checkmark.CHECKED_IMPLICITLY ||
checks[i] == Checkmark.UNCHECKED_EXPLICITLY_UNNECESSARY
);
boolean isCurrentUnchecked= (
checks[i] == Checkmark.UNCHECKED ||
checks[i] == Checkmark.UNCHECKED_EXPLICITLY_NECESSARY
checks[i] == Checkmark.UNCHECKED_EXPLICITLY_NECESSARY
);
if (habit.getData().type == Habit.NUMBER_HABIT || isCurrentChecked)
lastChecked = current;
if (isInStreak && isCurrentUnchecked)
if (isInStreak && checks[i] == Checkmark.SKIPPED_EXPLICITLY)
skipDaysInStreak += 1;
else if (isInStreak && isCurrentUnchecked)
{
list.add(lastChecked);
skipDaysInStreak -= lastChecked.daysUntil(current) - 1;
streaks.add(new Streak(streakStart, lastChecked, skipDaysInStreak));
isInStreak = false;
}
if (!isInStreak && isCurrentChecked)
else if (!isInStreak && isCurrentChecked)
{
list.add(current);
streakStart = current;
isInStreak = true;
skipDaysInStreak = 0;
}
current = current.plus(1);
}
if (isInStreak)
list.add(lastChecked);
{
skipDaysInStreak -= lastChecked.daysUntil(current) - 1;
streaks.add(new Streak(streakStart, lastChecked, skipDaysInStreak));
}
return list;
return streaks;
}
/**
* Finds the place where we should start when recomputing the streaks.
*
* @return
*/
@Nullable
protected Timestamp findBeginning()
{
Streak newestStreak = getNewestComputed();
if (newestStreak != null) return newestStreak.getStart();
Repetition oldestRep = habit.getRepetitions().getOldestSuccessful();
if (oldestRep != null) return oldestRep.getTimestamp();
return null;
}
protected abstract void add(@NonNull List<Streak> streaks);

@ -122,8 +122,8 @@ public class StreakListTest extends BaseUnitTest
public void testToString() throws Exception
{
Timestamp time = Timestamp.ZERO.plus(100);
Streak streak = new Streak(time, time.plus(10));
Streak streak = new Streak(time, time.plus(10), 3);
assertThat(streak.toString(), equalTo(
"{start: 1970-04-11, end: 1970-04-21}"));
"{start: 1970-04-11, end: 1970-04-21, skipDays: 3}"));
}
}
Loading…
Cancel
Save