2014-09-04 7 views
2

J'ai cette instruction if:Donner une instruction if une variable dans Ruby

if value_n_in_f > 0 && value_m_in_f != 1 
    puts "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}" 
    elsif value_n_in_f == 0 && value_m_in_f != 1 
    puts "I: f(x)=#{value_m_in_f}x" 
    elsif value_n_in_f < 0 && value_m_in_f != 1 
    puts "I: f(x)=#{value_m_in_f}x#{value_n_in_f}" 
    elsif value_n_in_f > 0 && value_m_in_f == 1 
    puts "I: f(x)=x+#{value_n_in_f}" 
    elsif value_n_in_f == 0 && value_m_in_f == 1 
    puts "I: f(x)=x" 
    elsif value_n_in_f < 0 && value_m_in_f == 1 
    puts "I: f(x)=x#{value_n_in_f}" 
    end` 

Je dois utiliser cette déclaration très souvent dans d'autres déclarations et il fait mon code inutilement long. Evidemment, if_for_f = if ....... end ne fonctionnera pas. Est-ce qu'il y a un autre moyen? Voici un exemple ce que je veux ressembler:

puts "Now we insert #{value_of_x} in #{if_for_f}" 

Est-il possible que je peux faire quelque chose comme ça? Notez que je suis absolument nouveau à cela.

Merci à l'avance, Kaiton

+1

Vous pouvez écrire une fonction appelée 'if_for_f' qui prend dans toutes les valeurs requises. – tadman

+1

Il me semble que la (seule) raison pour laquelle les conditions semblent désordonnées est parce que les noms de variables 'value_n_in_f' et' value_m_in_f' sont longs et inhabituels. Si vous leur faites une seule lettre, cela vous semblera simple. En fait, votre question n'est pas claire. – sawa

+0

Je veux juste mentionner que votre déclaration "Evidemment" est incorrecte. Vous pouvez affecter le résultat d'une instruction 'if' à une variable. Ce n'est pas ce que vous devriez faire ici, mais c'est possible - tout comme J-Dizzle attribue le résultat d'une instruction 'case' à une variable. –

Répondre

4

ne pas faire simplement une fonction def avec elle s fonction pour exécuter cette affaire déclaration et l'appeler puis quand j'en ai besoin?

Bien sûr:

def do_stuff(m, n) 
    if m == 1 
    if n > 0  then "I: f(x)=x+#{n}" 
    elsif n == 0 then "I: f(x)=x" 
    elsif n < 0 then "I: f(x)=x#{n}" 
    end 
    else 
    if n > 0  then "I: f(x)=#{m}x+#{n}" 
    elsif n == 0 then "I: f(x)=#{m}x" 
    elsif n < 0 then "I: f(x)=#{m}x#{n}" 
    end 
    end 
end 

puts do_stuff(1, 1) #I: f(x)=x+1 

Ou, si la compacité est l'objectif, nous pouvons arriver à ceci:

def do_stuff(m, n) 
    if m == 1 
    n == 0 ? "I: f(x)=x"  : "I: f(x)=x#{sprintf("%+d", n)}" 
    else 
    n == 0 ? "I: f(x)=#{m}x" : "I: f(x)=#{m}x#{sprintf("%+d", n)}" 
    end 
end 

... puis une doublure:

def do_stuff(m, n) 
    (m == 1) ? (n == 0 ? "I: f(x)=x" : "I: f(x)=x#{sprintf("%+d", n)}") : (n == 0 ? "I: f(x)=#{m}x" : "I: f(x)=#{m}x#{sprintf("%+d", n)}") 
end 
end 

Mais votre méthodologie a quelques problèmes avec les zéros et -1:

def do_stuff(value_m_in_f, value_n_in_f) 
if value_n_in_f > 0 && value_m_in_f != 1 
    puts "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}" 
    elsif value_n_in_f == 0 && value_m_in_f != 1 
    puts "I: f(x)=#{value_m_in_f}x" 
    elsif value_n_in_f < 0 && value_m_in_f != 1 
    puts "I: f(x)=#{value_m_in_f}x#{value_n_in_f}" 
    elsif value_n_in_f > 0 && value_m_in_f == 1 
    puts "I: f(x)=x+#{value_n_in_f}" 
    elsif value_n_in_f == 0 && value_m_in_f == 1 
    puts "I: f(x)=x" 
    elsif value_n_in_f < 0 && value_m_in_f == 1 
    puts "I: f(x)=x#{value_n_in_f}" 
    end 
end 

do_stuff(1, 0) 
do_stuff(1,-1) 
do_stuff(1, 1) 
do_stuff(0,-1) 
do_stuff(0, 0) 
do_stuff(-1, 1) 

--output:-- 
I: f(x)=x 
I: f(x)=x-1 
I: f(x)=x+1 
I: f(x)=0x-1 #<---HERE 
I: f(x)=0x  #<---HERE 
I: f(x)=-1x+1 #<---HERE 

Donc, nous allons corriger cela:

def get_line_equ(m, b) 
    constant = (b == 0) ? "" : sprintf("%+d", b) # 2 => "+2" 

    case m 
    when 0 
    xterm = "" 
    constant = b 
    when 1 
    xterm = "x" 
    when -1 
    xterm = "-x" 
    else 
    xterm = "#{m}x" 
    end 

    "I: f(x)=#{xterm}#{constant}" 
end 

puts get_line_equ(0, 0) 
puts get_line_equ(0, -1) 
puts get_line_equ(0, 1) 

puts get_line_equ(1, 0) 
puts get_line_equ(1,-1) 
puts get_line_equ(1, 1) 

puts get_line_equ(-1, 0) 
puts get_line_equ(-1, -1) 
puts get_line_equ(-1, 1) 

puts get_line_equ(2, 0) 
puts get_line_equ(2, -1) 
puts get_line_equ(2, 1) 

--output:-- 
I: f(x)=0 
I: f(x)=-1 
I: f(x)=1 
I: f(x)=x 
I: f(x)=x-1 
I: f(x)=x+1 
I: f(x)=-x 
I: f(x)=-x-1 
I: f(x)=-x+1 
I: f(x)=2x 
I: f(x)=2x-1 
I: f(x)=2x+1 

mieux?

spoiler:

La définition finale est pas aussi efficace qu'il pourrait l'être: doit être retiré de la première ligne et copié dans chacune des branches lorsque - à l'exception du premier.

En réponse au commentaire:

def my_sprintf(str, *numbers) 
    str.gsub(/% .*? [df]/x) do |match| #Looks for %...d or %...f sequences 
    puts match 
    end 
end 

my_sprintf("The answer is: %+d or %+d", -2, 3) 


--output:-- 
%+d 
%+d 

suivant:

def my_sprintf(str, *numbers) 

    str.gsub(/% .*? [df]/x) do |format_sequ| 
    number_as_str = numbers.shift.to_s 
    p number_as_str 

    if format_sequ[1] == "+" and number_as_str[0] != "-" 
     "+#{number_as_str}" 
    else 
     number_as_str 
    end 

    end 
end 

puts my_sprintf("The answer is: %+d or %+d.", -2, 3) 

--output:-- 
"-2" 
"3" 
The answer is: -2 or +3. 
+0

Merci, mais qu'est-ce que sprintf? – Kaiton

+0

D'accord, je pense avoir compris sprintf maintenant. J'ai un problème cependant, je veux des fractions, mais quand j'appelle sprintf {"% + f", 1.5} j'obtiens => 1.50000000, comment puis-je le faire agir comme une fraction habituelle, affichant seulement les chiffres que je lui donne? Et deuxièmement. Quelqu'un peut-il expliquer, pourquoi le plus dans "% + d" n'apparaît pas en donnant un négatif? Je veux dire que c'est super utile, mais je ne comprends pas pourquoi ça fait ça. – Kaiton

+0

@Kaiton, ** Quelqu'un peut-il expliquer, pourquoi le plus dans "% + d" n'apparaît pas lorsque vous donnez un n négatif? ** sprintf() est une méthode, et en tant que tel, il peut être programmé pour faire quoi que ce soit veut. Et c'est ainsi que cela a été programmé pour fonctionner. Ou est-ce que vous ne pouvez pas comprendre comment un programme informatique peut faire une chose dans une situation et une autre chose dans une autre situation? Voir le bas de ma réponse pour une implémentation simple de sprintf(). – 7stud

2

Un ou deux choses: vous pouvez mettre « puts » avant tout le si/bloc ELSIF et éviter d'avoir des puts sur chaque ligne, comme suit:

puts case 
    when (value_n_in_f > 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}" 
    when (value_n_in_f == 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x" 
end 

en second lieu, une déclaration de cas serait beaucoup plus facile à lire, comme ceci:

def big_compare(value_n_in_f, value_m_in_f) 
    msg = case 
    when (value_n_in_f > 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}" 
    when (value_n_in_f == 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x" 
    when (value_n_in_f < 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x#{value_n_in_f}" 
    when (value_n_in_f > 0 && value_m_in_f == 1) then "I: f(x)=x+#{value_n_in_f}" 
    when (value_n_in_f == 0 && value_m_in_f == 1) then "I: f(x)=x" 
    when (value_n_in_f < 0 && value_m_in_f == 1) then "I: f(x)=x#{value_n_in_f}" 
    end 
end 
puts big_compare(0, 0) 
+0

Je vois, c'est très utile. Je vous remercie. Donc, cela signifie qu'il n'y a aucun moyen d'assigner une instruction case/if à une variable, comme vous le faites avec une fonction? je ne peux pas simplement def une fonction avec sa fonction pour exécuter cette déclaration de cas et l'appeler alors quand j'en ai besoin? – Kaiton

4

Voici une manière plus compacte d'écrire votre déclaration de cas. Rappelons que a <=> b => -1 if a < b, a <=> b => 0 if a == b et a <=> b => -1 if a > b.

"I: f(x)=" + 
case [value_n_in_f <=> 0, value_m_in_f == 1] 
when [ 1,false] then "#{value_m_in_f}x+#{value_n_in_f}" 
when [ 0,false] then "#{value_m_in_f}x" 
when [-1,false] then "#{value_m_in_f}x#{value_n_in_f}" 
when [ 1,true] then "x+#{value_n_in_f}" 
when [ 0,true] then "x" 
when [-1,true] then "x#{value_n_in_f}" 
end 

Si vous souhaitez montrer comment la chaîne est construite, vous pouvez faire quelque chose comme ça (avec value_n_in_f et value_m_in_f renommé intercept et slope, respectivement):

"I: f(x)=" + 
case 
when slope.zero? 
    intercept.zero? ? "0" : "#{intercept}" 
else 
    case slope.to_f 
    when 1.0 then "" 
    when -1.0 then "-" 
    else "#{slope}" 
    end + "x" + 
    case intercept <=> 0 
    when 0 then "" 
    when -1 then "#{intercept}" 
    else "+#{intercept}"  
    end 
end 

Notez que cela permet slope < 0, ce qui ne fait pas partie de la spécification. Je l'ai testé cela pour diverses combinaisons de intercept et slope:

intercept slope string 
     -2.1 4  I: f(x)=4x-2.1 
     -2.1 -2.2 I: f(x)=-2.2x-2.1 
     -2.1 0  I: f(x)=-2.1 
     -2.1 0.0 I: f(x)=-2.1 
     -2.1 -1  I: f(x)=-x-2.1 
     -2.1 1.0 I: f(x)=x-2.1 
     0  4  I: f(x)=4x 
     0  -2.2 I: f(x)=-2.2x 
     0  0  I: f(x)=0 
     0  0.0 I: f(x)=0 
     0  -1  I: f(x)=-x 
     0  1.0 I: f(x)=x 
     0.0 4  I: f(x)=4x 
     0.0 -2.2 I: f(x)=-2.2x 
     0.0 0  I: f(x)=0 
     0.0 0.0 I: f(x)=0 
     0.0 -1  I: f(x)=-x 
     0.0 1.0 I: f(x)=x 
     3  4  I: f(x)=4x+3 
     3  -2.2 I: f(x)=-2.2x+3 
     3  0  I: f(x)=3 
     3  0.0 I: f(x)=3 
     3  -1  I: f(x)=-x+3 
     3  1.0 I: f(x)=x+3 
Questions connexes