🔀 merge master + some fixes and todo

pull/4/head
remrem 1 year ago
commit 00d7ba9b5a

@ -0,0 +1,39 @@
import pandas as pd
import numpy as np
from sklearn.calibration import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# Load data from CSV
df = pd.read_csv("data\\data_emple.csv")
category = df.iloc[0:len(df),0].values
otherData = df.iloc[0:len(df),1:6].values
print(otherData)
# Encode the categorical target variable
label_encoder = LabelEncoder()
category_encoded = label_encoder.fit_transform(category)
model = LinearRegression()
model.fit(otherData,category_encoded)
new_data = np.array([224.0,228.49,346.6000000000000,1.1007253886010361,101]).reshape(1, -1)
# Faites une prédiction avec le modèle entraîné
prediction = model.predict(new_data)
# Affichez la prédiction
print("Prédiction:", prediction)
# Supposons que label_encoder soit l'objet LabelEncoder que vous avez utilisé lors de l'entraînement
inverse_prediction = label_encoder.inverse_transform(prediction.astype(int))
# Affichez la prédiction sous forme de chaîne de caractères
print("Prédiction (en chaîne de caractères):", inverse_prediction)

@ -0,0 +1,6 @@
category,distance,timeOfActivity,denivelePositif,speedAvg,bpmAvg
walking,2147.0,1716.5,471.5999999999999,1.2740575455079353,114
walking,1013.0,933.24,393.2000000000004,1.2849015317286667,122
walking,225.0,228.49,346.6000000000006,1.1007253886010366,99
cycling,20525.4,6770.675,597.8000000000001,3.5130617816091947,143
1 category distance timeOfActivity denivelePositif speedAvg bpmAvg
2 walking 2147.0 1716.5 471.5999999999999 1.2740575455079353 114
3 walking 1013.0 933.24 393.2000000000004 1.2849015317286667 122
4 walking 225.0 228.49 346.6000000000006 1.1007253886010366 99
5 cycling 20525.4 6770.675 597.8000000000001 3.5130617816091947 143

@ -0,0 +1,29 @@
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
df = pd.read_csv("data\\data_emple.csv")
distance = df.iloc[0:len(df),1].values.reshape(-1, 1)
time = df.iloc[0:len(df),2].values.reshape(-1, 1)
model = LinearRegression()
# Entrainement
model.fit(time,distance)
# Afficher les coefficients du modèle
print("Coefficients :", model.coef_)
print("Intercept :", model.intercept_)
# Supposons que vous avez de nouvelles données pour lesquelles vous voulez faire des prédictions
new_time_data = np.array([1000]).reshape(1,-1) # Exemple de nouvelles données pour 'time'
# Faire des prédictions sur les nouvelles données
predicted_distance = model.predict(new_time_data)
# Afficher les prédictions
print("Prédictions de distance :", predicted_distance[0])

@ -0,0 +1,24 @@
# IA
## Fonctionnement
Déterminé une activité pour l'utilisateur
### Data
Utiliser les activityInfo (vitesseAvg,BPM,....)
### Raisonnement
L'utilisateur pourra noter son activiter "Facile,moyen,dur" demander une note sur 100
### Calcul
En fonction de la note
Il devra savoir et répondre une séance
-> Vous devrez faire tant de km à x vitesse
-> Vous serez entre x BPM
-> Essayer de faire x denivelé
-> .... etc

File diff suppressed because it is too large Load Diff

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common_widget/container/container_stats_activities.dart';
import 'package:smartfit_app_mobile/modele/convertisseur.dart';
class VolumesList extends StatelessWidget {
final Map<String, dynamic> volume;
const VolumesList({super.key, required this.volume});
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
// TODO: True message with variables and context aware
if (volume["nbActivity"] == 0) {
return const Text("Aucune activité ces x jours/mois/années");
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ContainerStatsActivities(volume["nbActivity"].toString(),
"Nombre Activitée(s)", Icons.numbers),
SizedBox(
width: media.width * 0.03,
),
ContainerStatsActivities(
"${Convertisseur.secondeIntoMinute(volume["durationActiviy"]).toStringAsFixed(2)} m",
"Temps Total",
Icons.timer),
SizedBox(
width: media.width * 0.03,
),
ContainerStatsActivities(
volume["bpmAvg"].toString(), "Bpm Moyens", Icons.favorite),
SizedBox(
width: media.width * 0.03,
),
ContainerStatsActivities(
" ${Convertisseur.msIntoKmh(volume["speedAvg"]).toStringAsFixed(2)} km/h",
"Vitesse Moyenne",
Icons.bolt),
SizedBox(
width: media.width * 0.03,
),
ContainerStatsActivities(
"${volume["denivelePositif"].toStringAsFixed(2)} m",
"Dénivelé Positif",
Icons.hiking),
],
),
);
}
}

@ -19,8 +19,8 @@ class MobileContainerStatsActivities extends StatelessWidget {
var media = MediaQuery.of(context).size;
return Container(
height: media.width * 0.4,
width: media.width * 0.27,
height: media.width * 0.33,
width: media.width * 0.28,
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
@ -49,7 +49,7 @@ class MobileContainerStatsActivities extends StatelessWidget {
iconBackground: TColor.secondaryColor1,
sizeIcon: 30.0,
),
const SizedBox(height: 20), // Espacement entre l'icône et le texte
const SizedBox(height: 10), // Espacement entre l'icône et le texte
Text(
designation,
style: const TextStyle(fontSize: 12),

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
class ProfileEntete extends StatelessWidget {
const ProfileEntete(this.username, {super.key});
@ -45,7 +44,6 @@ class ProfileEntete extends StatelessWidget {
],
),
),
],
);
}

@ -20,7 +20,7 @@ class WebContainerStatsActivities extends StatelessWidget {
return Container(
height: media.width * 0.2,
width: media.width * 0.3,
width: media.width * 0.28,
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(

@ -15,6 +15,7 @@ Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
localDB = await ObjectBox.create();
await localDB.init();
localDB.configBox.put(db.Config(0, true));
runApp(ChangeNotifierProvider(
create: (context) => User(), child: const MyApp()));

@ -18,7 +18,7 @@ class ActivityOfUser {
ActivityInfo get activityInfo => _activityInfo;
Map<String, int> get enteteCSV => _enteteCSV;
// -- Getter/Setter -- Ancien //
// -- Getter/Setter -- //
List<List<dynamic>> get contentActivity => _contentActivity;
set contentActivity(List<List<dynamic>> content) {
_contentActivity = content;
@ -39,7 +39,7 @@ class ActivityOfUser {
}
}
// -------------------------- FIN Localisation ---------------------- //
// -------------------------- ToMap ---------------------- //
Map<String, dynamic> toMapGeneric() {
Map<String, dynamic> map = {

@ -58,7 +58,7 @@ class ObjectBox {
}
void addUser(String username, String email, String token) {
userBox.put(User(1, username, email, token));
userBox.put(User(0, username, email, token));
}
// ===== Activity =====

@ -186,6 +186,7 @@ class ManagerFile {
Map<String, Map<String, String>> ligneDataResult = {};
// -- Skip ligne whith no data -- //
bool skip = true;
int nbData = 0;
// -- Si ce n'est pas de la data on pass -- //
if (listeField[0] != "Data") {
@ -198,7 +199,10 @@ class ManagerFile {
tmp["Unite"] = listeField[i + 2].toString();
ligneDataResult[listeField[i]] = tmp;
i += 2;
skip = false;
nbData += 1;
if (nbData >= 2) {
skip = false;
}
}
// -- Pour boucler -- //

@ -107,7 +107,10 @@ class ManagerSelectedActivity {
for (ActivityOfUser activityOfUser in activitySelected) {
somme += activityOfUser.activityInfo.bpmAvg;
}
return somme ~/ activitySelected.length;
if (somme != 0) {
return somme ~/ activitySelected.length;
}
return somme;
}
// ------------------ Fin BPM ------------------- //
@ -139,8 +142,27 @@ class ManagerSelectedActivity {
}
return somme / activitySelected.length;
}
// ------------------ Fin Altitude ------------------- //
// ------------------ Denivelé ----------------------- //
double getTotalDenivelePositifAllActivitySelected() {
double somme = 0;
for (ActivityOfUser activityOfUser in activitySelected) {
somme += activityOfUser.activityInfo.denivelePositif;
}
return somme;
}
double getTotalDeniveleNegatifAllActivitySelected() {
double somme = 0;
for (ActivityOfUser activityOfUser in activitySelected) {
somme += activityOfUser.activityInfo.denivelePositif;
}
return somme;
}
// ------------------ Fin Denivelé ------------------- //
// ------------------ Température -------------------- //
int getAvgTemperatureAllActivitySelected() {
int somme = 0;

@ -52,4 +52,35 @@ class User extends ChangeNotifier {
}
return totalDevNeg;
}
// ------------ Volume -------------- //
Map<String, dynamic> getVolumeWhithDuration(Duration timeSoustract) {
List<ActivityOfUser> liste = [];
for (ActivityOfUser activityOfUser in listActivity) {
// Si l'activité à commencer après la dateActuelle moins 7 jours
if (activityOfUser.activityInfo.startTime
.isAfter(DateTime.now().subtract(timeSoustract))) {
liste.add(activityOfUser);
}
}
return _getVolume(liste);
}
Map<String, dynamic> getVolumeAllTime() {
return _getVolume(listActivity);
}
Map<String, dynamic> _getVolume(List<ActivityOfUser> list) {
Map<String, dynamic> map = {};
ManagerSelectedActivity selected = ManagerSelectedActivity();
selected.activitySelected = list;
map["nbActivity"] = selected.activitySelected.length;
map["bpmAvg"] = selected.getBpmAvgAllActivitieSelected();
map["denivelePositif"] =
selected.getTotalDenivelePositifAllActivitySelected();
map["speedAvg"] = selected.getAvgSpeedAllActivitySelected();
map["durationActiviy"] = selected.getTimeAllActivitySelected();
return map;
}
}

@ -66,7 +66,6 @@ class ListActivityUtile {
Provider.of<User>(context, listen: false).listActivity.clear();
notZero = true;
}
// -- connaitre le type de categorie pour changer le type d'info -- //
Provider.of<User>(context, listen: false).addActivity(ActivityOfUser(
ActivityInfo.fromJson(element["info"]),

@ -47,8 +47,13 @@ class _MobileHomeView extends State<MobileHomeView> {
// -- Speed -- //
double maxSpeed = managerSelectedActivity.getMaxSpeedAllActivitySelected();
double avgSpeed = managerSelectedActivity.getAvgSpeedAllActivitySelected();
double minSpeed = managerSelectedActivity.getMinSpeedAllActivitySelected();
data.maxSpeed = maxSpeed;
data.time = context.watch<User>().managerSelectedActivity.getTimeAllActivitySelected();
data.time = context
.watch<User>()
.managerSelectedActivity
.getTimeAllActivitySelected();
return Scaffold(
backgroundColor: TColor.white,
body: SingleChildScrollView(
@ -107,14 +112,14 @@ class _MobileHomeView extends State<MobileHomeView> {
),
LigneContainerStats(
"${double.parse(maxSpeed.toStringAsFixed(2))} m/s",
"${double.parse(minSpeed.toStringAsFixed(2))} m/s",
"${double.parse(avgSpeed.toStringAsFixed(2))} m/s",
"${avgBpm.toString()} BPM",
"Max Speed",
"Moyenne Speed",
"Moyenne BPM",
"Max vitesse",
"Min vitesse",
"Moyenne vitesse",
Icons.trending_down,
Icons.trending_up,
Icons.favorite_outline),
Icons.trending_up),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -135,9 +140,9 @@ class _MobileHomeView extends State<MobileHomeView> {
"${minAltitude.toInt()} M",
"${maxAltitude.toInt()} M",
"${avgAltitude.toInt()} M",
"Minimum",
"Maximum",
"Moyenne",
"Altitude minimum",
"Altitude maximum",
"Altitude moyenne",
Icons.trending_down,
Icons.trending_up,
Icons.favorite_outline),

@ -139,7 +139,7 @@ class _StatAtivities extends State<StatAtivities> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
ContainerStatsActivities(
"$avgSpeed m/s", "Moyenne vitesse", Icons.bolt),
"${avgSpeed.toStringAsFixed(2)} m/s", "Moyenne vitesse", Icons.bolt),
SizedBox(
width: media.width * 0.03,
),
@ -179,7 +179,7 @@ class _StatAtivities extends State<StatAtivities> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
ContainerStatsActivities(
"$avgAltitude m", "Moyenne Altitude", Icons.landscape),
"${avgAltitude.toStringAsFixed(2)} m", "Moyenne Altitude", Icons.landscape),
SizedBox(
width: media.width * 0.03,
),

@ -1,10 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:smartfit_app_mobile/modele/utile/login_user.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart';
import 'package:smartfit_app_mobile/main.dart';
import 'package:smartfit_app_mobile/modele/utile/login_user.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:tuple/tuple.dart';
class MobileLoginView extends StatefulWidget {
@ -164,7 +165,8 @@ class _MobileLoginView extends State<MobileLoginView> {
"Impossible de récupéré les données de l'utilisateur - {$infoUser.item2}");
} else {
util.fillUser(context, infoUser.item2, result.item2);
localDB.addUser(infoUser.item2["username"],
infoUser.item2["email"], result.item2);
Navigator.push(
context,
MaterialPageRoute(

@ -1,12 +1,11 @@
import 'package:smartfit_app_mobile/modele/local_db/model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:smartfit_app_mobile/main.dart';
import 'package:smartfit_app_mobile/modele/utile/login_user.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart';
import 'package:smartfit_app_mobile/main.dart';
import 'package:smartfit_app_mobile/modele/utile/login_user.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:tuple/tuple.dart';
class WebLoginView extends StatefulWidget {
@ -152,6 +151,7 @@ class _WebLoginView extends State<WebLoginView> {
RoundButton(
title: "Se connecter",
onPressed: () async {
// TODO: utiliser la vrai validation
if (!emailValidate || !passwordValidate) {
_printMsgError("Les champs renseigné ne sont pas valide");
return;
@ -170,9 +170,8 @@ class _WebLoginView extends State<WebLoginView> {
"Impossible de récupéré les données de l'utilisateur - {$infoUser.item2}");
} else {
util.fillUser(context, infoUser.item2, result.item2);
localDB.userBox.put(User(0, infoUser.item2["username"],
infoUser.item2["email"], result.item2));
localDB.configBox.put(Config(0, false));
localDB.addUser(infoUser.item2["username"],
infoUser.item2["email"], result.item2);
Navigator.push(
context,
MaterialPageRoute(

@ -6,6 +6,7 @@ import 'package:smartfit_app_mobile/view/home/home_view.dart';
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/view/map/my_map.dart';
import 'package:smartfit_app_mobile/view/profile/profile_view.dart';
import 'package:smartfit_app_mobile/view/volumes/volumes_view.dart';
class MobileMainTabView extends StatefulWidget {
const MobileMainTabView({super.key});
@ -88,15 +89,26 @@ class _MobileMainTabViewState extends State<MobileMainTabView> {
setState(() {});
}
}),
TabButton(
icon: "assets/img/Activity_tab.svg",
selectIcon: "assets/img/Activity_tab_select.svg",
isActive: selectTab == 2,
onTap: () {
selectTab = 2;
currentTab = const VolumesView();
if (mounted) {
setState(() {});
}
}),
const SizedBox(
width: 40,
),
TabButton(
icon: "assets/img/mapIcon.svg",
selectIcon: "assets/img/mapIcon_selected.svg",
isActive: selectTab == 2,
isActive: selectTab == 3,
onTap: () {
selectTab = 2;
selectTab = 3;
currentTab = const MyMap();
if (mounted) {
setState(() {});
@ -105,9 +117,9 @@ class _MobileMainTabViewState extends State<MobileMainTabView> {
TabButton(
icon: "assets/img/Profile_tab.svg",
selectIcon: "assets/img/Profile_tab_select.svg",
isActive: selectTab == 3,
isActive: selectTab == 4,
onTap: () {
selectTab = 3;
selectTab = 4;
currentTab = const ProfileView();
if (mounted) {
setState(() {});

@ -42,24 +42,26 @@ class _ChoseMap extends State<ChoseMap> {
height: media.height * 0.1,
),
RoundButton(
title: "Use map with google map",
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MobileMyMaps()));
},
),
title: "Use map with google map",
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MobileMyMaps()));
},
),
SizedBox(
height: media.height * 0.03,
),
RoundButton(
title : "Use map with Open Street Map",
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => const MyMapOSM()));
},
),
title: "Use map with Open Street Map",
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MyMapOSM()));
},
),
Spacer(),
],
),
@ -67,18 +69,5 @@ class _ChoseMap extends State<ChoseMap> {
),
),
);
return Scaffold(
backgroundColor: TColor.white,
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Mettre une image la en mode une personne avec des jumelles")
],
)),
);
}
}

@ -28,9 +28,9 @@ class _MyMapState extends State<MyMap> {
if (listSelected.length > 1) {
return ScreenTypeLayout.builder(
mobile: (_) => const NoActivityView(
"Qu'une seule activité doit être sélectionner"),
"Une seule activité doit être sélectionnée"),
desktop: (_) => const NoActivityView(
"Qu'une seule activité doit être sélectionner"),
"Une seule activité doit être sélectionnée"),
);
}
return ScreenTypeLayout.builder(

@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/common_widget/container/list/volumes_list.dart';
import 'package:smartfit_app_mobile/common_widget/other/entete_home_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/modele/utile/home_view/data_home_view.dart';
class VolumesView extends StatefulWidget {
const VolumesView({super.key});
@override
State<VolumesView> createState() => _VolumesViews();
}
class _VolumesViews extends State<VolumesView> {
late DataHomeView data;
TextEditingController bpmController = TextEditingController();
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
User user = context.watch<User>();
DateTime date = DateTime.now();
Map<String, dynamic> volume7Days =
user.getVolumeWhithDuration(const Duration(days: 7));
Map<String, dynamic> volume1Months =
user.getVolumeWhithDuration(const Duration(days: 30));
Map<String, dynamic> volume1Year =
user.getVolumeWhithDuration(const Duration(days: 366));
Map<String, dynamic> volumeAllTime = user.getVolumeAllTime();
return Scaffold(
backgroundColor: TColor.white,
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: media.width * 0.03,
),
const EnteteHomeView(),
SizedBox(
height: media.width * 0.05,
),
Text(
"Derniere semaine : ${date.day}/${date.month}/${date.year} - ${date.subtract(const Duration(days: 7)).day}/${date.subtract(const Duration(days: 7)).month}/${date.subtract(const Duration(days: 7)).year}",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
SizedBox(
height: media.width * 0.03,
),
VolumesList(volume: volume7Days),
SizedBox(
height: media.width * 0.03,
),
Text(
"Dernier Mois : ${date.day}/${date.month}/${date.year} - ${date.subtract(const Duration(days: 30)).day}/${date.subtract(const Duration(days: 30)).month}/${date.subtract(const Duration(days: 30)).year}",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
VolumesList(volume: volume1Months),
SizedBox(
height: media.width * 0.03,
),
Text(
"Dernière année : ${date.day}/${date.month}/${date.year} - ${date.subtract(const Duration(days: 366)).day}/${date.subtract(const Duration(days: 366)).month}/${date.subtract(const Duration(days: 366)).year}",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
VolumesList(volume: volume1Year),
SizedBox(
height: media.width * 0.03,
),
Text(
"Total",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
VolumesList(volume: volumeAllTime),
SizedBox(
height: media.width * 0.03,
),
],
),
),
),
),
);
}
}
Loading…
Cancel
Save