Lancer un script comprenant une interaction utilisateur dans une boucle

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

theo daon
Messages : 9
Enregistré le : 11 Fév 2020, 08:07

Lancer un script comprenant une interaction utilisateur dans une boucle

Messagepar theo daon » 11 Fév 2020, 09:17

Bonjour,

Désolé pour ce titre un peu long mais il résume bien mon problème. Voilà une version simplifiée de mon script :

Code : Tout sélectionner

genes <- c("DX","TR","VU","ZT","SR","TU","CO")
geneskept <- c()

for (i in 1:length(genes)) {
  a = genes[i]
  cat("\nkeep gene",a,"?")
  choix=c("yes","no")   
  answer 
<- menu(choix)
  if(answer == 1){cat("gene",a,"will be kept\n");geneskept <- c(geneskept,a)}
  if(answer == 2){cat("gene",a,"won't be kept\n")}
}

cat("\ngene(s)",setdiff(genes,geneskept),"won't be kept\n")


Si je ne lance pas le script complet (i.e si j’omets la dernière ligne), je peux bien choisir de conserver ou non les différents éléments du vecteur "genes". Seulement, si je lance le script complet, voici les première lignes de ma console...

Code : Tout sélectionner

Selection:
Entrer un des items du menu, ou 0 pour sortir
Selection:
Entrer un des items du menu, ou 0 pour sortir
Selection: cat("\ngene(s)",setdiff(genes,geneskept),"won't be kept\n")
Entrer un des items du menu, ou 0 pour sortir
Selection:


Je peux ensuite choisir de conserver ou non les différents éléments du vecteur "genes" mais le script s'arrête là. Si jamais je rajoute des lignes elles sont lues de la même manière et passent à la trappe.

Une idée ? :)

Eric Casellas
Messages : 767
Enregistré le : 06 Jan 2009, 14:59

Re: Lancer un script comprenant une interaction utilisateur dans une boucle

Messagepar Eric Casellas » 11 Fév 2020, 09:53

Salut,

A priori ton soucis viens du fait qu'il utilise les lignes de codes comme si c'était des réponses de l'utilisateur.
Tu peut forcer le périmètre de ton code si tu met ton code entre {} ou carrément dans une fonction que tu appelle...

Et sinon autre petite remarque sur ton code tu peut faire ta boucle directement sur ton objet genes vu que ton i ne sers qu'à ça (for (a in genes))

Eric
Eric

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Lancer un script comprenant une interaction utilisateur dans une boucle

Messagepar Mickael Canouil » 11 Fév 2020, 10:56

Bonjour,

Une réponse (proche de celle de Eric) : viewtopic.php?f=3&t=6637

EDIT: ne pas mélanger les signes d'affectations (<- et =; privilégiez <-) pour des questions de lisibilité.
La fonction switch() me semble plus approprier que plusieurs if surtout qu'ils sont basés sur le même objet.

EDIT2: voici ce que je ferai dans le cas présent

Code : Tout sélectionner

ask_gene <- function(genes) {
  choices <- c("yes", "no")
  genes_kept <- sapply(genes, function(igene) {
    cat("\nkeep gene", igene, "?")
    switch(menu(choices),
      "1" = {
        cat("gene", igene, "will be kept\n")
        TRUE
      
},
      "2" = {
        cat("gene", igene, "won't be kept\n")
        FALSE
      
}
    )
  })
  cat("\ngene(s)", genes[!genes_kept], "won't be kept\n")
  genes[genes_kept]
}


Code : Tout sélectionner

geneskept <- ask_gene(c("DX", "TR", "VU", "ZT", "SR", "TU", "CO"))


Avec un if else

Code : Tout sélectionner

ask_gene <- function(genes) {
  choices <- c("yes", "no")
  genes_kept <- sapply(genes, function(igene) {
    cat("\nkeep gene", igene, "?")
    is_yes <- menu(choices) == 1
    if 
(is_yes) {
      cat("gene", igene, "will be kept\n")
    } else {
      cat("gene", igene, "won't be kept\n")
    }
    is_yes
  
})
  cat("\ngene(s)", genes[!genes_kept], "won't be kept\n")
  genes[genes_kept]


Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Lancer un script comprenant une interaction utilisateur dans une boucle

Messagepar Logez Maxime » 11 Fév 2020, 13:27

Bonjour,

tu peux remplacer menu par readLines :

Code : Tout sélectionner

genes <- c("DX","TR","VU","ZT","SR","TU","CO")
geneskept <- c()

for (i in 1:length(genes)) {
  a = genes[i]
  cat("\nkeep gene",a,"?\n1: yes\n2: no\n")
  answer <- readLines(n = 1)
  if(answer == 1){cat("gene",a,"will be kept\n");geneskept <- c(geneskept,a)}
  if(answer == 2){cat("gene",a,"won't be kept\n")}
}

cat("\ngene(s)",setdiff(genes,geneskept),"won't be kept\n")
Cordialement,
Maxime

theo daon
Messages : 9
Enregistré le : 11 Fév 2020, 08:07

Re: Lancer un script comprenant une interaction utilisateur dans une boucle

Messagepar theo daon » 13 Fév 2020, 08:00

Bonjour !

Merci à vous pour vos retours !
Forcer le périmètre du code fonctionne très bien. Les autres propositions également d'ailleurs :)

J'ai commencé par mettre des "=" partout. Je me force à tout mettre en "<-" maintenant mais ça m'échappe encore quelque fois !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité

cron