mboost-dp1
Hvem har lært nok Java 8 til at kunne skrive ulæselig kode?
- Forside
- ⟨
- Forum
- ⟨
- Tagwall
Claus Jørgensen (36) skrev:
heh, 1-based arrays. Det minder mig om da min mor var i Stockholm den anden uge og på undergrundsbanen så hun at der hang en programmerings gåde (fra et konsulentfirma der hyrer folk) med noget array/string manipulation (for at lave en URL man kan besøge)
Hun var meget forvirret indtil jeg forklarede at array indexing er 0-based i Python (og de fleste andre sprog) :p
I PL/I starter arrays nemlig også med 1
Default starter med 1.
Man kan angive eksplicit.
ArIx: procedure options(main);
declare a1 dimension(10) fixed binary(31);
declare a2 dimension(1:10) fixed binary(31);
declare a3 dimension(0:9) fixed binary(31);
declare a4 dimension(-5:4) fixed binary(31);
declare ix1 fixed binary(31);
declare ix2 fixed binary(31);
declare ix3 fixed binary(31);
declare ix4 fixed binary(31);
do ix1 = lbound(a1) to hbound(a1);
a1(ix1) = ix1 * ix1;
put skip list(ix1,' ',a1(ix1));
end;
do ix2 = lbound(a2) to hbound(a2);
a2(ix2) = ix2 * ix2;
put skip list(ix2,' ',a2(ix2));
end;
do ix3 = lbound(a3) to hbound(a3);
a3(ix3) = ix3 * ix3;
put skip list(ix3,' ',a3(ix3));
end;
do ix4 = lbound(a4) to hbound(a4);
a4(ix4) = ix4 * ix4;
put skip list(ix4,' ',a4(ix4));
end;
end;
#52
Jeg undrede mig over at der kun skulle være en mulighed.
PL/I var det første sprog med den vanvittige ide at sproget skulle kunne alt og kunne bruges til alt.
Men jeg måtte lige have fat i en PL/I compiler og de hænger ikke på træerne.
Men det er muligt at få en hobbyist licens til VMS PL/I. Og ganske vist er der visse forskelle på IBM mainframe PL/I og VMS PL/I, men jeg tror ikke for array indexes.
:-)
Jeg undrede mig over at der kun skulle være en mulighed.
PL/I var det første sprog med den vanvittige ide at sproget skulle kunne alt og kunne bruges til alt.
Men jeg måtte lige have fat i en PL/I compiler og de hænger ikke på træerne.
Men det er muligt at få en hobbyist licens til VMS PL/I. Og ganske vist er der visse forskelle på IBM mainframe PL/I og VMS PL/I, men jeg tror ikke for array indexes.
:-)
$51
Og så kan man forkorte:
Og så kan man forkorte:
ArIx2: procedure options(main);
dcl a1(10) fixed bin(31);
dcl a2(1:10) fixed bin(31);
dcl a3(0:9) fixed bin(31);
dcl a4(-5:4) fixed bin(31);
dcl ix1 fixed bin(31);
dcl ix2 fixed bin(31);
dcl ix3 fixed bin(31);
dcl ix4 fixed bin(31);
do ix1 = lbound(a1) to hbound(a1);
a1(ix1) = ix1 * ix1;
put skip list(ix1,' ',a1(ix1));
end;
do ix2 = lbound(a2) to hbound(a2);
a2(ix2) = ix2 * ix2;
put skip list(ix2,' ',a2(ix2));
end;
do ix3 = lbound(a3) to hbound(a3);
a3(ix3) = ix3 * ix3;
put skip list(ix3,' ',a3(ix3));
end;
do ix4 = lbound(a4) to hbound(a4);
a4(ix4) = ix4 * ix4;
put skip list(ix4,' ',a4(ix4));
end;
end;
#54 lol
Jeg synes der er to gode grunde til at 0 indekserede arrays er bevaret i moderne sprog som default:
1. Der er hvad hardwaren gør i sidste ende. Et nulstillet index vil pege på første element.
2. Det fungerer bedre med modulo og heltalsdivision, eg. at tilgå et element i en 10x10 matrix med et overordnet index er meget ligetil når alt er zerobased:
import numpy as np
matrix = np.zeros((10, 10))
matrix[index % 10][index // 10] = 42
Hvis tingene havde været 1 baserede, skulle man alligevel have været et smut forbi zerobased:
onebased_matrix[(onebased_index - 1) % 10 + 1][(onebased_index - 1) // 10 + 1]
Jeg synes der er to gode grunde til at 0 indekserede arrays er bevaret i moderne sprog som default:
1. Der er hvad hardwaren gør i sidste ende. Et nulstillet index vil pege på første element.
2. Det fungerer bedre med modulo og heltalsdivision, eg. at tilgå et element i en 10x10 matrix med et overordnet index er meget ligetil når alt er zerobased:
import numpy as np
matrix = np.zeros((10, 10))
matrix[index % 10][index // 10] = 42
Hvis tingene havde været 1 baserede, skulle man alligevel have været et smut forbi zerobased:
onebased_matrix[(onebased_index - 1) % 10 + 1][(onebased_index - 1) // 10 + 1]
larsp (55) skrev:
1. Der er hvad hardwaren gør i sidste ende. Et nulstillet index vil pege på første element.
Umiddelbart virker:
address = base address + index * element size
mere logisk end:
address = base address + (index - 1) * element size
Men det sidste er ikke hvad compilere gør i praksis. De gør:
address = (base address - 1 * element size) + index * element size
Hvilket er samme kode bare med en anden basis addresse.
larsp (55) skrev:
2. Det fungerer bedre med modulo og heltalsdivision, eg. at tilgå et element i en 10x10 matrix med et overordnet index er meget ligetil når alt er zerobased:
import numpy as np
matrix = np.zeros((10, 10))
matrix[index % 10][index // 10] = 42
Hvis tingene havde været 1 baserede, skulle man alligevel have været et smut forbi zerobased:
onebased_matrix[(onebased_index - 1) % 10 + 1][(onebased_index - 1) // 10 + 1]
Ja.
Men du er allerede ude i noget low level hvor du mapper 1 dim til 2 dim.
Den pæne kode som tilgår et 2 dim array har naturligvis 2 index.
larsp (55) skrev:import numpy as np
matrix = np.zeros((10, 10))
matrix[index % 10][index // 10] = 42
Bemærk iøvrigt at mapningen fra 1 dim til 2 dim ikke følger memory layout.
Per dokumentation følger np.zeros per default (uden order 'F') C konvention og ikke Fortran konvention.
arne_v (56) skrev:De gør:
address = (base address - 1 * element size) + index * element size
Hvilket er samme kode bare med en anden basis addresse.
Det er en oplagt optimering, ja. Men hvis man i andre sammenhænge skal flytte rundt på data eller memory free allokeringen, skal man stadig bruge den rigtige base addresse. Så det forekommer lidt bøvlet.
arne_v (56) skrev:Men du er allerede ude i noget low level hvor du mapper 1 dim til 2 dim.
Den pæne kode som tilgår et 2 dim array har naturligvis 2 index.
Det var bare et eksempel hvor både modulo og heltals division indgår på én linje.
Men modulo kan optræder jo mange andre steder. F.eks. hvis man vil cykle mellem værdier:
monster_farve = farver[monster_nummer % 5]
#57 Det vidste jeg ikke. Jeg har iøvrigt meget sjældent brugt C's multidimensionelle arrays. Foretrækker structs i structs, eg. row[4].col[6]
larsp (58) skrev:
#57 Det vidste jeg ikke. Jeg har iøvrigt meget sjældent brugt C's multidimensionelle arrays. Foretrækker structs i structs, eg. row[4].col[6]
Du vidste nu nok hvordan C gemmer i memory.
char s[10][256];
...
strcpy(s[ix], "This is a test");
virker kun fordi de ligger i memory som:
s[0][0]
...
s[0][255]
s[1][0]
...
s[1][255]
...
Hvis de lå som:
s[0][0]
...
s[9][0]
s[0][1]
...
s[9][1]
...
virkede det ikke.
Alle Fortran programmører (det er en ret lille gruppe!) ved at Fortran gør det omvendt.
Jeg havde ingen anelse om hvad Python numpy gjorde, så jeg måtte slå det op.
Det overrasker mig ikke at Python understøtter begge. At kalde C fra Python er helt standard. Men da der lige netop indenfor scientific computing/HPC/linear algrebra/matrix beregninger stadig bruges Fortran i vid omfang, så giver det mening at Python numpy kan lave et 2D array efter Fortran konvention hvis man beder om det.
arne_v (59) skrev:
Men da der lige netop indenfor scientific computing/HPC/linear algrebra/matrix beregninger stadig bruges Fortran i vid omfang, så giver det mening at Python numpy kan lave et 2D array efter Fortran konvention hvis man beder om det.
SciPy har faktisk Fortran source code.
NumPy selv er lidt grumset. De tager Fortran kode, kører en fortran-til-C konvertering på den og oversætter den generede C kode.
Mere 0 vs 1 baseret.
Jeg kan sagtens finde ud af 1 baserede arrays.
Men der er et tilfælde af 1 baseret som virkeligt irriterer mig.
Men først lidt baggrund.
Alle kender C kode som:
if(s[ix] == 0)
man sammenligner bare en char med en int og det virker fint.
I de lidt mere type sikre sprog skal man eksplicit konvertere fra char til int.
Pascal:
if ord(s[ix]) = 0 then
Fortran:
if(ichar(s(ix:ix)).eq.0) then
Det virker fint. Pascal koden er særdeles pæn efter min mening. Fortran koden er lidt mere tung, men den kan læses.
Det der irriterer mig er Cobol.
if function ord(s(ix:1)) = 1 then
At man skal prefixe et funktions kald med function keyword er lidt tungt, men det kan stadig læses.
Men "= 1"? WTF??
Cobol er så meget 1 baseret at ORD funktionen returnerer værdier 1-256 for bytes. En nul byte giver 1, CR LF er 14 og 11 etc..
Det er for meget!!
Jeg kan sagtens finde ud af 1 baserede arrays.
Men der er et tilfælde af 1 baseret som virkeligt irriterer mig.
Men først lidt baggrund.
Alle kender C kode som:
if(s[ix] == 0)
man sammenligner bare en char med en int og det virker fint.
I de lidt mere type sikre sprog skal man eksplicit konvertere fra char til int.
Pascal:
if ord(s[ix]) = 0 then
Fortran:
if(ichar(s(ix:ix)).eq.0) then
Det virker fint. Pascal koden er særdeles pæn efter min mening. Fortran koden er lidt mere tung, men den kan læses.
Det der irriterer mig er Cobol.
if function ord(s(ix:1)) = 1 then
At man skal prefixe et funktions kald med function keyword er lidt tungt, men det kan stadig læses.
Men "= 1"? WTF??
Cobol er så meget 1 baseret at ORD funktionen returnerer værdier 1-256 for bytes. En nul byte giver 1, CR LF er 14 og 11 etc..
Det er for meget!!
Claus Jørgensen (41) skrev:
Jeg synes personligt dette her er nemmere at forstå (Swift ranges):
0...9
0..<9
https://developer.apple.com/documentation/swift/ra...
Jeg har lige opdaget at Kotlin har kopieret ideen for ikke inklusive range. Gradvis indfaset men fuldt indfaset i 1.9. Den gamle syntax var også meget svær at gennemskue.
Før:
0..9
o until 9
Nu:
0..9
0..<9
Opret dig som bruger i dag
Det er gratis, og du binder dig ikke til noget.
Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.