SQL Server? Tip voor de volgende keer: SQL Profiler (of AnjLab.SqlProfiler bij SQL Express)
stukje lelijke code van mezelf (vandaag geschreven)
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| for i := 1 to System.ParamCount do begin if LowerCase(ParamStr(i)) = '/?' then begin MessageBox(0, '/? : Deze informatie'+#10+#13+ '/autostart : Start meteen met scannen bij het starten van de applicatie'+#10+#13+ '/autoexport : Ga meteen beginnen met exporteren naar excel als de scan is afgerond'+#10+#13+ '/exportpath= : Geef het pad aan waar de excelbestanden moeten worden neergezet'+#10+#13+ '/threads= : Hoeveel draadjes voor het scannen er gestart mogen worden'+#10+#13+ '/autoemail : Autmatisch e-mailen van de export bestanden'+#10+#13+ '/to= : Naar wie moet het gestuurd worden (meerdere adressen scheiden met een , )'+#10+#13+ '/cc= : Wie krijgt een kopie van de e-mail (meerdere adressen scheiden met een , )'+#10+#13+ '/bcc= : Wie krijgt een blinde kopie van de e-mail (meerdere adressen scheiden met een , )'+#10+#13+ '/database : Gebruik de database'+#10+#13+ '/exitafterrun : Sluit de applicatie als de scan is afgerond'+#10+#13+#10+#13+ 'Voorbeeld:'+#10+#13+ '/autostart /autoexport /exportpath=b:\ /exitafterrun /threads=15', 'Beschikbare parameters', +mb_Ok +mb_ICONINFORMATION); application.Terminate; end else if LowerCase(ParamStr(i)) = '/autostart' then begin AutoStart := True; end else if LowerCase(ParamStr(i)) = '/autoexport' then begin AutoExport := True; end else if LowerCase(ParamStr(i)) = '/autoemail' then begin AutoEmail := True; end else if LowerCase(ParamStr(i)) = '/database' then begin UseDatabase := True; end else if LeftStr(LowerCase(ParamStr(i)), 4) = '/to=' then begin strTo := RightStr(LowerCase(ParamStr(i)), Length(ParamStr(i)) - 4); end else if LeftStr(LowerCase(ParamStr(i)), 4) = '/cc=' then begin strCC := RightStr(LowerCase(ParamStr(i)), Length(ParamStr(i)) - 4); end else if LeftStr(LowerCase(ParamStr(i)), 5) = '/bcc=' then begin strBCC := RightStr(LowerCase(ParamStr(i)), Length(ParamStr(i)) - 5); end else if LeftStr(LowerCase(ParamStr(i)), 12) = '/exportpath=' then begin ExportPath := RightStr(LowerCase(ParamStr(i)), Length(ParamStr(i)) - 12); end else if LeftStr(LowerCase(ParamStr(i)), 9) = '/threads=' then begin seMaxThreads.Value := StrToInt(RightStr(LowerCase(ParamStr(i)), Length(ParamStr(i)) - 9)); end else if LowerCase(ParamStr(i)) = '/exitafterrun' then begin ExitAfterRun := True; end; end; |
Nee niet echt, maar dit was geschreven zonder koffie....
Behalve dat je LowerCase(ParamStr(i)) net zo goed aan het begin had kunnen doen zie ik er niet iets verkeerds aan. Het is simpele code die je arguments parsed zonder poespas.
lekkere regex tegengekomen 
code:
1
| (.*\.([gG][iI][fF]|[jJ][pP][eE]?[gG]|[bB][mM][pP]|[pP][nN][gG]|[tT][iI][fF]{2})$) |
This message was sent on 100% recyclable electrons.
Fantastisch! Je hebt een regex gevonden die leesbaar isBasieP schreef op dinsdag 09 augustus 2011 @ 16:27:
lekkere regex tegengekomen
code:
1 (.*\.([gG][iI][fF]|[jJ][pP][eE]?[gG]|[bB][mM][pP]|[pP][nN][gG]|[tT][iI][fF]{2})$)
De case insensitive flag zetten is te makkelijk.
¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸
So you've got a problem, and you've decided to solve it with Regular Expressions. Now you've got two problems.BasieP schreef op dinsdag 09 augustus 2011 @ 16:27:
lekkere regex tegengekomen
code:
1 (.*\.([gG][iI][fF]|[jJ][pP][eE]?[gG]|[bB][mM][pP]|[pP][nN][gG]|[tT][iI][fF]{2})$)
Afhankelijk van de taal was een pathinfo (PHP) of FileInfo (.NET) of andere dedicated methode/class natuurlijk te moeilijk. En anders is alles na het laatste puntje zoeken en een substring nog steeds stukke duidelijker.
Cliché quotes, nice!RobertMe schreef op dinsdag 09 augustus 2011 @ 17:47:
[...]
So you've got a problem, and you've decided to solve it with Regular Expressions. Now you've got two problems.
;)52.“First, solve the problem. Then, write the code.”
(John Johnson)
Flauwe quote, maar tbf wel waar voor een hoop (daily)wtfs.
Hij 's fijn.The bulk of all patents are crap. Spending time reading them is stupid. It’s up to the patent owner to do so, and to enforce them.
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
maar toch heb ik het gevoel dat het makkelijker en korter kan...PrisonerOfPain schreef op dinsdag 09 augustus 2011 @ 15:49:
Behalve dat je LowerCase(ParamStr(i)) net zo goed aan het begin had kunnen doen zie ik er niet iets verkeerds aan. Het is simpele code die je arguments parsed zonder poespas.
Je zou zoiets kunnen doen:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| function ParamIsForKey(param, key: String): Boolean; begin result := (LeftStr(param, Lenght(key) + 2) = ('/' + key + '='); end; function GetParamValue(param, key: String): String; begin result := RightStr(param, Length(param - Length(key) + 2)); end; for i := 1 to System.ParamCount do begin param := LowerCase(ParamStr(i)); if param = '/?' then begin ShowHelpMessage(); ;) end else if param = '/autostart' then begin AutoStart := True; end else if param = '/exitafterrun' then begin ExitAfterRun := True; end // Knip rest van de booleans else if ParamIsForKey(param, 'cc') then begin strCC := GetParamValue(param, 'cc'); end else if ParamIsForKey(param, 'to') then begin strTo := GetParamValue(param, 'to'); end // Knip rest van de strings else if ParamIsForKey(param, 'threads') then begin seMaxThreads.Value := StrToInt(GetParamValue(param, 'threads')); end; end; |
[ Voor 17% gewijzigd door CodeCaster op 09-08-2011 22:49 ]
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
select case?eagle00789 schreef op dinsdag 09 augustus 2011 @ 22:23:
[...]
maar toch heb ik het gevoel dat het makkelijker en korter kan...
Noobs don't use "F1", Pro's do, but they can't find the information they needed
Waarop dan?FireWood schreef op dinsdag 09 augustus 2011 @ 22:53:
select case?
Ik denk dat Delphi geen ondersteuning biedt op string cases.
Daarnaast moet maar een gedeelte van de string matchen.
If money talks then I'm a mime
If time is money then I'm out of time
Ik denk dat er geen enkele grote taal is die kan matchen op zinsdelen in een switch-statement. Ik vind CodeCasters voorbeeld een prima oplossing. Toch word ik helemaal kriebelig van al dat begin en end gedoe
.
Een dag voor de deadline, moe, lichtelijk geirriteerd wegens de change request zo laat in het project.Dan krijg je dus dit soort code:
Het zou vast makkelijker en efficienter kunnen... Iets voor de update later dit jaar
Vervelende server gasten hadden gewoon de sorting moeten doen zoals in de specificatie stond
Hebben ze geen "tijd" mee voor.Tisch zit ik er dus mooi mee opgescheept
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| public function groupAndSort(groupingField:String, sortField:String): Type2JackpotsVOFilter { var groupDataSet: Dictionary = new Dictionary( true ); var list: Array; var groupNameList: Array = []; for each ( var item: IJackpotWinningVO in _itemsData ) { var groupValue: * = item[ groupingField ]; if ( groupValue is Date ) { var valueAsDate: Date = groupValue as Date; var groupDate: Date = new Date( valueAsDate.time ); groupDate.setHours( 0, 0, 0 ); groupValue = groupDate.time.toString(); // change date to midnight } if ( !groupDataSet.hasOwnProperty(groupValue) ) { var result: Array = []; groupDataSet[groupValue] = result; groupNameList.push( parseInt(groupValue) ); } list = groupDataSet[groupValue]; list.push( item ); } // sort the groupNameList in ascending order groupNameList.sort( Array.NUMERIC ); // get all groups and sort the items of the group for each ( var groupName: String in groupNameList ) { var groupId: String = groupName.toString(); list = groupDataSet[groupId]; // sort the array var func: Function = function(x: IJackpotWinningVO, y: IJackpotWinningVO): Number { if ( x[sortField] > y[sortField] ) { return -1; } else if ( x[sortField] < y[sortField] ) { return 1; } else { return 0; } }; list.sort( func ); // re-assign the value to dictionary groupDataSet[groupName] = list; } // flatten the list back into a vector list var results: Vector.<IJackpotWinningVO> = new Vector.<IJackpotWinningVO>(); for ( groupName in groupDataSet ) { list = groupDataSet[groupName]; for each ( item in list ) { results.push( item ); } groupDataSet[groupName] = null; delete groupDataSet[groupName]; } _itemsData = results; return this; } |
Het zou vast makkelijker en efficienter kunnen... Iets voor de update later dit jaar
Vervelende server gasten hadden gewoon de sorting moeten doen zoals in de specificatie stond

[ Voor 14% gewijzigd door alienfruit op 10-08-2011 08:48 ]
nice clean code. just the way i like itCodeCaster schreef op dinsdag 09 augustus 2011 @ 22:41:
Je zou zoiets kunnen doen:
Delphi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 function ParamIsForKey(param, key: String): Boolean; begin result := (LeftStr(param, Lenght(key) + 2) = ('/' + key + '='); end; function GetParamValue(param, key: String): String; begin result := RightStr(param, Length(param - Length(key) + 2)); end; for i := 1 to System.ParamCount do begin param := LowerCase(ParamStr(i)); if param = '/?' then begin ShowHelpMessage(); ;) end else if param = '/autostart' then begin AutoStart := True; end else if param = '/exitafterrun' then begin ExitAfterRun := True; end // Knip rest van de booleans else if ParamIsForKey(param, 'cc') then begin strCC := GetParamValue(param, 'cc'); end else if ParamIsForKey(param, 'to') then begin strTo := GetParamValue(param, 'to'); end // Knip rest van de strings else if ParamIsForKey(param, 'threads') then begin seMaxThreads.Value := StrToInt(GetParamValue(param, 'threads')); end; end;
toch nog een paar kleine wijzigingen:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
| procedure TMainForm.ShowHelp; begin MessageBox(0, '/? : Deze informatie'+NewLine+ '/autostart : Start meteen met scannen bij het starten van de applicatie'+NewLine+ '/autoexport : Ga meteen beginnen met exporteren naar excel als de scan is afgerond'+NewLine+ '/exportpath= : Geef het pad aan waar de excelbestanden moeten worden neergezet'+NewLine+ '/threads= : Hoeveel draadjes voor het scannen er gestart mogen worden'+NewLine+ '/autoemail : Autmatisch e-mailen van de export bestanden'+NewLine+ '/to= : Naar wie moet het gestuurd worden (meerdere adressen scheiden met een , )'+NewLine+ '/cc= : Wie krijgt een kopie van de e-mail (meerdere adressen scheiden met een , )'+NewLine+ '/bcc= : Wie krijgt een blinde kopie van de e-mail (meerdere adressen scheiden met een , )'+NewLine+ '/database : Gebruik de database'+NewLine+ '/exitafterrun : Sluit de applicatie als de scan is afgerond'+NewLine+NewLine+ 'Voorbeeld:'+NewLine+ '/autostart /autoexport /exportpath=b:\ /exitafterrun /threads=15', 'Beschikbare parameters', +mb_Ok +mb_ICONINFORMATION); application.Terminate; end; procedure TMainForm.SetParams; var i: Integer; param: String; function ParamIsForKey(param, key: String): Boolean; begin result := (LeftStr(param, Length(key) + 2) = ('/' + key + '=')); end; function GetParamValue(param, key: String): String; begin result := RightStr(param, Length(param) - Length(key) + 2); end; begin for i := 1 to System.ParamCount do begin param := LowerCase(ParamStr(i)); if param = '/?' then begin ShowHelp; end else if param = '/autostart' then begin AutoStart := True; end else if param = '/autoexport' then begin AutoExport := True; end else if param = '/autoemail' then begin AutoEmail := True; end else if param = '/database' then begin UseDatabase := True; end else if param = '/exitafterrun' then begin ExitAfterRun := True; end else if ParamIsForKey(param, 'to') then begin strTo := GetParamValue(param, 'to'); end else if ParamIsForKey(param, 'cc') then begin strCC := GetParamValue(param, 'cc'); end else if ParamIsForKey(param, 'bcc') then begin strBCC := GetParamValue(param, 'bcc'); end else if ParamIsForKey(param, 'exportpath') then begin ExportPath := GetParamValue(param, 'exportpath'); end else if ParamIsForKey(param, 'threads') then begin seMaxThreads.Value := StrToInt(GetParamValue(param, 'threads')); end; end; end; |
De database waar ik mee moet werken zit helaas niet lekker in elkaar.
Er zitten totaal geen foreign keys in, de indexen zijn zomaal op wat velden gezet die 'waarschijnlijk' wel de goede velden voor indexen zijn, en laatst kwam ik er zelf achter dat er zelfs velden missen.
Toen ik aan de programmeur vroeg waarom die er niet in zaten was het antwoord "tja, die heb ik nog niet nodig gehad dus heb ik er nog niet in aangemaakt", met het gevolg dat je nu dus met updates ook de database moet gaan updaten terwijl dat eigenlijk helemaal niet nodig had hoeven zijn. En geloof mij, als je bij grote organisaties software wilt updaten is het handig als je de dba helemaal niet nodig hebt.
Er zitten totaal geen foreign keys in, de indexen zijn zomaal op wat velden gezet die 'waarschijnlijk' wel de goede velden voor indexen zijn, en laatst kwam ik er zelf achter dat er zelfs velden missen.
Toen ik aan de programmeur vroeg waarom die er niet in zaten was het antwoord "tja, die heb ik nog niet nodig gehad dus heb ik er nog niet in aangemaakt", met het gevolg dat je nu dus met updates ook de database moet gaan updaten terwijl dat eigenlijk helemaal niet nodig had hoeven zijn. En geloof mij, als je bij grote organisaties software wilt updaten is het handig als je de dba helemaal niet nodig hebt.
486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22
Ik vind dat die programmeur wel een punt heeft. Het heeft weinig nut om velden in de database op te gaan nemen waarbij je misschien denkt ze in de toekomst nodig te hebben. Een alter table query is toch geen probleem? Het is onmogelijk om de toekomst te voorspellen, dus doe dat dan ook niet.
"Beauty is the ultimate defence against complexity." David Gelernter
Vier manieren om een ajax-call te maken op één pagina.
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <script type="text/javascript" language="JavaScript" src="jquery-1.2.4a.min.js"></script> <script type="text/javascript" language="JavaScript" src="taconite-client.js"></script> <script type="text/javascript" language="JavaScript" src="taconite-parser.js"></script> <script type="text/javascript" language="JavaScript" src="AjaxRequest.js"></script> function getHTTPObject() { var xmlhttp; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else if (window.ActiveXObject) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp; } |
omg
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| function translate_to_french( p_words in Varchar2 ) return varchar2 as begin return replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( lower(p_words) , ' and ' , ' et ' ) , 'dollars' , 'dollars' ) , 'cents' , 'cents' ) , 'duodecillion' , 'bidecillion' ) , 'quintillion' , 'cintillion' ) , 'billion' , 'milliard' ) , 'thousand' , 'mille' ) , 'hundred' , 'cent' ) , 'ninety' , 'quatre-vingt-dix') , 'eighty' , 'quatre-vingts' ) , 'seventy' , 'soixante-dix' ) , 'sixty' , 'soixante' ) , 'fifty' , 'cinquante' ) , 'forty' , 'quarante' ) , 'thirty' , 'trente' ) , 'twenty' , 'vingt' ) , 'nineteen' , 'dix-neuf' ) , 'eighteen' , 'dix-huit' ) , 'seventeen' , 'dix-sept' ) , 'sixteen' , 'seize' ) , 'fifteen' , 'quinze' ) , 'fourteen' , 'quatorze' ) , 'thirteen' , 'treize' ) , 'twelve' , 'douze' ) , 'eleven' , 'onze' ) , 'ten' , 'dix' ) , 'nine' , 'neuf' ) , 'eight' , 'huit' ) , 'seven' , 'sept' ) , 'six' , 'six' ) , 'five' , 'cinq' ) , 'four' , 'quatre' ) , 'three' , 'trois' ) , 'two' , 'deux' ) , 'one' , 'un' ) , 'dix-six' , 'seize' ) , 'dix-cinq' , 'quinze' ) , 'dix-quatre' , 'quatorze' ) , 'dix-trois' , 'treize' ) , 'dix-deux' , 'douze' ) , 'dix-un' , 'onze' ) , '-un ' , '-une ' ) , 'un cent' , 'cent' ) , 'un mille' , 'mille' ) , 'une' , 'un' ) , 'soixante-onze' , 'soixante et onze') , 'quatre-vingts-' , 'quatre-vingt-' ) , '-un' , ' et un' ) , 'quatre-vingt et un', 'quatre-vingt-un' ) ; End translate_to_french; |
Haha. Lang leve thedailywtf.com
Ook mooi zijn die, duodicellion dingen.
Ook mooi zijn die, duodicellion dingen.
Vooral ook het lekker consequent zijn en 'dollar' en 'cents' ook vervangen door zichzelf...

Zo scherp als een voetbal!
En natuurlijk dat 'seize' blijkbaar 'dix-six' in het Engels is
.
Wel een mooie vertaalfunctie
If money talks then I'm a mime
If time is money then I'm out of time
Nee, dat zijn de uitzonderingen in de Franse taal. Dix-six is juist seize...YopY schreef op zaterdag 13 augustus 2011 @ 22:19:
En natuurlijk dat 'seize' blijkbaar 'dix-six' in het Engels is.
Wel mooie indenting overigens! Het had ook een oneliner kunnen zijn
Dat is even logisch als "olifant is seize". Hoe kom je ooit aan de dix-six voor de input?H004 schreef op zondag 14 augustus 2011 @ 07:49:
Nee, dat zijn de uitzonderingen in de Franse taal. Dix-six is juist seize...
Dan moet er toch echt eerst iemand ten-six gebruikt hebben waar ie sixteen bedoelde.
-six of dix- staat ook nergens in de rechterkolom, dus het is ook geen intermediate result.
Ik zie echt niet wat er met dix-six t/m dix-un bedoeld is geweest, maar ik kan natuurlijk iets obver het hoofd zien
Zo'n replace(replace(replace constructie maakt geloof ik ook voor elke replace weer een mooie nieuwe string aan in C#, en ik neem aan ook in andere talen. Die worden wel weer netjes opgeruimt als de GC zijn werk doet, maar als het even kan probeer ik altijd zo min mogelijk nieuwe objecten te creeren die gelijk weer weg mogen.
486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22
Geheugen kost toch niks meer, why bother?PiepPiep schreef op zondag 14 augustus 2011 @ 13:40:
Zo'n replace(replace(replace constructie maakt geloof ik ook voor elke replace weer een mooie nieuwe string aan in C#, en ik neem aan ook in andere talen. Die worden wel weer netjes opgeruimt als de GC zijn werk doet, maar als het even kan probeer ik altijd zo min mogelijk nieuwe objecten te creeren die gelijk weer weg mogen.
Doe je ookDido schreef op zondag 14 augustus 2011 @ 13:34:
[...]
Dat is even logisch als "olifant is seize". Hoe kom je ooit aan de dix-six voor de input?
Dan moet er toch echt eerst iemand ten-six gebruikt hebben waar ie sixteen bedoelde.
-six of dix- staat ook nergens in de rechterkolom, dus het is ook geen intermediate result.
Ik zie echt niet wat er met dix-six t/m dix-un bedoeld is geweest, maar ik kan natuurlijk iets obver het hoofd zien
Verdomd, daar stond ie. Het stomme is dat ik gisteravond dacht hem gezien te hebben en er nu dus straal overheen keekH004 schreef op zondag 14 augustus 2011 @ 14:32:
Doe je ook76 is seventy-six in het Engels. Dat wordt in de functie eerst 'soixante-dix', en dan 'soixante-dix-six'. Dat wordt dan vervolgens gereplaced naar 'soixante-seize'
Mwah, dan upgrade je de hardware toch?Olaf van der Spek schreef op zondag 14 augustus 2011 @ 14:33:
Performance...
Pff, volgens mij wordt het tijd om te investeren in betere programmeurs, dan blijkt dat de hardware die we tegenwoordig hebben ineens weer overkill
.
Dido schreef op zondag 14 augustus 2011 @ 15:06:
Mwah, dan upgrade je de hardware toch?

If money talks then I'm a mime
If time is money then I'm out of time
Amen.Aloys schreef op zondag 14 augustus 2011 @ 15:21:
Pff, volgens mij wordt het tijd om te investeren in betere programmeurs, dan blijkt dat de hardware die we tegenwoordig hebben ineens weer overkill.
Twee gestileerde voorbeeldjes uit de praktijk die zelfs met hardware lastig op te lossen zijn:
Probleem 1:
We hebben voor externe applicaties taalcodes nodig die afhankelijk zijn van de huidige taal van de gebruiker.
Oplossing:
We maken een tabel met interne taalcode, applicatie en externe taalcode.
So far so good. Het resultaat is een tabel de er ruwweg zo uitziet:
code:
1
2
3
4
5
6
| NL app1 123 NL app2 DUT EN app1 124 EN app2 ENG FR app1 125 FR app2 FRA |
Dan zou je denken dat je met het lezen van 6 records alle mogelijk taalcodes in het geheugen kunt hebben, right?
Nopes.
We kunnen natuurlijk niet zomaar app1 en app2 invullen, dus hebben we een aparte tabel waarin alle mogelijke externe applicaties staan die we gebruiken. Op zich niet zo gek.
Om de "vertaaltabel" uit te lezen lezen we dus eerst alle mogelijke applicaties, om dan te kijken of we er een record voor hebben in de vertaaltabel. En we hebben 20 applicaties. Dat worden dus geen 6, maar 26 succesvolle leesacties plus 18 niet-succesvolle. 44 I/O's.
O wacht, we hebben natuurlijk ook de talen in de linkerkolom niet aan het toeval overgelaten. Hoewel we momenteel vijf interne talen ondersteunen zijn we op de toekomst voorbereid. We hebben alle mogelijke ISO-talen (zo'n 140 stuks) óók in een externe tabel staan. Uiteraard lezen we die ook eerst helemaal door!
Dat worden dus 140 x 20 leesacties op die stamtabellen, waarna we checken of de combinatie taal/applicatie in de vertaaltabel staat. Dat is in uiteraard maar in 6 gevallen waar. 2806 succesvolle leesacties en 2794 voor Jan met de korte achternaam.
En dan mag ik uitleggen waarom er 5600 I/O's plaatsvinden om 6 recods op te halen.

Probleem 2:
We maken specificaties, sets van geselecteerde items per productgroep. We maken gebruik van een database met productinformatie (plaatjes) die bij die items horen.
Een volledige specificatie bestaat uit zo'n productgroepen met een geslecteerd item. Daarvan heeft ongeveer de helft relevante productinformatie.
We willen graag kunnen inrichten of die productinformatie op het geprinte document terechtkomt of niet. (In de externe database staat die informatie al, maar dat zou te makkelijk zijn

Oplossing:
We maken een setup waarin een administrator voor alle mogelijke productgroepen, en daarbinnen alle mogelijke selecteerbare items, en daarbinnen alle aanwezige plaatjes mag aanvinken als ze op de print moeten komen.
De eerste WTF is dus dat er een simpele ziel zo'n 36000 plaatjes mag af- en aanvinken.
Als dat eenmaal gebeurd is moeten we de informatie gaan gebruiken. Zoals gezegd, een specificatie bestaat uit zo'n 600 items, waarvan de helft relevant productinformatie heeft. Laten er gemiddeld 2 plaatjes bij een product beschikbaar zijn als er informatie is, dan gaat het dus over zo'n 600 plaatjes die al dan niet geprint moeten worden.
Dus lezen we voor elke specificatie natuurlijk alle 36000 mogelijke items in het geheugen.
We werken onder Citrix, en GC is niet aanwezig. Niemand snapte waarom de applicatie opeens van traag naar "huh, hij hangt steeds vast" ging

Ha jij kan schrijven voor the daily WTF, mooie verhalen 
Bij probleem #2 serieus 36000 vinkjes aan/uitvinken, terwijl die informatie al in de externe db staat? Klinkt als werkverschaffing. Lijkt me ook best foutgevoelig...
Bij probleem #2 serieus 36000 vinkjes aan/uitvinken, terwijl die informatie al in de externe db staat? Klinkt als werkverschaffing. Lijkt me ook best foutgevoelig...
36.000 vinkjes? Hoe zeer moet je een hekel hebben aan de eindgebruikers om zo'n design te maken?

We are shaping the future
Dat niet alleen, maar (afhankelijk van de implementatie van het String object) voor elke replace wordt er over de gehele string geitereerd, op zoek naar een match op het te vervangen woord.PiepPiep schreef op zondag 14 augustus 2011 @ 13:40:
Zo'n replace(replace(replace constructie maakt geloof ik ook voor elke replace weer een mooie nieuwe string aan in C#, en ik neem aan ook in andere talen. Die worden wel weer netjes opgeruimt als de GC zijn werk doet, maar als het even kan probeer ik altijd zo min mogelijk nieuwe objecten te creeren die gelijk weer weg mogen.
En een beheerder die 36,000 vinkjes gaat zetten is gek,
als je niet beter wist, dan is dit toch juist knap bedacht? 
je kunt toch niet verwachten dat zoiets al anders is opgelost ?
je kunt toch niet verwachten dat zoiets al anders is opgelost ?
YopY schreef op zaterdag 13 augustus 2011 @ 21:30:
omg
C:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 function translate_to_french( p_words in Varchar2 ) return varchar2 as begin return replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( lower(p_words) , ' and ' , ' et ' ) , 'dollars' , 'dollars' ) , 'cents' , 'cents' ) , 'duodecillion' , 'bidecillion' ) , 'quintillion' , 'cintillion' ) , 'billion' , 'milliard' ) , 'thousand' , 'mille' ) , 'hundred' , 'cent' ) , 'ninety' , 'quatre-vingt-dix') , 'eighty' , 'quatre-vingts' ) , 'seventy' , 'soixante-dix' ) , 'sixty' , 'soixante' ) , 'fifty' , 'cinquante' ) , 'forty' , 'quarante' ) , 'thirty' , 'trente' ) , 'twenty' , 'vingt' ) , 'nineteen' , 'dix-neuf' ) , 'eighteen' , 'dix-huit' ) , 'seventeen' , 'dix-sept' ) , 'sixteen' , 'seize' ) , 'fifteen' , 'quinze' ) , 'fourteen' , 'quatorze' ) , 'thirteen' , 'treize' ) , 'twelve' , 'douze' ) , 'eleven' , 'onze' ) , 'ten' , 'dix' ) , 'nine' , 'neuf' ) , 'eight' , 'huit' ) , 'seven' , 'sept' ) , 'six' , 'six' ) , 'five' , 'cinq' ) , 'four' , 'quatre' ) , 'three' , 'trois' ) , 'two' , 'deux' ) , 'one' , 'un' ) , 'dix-six' , 'seize' ) , 'dix-cinq' , 'quinze' ) , 'dix-quatre' , 'quatorze' ) , 'dix-trois' , 'treize' ) , 'dix-deux' , 'douze' ) , 'dix-un' , 'onze' ) , '-un ' , '-une ' ) , 'un cent' , 'cent' ) , 'un mille' , 'mille' ) , 'une' , 'un' ) , 'soixante-onze' , 'soixante et onze') , 'quatre-vingts-' , 'quatre-vingt-' ) , '-un' , ' et un' ) , 'quatre-vingt et un', 'quatre-vingt-un' ) ; End translate_to_french;
Vooral deze drie zijn erg overbodig:
SQL:
1
2
3
| , '-un ' , '-une ' ) , 'une' , 'un' ) , '-un' , ' et un' ) |

Ik zou ze d'r niet eens blind uit durven gooien, zonder eens de hele reeks 0-100 (*) door te lopen. Misschien is dit ook een
(*) zero/zero zit er niet eens in! Mooie optimalisatie, ware het niet dat het zéro moet zijn... just my zero dollars et deux cents
.
SQL:
-achtig gevalletje.1
| , 'dix-cinq' , 'quinze' ) |
(*) zero/zero zit er niet eens in! Mooie optimalisatie, ware het niet dat het zéro moet zijn... just my zero dollars et deux cents
Zo scherp als een voetbal!
De informatie in de externe DB was niet bijgewerkt (lees: alle vinkjes stonden uit) en er had niemand zin om het daar aan te passen. Dus mogen alle clientsystemen het oplossen.alwinuzz schreef op zondag 14 augustus 2011 @ 17:04:
Ha jij kan schrijven voor the daily WTF, mooie verhalen
Bij probleem #2 serieus 36000 vinkjes aan/uitvinken, terwijl die informatie al in de externe db staat? Klinkt als werkverschaffing. Lijkt me ook best foutgevoelig...

Ik ben dan ook ten zeerste verbaasd dat we ueaberhaupt 1 gebruiker hebben gevonden die die vinkjes daadwerkelijk gezet heeft.Alex) schreef op zondag 14 augustus 2011 @ 17:21:
36.000 vinkjes? Hoe zeer moet je een hekel hebben aan de eindgebruikers om zo'n design te maken?

Na een grondige heroverweging staan die 36000 vinkjes nu in een recordje of 20 a 30 opgeslagen.
Daar is iedereen blij mee, behalve degene die die vinkjes gezet had

Ja, dat snap ik. Die man/vrouw heeft zich het leplazerus zitten klikken om ze goed te zetten, en nu maken jullie zijn werk even overbodig.Dido schreef op zondag 14 augustus 2011 @ 20:53:
[...]
Na een grondige heroverweging staan die 36000 vinkjes nu in een recordje of 20 a 30 opgeslagen.
Daar is iedereen blij mee, behalve degene die die vinkjes gezet had
We are shaping the future
Da's het mooie van automatisering, tochAlex) schreef op zondag 14 augustus 2011 @ 23:32:
Ja, dat snap ik. Die man/vrouw heeft zich het leplazerus zitten klikken om ze goed te zetten, en nu maken jullie zijn werk even overbodig.
Maar als goedmakertje zijn de responsetijden in het hele systeem gemiddeld met 50% gedaald.
Ik heb een keer gehoord van iemand die ooit eens bij bol.com iets geprogrammeerd heeft als externe dat het daar dus een serieuze oplossing is.Dido schreef op zondag 14 augustus 2011 @ 15:06:
Mwah, dan upgrade je de hardware toch?
Er waren nog genoeg manieren om het systeem wat sneller te maken, maar gewoon wat servers erbij pleuren was makkelijker en dus de oplossing die ze daar kozen.
486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22
Soms is het ook de goedkoopste oplossing op de korte termijn.
Wij staan hier ook voor de keuze, plaatsen we een 265K of een 512K STM32-microcontroller. De kosten liggen op 8 en 10 euro resp.
Aangezien we ongeveer 1000 van die borden per jaar verkopen, loont het dus niet om zwaar te gaan optimaliseren, maar smijten we er een 512K op.
Wij staan hier ook voor de keuze, plaatsen we een 265K of een 512K STM32-microcontroller. De kosten liggen op 8 en 10 euro resp.
Aangezien we ongeveer 1000 van die borden per jaar verkopen, loont het dus niet om zwaar te gaan optimaliseren, maar smijten we er een 512K op.
If money talks then I'm a mime
If time is money then I'm out of time
Uitbreiden van bestaand systeem PHP/MySQL -- datumvelden (DB) zijn strings en in verschillende formaten.
Om te filteren op datum is er code als: (32 december?)
Om te filteren op datum is er code als: (32 december?)
PHP:
1
2
3
4
5
6
| function fun($d) { if ( $d == '2010Q4' ) { $d1 = '20100930'; $d2 = '20101232'; } $sql = 'SELECT [...] WHERE datum > '.$d1.' AND datum < '.$d2; } |
Developer Accused Of Unreadable Code Refuses To Comment
Als er voor d1 ook maar consequent een 0 januari voor Q1 gebruikt wordt, vind ik het best
.
Zo scherp als een voetbal!
Bakkes, refactoren en opschonen, neem maar een paar uur extra, vertel het de opdrachtgever niet, en als ze toch vragen zeg je iets als 'technical debt resolven' of een andere dure term die ze niet begrijpenIcelus schreef op maandag 15 augustus 2011 @ 16:25:
Uitbreiden van bestaand systeem PHP/MySQL -- datumvelden (DB) zijn strings en in verschillende formaten.
Om te filteren op datum is er code als: (32 december?)
Verwijderd
En dan kom je tegen dat querys harcoded in elk bestand staan....YopY schreef op maandag 15 augustus 2011 @ 17:05:
[...]
Bakkes, refactoren en opschonen, neem maar een paar uur extra, vertel het de opdrachtgever niet, en als ze toch vragen zeg je iets als 'technical debt resolven' of een andere dure term die ze niet begrijpen.

Dan maar hopen dat je file(s)->replace functie goed werkt
Je zou natuurlijk ook joins kunnen gebruikenDido schreef op zondag 14 augustus 2011 @ 15:53:
[...]
Amen.
Twee gestileerde voorbeeldjes uit de praktijk die zelfs met hardware lastig op te lossen zijn:
Probleem 1:
We hebben voor externe applicaties taalcodes nodig die afhankelijk zijn van de huidige taal van de gebruiker.
Oplossing:
We maken een tabel met interne taalcode, applicatie en externe taalcode.
So far so good. Het resultaat is een tabel de er ruwweg zo uitziet:
code:
1 2 3 4 5 6 NL app1 123 NL app2 DUT EN app1 124 EN app2 ENG FR app1 125 FR app2 FRA
Dan zou je denken dat je met het lezen van 6 records alle mogelijk taalcodes in het geheugen kunt hebben, right?
Nopes.
We kunnen natuurlijk niet zomaar app1 en app2 invullen, dus hebben we een aparte tabel waarin alle mogelijke externe applicaties staan die we gebruiken. Op zich niet zo gek.
Om de "vertaaltabel" uit te lezen lezen we dus eerst alle mogelijke applicaties, om dan te kijken of we er een record voor hebben in de vertaaltabel. En we hebben 20 applicaties. Dat worden dus geen 6, maar 26 succesvolle leesacties plus 18 niet-succesvolle. 44 I/O's.
O wacht, we hebben natuurlijk ook de talen in de linkerkolom niet aan het toeval overgelaten. Hoewel we momenteel vijf interne talen ondersteunen zijn we op de toekomst voorbereid. We hebben alle mogelijke ISO-talen (zo'n 140 stuks) óók in een externe tabel staan. Uiteraard lezen we die ook eerst helemaal door!
Dat worden dus 140 x 20 leesacties op die stamtabellen, waarna we checken of de combinatie taal/applicatie in de vertaaltabel staat. Dat is in uiteraard maar in 6 gevallen waar. 2806 succesvolle leesacties en 2794 voor Jan met de korte achternaam.
En dan mag ik uitleggen waarom er 5600 I/O's plaatsvinden om 6 recods op te halen.
[Probleem 2 deleted]
Als je SQL zou kunnen gebruiken om je database te benaderen wel ja. Maar nou mag je drie keer raden...
Voor de duidelijkheid: we werken tegen een DBII-400 database aan die we benaderen via een proprietary I/O-schil (gegenereerde RPG) die onder meer file-triggers en virtual fields afhandeld (dus je leest uit bestand X een code met een omschrijving, maar onder water wordt die beschrijving uit bestand Y bijgelezen).
Leuk voorbeeldje van hoe een ondoordachte actie je performance om zeep helpt:
We hebben een bestand (laten we het X noemen) waar we batches van zo'n 700 records tegelijk in opslaan. Dat doen we door de hele lijst over de muur te gooien naar een server-functie op de iSeries, die eerst de eventueel bestaande records wegflikkert, om vervolgens 700 inserts te doen.
So far, so good. De delete gebeurt met een partial key, en wordt intern kennelijk geoptimaliseerd tot 1 enkel SQL-statement.
Toen kwam er een tweede bestand (Y) bij, waar in paar extra attributen werden opgeslagen van sommige van die 700 records. Denk aan een stuk of 5 a tien records die die extra attributen hebben. Het feit dat het er maar een paar waren was ook de reden dat er een apat bestand voor moest komen...
Natuurlijk wil je niet dat iemand per ongeluk records uit X verwijderd zonder de bijbehorende records uit Y te verwijderen, dus wordt er een triggerfunctie gedefinieerd die daar zorg voor draagt, en die wordt aan bestand X gehangen.
Ondertussen werd de serverfunctie die de delete-actie op X uitvoerde uitgebreid: voordat de delete op X gebeurt, wordt eerst met dezelfde partial key bestand Y opgeschoond.
Gevolg: de delete-actie op X duurde opeens 4 seconden. Want: waar er eerst 1 SQL-statement werd uitgevoerd, waren dat er nu 700. En voor elk record werd eerst een delete uitgevoerd op bestand Y, via een aparte functie die automagisch aangeroepen werd. Terwijl Y net al leeggegooid was

1400 aparte acties in plaats van 2 - gek dat het wat trager werd

Sterker nog, te veel indexen kunnen a) database trager maken bij frequente modificaties, b) oorzaak zijn van verkeerde executieplannen in bijvoorbeeld Oracle of SQL Server.Macros schreef op vrijdag 12 augustus 2011 @ 11:07:
Ik vind dat die programmeur wel een punt heeft. Het heeft weinig nut om velden in de database op te gaan nemen waarbij je misschien denkt ze in de toekomst nodig te hebben. Een alter table query is toch geen probleem? Het is onmogelijk om de toekomst te voorspellen, dus doe dat dan ook niet.
Beheerders, Consultants, Servicedesk medewerkers. We zoeken het allemaal. Stuur mij een PM voor meer info of kijk hier De mooiste ICT'er van Nederland.
Ah bad query plan joy, ik moest een keer (voor een loadtest) data in bulk uit een Oracle database trekken. Mijn oorspronkelijke query had tientallen minuten zoniet uren nodig om de benodigde records uit de database te trekken (enkele duizenden uit een veelheid aan tabellen en ook uit verschillende(!) databases, met nogal complexe voorwaarden). Ik mocht de database zelf niet wijzigen: het moest nl vergelijkbaar blijven met de productie omgeving en was getuned op productie gebruik, en niet op het verkrijgen van de testdata. Ik heb me toen gestort op (Oracle) query hints; de juiste hints brachten queries terug tot minuten of zelfs seconde werkWim-Bart schreef op dinsdag 16 augustus 2011 @ 01:09:
[...]
Sterker nog, te veel indexen kunnen a) database trager maken bij frequente modificaties, b) oorzaak zijn van verkeerde executieplannen in bijvoorbeeld Oracle of SQL Server.
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <div class="col_1 maxheight"> <div class="indent maxheight"> <div class="block-content maxheight"> <div class="t maxheight"> <div class="r maxheight"> <div class="b maxheight"> <div class="l maxheight"> <div class="l_t maxheight"> <div class="r_t maxheight"> <div class="r_b maxheight"> <div class="l_b maxheight"> <div class="ind1"> <div class="aligncenter"><br /><br /></div> |

Laat me raden, bedoeld voor ronde hoekjes
Lol, wat is dan de functie van l_t en r_t ? (left top / right top ?) De overigen (l, b, t, r) kan ik nog enigzins inkomen dat iemand denkt dat het zo werkt.. maar de l_t en r_t?

Werkelijk geen flauw idee, ik weet wel dat ik het direct heb weggeknikkerd de hele zooi.GateKeaper schreef op dinsdag 16 augustus 2011 @ 11:16:
[...]
Lol, wat is dan de functie van l_t en r_t ? (left top / right top ?) De overigen (l, b, t, r) kan ik nog enigzins inkomen dat iemand denkt dat het zo werkt.. maar de l_t en r_t?
Als je zo vaak achter elkaar dezelfde classname gebruikt, heb je sowieso niet helemaal begrepen hoe CSS selectors werken.
Ik had even een minder helder moment toen ik dit schreef. En ik maar afvragen waarom de applicatie crashte na verwijder acties.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| //Where int = UserId protected Dictionary<int, User> _users; private void UpdateUserGrid() { for (int i = 0; i < _users.Count; i++) { User user = _users[i]; ... //Offset y calculation for a label double offsetY = 27 * i; Label lblName = new Label(); lblName.Margin = new Thickness(10, offsetY, 0, 0); lblName.Content = user.Username; ... } } |
[ Voor 2% gewijzigd door Sentienel op 16-08-2011 13:46 . Reden: Code opmaak ]
Lijkt wel op een stukje HTML gemaakt met Adobe Muse.T.H. Lassche schreef op dinsdag 16 augustus 2011 @ 10:52:
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 <div class="col_1 maxheight"> <div class="indent maxheight"> <div class="block-content maxheight"> <div class="t maxheight"> <div class="r maxheight"> <div class="b maxheight"> <div class="l maxheight"> <div class="l_t maxheight"> <div class="r_t maxheight"> <div class="r_b maxheight"> <div class="l_b maxheight"> <div class="ind1"> <div class="aligncenter"><br /><br /></div>

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.
Lol.. moet toch maar eens kijken naar dat geweldige pakket. Blijkbaar kan hij ook complexere structuren aan.OkkE schreef op dinsdag 16 augustus 2011 @ 13:50:
[...]
Lijkt wel op een stukje HTML gemaakt met Adobe Muse.![]()

Ja, prachtig pakket. Binnenkort zijn webdevelopers niet meer nodig! Kan zelfs cross-browser code maken, check deze source maar eens:GateKeaper schreef op dinsdag 16 augustus 2011 @ 14:28:
[...]
Lol.. moet toch maar eens kijken naar dat geweldige pakket. Blijkbaar kan hij ook complexere structuren aan.

http://static.elliotjaystocks.com/muse/muse-test-01/
“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.
foreach to the rescue!Sentienel schreef op dinsdag 16 augustus 2011 @ 13:42:
Ik had even een minder helder moment toen ik dit schreef. En ik maar afvragen waarom de applicatie crashte na verwijder acties.
C#:
1...
Dat pakket gaat inderdaad bergen tijd schelen! Als je dit zelf zou moeten bedenken dan ben je nogal even bezig.OkkE schreef op dinsdag 16 augustus 2011 @ 14:35:
[...]
Ja, prachtig pakket. Binnenkort zijn webdevelopers niet meer nodig! Kan zelfs cross-browser code maken, check deze source maar eens:![]()
http://static.elliotjaystocks.com/muse/muse-test-01/

Maar er zitten geen tables in, da's toch beter dan vroeger?
Inderdaad. Maar..., ik heb wel die i nodig dus had ik die er zo bijgezet:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
| private void UpdateUserGrid() { int i = 0; foreach (KeyValuePair<int, User> pair in _users) { User user = pair.Value; ... i++; } } |
Of is dit een beter leesbare oplossing?
C#:
1
2
3
4
5
6
7
8
9
| private void UpdateUserGrid() { for (int i = 0; i < _users.Count; i++) { User user = _users.ElementAt(i).Value; ... } } |
Meest duidelijke lijkt mij zoiets:Sentienel schreef op dinsdag 16 augustus 2011 @ 16:10:
[...]
Inderdaad. Maar..., ik heb wel die i nodig dus had ik die er zo bijgezet:
(evt de 27 nog ergens in parameter zetten)
C#:
1
2
3
4
5
6
7
8
9
10
11
| private void UpdateUserGrid() { double offsetY = 0; foreach (User user in _users.Values) { ... offsetY += 27; } } |
[ Voor 6% gewijzigd door YakuzA op 16-08-2011 16:31 ]
Death smiles at us all, all a man can do is smile back.
PSN
Beter dan vroeger betekend niet dat het goed is. Het is gewoon bagger code; terwijl we net een beetje van FrontPage-sites af beginnen te raken.MBV schreef op dinsdag 16 augustus 2011 @ 15:28:
Maar er zitten geen tables in, da's toch beter dan vroeger?
[ Voor 17% gewijzigd door OkkE op 16-08-2011 16:17 ]
“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.
Ik gok (en hoop) dat MBV sarcastisch wasOkkE schreef op dinsdag 16 augustus 2011 @ 16:15:
[...]
Beter dan vroeger betekend niet dat het goed is. Het is gewoon bagger code; terwijl we net een beetje van FrontPage-sites af beginnen te raken.
Eigenaar/brouwer Milky Road Brewery
Ik weet niets van C-hekje/CPoundSentienel schreef op dinsdag 16 augustus 2011 @ 16:10:
[...]
C#:
1 2 3 4 5 6 7 8 9 private void UpdateUserGrid() { for (int i = 0; i < _users.Count; i++) { User user = _users.ElementAt(i).Value; ... } }
Verwijderd
In Java kan je ook gewoon de Iterator gebruiken, en daar kan je op removen. Geen idee of dat dat gaat in C#
C# wordt C-sharp genoemd. Net als in de Wikipedia: Sharp (music)TheWickedD schreef op woensdag 17 augustus 2011 @ 05:39:
Ik weet niets van C-hekje/CPound, maar kun je niet gewoon achteruit tellen? Dan is dingen weggooien nooit een probleem.
If money talks then I'm a mime
If time is money then I'm out of time
TheWickedD schreef op woensdag 17 augustus 2011 @ 05:39:
[...]
Ik weet niets van C-hekje/CPound, maar kun je niet gewoon achteruit tellen? Dan is dingen weggooien nooit een probleem.
Probleem heeft hier niet mee te maken.In Java kan je ook gewoon de Iterator gebruiken, en daar kan je op removen. Geen idee of dat dat gaat in C#
Het probleem is dat de key de userid is. als je user 2 dus delete, bestaat key 2 niet meer.
Death smiles at us all, all a man can do is smile back.
PSN
Volgens mij kun je dat het beste oplossen met Linq. Hoewel er veel (mooiere) oplossingen zijn doet dit precies wat je wilt; _users.RemoveAt(integer)
Maar raakt dan die ID volgorde niet juist weer in de war? Volgens mij bedoeld hij meer dat de entry op locatie i moeten blijven bestaan, maar de user moet weg. Zodat de ID's van de rest nog kloppen, maar de betreffende user toch weg is. Kan je dat niet oplossen met:
Of mag zoiets niet in C#?
C#:
1
| _users.ElementAt(i).setValue = null; |
Of mag zoiets niet in C#?
Hehe, ik noemde het expres zo om duidelijk te maken dat ik nul ervaring met de taal hebMatis schreef op woensdag 17 augustus 2011 @ 07:54:
[...]
C# wordt C-sharp genoemd. Net als in de Wikipedia: Sharp (music)
Ik snap niet waar het hele probleem ligt. Dit is toch voldoende?
Of zie ik iets over het hoofd?
code:
1
| _users.RemoveAt(i--); |
Of zie ik iets over het hoofd?
Ja, het gaat niet om het verwijderen, maar het loopen door een lijst users waar gaten in de ID's zitten omdat er users zijn verwijderd. Foreach is volgens mij gewoon de netste oplossing.Soundless schreef op woensdag 17 augustus 2011 @ 11:46:
Of zie ik iets over het hoofd?
[ Voor 4% gewijzigd door CodeCaster op 17-08-2011 11:49 ]
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
Lijkt mij gewoon dé oplossing.YakuzA schreef op dinsdag 16 augustus 2011 @ 16:14:
[...]
Meest duidelijke lijkt mij zoiets:
(evt de 27 nog ergens in parameter zetten)
C#:
1 2 3 4 5 6 7 8 9 10 11 private void UpdateUserGrid() { double offsetY = 0; foreach (User user in _users.Values) { ... offsetY += 27; } }
Ah ok, dan zou ik inderdaad ook voor de foreach-oplossing gaan.[b]CodeCaster schreef op woensdag 17 augustus 2011 @ 11:49:
Ja, het gaat niet om het verwijderen, maar het loopen door een lijst users waar gaten in de ID's zitten omdat er users zijn verwijderd. Foreach is volgens mij gewoon de netste oplossing.
Aha, ik dacht meer aan het scenario waarbij de index het ID moest voorstellen. Denk aan een selectie uit een grid en dan moet die selectie verwijdert worden. Hoewel het idee van het i-- verhaal (van Soundless) dan nog steeds netter zou zijnCodeCaster schreef op woensdag 17 augustus 2011 @ 11:49:
[...]
Ja, het gaat niet om het verwijderen, maar het loopen door een lijst users waar gaten in de ID's zitten omdat er users zijn verwijderd. Foreach is volgens mij gewoon de netste oplossing.
Het probleem ontstond toen ik de collection van users omgezet had van een List naar een Dictionary. Omdat de Key van het type int is, compileerde alles prima, maar daar kom je tijdens runtime wel achter.
Het probleem was exact zoals YakuzA noemde.
Als het scenario het verwijderen van users zou zijn, dan blijft de RemoveAt(i) een rare oplossing omdat je itereert over de collection van users en niet van selected indices. In het eerste geval doe ik gewoon:
_users.Clear();
Het probleem was exact zoals YakuzA noemde.
Als het scenario het verwijderen van users zou zijn, dan blijft de RemoveAt(i) een rare oplossing omdat je itereert over de collection van users en niet van selected indices. In het eerste geval doe ik gewoon:
_users.Clear();
Mogelijk zie ik iets over het hoofd, maar waarom niet de drie tabellen overhalen naar een SQL-database (desnoods iets als SQLite als het lokaal moet) en dan mbv een paar simpele sql-queries mbv joins de juiste combinaties opvragen? Lijkt me wellicht een stuk sneller werken in de praktijk dan die duizenden I/O akties die je nodig hebt op die non-SQL database, zelfs als het nodig is om elke keer de drie tabellen te moeten ophalen.Dido schreef op dinsdag 16 augustus 2011 @ 00:46:
[...]
[...]
Als je SQL zou kunnen gebruiken om je database te benaderen wel ja. Maar nou mag je drie keer raden...
Developmenttijdarsimo schreef op woensdag 17 augustus 2011 @ 14:56:
Mogelijk zie ik iets over het hoofd
In een bedrijf blijft het een commerciële beslissing in plaats van een technische, helaas.
"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock
Welnee, het zou developmenttijd schelen zelfs als je goed doet. Ik moet juist dagelijk de zakelijk vs technische specten afwegen waar in regel de eerste winst.
Bij een nieuw product wel. Bij een product dat al jaren in gebruik en in onderhoud is daarentegen ...
Wij kregen het in ieder geval bij hem niet voor elkaar ... 'Jaja, komt wel een keer, maak nu eerst $nieuwe functionaliteit maar ...'
Wij kregen het in ieder geval bij hem niet voor elkaar ... 'Jaja, komt wel een keer, maak nu eerst $nieuwe functionaliteit maar ...'
"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock
omdat je geen 'lokaal' hebt op een iseriesarsimo schreef op woensdag 17 augustus 2011 @ 14:56:
[...]
Mogelijk zie ik iets over het hoofd, maar waarom niet de drie tabellen overhalen naar een SQL-database (desnoods iets als SQLite als het lokaal moet) en dan mbv een paar simpele sql-queries mbv joins de juiste combinaties opvragen? Lijkt me wellicht een stuk sneller werken in de praktijk dan die duizenden I/O akties die je nodig hebt op die non-SQL database, zelfs als het nodig is om elke keer de drie tabellen te moeten ophalen.
Driving a cadillac in a fool's parade.
Sja, het zijn dan ook het soort projecten die je het liefst in verloren tijd zou doen. Maar je moet wel oppassen, als het te lang duurt voordat je over gaat, wordt je op een gegeven moment door de concurrentie ingehaald. Wet van de remmende voorsprong.Paul schreef op woensdag 17 augustus 2011 @ 16:50:
Bij een nieuw product wel. Bij een product dat al jaren in gebruik en in onderhoud is daarentegen ...
Wij kregen het in ieder geval bij hem niet voor elkaar ... 'Jaja, komt wel een keer, maak nu eerst $nieuwe functionaliteit maar ...'
We hebben een freaking iSeries staan, die werrukt. Jij denkt dat ik iemand zo gek krijg om een redundante DB/server neer te zetten?arsimo schreef op woensdag 17 augustus 2011 @ 14:56:
Mogelijk zie ik iets over het hoofd, maar waarom niet de drie tabellen overhalen naar een SQL-database (desnoods iets als SQLite als het lokaal moet) en dan mbv een paar simpele sql-queries mbv joins de juiste combinaties opvragen? Lijkt me wellicht een stuk sneller werken in de praktijk dan die duizenden I/O akties die je nodig hebt op die non-SQL database, zelfs als het nodig is om elke keer de drie tabellen te moeten ophalen.
En dan nog, wat ga je doen met concurrent updates op de originele database? Wat doe je met bestaande business logic in je bestaande I/O-laag? Er zijn mensen die een rolberoerte krijgen omdat ik fscking TEMP-files niet op de iSeries zet

En ten slotte: waarom zou je in hemelsnaam zo'n omslachtige oplossing verzinnen als je het ook gewoon goed kunt doen, dus met veel minder I/O?
Zelfs met joins verdien je lijfstraf als je alle mogelijke talen gaat joinen op de koppeltabel in plaats van andersom (om dan de nulls eruit te filteren of te negeren). Gewoon de koppeltabel lezen en de omschrijvingen (zo nodig!!!!!) bijlezen kost je maximaal 18 I/O's. In de praktijk gebruiken we die omschrijvingen alleen maar tijdens de setup, dus ben je met 6 records al klaar.
We werken vanaf een Citrix-omgeving tegen een DB op de iSeries aan, de domme-terminalsversie is gelukkig jaren geleden uitgefaseerd (maar nog wel in gebruik!). Er is dus wel een vorm van "lokaal", maar iemand zover krijgen dat we daar even een database opbouwen gaat niet lukken.kwaakvaak_v2 schreef op woensdag 17 augustus 2011 @ 16:55:
Omdat je geen 'lokaal' hebt op een iseriesHet is een terminal omgeving, waar je rekening moet houden dat de client een domme greenscreen terminal is. Wat wel zou kunnen is beetje afhankelijk van de release is een MQT, materialized query table. Soort van materialized view dus, maar weet niet of die ook over meerdere tables mag en kan..
Bij volledige nieuwbouw wel ja. Zo ongeveer elke methode waar management mee aan komt zetten is daar ook altijd op gericht, maar onderhoud en aanbouw aan bestaande meuk wordt nooit gecoverd. En inderdaad, de overhead het management snapt nooit waarom projecten tegen problemen aanlopen als ze zich aan de status quo moeten conformeren.arsimo schreef op woensdag 17 augustus 2011 @ 16:24:
Welnee, het zou developmenttijd schelen zelfs als je goed doet. Ik moet juist dagelijk de zakelijk vs technische specten afwegen waar in regel de eerste winst.
Maar de voorbeelden die ik noemde waren simpelweg het gevolg van een a-technische functioneel ontwerper die dacht wel iets van een databaseontwerp te kunnen maken, en een paar slaafse programmeurs die dat klakkeloos overnamen. Er werken hier geen technisch ontwerpers, namelijk. Alleen functionele mensen en programmeurs. Sommigen van die programmeurs doen er ondertussen wat architectuur, systeemontwerp, technisch design, usability-analyse, performance overwegingen, standaardisatie, impactanalyses en meer van dat soort details bij, maar de meesten kijken naar een FO en gaan coden. En klagen als er nog geen tabelnamen zijn verzonnen

Ik heb de applicatie kunnen herschrijven (ik weet het, dat is foutPaul schreef op woensdag 17 augustus 2011 @ 16:50:
Bij een nieuw product wel. Bij een product dat al jaren in gebruik en in onderhoud is daarentegen ...
Wij kregen het in ieder geval bij hem niet voor elkaar ... 'Jaja, komt wel een keer, maak nu eerst $nieuwe functionaliteit maar ...'

Dat soort geintjes moet je echter niet te vaak uithalen, heb ik het idee (1 keer per paar jaar een paar man over de vloer waarvan je de naam normaal alleen in de mail ziet langskomen omdat ze opeens met een project in de maag zitten waar geen assignment directive voor was is meer dan genoeg
edit: lange post, zat ik niet in W&L dan?

[ Voor 55% gewijzigd door Dido op 17-08-2011 19:19 ]
Dit topic is gesloten.
Let op:
Uiteraard is het in dit topic niet de bedoeling dat andere users en/of topics aangehaald worden om ze voor gek te zetten. Lachen om je eigen code, of over dingen die je "wel eens tegengekomen bent" is prima, maar hou het onderling netjes.
Uiteraard is het in dit topic niet de bedoeling dat andere users en/of topics aangehaald worden om ze voor gek te zetten. Lachen om je eigen code, of over dingen die je "wel eens tegengekomen bent" is prima, maar hou het onderling netjes.