2009-09-03 11 views
7

Scrivo spesso codice di esclusione (in un research environment), ad esempio per esplorare un algoritmo o un modello per una proprietà o un processo scientifico. Molti di questi "esperimenti" sono una tantum ma a volte trovo che ne avrò bisogno in seguito. Per esempio ho appena scoperto il codice per la corrispondenza delle stringhe che ho scritto 7 anni fa (fermato a causa di altre priorità) ma che ora è prezioso per il progetto di un collega. Dopo averlo visto (ho davvero scritto un codice tanto impenetrabile?), Mi rendo conto che ci sono alcune cose che avrei potuto fare per aiutarmi quando ho riavviato il "progetto" ("esperimento" è ancora una parola migliore). L'esperimento precedente "funzionava", ma so che all'epoca non avrei avuto il tempo di fare il refattore poiché le mie priorità erano altrove.Buone strategie per lo sviluppo di codice usa e getta?

Quali sono i metodi più economici per consentire il recupero e il riutilizzo di tali lavori?

EDIT: ho risposto alla mia domanda (sotto) perché ci sono questioni al di là della sorgente vero e proprio.

risposta

9

Non sono d'accordo con tutte le risposte che dicono "scrivi commenti". Questo è stato offerto come un catch-all perché il codice stesso non è comprensibile.

Fatevi una copia di Code Complete (Steve McConnell, 2a edizione). Se impari le tecniche di scrittura del codice gestibile in primo luogo, non ti ci vorrà più tempo e sarai in grado di tornare al tuo lavoro più tardi con meno problemi.

Quale sarebbe si preferisce:

  • codice Cryptic con i commenti?
  • Per lo più codice OK senza?

Preferisco decisamente quest'ultimo, poiché il codice OK è più facile da capire nelle situazioni in cui il codice criptico era non commentato ei commenti sono un altro punto in cui lo sviluppatore originale può commettere errori. Il codice può essere buggy, ma non è mai errato.

Una volta che si ha familiarità con Codice completo, si consiglia The Pragmatic Programmer, in quanto fornisce consigli di sviluppo software leggermente più elevati.

+0

Sì, la scrittura di codice mantenibile è molto importante e certamente secondo il consiglio sulla lettura di codice completo (non ho letto The Pragmatic Programmer). Tuttavia, continuo a pensare che sia importante commentare perché hai preso le decisioni che hai fatto. Cose come il motivo per cui hai scelto un certo algoritmo di ordinamento rispetto ad altri (forse ti aspettavi che i dati fossero già parzialmente ordinati o che non sarebbe stato più di X records). I commenti possono chiarire un sacco di "Che diamine stavo pensando?" domande più tardi. – TLiebe

+2

Se i commenti potrebbero contraddire direttamente il codice, prendere in considerazione la possibilità di rimuoverli. In quasi tutti i casi, i commenti sono utili solo quando forniscono informazioni che non è possibile ottenere facilmente leggendo il codice. –

+0

@ Novelocrat Sono d'accordo. I commenti non sono il problema o la soluzione principale. Pubblicherò i miei problemi particolari in modo più dettagliato a breve, ma sono ancora interessato all'esperienza generale. (Come risultato di SO ora ho ordinato CC e sto iniziando ad immergerlo e adotterò sicuramente degli approcci quasi a costo zero. Come te preferisco il codice prevalentemente OK (che è questo) e non sono preoccupato per gli algoritmi difficili essendo senza commento - funzionano e io do un singolo puntatore alla sorgente generica: –

0

Alcune strategie:

  1. buoni commenti. Difficile riutilizzare ciò che non puoi trovare o capire in seguito.
  2. Salvare tutte le query in una cartella di cui è stato eseguito il backup o che si trova sotto il controllo del codice sorgente.
  3. Avere una libreria comune di funzioni utili a cui si "promuove" qualcosa una volta che è stata riutilizzata.
1

Penso che la cosa più importante (se non si effettua alcun refactoring non accadrà) è di commentare e documentare il processo di pensiero in quel momento. Contribuirà a rendere il codice meno impenetrabile e ti aiuterà a trovare i pezzi migliori quando necessario.

1

Commenti: descrivi cosa stavi pensando e perché hai scelto di implementare qualcosa in un certo modo, comprese le alternative che hai considerato. Ci sono probabilmente tutti i tipi di soluzioni di fantasia, ma solo commentare il tuo codice correttamente nel momento in cui stai scrivendo sembra funzionare al meglio.

1

Mi associo quello che gli altri hanno detto, per quanto commentando il "perché è" del perché il codice è stato scritto ed è destinato l'uso, ma vorrei anche aggiungere questo:

codice come se si stesse pensando di mettere questo in produzione anche quando stai solo scherzando. Codice in materia di:

  • chiarezza e leggibilità
  • seguire le convenzioni di codifica del tempo. (convenzioni di denominazione, ecc.). Anche se tali convenzioni cambiano nel tempo, se si rispettano gli standard è più probabile che sia in grado di capirlo in seguito.
  • di sicurezza (se applicabile)
  • prestazioni (se applicabile)

In particolare, vorrei sottolineare il primo punto, ma gli altri sono importanti pure. Trovo che se uso "codice di prova" più avanti, tendo a usarlo solo se funziona, piuttosto che a refactarlo.

2

Come le eccellenti risposte nel tuo other post indicano, e dalla mia esperienza, c'è un divario difficile da attraversare tra il software utilizzato per la ricerca e il software che è stato progettato. Secondo me, Code Complete potrebbe aiutare un po ', ma non molto. Come una domanda economica, vale la pena di refactoring di tutto per il riutilizzo rispetto alla ricompensa occasionale per trovare un uso successivo per qualcosa? Il tuo punto di equilibrio può variare.

Ecco un suggerimento pratico per la memorizzazione di frammenti. Invece di commenti in piena regola, gettare in alcune parole chiave:

  • "wrapper grafico isomorfismo"
  • "polimero ricottura simulata"
  • "match stringa Feynmann"
  • "equilibrio"

e poi metti il ​​codice in qualche posto ricercabile da Google, come un account GMail.

Edit:. Potrei aggiungere che liberi Google Sites sono i wiki davvero ricercabili che sono un buon posto per mettere il codice, sia sotto forma di allegati o incollato in

Inoltre, devo dire che io sono un fan del codice completo e ha dato copie agli studenti universitari che scrivono software per la ricerca scientifica per diversi anni. È un buon inizio, ma nessun proiettile d'argento. Sto scrivendo un articolo in questo momento sull'utilizzo di framework open source per risolvere i problemi di gestione dei dati scientifici e una delle conclusioni è che alcune competenze di ingegneria del software sono essenziali per i sistemi di lunga durata. Molti progetti scientifici dovrebbero probabilmente prevedere un bilancio fin dall'inizio.

+0

+1 Questa è un'idea eccellente. Se il codice fosse stato facilmente ricercabile (a differenza di Sourceforge, dove ho trovato impossibile cercare), avrebbe aiutato –

+0

un buon consiglio, ma * ogni * snippet dovrebbe essere definito all'interno del progetto, in un luogo ben visibile. Per una persona che è coinvolta nel progetto, sono ovvi, ma per un abitante esterno non lo sono affatto. –

1

No, No, No, No, No!

Non scrivere codice di richiamo anche in un ambiente di ricerca. Per favore!

Attualmente sto scherzando con un tale "codice throwaway", ovvero il progetto BLAST. Il fatto è che è iniziato come un parco giochi ma poi è diventato un po 'di successo, ora è uno strumento pulito con molti concetti implementati, ma il codice è praticamente impossibile da mantenere. Ma non è questo il punto principale.

Il punto principale è, si ricerca per gli ingegneri per beneficiare in seguito dei risultati. Avendo svolto un buon lavoro scientifico sul concetto generale e scrivendo uno strumento che lo dimostrasse di successo, puoi facilmente dimenticare che lo stai facendo non solo per la pubblicazione e solo per il dottorato. Lo fai a beneficio dell'umanità. Il tuo codice potrebbe contenere una serie di "casi speciali", difficili da debugare, una serie di stranezze e hack che non rientrano in alcun articolo della conferenza. È particolarmente importante documentare e commentare tali cose attraverso il tuo codice.

Se uno sviluppatore ha deciso di implementare i tuoi concetti in un prodotto commerciale, avrebbe potuto studiare le stranezze e gli hack del tuo codice e l'implementazione avrebbe dieci meno errori di quelli che avrebbe potuto avere. Tutti dicono "Wow, la sua ricerca su A è davvero utile!" Ma se scrivi "throwaway", loro dicono "il suo concetto sembra bello sulla carta, ma X ha cercato di implementarlo e annegato in un sacco di bug".

(MODIFICA: tratto dai commenti seguenti) Per aiutare gli sviluppatori futuri del codice base, non è necessario molto. Innanzitutto, commenta cosa fa ciascuna funzione. Secondo, assicurati che ogni correzione non ovvia di un bug insidioso venga inserita in un commit separato nel sistema di controllo di revisione (con un commento appropriato, ovviamente). Questo è abbastanza E se persino rendi le cose modulari (anche se non sono pronte per un riutilizzo definitivo - che è tre volte più costoso, secondo Brooks) sarai adorato dagli ingegneri che implementano la tua ricerca.

Penso che il mondo sarebbe un posto migliore se i ricercatori gettassero via la loro hybris e smesso di pensare altezzoso di non essere questi codificatori sporchi che fanno un lavoro umile di scrivere un buon codice. Scrivere un buon codice non è solo un lavoro per questi stupidi programmatori. È una cosa davvero preziosa che tutti dovrebbero sforzarsi. Senza questo, il tuo piano sperimentale, il tuo codice, il tuo cervello finiranno per morire.

+0

@Pavel Shved. Mi associo ai tuoi commenti. Ma difenderò il concetto di codice usa e getta - quello di cui sto parlando è il risultato di un progetto di allineamento di sequenza basato sul libro di Kruskal che ho impostato circa 20 anni fa - penso in BBC Basic - è passato da quello a C e poi a C++ e poi a Java e ora lo sto usando per l'allineamento del testo. In nessun momento è mai stato altro che un esercizio di apprendimento e un parco giochi. Quindi non possiedo alcuna responsabilità morale per la sua evoluzione e stato. Ma ora penso che abbia qualche valore aggiunto in un dominio differeht e quindi lo sto rifattendo. –

+0

@peter: nessuno ti obbliga a essere responsabile. Scrivere un buon codice è una buona abitudine e non richiede molto tempo per metterlo in pratica! Piccole descrizioni di ciò che le funzioni fanno, commenti sullo scopo del modulo, sistema di controllo delle revisioni che mi mostra * perché * esiste una linea particolare ('svn blame'). Questo renderà le persone semplicemente riutilizzabili e quindi ti daranno credito e attribuzione. –

+0

@Pavel. Grazie. È * perché * Desidero comportarmi in modo responsabile che sto sollevando questo problema. FWIW quando il codice originale è stato scritto SVN non esisteva :-) e il primitivo sistema CVS che avevamo non era mantenuto. –

5

[Risposta alla propria domanda] Ci sono molti altri aspetti del problema che non sono stati sollevati e che avrei trovato utile durante la sua revisione. Alcuni di questi potrebbero essere "evidenti" ma ricordate che questo codice era pre-SVN e IDE.

  • Discoverability. In realtà è stato difficile trovare il codice. Credo che sia nel mio progetto SourceForge ma ci sono così tante versioni e filiali in 7 anni che non riesco a trovarlo. Quindi dovrei avere un sistema che ha cercato il codice e fino a quando non sono apparsi gli IDE non penso che ce ne fossero.
  • Cosa fa?. Il checkout corrente contiene circa 13 classi (tutto in un unico pacchetto in quanto non era facile da refactoring al momento). Alcuni sono chiari (DynamicAligner) ma altri sono opachi (MainBox, denominati perché estendono una casella Swing). Esistono quattro programmi main() e in realtà ci sono circa 3 sottoprogetti nella distribuzione. Quindi è fondamentale avere un manifest esterno su cosa fossero effettivamente i componenti.
  • istruzioni su come eseguirlo. Quando si esegue il programma, main() offrirà un breve utilizzo della riga di comando (ad esempio DynamicAligner file1 file2) ma non dice quale sia il contenuto dei file in realtà. All'epoca lo sapevo, certo, ma non ora. Quindi dovrebbero essere associati i file di esempio nelle directory di pari livello. Questi sono più utili di provare a documentare i formati di file.
  • funziona ancora?. Dovrebbe essere possibile eseguire ogni singolo esempio senza pensare. La prima domanda sarà se le librerie associate, i runtime, ecc.sono ancora pertinenti e disponibili. Un ex collega ha scritto un sistema che funziona solo con una particolare versione di Python. L'unica risposta è riscrivere. Quindi, certamente, dovremmo evitare qualsiasi blocco, ove possibile, e mi sono allenato (anche se non necessariamente colleghi) per farlo.

Quindi, come posso evitare i problemi in futuro? Penso che il primo passo sia che ci dovrebbe essere una disciplina per la creazione di un "progetto" (anche se piccolo) quando si crea il codice e che questi progetti dovrebbero essere sotto il controllo della versione. Ciò potrebbe sembrare ovvio per alcuni di voi, ma in alcuni ambienti (accademici, nazionali) vi è un significativo sovraccarico nell'impostazione di un sistema di gestione dei progetti. Sospetto che la maggior parte del codice accademico non sia sotto nessun controllo di versione.

Poi c'è la domanda su come i progetti dovrebbero essere organizzati. Non possono essere su Sourceforge di default poiché il codice è (a) banale e (b) non aperto per impostazione predefinita. Abbiamo bisogno di un server dove possano esserci sia progetti comuni che privati. Calcolerei che lo sforzo per impostarlo ed eseguirlo è di circa 0,1 FTE - cioè 20 giorni all'anno da tutte le parti (installazione, formazione, manutenzione) - se ci sono opzioni più semplici mi piacerebbe sapere che questo è un grande spese in alcuni casi: passo il tempo a configurare un server o a scrivere documenti?

Il progetto dovrebbe cercare di incoraggiare una buona disciplina. Questo è davvero quello che speravo di ottenere da questa domanda. Si potrebbe includere:

  1. Un modello di componenti necessari (manifesti, README, registro di commit, esempi, librerie richieste, etc. Non tutti i progetti può essere eseguito con Maven - per esempio FORTRAN).
  2. Un mezzo per cercare un numero elevato (centinaia almeno) di piccoli progetti per stringhe mnemoniche (mi è piaciuta l'idea di scaricare il codice in Googledocs e questa potrebbe essere una strada fruttuosa, ma è uno sforzo di manutenzione extra).
  3. Convenzioni di denominazione chiare. Questi sono più preziosi dei commenti. Ora ho regolarmente nomi del tipo iterateOverAllXAndDoY. Cerco di usare createX() piuttosto che getX() quando la routine crea effettivamente informazioni. Ho la cattiva abitudine di chiamare procedure() piuttosto che convertAllBToY().

Sono a conoscenza ma non ho usato GIT e Mercurial e GoogleCode. Non so quanti sforzi si debbano impostare e quante delle mie preoccupazioni rispondono. Sarei lieto se esistesse un plug-in IDE che ha aiutato a creare codice migliore (ad esempio "scarsa scelta del nome del metodo").

E qualunque sia l'approccio che devono venire naturalmente alle persone che non hanno naturalità hanno una buona disciplina del codice e ne vale la pena.

+0

Peter, non potrei essere più d'accordo con il tuo suggerimento sulla convenzione di denominazione. I nomi chiari IMHO sono di gran lunga i più efficaci nel comunicare il tuo intento tramite codice. Abbiamo una linea guida: prendi almeno il doppio del tempo in cui originariamente volevi pensare a un buon nome. – LaszloG

+0

Git or Mercurial può aiutare con i problemi di scoperta e manutenzione, almeno in qualche modo. Se hai un'idea di una stringa che identifichi qualcosa che stai cercando, le operazioni di Git "grep" e "pickaxe" possono essere utili. Per quanto riguarda il mantenimento di un repository, se è possibile spostare alcuni file (con qualsiasi mezzo), è possibile distribuire il codice con tutta la sua cronologia. – Novelocrat

+0

Inoltre, dovresti davvero modificarlo nella domanda, poiché chiarisce, piuttosto che rispondere a, ciò che hai sbagliato sopra. – Novelocrat

0

Si potrebbe anche prendere in prestito l'idea di test di unità da parte del popolo TDD (sviluppo test-driven). Devi assicurarti che il codice throwaway funzioni in ogni caso OK, quindi perché non esprimere il check-in come test delle piccole unità? Ciò avrebbe due vantaggi:

  1. Leggendo il codice di prova comunica l'intento del usa e getta chiaramente: dopo tutto esprime le sue aspettative nella stessa lingua: codice.

  2. Sarebbe anche d'aiuto con il 4 ° problema della tua auto-risposta: "funziona ancora?". Bene, è facile: basta eseguire i test unitari e ti dicono cosa e dove (e con un po 'di fortuna) perché non funziona.

+0

Grazie. Io uso i test unitari per questo scopo. Questo tipo di test è normalmente "è arrivato alla fine senza crash". È molto difficile controllare che - per esempio - un output complesso con numeri in virgola mobile sia ancora corretto. –

+0

@ peter.murray.rust: puoi verificarlo con argomenti stupidi: ad es. la maggior parte delle equazioni differenziali ha un output noto quando si alimenta 0 per tutti gli argomenti. Assicurati che il codice lo stia facendo almeno correttamente. Modularizza tutto abbastanza, e puoi fare test di base sulla maggior parte del codice. – naught101

1

Probabilmente ho perso il punto di tutta questa discussione, ho spesso faccio, ma qui va, un invito per pezzi di mattone e downvoting ...

Se si tratta di codice usa e getta, buttarlo via!

Se non vuoi buttarlo via, segui il buon consiglio sopra. Per me, e scrivo una buona dose di codice usa e getta, la questione se sia buttata via o messa in uno stato riutilizzabile e mantenuta contro un giorno di pioggia si riduce all'economia.

Posso prevedere circostanze in cui questo codice sarà di nuovo utile? Una volta in una luna blu, due volte l'anno, ogni mese?

Potrò riscrivere questo codice in meno tempo di quanto necessario per renderlo riutilizzabile? Se la risposta a questa domanda è No, quante volte dovrò riutilizzarla per renderla valida migliorandola ora? (Torna alla domanda precedente)

Se faccio in modo che questo codice sia riutilizzabile, sarò in grado di trovarlo di nuovo quando lo desidero dopo? (Qualcuno ha mai avuto l'esperienza di sapere, con assoluta certezza, che da qualche parte nel tuo repository di codice c'è solo il frammento che vuoi, ma non ha idea di come è stato chiamato, né dove cercare né cosa cercare di fare?)

Infine, l'approccio in 3 fasi per rendere riutilizzabile il codice scritto rapidamente. Fermati dopo qualsiasi di questi passaggi ti piaccia:

1) Documenta il codice come una scatola nera. Ingressi, uscite, operazioni (s). File attentamente questo documento.

2) Scrivere le istruzioni su come creare/interpretare/installare il codice, nel caso in cui sia necessario portarlo. Archiviare attentamente queste istruzioni.

3) Solo se ne vale la pena: migliorare la qualità del codice sorgente per rendere il codice mantenibile in futuro. Assicurarsi che le fonti siano nel sistema di controllo del codice sorgente e trovabili.

saluti

Mark

+2

Giusto, quando si tratta di esso c'è una distinzione tra codice usa e getta e codice non finito. La mancanza di definizione per definizione non è sufficientemente complessa da volere o da mantenere, quindi può essere facilmente rigenerata in un'epoca più illuminata. Il codice Throwaway è un colpo di tequila economica. Il codice incompiuto, d'altro canto, ha VERAMENTE bisogno di una buona cura: avvolto in lana di cotone (commentata), tenuto a temperatura costante in un luogo buio, girato ad intervalli regolari e con "Mastering Regular Expressions" letto ad alta voce all'ora di dormire. –

Problemi correlati