2009-11-19 15 views
7

ho fatto un compito per casa, ecco la dichiarazione del problema:C# file di I/O Efficienza

Il vostro programma dovrebbe funzionare come segue:

  1. chiedere all'utente di dare un nome di file. Ottieni il nome del file e salvalo.
  2. Apre il file.
  3. Dal file leggere una temperatura e una velocità del vento. Entrambi i valori devono essere memorizzati in variabili dichiarate doppie. Il file è un file di testo. Ogni riga del file contiene una temperatura e un valore della velocità del vento.
  4. calcolare il fattore wind chill utilizzando un metodo programmatore scritta, e visualizzare il risultato nella forma:

    Per T = temperatura da file e v = velocità del vento da file vento indice freddo = risultato calcolato gradi Fahrenheit .

    Mostra tutti i numeri con due cifre dopo il punto decimale. (Ricorda: nessun numero magico!)

  5. Ripetere questi passaggi finché non si incontra la fine del file.

ho completato l'incarico, il mio codice è al di sotto, mi stavo chiedendo se ci fosse un modo per renderlo più efficiente, o se ci sono alcuni modi diversi e creativi per ottenere questo problema, ho già girato questo e ottenuto 50/50, ma sono solo curioso di sapere come alcuni di voi programmatori avanzati e qualificati si avvicinerebbero a questo problema.

using System; 
using System.IO; 

class Program 
{ 
    // declare constants to use in wind chill factor equation - no magic numbers 
    const double FIRST_EQUATION_NUMBER = 35.74; 
    const double SECOND_EQUATION_NUMBER = 0.6215; 
    const double THIRD_EQUATION_NUMBER = 35.75; 
    const double FOURTH_EQUATION_NUMBER = 0.4275; 
    const double EQUATION_EXPONENT = 0.16; 
    const int DEGREE_SYMBOL_NUMBER = 176; 

    static void Main() 
    { 
     // declare and initialize some variables 
     string filePath = ""; 
     string line = ""; 
     double temperature = 0.0; 
     double windSpeed = 0.0; 
     double windChillFactor = 0.0; 
     char degreeSymbol = (char)DEGREE_SYMBOL_NUMBER; 

     // ask user for a file path 
     Console.Write("Please enter a valid file path: "); 
     filePath = Console.ReadLine(); 

     // create a new instance of the StreamReader class 
     StreamReader windChillDoc = new StreamReader(@filePath); 

     // start the read loop 
     do 
     { 
      // read in a line and save it as a string variable 
      line = windChillDoc.ReadLine(); 

      // is resulting string empty? If not, continue execution 
      if (line != null) 
      { 
       string[] values = line.Split(); 
       temperature = double.Parse(values[0]); 
       windSpeed = double.Parse(values[1]); 

       windChillFactor = WindChillCalc(temperature, windSpeed); 

       Console.WriteLine("\nFor a temperature {0:f2} F{1}", temperature, degreeSymbol); 
       Console.WriteLine("and a wind velocity {0:f2}mph", windSpeed); 
       Console.WriteLine("The wind chill factor = {0:f2}{1}\n", windChillFactor, degreeSymbol); 
      } 
     } while (line != null); 

     windChillDoc.Close(); 

     Console.WriteLine("\nReached the end of the file, press enter to exit this program"); 

     Console.ReadLine(); 
    }//End Main() 

    /// <summary> 
    /// The WindChillCalc Method 
    /// Evaluates a wind chill factor at a given temperature and windspeed 
    /// </summary> 
    /// <param name="temperature">A given temperature</param> 
    /// <param name="ws">A given windspeed</param> 
    /// <returns>The calculated wind chill factor, as a double</returns> 
    static double WindChillCalc(double temperature, double ws) 
    { 
     double wci = 0.0; 
     wci = FIRST_EQUATION_NUMBER + (SECOND_EQUATION_NUMBER * temperature) - (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT))); 
     return wci; 
    } 
}//End class Program 

Sentiti libero di dirmi cosa ne pensi.

+1

Quando si ha una funzione che restituisce un risultato calcolato in base a un'equazione impostata, è utile avere l'equazione scritta nel riepilogo della funzione. –

risposta

7

Non si otterrà molto più zippier di quello per il file IO in C#. A seconda delle dimensioni del set di dati, potrebbe valere la pena utilizzare un lettore bufferizzato, ma per file sufficientemente piccoli, non ne vale la pena. Lo lascerei così com'è.

+0

Finora l'unica persona a rispondere direttamente alla sua domanda "principale" :) –

+0

Grazie per la risposta, il tuo diritto ovviamente, con un semplice programma io di file come questo, non puoi ottenere molto più efficiente. P.S Grazie a tutti voi per i vostri suggerimenti, sono stati tutti utili. – Alex

+0

Vorrei sottolineare che non ha fatto questa domanda direttamente, ha chiesto "Sono solo curioso di sapere come alcuni di voi programmatori esperti e qualificati si avvicinerebbero a questo problema". – RCIX

6

La maggior parte dei vostri commenti sono estranei. The code should tell you how...the comments should tell you why.

+2

Ovviamente avete ragione, ma secondo la mia esperienza, molte università richiedono un livello non necessario di commenti. –

+0

È vero. I miei professori avevano un amore inquietante per i commenti e spesso li avevamo inclusi solo per il piacere che ci fossero. È una gran perdita di tempo se me lo chiedi. I commenti dovrebbero essere davvero necessari solo se l'implementazione non è ovvia (o stai creando un sistema documentato). –

+0

Sì, sono d'accordo personalmente con il link di Mike, ma il mio professore richiede una quantità enorme di commenti nei nostri compiti. – Alex

9

Il tuo modo sembra buono, ma:

  • Sarebbe aspetto molto più gradevole se si è utilizzato PascalCase per le costanti, come questo è ciò che convenzioni di codifica per C# uso.
  • si dovrebbe includere lo StreamReader in un'istruzione using, in modo che venga correttamente eliminato una volta terminato.
  • Probabilmente dovresti anche racchiuderlo in un blocco try (e un catch per gestire correttamente l'eccezione) per assicurarti di non ottenere un'eccezione FileNotFound.
  • E 'probabilmente una migliore idea di strutturare il ciclo while seguente modo:

while((line = windChillDoc.ReadLine()) != null) { ... } [! Formattazione Darn non funziona a destra]

Oltre a questo, però, non saprei come Non ho familiarità con i calcoli meteorologici :)

+2

+1 per il suggerimento di UTILIZZO. http://msdn.microsoft.com/en-us/library/yh598w02.aspx –

+2

Non sono d'accordo che sembrerebbe "più bello", ma hai ragione - le convenzioni stabiliscono che PascalCase dovrebbe essere usato per le costanti . Mi piace lo stile UPPERCASE_WITH_UNDERSCORES, in quanto distingue chiaramente i commenti ed è stato usato per così tanto tempo. –

+0

'foreach (riga di stringa in File.ReadAllLines (fileName)) {...}' –

4

Perché il fa/mentre?Nel tuo do controlli nullo. Nel tuo mentre controlli nullo. Perché non basta renderlo un mentre l'istruzione?

string line; 
while((line = windChillDoc.ReadLine()) != null) 
{ 
    //Logic 
} 

EDIT: Risolto l'errore di compilazione. La cosa divertente era che l'avevo originariamente. Questa casella Rich Text ha bisogno di un compilatore! : P

+1

Ho appena aggiunto lo stesso punto alla mia domanda! – RCIX

+1

Non ho controllato, ma I * think * è necessario dichiarare 'line' al di fuori del ciclo. –

+0

Ugh, perché ottengo sempre quelli capovolti? * rispondi * non * domanda *! – RCIX

5
string filePath = ""; 
... 
filePath = Console.ReadLine(); 

Non inizializzare con valori che non vengono mai utilizzati; e mantenere la dichiarazione e l'inizializzazione vicini tra loro:

string filePath = Console.ReadLine(); 

using è stato detto - ma non usare @ inutilmente:

new StreamReader(@filePath); 

dovrebbe essere solo:

new StreamReader(filePath); 

Personalmente, userei LINQ per il line-reader, ma sono solo io ;-p

6

Minor nitpick, ma "WindChillCalc" dovrebbe essere "CalcWindChill" se si stanno utilizzando nomi di metodi inglesi (il verbo va primo).

+0

Ah, grazie per la cattura. – Alex

0

In piccoli programmi accademici come questo, a meno che non si faccia qualcosa di veramente stupido, le prestazioni non saranno un problema. Un modo semplice per capire se la prestazione è un problema è porre la domanda: "Mi fa aspettare?"

Se ci fosse un'enorme quantità di input, vorrei chiedere a chi sta fornendo l'input e chi sta leggendo l'output. Questo mi direbbe se potrei fare l'I/O in binario anziché in testo, perché così com'è, la maggior parte dell'elaborazione sarà nella conversione del testo in numeri in input e in numeri in testo in uscita, in particolare virgola mobile.

2

Se stai ricevendo segnato sullo stile ecc poi c'è un paio di cose molto minori

  • inizializzazione raddoppia a 0,0 è ridondante.
  • string.Empty è preferito al posto di ""
  • Il vostro metodo di Windchill può essere cambiato semplicemente (anche se, durante la compilazione, penso che WCI sarà ottimizzato fuori - quindi è funzionalmente lo stesso):

(cambio formattazione per SO leggibilità)

static double WindChillCalc(double temperature, double ws) 
{ 
    return FIRST_EQUATION_NUMBER + 
     (SECOND_EQUATION_NUMBER * temperature) - 
     (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + 
     (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT))); 
} 
3

Anche se non proprio in materia di prestazioni (la questione principale)

IMO:

const double FIRST_EQUATION_NUMBER = 35.74; 
const double SECOND_EQUATION_NUMBER = 0.6215; 
const double THIRD_EQUATION_NUMBER = 35.75; 
const double FOURTH_EQUATION_NUMBER = 0.4275; 
const double EQUATION_EXPONENT = 0.16; 

non è molto meglio di un numero magico. Guardando a questo, non ho idea di cosa sia usato da FIRST_EQUATION_NUMBER per altre da un'equazione, e non posso dire che siano nella stessa equazione o che tu abbia quattro equazioni che usano numeri diversi?Potrebbero anche essere inseriti nel metodo reale in quanto è l'unico posto in cui vengono utilizzati.

Vorrei cambiare degreeSymbol in un const invece di lavorarlo da un const int in seguito.

const char DEGREE_SYMBOL = (char)176;