PHP Come posso sbarazzarmi delle affermazioni ridondanti

0

Ho un sacco di istruzioni if scritte in PHP per un progetto su cui sto lavorando. Il modello è che quando il prezzo del $ aumenta di 5 cent ogni volta che le riviste aumentano di 10. Quando la quantità di riviste raggiunge 91, il prezzo sopra tutto è fisso.

  if($total_magazines <= 10 && $total_magazines >= 1)
  {
    $price = 0.75;
    $total_amount = $total_magazines * $price;
  }
  if($total_magazines <= 20 && $total_magazines >= 11)
  {
    $price = 1.25;
    $total_amount = $total_magazines * $price;
  }
  if($total_magazines <= 30 && $total_magazines >= 21)
  {
    $price = 1.75;
    $total_amount = $total_magazines * $price;
  }

Questo è solo un frammento di esso. In realtà è scritto fino in fondo

if($total_magazines > 91)
{
  $price = 5.25;
  $total_amount = $total_magazines * $price;
}

Anche se fa quello che voglio che faccia, ma sento che posso renderlo molto più semplice. c'è un modo per farlo? Grazie mille!

    
posta SpookyBoogy 08.09.2018 - 21:54
fonte

3 risposte

3

Benvenuti in SoftwareEngineering.SE. Dato che sei nuovo qui, potresti essere interessato leggendo i Apri la lettera agli studenti con i problemi a casa per prima.

torna al problema, ecco alcuni suggerimenti per portarti sulla giusta strada.

Rimozione della condizione

Prendi uno dei blocchi:

if($total_magazines <= 30 && $total_magazines >= 21)
{
  $price = 1.75;
  $total_amount = $total_magazines * $price;
}

Invertendo l'ordine delle condizioni, si ottiene (il codice significa quasi la stessa cosa per la macchina, ma è leggermente più leggibile per un essere umano in questo modo):

if($total_magazines >= 21 && $total_magazines <= 30)
{
  $price = 1.75;
  $total_amount = $total_magazines * $price;
}

Per soddisfare questa condizione, un numero intero dovrebbe essere uno di quei valori: 21, 22, 23, ⋯ 29, 30.

Cosa succede se dividi uno di quei numeri per dieci? In un caso di trent'anni, è facile: il risultato è tre. Nel caso di nove altri numeri, ottieni un numero variabile come risultato delle divisioni: 2.1, 2.2, 2.3, ⋯ 2.9, 3.

PHP ha un mucchio di funzioni per lavorare con i numeri in virgola mobile. C'è uno di quelli che, per tutti i numeri sopra elencati (incluso l'ultimo), danno lo stesso risultato esatto. Potresti scoprire quale è?

Dai tuoi commenti, sembra che tu l'abbia trovato. Hai ragione, ceil restituisce 3 per 2.1, 2.2, ecc., Nonché 3. La parte successiva della risposta è stata modificata di conseguenza.

Rimozione della duplicazione del codice

Ora, in base ai tuoi commenti, hai scoperto che devi utilizzare ceil , la parte precedente del codice può essere riscritta in questo modo:

if (ceil($total_magazines) == 3)
{
  $price = 1.75;
  $total_amount = $total_magazines * $price;
}

Ma aspetta, perché dovresti scrivere codice ripetitivo ancora e ancora? in gergo tecnico, si chiama duplicazione del codice, e ci sono solo pochi casi in cui la duplicazione del codice va bene. Questo non è uno di questi.

Vediamo come possiamo modificare il codice per evitare la duplicazione del codice. L'obiettivo qui è di esprimere il $total_amount per diversi valori di ceil . Esiste, infatti, un semplice calcolo che, dato un intero, ti darebbe il $total_amount .

Per capirlo, un semplice approccio è quello di elencare i valori (cioè il risultato di ceil e il previsto $price .

  • 1 → 0.75
  • 2 → 1.25
  • 3 → 1.75
  • 9 → 4.75

Se non riesci a individuare il modello (e se la descrizione originale del problema non aiuta), un riflesso positivo sarebbe quello di disegnare quei punti su un pezzo di carta e vedere come appare. È una curva? Una linea retta? Perché? Una volta trovato, esprimerlo come una funzione matematica non dovrebbe essere un problema.

Gestione del caso limite

Una volta ottenuti i valori da 1 a 90 a destra, c'è un caso limite, espresso nella tua domanda dalla condizione $total_magazines > 91 (a proposito, c'è un errore: è piuttosto $total_magazines >= 91 ).

Ovviamente puoi avere un'istruzione condizionale che restituisce una costante per qualsiasi input superiore o uguale a 91, ma tornando alle funzioni matematiche di PHP, ce n'è una che può aiutarti ad evitare la condizione.

È una buona cosa sbarazzarsi della condizione? Forse sì forse no. Dipende da ciò che il tuo insegnante si aspettava in uno specifico contesto di questo compito. In generale, si preferirebbe utilizzare una condizione per rendere più chiaro il caso limite, ma forse l'aspettativa era che gli studenti si affidassero ampiamente alle funzioni matematiche per fare un'espressione senza flusso di controllo alternativo.

    
risposta data 08.09.2018 - 22:10
fonte
0

Dopo aver consultato le note e i consigli di @Arseni Mourzenko, sono stato in grado di venire con una soluzione più semplice anziché limitarsi a codificarla. Dal momento che il prezzo scala con il numero di riviste acquistate ...

  • 1 - > 0.75
  • 2 - > 1.25
  • 3 - > 1.75
  • 4 - > 2,25 ... ... e così via.

    Tutto quello che devo fare è eseguire un ciclo for.

    for($i = 1; $i <= $calc_magazines; $i++)
    {
      if($i == 1)
      {
        $price = 0.75;
      }
      else
      {
        $price += 0.5;
      }
    }
    $total_amount = $total_magazines * $price;
    

    Con $calc_magazines che è già ceil() , allora tutto quello che devo fare è dargli una condizione in cui se $i = $calc_magazines = 1 e impostare il prezzo su tale, qualsiasi quantità di riviste successive o superiore a 10, il prezzo sarebbe incremento di 0,5. Quindi per riempire la condizione finale in cui l'importo della rivista è > 91 ... Ho inserito questo ciclo for in un'istruzione if-else in cui if($total_magazines > 91) ... esegue il proprio calcolo ... quindi else{ for-loop } .

risposta data 11.09.2018 - 00:33
fonte
0

Più conciso può essere usare la matematica, in particolare la divisione di interi forzati tramite intdiv() - pensa "opposto di% operator".

<?php

$totalM=array(1,9,10,11,21,31,41,49,50,51,89,90,91,92,100);

foreach($totalM as $total_magazines){
    if(($total_magazines > 0) && ($total_magazines < 92)){
        $price_level=intdiv($total_magazines,10);
        $price=.75+(.5*$price_level);
    }elseif($total_magazines>91){
        $price = 5.25;
    }
    print($total_magazines." magazines price ".$price." each is ".($total_magazines * $price)."\n");
}
?>

1 magazines price 0.75 each is 0.75
9 magazines price 0.75 each is 6.75
10 magazines price 1.25 each is 12.5
11 magazines price 1.25 each is 13.75
21 magazines price 1.75 each is 36.75
31 magazines price 2.25 each is 69.75
41 magazines price 2.75 each is 112.75
49 magazines price 2.75 each is 134.75
50 magazines price 3.25 each is 162.5
51 magazines price 3.25 each is 165.75
89 magazines price 4.75 each is 422.75
90 magazines price 5.25 each is 472.5
91 magazines price 5.25 each is 477.75
92 magazines price 5.25 each is 483
100 magazines price 5.25 each is 525
    
risposta data 13.10.2018 - 19:11
fonte

Leggi altre domande sui tag