Skip to content

Commit

Permalink
Merge pull request #9 from FlutterFriends/brylie/refactor-diversity-s…
Browse files Browse the repository at this point in the history
…core

Refactor workout diversity score calculation
  • Loading branch information
brylie authored Jul 28, 2024
2 parents 314df37 + 2165a95 commit fc940df
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 180 deletions.
53 changes: 31 additions & 22 deletions random_workout/lib/providers/app_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ class AppState extends ChangeNotifier {

Exercise _selectBalancedExercise() {
_availableExercises.sort((a, b) {
int scoreA = _calculateDiversityScore(a);
int scoreB = _calculateDiversityScore(b);
int scoreA = a.score;
int scoreB = b.score;
return scoreB.compareTo(scoreA); // Higher score is better
});

Expand All @@ -101,24 +101,6 @@ class AppState extends ChangeNotifier {
return _availableExercises[Random().nextInt(selectionPool)];
}

int _calculateDiversityScore(Exercise exercise) {
int score = 0;

exercise.muscleTargets?.forEach((muscle) {
score += 3 - min(2, _targetCounts[muscle] ?? 0);
});

exercise.jointTargets?.forEach((joint) {
score += 3 - min(2, _targetCounts[joint] ?? 0);
});

exercise.focusAreas?.forEach((focus) {
score += 3 - min(2, _targetCounts[focus] ?? 0);
});

return score;
}

void removeExercise(int index) {
_currentWorkout.removeAt(index);
_updateAvailableExercises();
Expand All @@ -135,11 +117,38 @@ class AppState extends ChangeNotifier {
}
}

/// Calculates the workout diversity score based on the number of unique targets engaged.
///
/// The score is calculated by counting the unique muscle targets, joint targets,
/// and focus areas engaged by all exercises in the current workout.
///
/// Returns the total diversity score of the current workout.
int get workoutDiversityScore {
return _currentWorkout.fold(
0, (sum, exercise) => sum + _calculateDiversityScore(exercise));
Set<dynamic> uniqueTargets = {};

for (var exercise in _currentWorkout) {
exercise.muscleTargets?.forEach((muscle) {
uniqueTargets.add(muscle);
});

exercise.jointTargets?.forEach((joint) {
uniqueTargets.add(joint);
});

exercise.focusAreas?.forEach((focus) {
uniqueTargets.add(focus);
});
}

return uniqueTargets.length;
}

/// Groups the target counts by type (Muscles, Joints, Focus Areas) and sorts them.
///
/// The target counts are grouped into three categories: Muscles, Joints, and Focus Areas.
/// Each group is sorted in descending order based on the count.
///
/// Returns a map where the keys are the group names and the values are the sorted target counts.
Map<String, List<MapEntry<dynamic, int>>> getGroupedTargetCounts() {
Map<String, List<MapEntry<dynamic, int>>> groupedCounts = {
'Muscles': [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class WorkoutDiversityDialog extends StatelessWidget {

@override
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);
final appState = Provider.of<AppState>(context, listen: false);
final groupedTargets = appState.getGroupedTargetCounts();

return AlertDialog(
Expand Down
44 changes: 40 additions & 4 deletions random_workout/test/mocks/mock_app_state.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:random_workout/providers/app_state.dart';
// import 'package:random_workout/models/exercise.dart';
import 'package:random_workout/models/exercise.dart';

@GenerateNiceMocks([MockSpec<AppState>()])
void main() {}
class MockAppState extends Mock implements AppState {
@override
bool get isDarkMode => super.noSuchMethod(
Invocation.getter(#isDarkMode),
returnValue: true,
returnValueForMissingStub: true,
);

@override
List<Exercise> get currentWorkout => super.noSuchMethod(
Invocation.getter(#currentWorkout),
returnValue: <Exercise>[],
returnValueForMissingStub: <Exercise>[],
);

@override
int get workoutDiversityScore => super.noSuchMethod(
Invocation.getter(#workoutDiversityScore),
returnValue: 0,
returnValueForMissingStub: 0,
);

@override
Map<String, List<MapEntry<dynamic, int>>> getGroupedTargetCounts() =>
super.noSuchMethod(
Invocation.method(#getGroupedTargetCounts, []),
returnValue: <String, List<MapEntry<dynamic, int>>>{
'Muscles': [],
'Joints': [],
'Focus Areas': [],
},
returnValueForMissingStub: <String, List<MapEntry<dynamic, int>>>{
'Muscles': [],
'Joints': [],
'Focus Areas': [],
},
);
}
145 changes: 0 additions & 145 deletions random_workout/test/mocks/mock_app_state.mocks.dart

This file was deleted.

4 changes: 2 additions & 2 deletions random_workout/test/models/exercise_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ void main() {
expect(exercise.category, ExerciseCategory.strength);
expect(
exercise.muscleTargets, [MuscleTarget.chest, MuscleTarget.triceps]);
expect(exercise.jointTargets, isNull);
expect(exercise.focusAreas, isNull);
expect(exercise.jointTargets, [JointTarget.elbow]);
expect(exercise.focusAreas, [FocusArea.upperBody]);
});

test('should return correct labels for targets', () {
Expand Down
Loading

0 comments on commit fc940df

Please sign in to comment.