Avatar billede mikkel_breum Nybegynder
09. december 2003 - 16:22 Der er 26 kommentarer

optimering af kode

Hej

Denne forespørgsel er af lidt generel karakter, og kommentarer til, hvor dette burde placeres er velkomne.

Jeg er selvlært mht. til at programmere, og jeg har på fornemmelsen at mine koder ikke altid er lige optimale..

Er der nogen der har lyst til at give et par kommentarer til nogle bidder PHP kode jeg har lavet, mht. hvorvidt den måde jeg koder på er usmart eller på anden måde kunne gøres bedre?

dvs. dette er ikke et specifikt problem, men mere en forespørgsel efter lidt generelle tips.
Avatar billede Slettet bruger
09. december 2003 - 16:28 #1
Prøv at smide noget kode, sådan så vi kan kommentere på det... meeeeeen, det er nok lidt for optimistisk at håbe på en tutor for 30 point... Det skal du lede længe efter
Avatar billede jakoba Nybegynder
09. december 2003 - 16:28 #2
Ok.
Avatar billede mikkel_breum Nybegynder
09. december 2003 - 17:02 #3
Jeg leder heller ikke efter en tutor som sådan.. det er bare, hvis der er nogen som synes det er sjovt at gå ind i sådan en snak.. men her lidt flere point anyway.. :)
Avatar billede mikkel_breum Nybegynder
09. december 2003 - 17:02 #4
her er fx. et eksempel at tage udgangspunkt i:

på adressen http://www.jooze.dk/ord har jeg lavet et lille php baseret program, der kan generere de "letlæselige" volapyk ord, som alle modtager på sms og mail for tiden. (det med at det 1. og sidste ord skal blive på deres pladser og så kan man bytte om på resten.

fx: det er ikke så svræt at læse krotere ord på dnnee
eller: men lange ord som ssrftsoeenkejr og bnikasarello er sveærre

min kode ser sådan ud:


<?php

// opret array over ord
// php scriptet modtager en varialbel $txt som er den streng der skal behandles
# til dette eksempel er $txt sat i scriptet


$splitter = " ";
$listen = explode ( $splitter, $txt);


// f¿rst opretter jeg et array, der rummer hvert enkelt ord fra s¾tningen i $txt
// t¾l antallet af ord
$antal_ord = count($listen);

// og lad en l¿kke kalde min shuffler funktion, en gang for hvert ord.
for ($i = 0; $i < $antal_ord; $i++) {

// Shuffler funktionen returnerer et array, som jeg konverterer til en streng (med implode)
// hvorefter jeg printer denne streng
print (implode("", shuffler($listen[$i]) ));

// efter denne streng (det enkelte ord), tilf¿jes eventuelt specialtegn (, . ; ? eller !)
// samt et mellemrum.
print ($special." ");
}




// her f¿lger funktionen som foretager selve manipulationen med de enkelte ord
// (bytter rundt pŒ bogstaverne, undtagen det f¿rste og det sidste.


function shuffler($t){

//nulstil tmp
$tmp = array();

// g¿r $special global, sŒ den kan afl¾ses uden for denne funktion
// $special angiver om der er et komme eller lign tegn efter det aktuelle ord,
//og i givet faald hvilket tegn det drejer sig om..
// kunne man her benytte en 'smart' metode til slet og ret at teste for 'non-alphbetic' tegn?
// ligesom man kan definere tegnklasser i grep ned diverse koder (\n)
global $special;

// routine til at hŒndtere eventuelle kommaer, punktum og lign i slutningen af et ord
// hvos et ord slutter med et af disse tegn, skal dette tegn sk¾res fra, f¿r ordet manipuleres.
//Efterf¿lgende skal det s¾ttes pŒ igen.
switch (substr($t,-1)) {
    case ",":
        $special = substr($t,-1);
        break;
    case ".":
        $special = substr($t,-1);
        break;
    case ";":
        $special = substr($t,-1);
        break;
    case "?":
        $special = substr($t,-1);
        break;
    case "!":
        $special = substr($t,-1);
        break;
    default:
        $special = FALSE;
        }

// hvis der er et , . ; ? eller ! eller lign, sŒ klip det af.
if($special){$t=substr($t,0,strlen($t)-1);}



// t¾l antallet af bogstaver i det aktuelle ord, efter eventuelle kommategn er fjernet
// dette tal benyttes til at konstruere en l¿kke, der kan opbygge et array med ordets bogstaver
$antal_tegn = strlen($t);


// opret et array der rummer hvert bogstav i ordet
// jeg konverterer ordet til et array for lettere at kunne manipulere med
// de enkelte elementer (bogtaver) i ordet

// her benytter jeg $j i stedet for $i i min l¿kke, for ikke at komme i problemer
// med den hovedl¿kke, som denne lykke er indlejret i.. men er det n¿dvendigt?
// her stŒr l¿kken jo i sin egen funktion og er ikke en global..
for ($j = 0; $j < $antal_tegn; $j++) {
$tmp_orginal[] = substr($t,$j,1);
}

// nu har l¿kken lavet et array $temp-original["ord1","ord2","ord3"]
// herefter laver jeg en kopi af dette array, sŒ jeg kan manipulere med det,
//uden at miste min original, jeg skal bruge den senere..
$tmp = $tmp_orginal;


// nu fjerner jeg f¿rste og sidste element (bogstav) i mit array
// det f¿rste
unset($tmp[0]);
// reindekserer mit array
$tmp = array_values($tmp);
// fjerner det sidste
unset($tmp[count($tmp)-1]);

// jeg unders¿ger om mit ord overhovedet er langt nok til,
// at en rokade af de midterste bokstaver vil have en effekt..
// hvis ikke skipper jeg rokaden.
// dette tjek burde nok stŒ tidligere, sŒ jeg kunne spare noget mere kode,
// som i sŒ fald ogsŒ er overfl¿dig..
if($antal_tegn > 3){
// seeing (men kan man seede shuffle() med srand() ??)
srand((float)microtime()*1000000);
// shuffler et par gange
// (to gange har tendens til, at skabe ord der ikke er helt sŒ langt fra originalen)
// eller er det mig der bilder mig noget ind?
shuffle($tmp);shuffle($tmp);
}

// nu er $tmp (som er det midterste af mit ord9 blevet blandet rundt et par gange..
// .. og de f¿rste og sidste ord skal puttes pŒ igen
$tmp2 = array_merge($tmp_orginal[0],$tmp,$tmp_orginal[$antal_tegn-1]);

// herefter returnere funktionen resultatet i form af et array,
// hvor alle bogstaver pŒ n¾r det f¿rste og det sidste er blevet blandet
return $tmp2;
}

?>
Avatar billede mikkel_breum Nybegynder
09. december 2003 - 17:04 #5
how $txt var ikke sat i scriptet, men der skal tilføjes fx:
$txt = "denne tekst kan manipuleres";

i starten af scriptet..
Avatar billede mikkel_breum Nybegynder
09. december 2003 - 17:07 #6
jeg har pastet fra en mac, via en PC, derfor lidt problemer med æ,ø,å
Avatar billede mikkel_breum Nybegynder
09. december 2003 - 17:21 #7
jeg har en idé om, at en så simpel procedure, måske kunne fulde det halve, og være mere overskuelig samtidig.
Avatar billede jakoba Nybegynder
09. december 2003 - 17:22 #8
Først og fremmest:  INDRYKNINGER.
tag dem alvorligt. efter en { skal alt være rykket en tand ind indtil den afsluttende }.

Du har lavet indrykning i din switch sætning, og helt smukt bortset fra den afsluttende } som jeg ville rykke ud i niveeau med det indledende ord switch for at fortælle at det er HELE switch sætningen der ender der.

man lad være med at nøjes med indrykning på de steder du selv er lidt i tvivl. brug dem i enhver if/while/do/... sætning du laver, selv når den ikke er ret komplex.

kommentarer er godt. men prøv at skrive dem så man ikke visuelt blander dem sammen med koden. fx:  ( //2/ er mine kommentarer tiil kommentarerne

                            //2/ du har generelt dine komemtarer foran den linie der
                            //2/ kommenteres. det er en fin ide.
    // her f¿lger funktionen som foretager selve manipulationen med de enkelte ord
    // (bytter rundt pŒ bogstaverne, undtagen det f¿rste og det sidste.
    //                    //2/ forbinder kommentaren ned den linie den hører til
function shuffler($t){      //2/ med indrykkede kommentarer kan du spare linier

    $tmp = array();    //nulstil tmp  //2/ ofte kan kommentare stå efter linien

        // g¿r $special global, sŒ den kan afl¾ses uden for denne funktion
        // $special angiver om der er et komme eller lign tegn efter det aktuelle ord,
        //og i givet faald hvilket tegn det drejer sig om..
        // kunne man her benytte en 'smart' metode til slet og ret at teste for 'non-alphbetic' tegn?
        // ligesom man kan definere tegnklasser i grep ned diverse koder (\n)
    global $special;

min generelle reger er at kommentarer er rykket 'lidt mere ind'. det er kun for helt store kommetarblokke (fx. inledningen i toppen af filen jeg laver blokke af kommentarer uden indrykning.)

dine variabelnavne ser ganske gode ud. den eneste jeg er lidt muggen på er $tmp2, den ville jeg kalde $res eller $resultat for at give forvarsel om at det er hvad funktionen returnerer.

mvh JakobA
Avatar billede mikkel_breum Nybegynder
09. december 2003 - 17:31 #9
ok.. gode fif, Tak! Hvad med selve koden da?
Er selve problemet løst på en nogenlunde kode-økonomisk måde, koder jeg skrukturelt set på en fornuftig måde i dette eksempel 8som jo er meget simpelt)?

jeg har nogen gange set kode lavet af personer som har læst datalogi fx., og jeg kan se at de koder lidt mere indforstået, og måske mere kompatibelt end jeg.. Hvad hvis en anden programmør skulle arbejde videre med min kode.. ville de så forvente en anden logik? bl.a. det du siger med variabelnavnet $tmp2 kan jeg se kunne være et issue i sådan en sammenhæng.. men selvfølgelig gør det det også mere overskueligt for mig selv.
Avatar billede jakoba Nybegynder
09. december 2003 - 17:36 #10
noget andet er at ikke alle kommentarer er lige gode:
    $tmp = array();    // nulstil tmp
    $i++;              // tæl $i een op
osv. Det er såkaldte 'begynderkommentarer' der ikke fortæller sporsomhelst andet end hvad enkver kan se på koden at den gør. Det er helt fint at du skriver dem sålænge du har brug for dem (det gør jeg også selv når jeg roder med et nyt sprog).
Men vær opmærksom på at de 'gode' kommentarer er dem der 'bygger bro', der skaber en sammenhæng immellem programkoden og det problem der løses.
sammenlign:
    for ($i=0; $i<$seder; $i++) {  //for $i fra 0 optil $seder
    for ($i=0; $i<$seder; $i++) {  //for hvert sæde i bilen

Jeg synes den nederste kommentar er den nyttigste :-))
Avatar billede jakoba Nybegynder
09. december 2003 - 17:49 #11
// her benytter jeg $j i stedet for $i i min l¿kke, for ikke at komme i problemer
    // med den hovedl¿kke, som denne lykke er indlejret i.. men er det n¿dvendigt?
    // her stŒr l¿kken jo i sin egen funktion og er ikke en global..
for ($j = 0; $j < $antal_tegn; $j++) {
    $tmp_orginal[] = substr($t,$j,1);
}

    // nu har l¿kken lavet et array $temp-original["ord1","ord2","ord3"]
        //2/ hvis linien ovenover er korrekt er det IKKE bogstaver du har i
        //2/ arrayet $tmp_original.  DET ER EN DECIDERET FY-FY !
        //2/ hvis dine kommentarer ikke er opdateret er det bedre slet ikke
        //2/ at have nogen kommentar der.
    // herefter laver jeg en kopi af dette array, sŒ jeg kan manipulere med det,
    //uden at miste min original, jeg skal bruge den senere..
$tmp = $tmp_orginal;
        //2/ er du HELT sikker på at det giver en kopi af dit array, og ikke
        //2/ blot en extra reference til det samme array?  TEST DET!
Avatar billede jakoba Nybegynder
09. december 2003 - 18:05 #12
.  // her benytter jeg $j i stedet for $i i min l¿kke, for ikke at komme i problemer
    // med den hovedl¿kke, som denne lykke er indlejret i.. men er det n¿dvendigt?
        //2/ her ville jeg starte forfra med $i fordi php jo har en klar scope-regel
        //2/ om at navne i funktioner kun gælder i den funktion og ikke kan forveksles
        //2/ med navne udenfor.
        //2/ i andre sprog benytter jeg ofte et 'større' navn for
        //2/ tællevariablen udenfor for at være sikker på at $i, $j, $k
        //2/ er ledige til at blive brugt som tællere i diverse funktioner
        //2/ uden risiko for at jeg bruger en global variabel som teller
        //2/ indeni en funktion (fx ved at glemme at erklære $i lokalt)
Avatar billede detox Nybegynder
09. december 2003 - 19:17 #13
Rent kodemæssigt kan du spare lidt her på di switch:

switch (substr($t,-1)) {
    case ",":
    case ".":
    case ";":
    case "?":
    case "!":
        $special = substr($t,-1);
        break;
    default:
        $special = FALSE;
    }
Avatar billede detox Nybegynder
11. december 2003 - 11:28 #14
Endnu mere simpelt kunne du skrive tegnene i en string fx:
$special = ',.;?!:';
og tjekke med:
if (strstr(substr($t,-1), $special)) {//osv...
Avatar billede detox Nybegynder
22. december 2003 - 12:48 #15
Sker der noget her?
Avatar billede mikkel_breum Nybegynder
22. december 2003 - 12:57 #16
ja.. tak for alle jeres kommentarer! Hvis nogle vil have point skal de jo svare og ikke kommenterer..

Alle der vil have point, send et lille svar, så fordeler jeg senere på dagen
Avatar billede erikjacobsen Ekspert
22. december 2003 - 13:05 #17
Det er bestemt ikke for at få point, men jeg legede med samme problem en
gang og ville prøve at lave det så kort som muligt, og nåede frem til:

<?
  function f($a) {
    for ($i=1; $i<strlen($a)-1;$i++) {
      $j=rand(1,strlen($a)-2);
      $t=$a[$i]; $a[$i]=$a[$j]; $a[$j]=$t;
    }
    return $a;
  }

  $a = 'Der er meget lange ord, og så er der jo æblegrøden!!!';
  $b = preg_replace('/(\w+)/e','f($1)',$a);
  print $b;
?>
Avatar billede mikkel_breum Nybegynder
22. december 2003 - 16:47 #18
hvad betegner $1 i denne kode: preg_replace('/(\w+)/e','f($1)',$a);  ?
Avatar billede detox Nybegynder
22. december 2003 - 17:04 #19
$1 er resultatet fra det første udtryk: '/(\w+)/e', altså et ord.
Det skulle måske være:
$b = preg_replace('/(\w+)/e','f("$1")',$a);
Avatar billede erikjacobsen Ekspert
22. december 2003 - 17:22 #20
Ja, det er korrekt detox. Det "virker" uden, så længe der ikke er
defineret konstanter, og der så er sammenfald.
Avatar billede detox Nybegynder
22. december 2003 - 17:32 #21
erik -> Det er en effektiv kode du har brygget der. Jeg legede lidt med den og str_shuffle(), det blev til:

<?
  function f($a) {
    $a = str_shuffle($a);
    return $a;
  }
  $a = 'Der er meget lange ord, og så er der jo æblegrøden!!!';
  $b = preg_replace('/(\w)(\w+)(\w)/e','"\\1".f("\\2")."\\3"',$a);
  print $b;
?>
Avatar billede detox Nybegynder
22. december 2003 - 17:34 #22
Det skal lige siges at: \\1, \\2 og \\3 repræsenterer hver af parenteserne.
Avatar billede erikjacobsen Ekspert
22. december 2003 - 17:46 #23
Skal vi så ikke lige yderligere:

  function f($a) {
    return str_shuffle($a);
  }

eller blot:

$b = preg_replace('/(\w)(\w+)(\w)/e','"\\1".str_shuffle("\\2")."\\3"',$a);
Avatar billede detox Nybegynder
22. december 2003 - 17:52 #24
Jo, så bliver den vidst heller ikke meget kortere ;o)

<?
  $a = 'Der er meget lange ord, og så er der jo æblegrøden!!!';
  echo preg_replace('/(\w)(\w+)(\w)/e','"\\1".str_shuffle("\\2")."\\3"',$a);
?>
Avatar billede erikjacobsen Ekspert
22. december 2003 - 17:59 #25
En anelse mere logisk måske:

  $b = preg_replace('/(?<=\w)(\w+)(?=\w)/e','str_shuffle("$1")',$a);
Avatar billede detox Nybegynder
22. december 2003 - 18:07 #26
Ja og sørme osse en anelse kortere.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester