Mon terrarium Lowland

Comment faire pour créer, entretenir un terrarium, une tourbière ou encore un serre. N'hésiter pas à poster les photos de vos propres installations.
Guttata
Messages : 1069
Enregistré le : 23 janv. 2005 19:46
Localisation : 78
Contact :

Re: Mon terrarium Lowland

Message par Guttata »

Si ce n'est pas indiscret pourrais-tu m'envoyer un de tes scripts nécessitant d'être killé ?

Le script contient une boucle infini ? Ou est il lancé par un cron ?



Avatar du membre
Vince81
Administrateur
Administrateur
Messages : 4147
Enregistré le : 23 sept. 2007 20:16
Localisation : Paris

Re: Mon terrarium Lowland

Message par Vince81 »

Merci pour les infos, je n'avais pas pensé à utiliser un script pour lancer l'autre script.
Le script contient une boucle infini ? Ou est il lancé par un cron ?
Ca change quoi ? Je suis sur une boucle infini (enfin, plutôt une fonction récursive, qui s'appelle elle-même). C'est grave docteur ?
Vince
Mes plantes
Mon terrarium highland
Liste de culture

"Il n'y a pas de plante difficile, il faut juste trouver les bonnes conditions"

Aide-toi et le ciel forum t'aidera.

Guttata
Messages : 1069
Enregistré le : 23 janv. 2005 19:46
Localisation : 78
Contact :

Mon terrarium Lowland

Message par Guttata »

De manière générale les boucles infinies sont à proscrire, sauf réelle nécessité :
Exemple: Boucle de jeu dans un jeu vidéo.

 quoi sert ton script ? Faire un relevé de température à intervalle régulier ?
Il serait plus propre de créer une tache cron exécutant ton script à la fréquence voulue plutôt que de faire un while true avec des timers dans tous les sens.

Tu as fait de la récursivité :D c'est un concept difficile à comprendre normalement en programmation :O tu dois absolument avoir un état initial(ton appel de fonction) et un cas final (qui te permets de sortir de la récursivité)
La récursivité ne s'emploie pas pour gérer une boucle infinie (autant faire le while true).
A chaque fois que tu appelles ta fonction tu empiles des informations dans ta stack. Quand tu sors de ta fonction les éléments empilés sont dépilés.
Exemple: je browse un répertoire avec des sous dossiers (j'empile à chaque fois que je vais en profondeur)et des sous sous dossiers. À la fin de ton browsing tu es censé être revenu en arrière de répertoire en répertoire jusqu'à ton répertoire initial.

Après si ça marche ça ne vaut pas le coup de tout revoir.

Si vous le souhaitez je peux vous partager mes sources (sites web, bdd, scripts). Des choses auraient pu être mieux codées mais c'est déjà pas trop mal.

Avatar du membre
Vince81
Administrateur
Administrateur
Messages : 4147
Enregistré le : 23 sept. 2007 20:16
Localisation : Paris

Re: Mon terrarium Lowland

Message par Vince81 »

Guttata a écrit :Â quoi sert ton script ? Faire un relevé de température à intervalle régulier ?
Il serait plus propre de créer une tache cron exécutant ton script à la fréquence voulue plutôt que de faire un while true avec des timers dans tous les sens.
Il fait tout : il récupère les données des capteurs, actualise les données sur ma p'tite interface, compare les données avec les valeurs seuils, vérifie que je n'ai pas de conditions prioritaires avant de comparer avec les valeurs seuils... Et il est reparti pour un tour :).
Et il le fait toutes les 5 secondes je crois (pour donner du temps à faire le script, parce que certains capteurs n'aiment pas être stimulés plus régulièrement que ça, mais pas plus long parce que je veux que si j'ouvre la porte, cela soit détecté assez rapidement, et pas avoir à attendre 1 minute). Il me semblait qu'un cron ne pouvait pas passer sous la minute :roll: .
Tu as fait de la récursivité :D c'est un concept difficile à comprendre normalement en programmation :O tu dois absolument avoir un état initial(ton appel de fonction) et un cas final (qui te permets de sortir de la récursivité)
La récursivité ne s'emploie pas pour gérer une boucle infinie (autant faire le while true).
A chaque fois que tu appelles ta fonction tu empiles des informations dans ta stack. Quand tu sors de ta fonction les éléments empilés sont dépilés.
Exemple: je browse un répertoire avec des sous dossiers (j'empile à chaque fois que je vais en profondeur)et des sous sous dossiers. À la fin de ton browsing tu es censé être revenu en arrière de répertoire en répertoire jusqu'à ton répertoire initial.

Après si ça marche ça ne vaut pas le coup de tout revoir.
J'ai vu la récursivité quand j'ai commencé à vouloir afficher l'heure sur mon interface. Ca me permettait d'éviter de passer par des threads ou du parallélisme dans ce goût là. J'avais plusieurs fonctions récursives, mais je me suis dit que cela devait certainement être plus difficile pour le RPI d'avoir plusieurs fonctions récursives avec différents temps de rafraichissement qu'une seule fonction, avec un temps "moyen".
Par contre, empiler et dés-empiler, si je vois très bien ton image, dans la pratique, je ne vois pas à quoi ça correspond :lol:. Je me demande ce que j'empile et que je dés-empile (ou pas pour ce dernier point) dans ma fonction.

Pour le "si ça marche...", j'avais un bug, assez régulier avant de passer sur le circuit imprimé. Lorsque j'avais ce bug, Python ne répondait plus. Si je ctrl+C ou ctrl+Z pour arrêter, lorsque j'essayais de relancer le script, cela ne voulait pas. Cela empêchait également le RPI de s'éteindre complètement.
Du coup, vu que j'ai fini de réinstaller le RPI proprement, je suis en phase de test pour voir si le bug était d'origine "codesque" ou "electroniquesque".
D'où la question sur la récursivité, pour voir si cela pourrait avoir un lien avec ce bug que j'avais (et que j'ai peut-être encore, même si cela a l'air moins sur).

La hiérarchisation de mon programme est assez naïve, Merwnn me disait qu'il valait mieux tout threader (ou mieux programmer dans l'ensemble, que je n'aille pas lui faire dire ce qu'il n'a pas dire). Mais bon, on se rapproche de compétences que le chaland n'a pas forcément :razz:.
Si vous le souhaitez je peux vous partager mes sources (sites web, bdd, scripts). Des choses auraient pu être mieux codées mais c'est déjà pas trop mal.
Si c'est compréhensible pour le commun des lecteurs, je veux bien :lol:. S'il faut être assez initié pour pouvoir bien tout comprendre, on posera des questions :razz:.

@ Max, souhaites-tu que je divise le poste ou pas ? Je me suis un peu étaler sur ton topic avec cette histoire d'anticiper les bugs. Tu me diras ce que tu préfères :wink:.
Vince
Mes plantes
Mon terrarium highland
Liste de culture

"Il n'y a pas de plante difficile, il faut juste trouver les bonnes conditions"

Aide-toi et le ciel forum t'aidera.

Guttata
Messages : 1069
Enregistré le : 23 janv. 2005 19:46
Localisation : 78
Contact :

Mon terrarium Lowland

Message par Guttata »

Hello,
Au début de l'exécution d'un programme, une pile d'exécution se créée.
Dans cette pile, ton programme va empiler :
- les adresses de retour des fonctions que tu appelles. Cela permet au programme à la sortie de la fonction active de savoir où reprendre le fil de son exécution
- les paramètres que tu donnes à tes fonctions
- toutes les variables que tu créées dans tes fonctions

L'idée comme je l'ai dis c'est bien sûr de dépiler au fur et à mesure (en remontant les appels de fonction => les fonctions se terminent) sinon tu risques d'exploser la pile (erreur stackoverflow).

Aujourd'hui ta récursivité si je comprend bien empile, empile, ..... Et empile :) tu ne dépiles jamais car tu ne termines jamais ta fonction.
Je pense que l'instabilité de ton Pi vient de là.

Je me renseigne plus en détails sur les particularités en Python (memory management, garbage collector)
Modifié en dernier par Guttata le 10 janv. 2015 10:08, modifié 1 fois.

Avatar du membre
Vince81
Administrateur
Administrateur
Messages : 4147
Enregistré le : 23 sept. 2007 20:16
Localisation : Paris

Re: Mon terrarium Lowland

Message par Vince81 »

Merci pour la réponse !

Du coup, soit il me faut vérifier d'avoir un return à la fin de chaque fonction, soit, il vaut mieux que je passes sur un while True ?
Vince
Mes plantes
Mon terrarium highland
Liste de culture

"Il n'y a pas de plante difficile, il faut juste trouver les bonnes conditions"

Aide-toi et le ciel forum t'aidera.

Guttata
Messages : 1069
Enregistré le : 23 janv. 2005 19:46
Localisation : 78
Contact :

Re: Mon terrarium Lowland

Message par Guttata »

Ce qui serait intéressant avant de toucher le code c'est de lancer manuellement le garbage collector (le poubelle manager :) ) cet outil a pour objectif de nettoyer la mémoire du programme.

import gc
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)

Il faudrait que tu l'invoques ou bout d'un certain nombres d'appels pour être représentatif (ie, au bout de 5000 appels récursifs exécution de l'instruction) .

As-tu une seule fonction récursive avec 400lignes
ou
Une fonction récursive de 20lignes qui appelle des fonctions ?

Avatar du membre
Vince81
Administrateur
Administrateur
Messages : 4147
Enregistré le : 23 sept. 2007 20:16
Localisation : Paris

Re: Mon terrarium Lowland

Message par Vince81 »

Guttata a écrit :Ce qui serait intéressant avant de toucher le code c'est de lancer manuellement le garbage collector (le poubelle manager :) ) cet outil a pour objectif de nettoyer la mémoire du programme.

import gc
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)

Il faudrait que tu l'invoques ou bout d'un certain nombres d'appels pour être représentatif (ie, au bout de 5000 appels récursifs exécution de l'instruction) .
Je vais voir ce que ça fait.
Vu que la fonction se lance toutes les 5 secondes, je suis très rapidement à 5000 appels :-D.

EDIT: Tu le lances pendant que l'autre script tourne ou après ?
As-tu une seule fonction récursive avec 400lignes
ou
Une fonction récursive de 20lignes qui appelle des fonctions ?
Au final, j'ai une fonction récursive avec plus de 400 lignes, avec des appels de fonction également (notamment pour récupérer les valeurs des capteurs).
Vince
Mes plantes
Mon terrarium highland
Liste de culture

"Il n'y a pas de plante difficile, il faut juste trouver les bonnes conditions"

Aide-toi et le ciel forum t'aidera.

Guttata
Messages : 1069
Enregistré le : 23 janv. 2005 19:46
Localisation : 78
Contact :

Mon terrarium Lowland

Message par Guttata »

Ouchh aille caramba. Ce que je recommanderai : découper au maximum le code, le structurer.

En gros :
Main()
while(true)
Probes = getProbes()
checkTreshold (Probes)
dsplayOnScreen(Probes)
Return

Dans getProbes()
getHygro
getTemp
getLight
Return Probes

...

Je suis sur l'iPhone, donc je ne me suis pas amusé à être exhaustif sur la définition des variables etc ;)

Guttata
Messages : 1069
Enregistré le : 23 janv. 2005 19:46
Localisation : 78
Contact :

Mon terrarium Lowland

Message par Guttata »

Il faut lancer le collector dans ton code (fonction récursive).
Tu ajoutes un paramètre (disons i) à ta fonction.

La première fois que tu appelles la fonction, tu mets 0 pour i

Tu incrémentes ce i de 1 dans ton code et tu ajoutes une condition.
Si i == 5000
gc.collect()
Print "garbage ...."

----------------------------------------

Def recurcive(i)
i++
If i == 5000:
Code garbage
.....
recurcive (i)
Return

Premier appel:
recurcive(0)

Répondre