Mwah, dan moet je óf de klant overtuigen van de waarde van nette code en dergelijke, of gewoon een ruimere schatting aangeven waar je nette afronding in meeneemt.Maar ja, dingen die voor mij logisch zijn, zijn dat voor klanten niet en dat vergeet ik wel eens
"als het kan" lijkt me nou niet een erg goed onderbouwd advies.Sebazzz schreef op donderdag 30 december 2010 @ 20:49:
[...]
Het wordt sowieso aangeraden om als het kan te inheriten van een class in plaats van een extension ervoor te schrijven.
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Een juweeltje van mijzelf 
Ik heb in een folder op een webserver een aantal csv-bestanden staan, met daarin de speelschema's voor onze voetbalvereniging. De bestandsnaam van de bestanden zijn als volgt: yyyy_ww.csv. De ww zijn de weeknummers waarin de bepaalde wedstrijden vallen (lopende van maandag tot en met zondag). Die data krijg ik kant en klaar aangeleverd en kan ik zelf dus niets mee doen / aan veranderen.
In de map met wedstrijdgegevens stonden een tweetal programma's voor week 04 en 05 van 2011.
2011_04.csv en 2011_05.csv dus.
Echter heeft mijn script nu kuren, want hij laat alleen weken zien die nog moeten komen in de tijd. Ik explode de bestandsnaam met de _ als delimiter en check dan of de
Echter deed de code het na de jaarwisseling niet meer. Na een hoop debug-werk (het is nog vroeg
) zonder koffie kwam ik er eindelijk achter dat het (volgens het script) nu week 52 is in het jaar 2011 
Het is verklaarbaar gedrag, maar wel vervelend. Nu nog een deftige manier vinden om het op te lossen. Ik heb nu (als lelijke workaround) de weeknummering in PHP %52 gedaan, waardoor het nu week 0 is van 2011.
Mocht iemand een nettere oplossing weten, dan hoor ik het graag
Ik heb in een folder op een webserver een aantal csv-bestanden staan, met daarin de speelschema's voor onze voetbalvereniging. De bestandsnaam van de bestanden zijn als volgt: yyyy_ww.csv. De ww zijn de weeknummers waarin de bepaalde wedstrijden vallen (lopende van maandag tot en met zondag). Die data krijg ik kant en klaar aangeleverd en kan ik zelf dus niets mee doen / aan veranderen.
In de map met wedstrijdgegevens stonden een tweetal programma's voor week 04 en 05 van 2011.
2011_04.csv en 2011_05.csv dus.
Echter heeft mijn script nu kuren, want hij laat alleen weken zien die nog moeten komen in de tijd. Ik explode de bestandsnaam met de _ als delimiter en check dan of de
PHP:
1
2
3
4
5
6
7
| $speelweek_array = explode('_', pathinfo($programma_file, PATHINFO_FILENAME)); if ($speelweek_array[1] < date("W") && $speelweek_array[0] <= date("Y")) { continue; } // hierna wordt de rest van het bestand ingelezen en bewerkt etc. } |
Echter deed de code het na de jaarwisseling niet meer. Na een hoop debug-werk (het is nog vroeg
Het is verklaarbaar gedrag, maar wel vervelend. Nu nog een deftige manier vinden om het op te lossen. Ik heb nu (als lelijke workaround) de weeknummering in PHP %52 gedaan, waardoor het nu week 0 is van 2011.
Mocht iemand een nettere oplossing weten, dan hoor ik het graag
If money talks then I'm a mime
If time is money then I'm out of time
Het is ook de onderbouwing niet, het is het statement. De onderbouwing vind je hier:RayNbow schreef op vrijdag 31 december 2010 @ 10:37:
[...]
"als het kan" lijkt me nou niet een erg goed onderbouwd advies.
In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance (C# Programming Guide).
When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.
If you do implement extension methods for a given type, remember the following two points:
An extension method will never be called if it has the same signature as a method defined in the type.
Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they will all be brought into scope by the using Extensions; directive.
[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]
Matis schreef op zaterdag 01 januari 2011 @ 11:41:
Een juweeltje van mijzelf
Ik heb in een folder op een webserver een aantal csv-bestanden staan, met daarin de speelschema's voor onze voetbalvereniging. De bestandsnaam van de bestanden zijn als volgt: yyyy_ww.csv. De ww zijn de weeknummers waarin de bepaalde wedstrijden vallen (lopende van maandag tot en met zondag). Die data krijg ik kant en klaar aangeleverd en kan ik zelf dus niets mee doen / aan veranderen.
In de map met wedstrijdgegevens stonden een tweetal programma's voor week 04 en 05 van 2011.
2011_04.csv en 2011_05.csv dus.
Echter heeft mijn script nu kuren, want hij laat alleen weken zien die nog moeten komen in de tijd. Ik explode de bestandsnaam met de _ als delimiter en check dan of de
PHP:
1 2 3 4 5 6 7 $speelweek_array = explode('_', pathinfo($programma_file, PATHINFO_FILENAME)); if ($speelweek_array[1] < date("W") && $speelweek_array[0] <= date("Y")) { continue; } // hierna wordt de rest van het bestand ingelezen en bewerkt etc. }
Echter deed de code het na de jaarwisseling niet meer. Na een hoop debug-werk (het is nog vroeg) zonder koffie kwam ik er eindelijk achter dat het (volgens het script) nu week 52 is in het jaar 2011
Het is verklaarbaar gedrag, maar wel vervelend. Nu nog een deftige manier vinden om het op te lossen. Ik heb nu (als lelijke workaround) de weeknummering in PHP %52 gedaan, waardoor het nu week 0 is van 2011.
Mocht iemand een nettere oplossing weten, dan hoor ik het graag
je moet dus "o" gebruiken in plaats van "Y"Dit staat gewoon duidelijk in de php documentatie:
o ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0) Examples: 1999 or 2003
Wolf87 schreef op zaterdag 01 januari 2011 @ 11:47:
je moet dus "o" gebruiken in plaats van "Y"

Ik was op zoek naar een manier om de weeknummering te corrigeren, maar om het jaar aan te passen was nog niet in me opgekomen.
Thnx iig voor de beste oplossing
If money talks then I'm a mime
If time is money then I'm out of time
Zoek een manier om weeknummer + jaar om te zetten naar een unix timestamp en doe je vergelijking tegen die timestamp.Matis schreef op zaterdag 01 januari 2011 @ 11:41:
Mocht iemand een nettere oplossing weten, dan hoor ik het graag
Edit: je hebt al oplossing
[ Voor 4% gewijzigd door Gamebuster op 01-01-2011 11:52 ]
Let op: Mijn post bevat meningen, aannames of onwaarheden
Dan was je vroeg of laat weer in de problemen gekomen. Sommige jaren hebben namelijk 53 wekenMatis schreef op zaterdag 01 januari 2011 @ 11:50:
[...]
![]()
Ik was op zoek naar een manier om de weeknummering te corrigeren, maar om het jaar aan te passen was nog niet in me opgekomen.
Dat klopt, maar er zijn geen weken met nummer 0. Duys 53 % 52 wordt dan week 1. En laat dat nu eens precies de eerste week zijn van het nieuwe jaar. Dus echt in de problemen zou ik niet komen, maar de oplossing die ik nu heb is de besteLight schreef op zaterdag 01 januari 2011 @ 14:50:
Dan was je vroeg of laat weer in de problemen gekomen. Sommige jaren hebben namelijk 53 weken
If money talks then I'm a mime
If time is money then I'm out of time
Wat is de onderbouwing? Dat het kan breken wanneer de classes waarop de extension methods werken veranderen? Hoe is dit verschillend met inheritance? Als een superclass van gedrag verandert, kunnen subclasses ook breken.Sebazzz schreef op zaterdag 01 januari 2011 @ 11:45:
[...]
Het is ook de onderbouwing niet, het is het statement. De onderbouwing vind je hier:
[...]
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Misschien is het verschil wel dat extension veelal voor primitieve / basistypes wordt gebruikt en inheritance juist voor complexere klasses / objecten.RayNbow schreef op zaterdag 01 januari 2011 @ 19:20:
[...]
Wat is de onderbouwing? Dat het kan breken wanneer de classes waarop de extension methods werken veranderen? Hoe is dit verschillend met inheritance? Als een superclass van gedrag verandert, kunnen subclasses ook breken.
Bij primitieve types kan er 'zomaar' iets veranderd worden aan de implementatie (ook al zal dat niet snel gebeuren), bij klasses zullen methodes eerst als 'deprecated' aangemerkt worden voor ze eruit gesloopt worden en heb je dus nog kans om het één en ander aan te passen.
Ik denk dat het zo ongeveer zit.
Toch zie ik niet wat er mis is om een eigen library te maken met handige extension methods voor bijvoorbeeld strings. Die kun je dan gewoon in een eigen namespace gooien en dan kun je er voor kiezen om ze al dan niet te includen.
Een extension method kan worden overruled zonder foutmelding. Als je in een base class in eens een method schrijft die in een afgeleide class ook is gemaakt moet die als virtual worden gemerkt, want anders gaat de compiler muiten bij de afgeleide class.
Denk iig dat het zoiets is.
[ Voor 47% gewijzigd door Caelorum op 01-01-2011 20:15 ]
Interessant stukje code van een collega van me:
De property was een decimal welke omgezet moest worden naar een int voor een timer interval.Ik vond het wel leuk gevonden
C#:
1
2
3
4
5
| int interval = 15000; if (Int32.TryParse(Convert.ToInt32(Properties.Settings.Default.Interval * 1000).ToString(), out interval) && interval > 0) { timer.Interval = interval; } |
De property was een decimal welke omgezet moest worden naar een int voor een timer interval.Ik vond het wel leuk gevonden
Hail to the king baby!
Voor een aantal classes uit het SharePoint Object Model hebben we extension methods gemaakt, dit omdat we bijvoorbeeld niet zomaar kunnen wijzigen dat een SPList SPListItems bevat. In die gevallen hebben we onze eigen extension methods die hun werk prima doen.
We are shaping the future
Daar zal het hem inderdaad wel in zitten.Caelorum schreef op zaterdag 01 januari 2011 @ 20:05:
[...]
Een extension method kan worden overruled zonder foutmelding. Als je in een base class in eens een method schrijft die in een afgeleide class ook is gemaakt moet die als virtual worden gemerkt, want anders gaat de compiler muiten bij de afgeleide class.
Denk iig dat het zoiets is.
Maar dan nog vind ik het beter om extension methods te schrijven op framework classes dan framework classes te inheriten.
Als je inheritance gaat gebruiken, dan moeten andere programmeurs binnen je project maar net weten dat ze de eigen class moeten gebruiken i.p.v. de framework class. Nog leuker wordt het wanneer een framework class een sealed class is: mag je lekker thin wrappers voor alle public fields, properties en methods gaan schrijven en dan je eigen methods er bij aan schuiven. En wat als je een hele familie reeds van elkaar overervende framework classes hebt waar je functionaliteit aan toe wilt voegen?
Gebruik je extension methods en zet je die in dezelfde namespace als het framework type, dan ben je er tenminste van verzekerd dat iedereen de functionaliteit ook meteen in z'n intellisense / autocomplete ziet verschijnen. Dat verlaagt drastisch de kans dat er mensen komen die vierkante wielen gaan heruitvinden en dat is toch echt wel het éénmalige risico waard dat Microsoft framework classes gaat wijzigen.
(Niemand die serieus bezig is gaat zomaar een applicatie of library ineens op een nieuwe versie v/h .NET framework laten draaien zonder unit tests, integratie tests etc. te draaien of in elk geval met de hand te kijken of alles nog werkt. Verifiëren dat extension methods het nog doen kun je dan net zo goed op je lijstje checkpoints bijschrijven.)
Of ik begrijp C# niet, of dit is baggercode. Int32.TryParse(ConvertToInt32(x).ToString(), y) kan toch nooit iets nuttigs doen? Als de conversie faalt wordt er een exception geraised (waar hier niets mee gedaan wordt; zou een fout kunnen zijn, maar dat is aan de context niet duidelijk) en anders heb je een geldige integer, en dan is het hele ToString() en TryParse() zinloos.urk_forever schreef op zaterdag 01 januari 2011 @ 22:15:
Interessant stukje code van een collega van me:
C#:
1 2 3 4 5 int interval = 15000; if (Int32.TryParse(Convert.ToInt32(Properties.Settings.Default.Interval * 1000).ToString(), out interval) && interval > 0) { timer.Interval = interval; }
Het lijkt me dus dat de code zo veel beter zou zijn:
C#:
1
2
3
4
5
6
| int interval = 15000; if (Properties.Settings.Default.Interval > 0) { interval = Convert.ToInt32(Properties.Settings.Default.Interval * 1000); } timer.interval = interval; |
(En dan eventueel om een try/catch clause om die Convert.ToInt32 heen.)
Ik gok dat dat de reden is waarom dit topic onder de noemer 'Slechtste programmeervoorbeelden' het leven doorgaat.Soultaker schreef op zondag 02 januari 2011 @ 14:19:
[...]
Of ik begrijp C# niet, of dit is baggercode.
Had je de topictitel al 's bekeken?Soultaker schreef op zondag 02 januari 2011 @ 14:19:
[...]
Of ik begrijp C# niet, of dit is baggercode.
All my posts are provided as-is. They come with NO WARRANTY at all.
Dat ik het zelf zag moest ik ook eerst even drie keer kijken om het goed te begrijpen. Maar inderdaad zoals het was was het nogal dubieusSoultaker schreef op zondag 02 januari 2011 @ 14:19:
[...]
Of ik begrijp C# niet, of dit is baggercode. Int32.TryParse(ConvertToInt32(x).ToString(), y) kan toch nooit iets nuttigs doen? Als de conversie faalt wordt er een exception geraised (waar hier niets mee gedaan wordt; zou een fout kunnen zijn, maar dat is aan de context niet duidelijk) en anders heb je een geldige integer, en dan is het hele ToString() en TryParse() zinloos.
Het lijkt me dus dat de code zo veel beter zou zijn:
C#:
1 2 3 4 5 6 int interval = 15000; if (Properties.Settings.Default.Interval > 0) { interval = Convert.ToInt32(Properties.Settings.Default.Interval * 1000); } timer.interval = interval;
(En dan eventueel om een try/catch clause om die Convert.ToInt32 heen.)
Ik heb de property maar gewoon als int gedefinieerd. Dan kan het hele conversie verhaal er in één keer uit en hou je zoiets over:
C#:
1
| timer.interval = (Properties.Settings.Default.Interval > 0 ? Properties.Settings.Default.Interval : 15000); |
@Alex): Maar de Convert.ToInt32 zal wel een exceptie geven als de ingegeven waarde niet naar een int geconverteerd kan worden.
[ Voor 10% gewijzigd door urk_forever op 02-01-2011 15:28 ]
Hail to the king baby!
TryParse() gooit geen exception, maar retourneert dan 'false'. De out-parameter wordt gebruikt om de geconverteerde waarde door te geven.
We are shaping the future
Oops, ik meende even in de Coffeecorner te zitten.
TryParse zal nooit falen op een argument dat gegenereerd is door Int32.ToString. Int32.TryParse en Int32.ToString zijn elkaars inverse, lijkt me. Het is echter de Convert.ToInt32() die wél kan falen (als de betreffende decimal te groot is).Alex) schreef op zondag 02 januari 2011 @ 15:25:
TryParse() gooit geen exception, maar retourneert dan 'false'. De out-parameter wordt gebruikt om de geconverteerde waarde door te geven.
[ Voor 45% gewijzigd door Soultaker op 02-01-2011 15:45 ]
Zojuist weer eens een klassiek overbodig stukje code geklopt:
Tijd om er mee te stoppen voor vandaag.
code:
1
| return status == ResultStatus.FINISHED ? true : false; |
Tijd om er mee te stoppen voor vandaag.
Een bekende, paar weken terug tikte ik dat ook (einde van een lange lange dag) en een uurtje later scrollde ik weer eens wat door de code en heb het maar netjes verbeterd.sub0kelvin schreef op maandag 03 januari 2011 @ 21:48:
Zojuist weer eens een klassiek overbodig stukje code geklopt:
code:
1 return status == ResultStatus.FINISHED ? true : false;
Tijd om er mee te stoppen voor vandaag.
Liefhebber van schieten en schijten. Ouwehoer en niet-evangelisch atheist.
Daniel36: Dat zeg ik(?) Nee, dat zeg ik niet, je hebt gelijk.
Wat nu als je FileNotFound wilt terugsturen?sub0kelvin schreef op maandag 03 januari 2011 @ 21:48:
Zojuist weer eens een klassiek overbodig stukje code geklopt:
code:
1 return status == ResultStatus.FINISHED ? true : false;
Tijd om er mee te stoppen voor vandaag.
Och, ik heb met een collega te maken die gewoon liever if (whatever == true) typet.sub0kelvin schreef op maandag 03 januari 2011 @ 21:48:
Zojuist weer eens een klassiek overbodig stukje code geklopt:
code:
1 return status == ResultStatus.FINISHED ? true : false;
Tijd om er mee te stoppen voor vandaag.
Maar diezelfde collega prefereert 4GL (Progress OpenEdge) boven elke moderne OO-taal.
Easy toch?
code:
1
| return ( status == ResultStatus.FINISHED || 'FileNotFound' ); |
of ..
code:
1
| return ( status == ResultStatus.FINISHED || ResultStatus.FILE_NOT_FOUND ); |
Als je te maken hebt met nullable booleans is whatever == true helemaal zo gek nog niet.Davio schreef op dinsdag 04 januari 2011 @ 09:26:
[...]
Och, ik heb met een collega te maken die gewoon liever if (whatever == true) typet.
Maar diezelfde collega prefereert 4GL (Progress OpenEdge) boven elke moderne OO-taal.
Kater? Eerst water, de rest komt later
Haan schreef op dinsdag 04 januari 2011 @ 09:34:
[...]
Als je te maken hebt met nullable booleans is whatever == true helemaal zo gek nog niet.
whatever | true | false | null |
---|---|---|---|
whatever == true | true | false | null |
whatever == false | false | true | null |
!whatever | false | true | null |
Als je dan if(whatever) gebruikt, komt hij alleen in de if als whatever gewoon true is, dus daarvoor maakt het niet uit.
Als je in plaats daarvan if(!whatever) gebruikt, dan moet je (als je dat wil) ook checken op null, dus daarvoor maakt het wel uit en ik heb dit dan ook al meer dan eens in moeten tikken.
Dat verschilt per taal. In Java krijg je een NullPointerException als je if (whatever) doet waarbij whatever null is. Dan gebruik je dus if (whatever == Boolean.TRUE). Javascript daarentegen autocast null naar de boolean false.Davio schreef op dinsdag 04 januari 2011 @ 10:19:
[...]
whatever true false null whatever == true true false null whatever == false false true null !whatever false true null
Als je dan if(whatever) gebruikt, komt hij alleen in de if als whatever gewoon true is, dus daarvoor maakt het niet uit.
Als je in plaats daarvan if(!whatever) gebruikt, dan moet je (als je dat wil) ook checken op null, dus daarvoor maakt het wel uit en ik heb dit dan ook al meer dan eens in moeten tikken.
De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"
Ik neem aan dat je bedoelt dat je een compiler error krijgt. Je kunt immers alleen if( boolean ) doen, dus als je een expressie die geen boolean als resultaat heeft gebruikt krijg je gewoon een compiler error.NetForce1 schreef op dinsdag 04 januari 2011 @ 11:03:
[...]
Dat verschilt per taal. In Java krijg je een NullPointerException als je if (whatever) doet waarbij whatever null is. Dan gebruik je dus if (whatever == Boolean.TRUE). Javascript daarentegen autocast null naar de boolean false.
[ Voor 5% gewijzigd door Woy op 04-01-2011 11:10 ]
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Nee, sinds 1.5 is er autoboxing in Java, dan kun je dus het volgende doen:Woy schreef op dinsdag 04 januari 2011 @ 11:07:
[...]
Ik neem aan dat je bedoelt dat je een compiler error krijgt. Je kunt immers alleen if( boolean ) doen, dus als je een expressie die geen boolean als resultaat heeft gebruikt krijg je gewoon een compiler error.
Java:
1
2
3
4
| Boolean test = null; if (test) { // NPE, autoboxing vertaald dit naar if (test.booleanValue()) { System.err.println("This line should never be called!"); } |
De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"
Ok, ik wist niet dat kon. In .NET heb je daar nullable types voor, maar daar moet je expliciet .Value op aanroepen om ze in een if statement te gebruiken, aangezien er geen impliciete conversie van Nullable<bool> naar bool is. Ik had verwacht dat dat bij Java ook moest.NetForce1 schreef op dinsdag 04 januari 2011 @ 11:17:
[...]
Nee, sinds 1.5 is er autoboxing in Java, dan kun je dus het volgende doen:
Java:
1 2 3 4 Boolean test = null; if (test) { // NPE, autoboxing vertaald dit naar if (test.booleanValue()) { System.err.println("This line should never be called!"); }
[ Voor 5% gewijzigd door Woy op 04-01-2011 11:24 ]
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Goed, maar in Progress bestaat null niet echt op die manier.
Je hebt de unknown value: ?.
En uit alle vergelijkingen met ? komt ook gewoon ?.
Het is wel gek om zo naar een boolean te kijken die dus 3 ipv 2 waarden kan hebben, maar logisch is het wel.
Gebruikers kunnen bijvoorbeeld mannelijk of vrouwelijk zijn óf het is niet bekend (gekke transgenderachtige toestanden daargelaten). Maar dan is het ook niet echt een klassieke boolean (volgens Boole), maar meer een enum met 3 mogelijkheden: T/F/Unknown.
Edit, dit dan: As of the 1999 standard, SQL specified a Boolean data type with four possible values: true, false, unknown or null. However, vendors could choose to equate the last two values.[6]. Because of this inconsistency most SQL implementations (with the notable exception of Postgresql)[7] use other data types (like bit, byte, and character) to simulate Boolean values.
Je hebt de unknown value: ?.
En uit alle vergelijkingen met ? komt ook gewoon ?.
Het is wel gek om zo naar een boolean te kijken die dus 3 ipv 2 waarden kan hebben, maar logisch is het wel.
Gebruikers kunnen bijvoorbeeld mannelijk of vrouwelijk zijn óf het is niet bekend (gekke transgenderachtige toestanden daargelaten). Maar dan is het ook niet echt een klassieke boolean (volgens Boole), maar meer een enum met 3 mogelijkheden: T/F/Unknown.
Edit, dit dan: As of the 1999 standard, SQL specified a Boolean data type with four possible values: true, false, unknown or null. However, vendors could choose to equate the last two values.[6]. Because of this inconsistency most SQL implementations (with the notable exception of Postgresql)[7] use other data types (like bit, byte, and character) to simulate Boolean values.
[ Voor 27% gewijzigd door Davio op 04-01-2011 11:30 ]
Hehe, het .NET framework heeft ook wel wat rare constructies
Kan best handig zijn hoor, wist niet eens dat het bestond, maar vaak heb je ergens een basepath en wil je daar subfolders in "bezoeken" normaal moet je dan altijd checken of er een \ op het einde staat, zo niet moet je zelf een \ toevoegen alvorens de subdirs toe te voegen. Op deze manier kun je mooi een path laten genereren aan de hand van alleen de base directory en dan de gewenste subpaden zonder je druk te hoeven maken om je scheidingsteken.CyCloneNL schreef op woensdag 05 januari 2011 @ 14:37:
Hehe, het .NET framework heeft ook wel wat rare constructies
Voor dit soort dingen vind je meestal zelf wel een mooie oplossing in de vorm van een leuke functie, maar iets van het framework gebruiken is nog veel beter. Waarom het wiel opnieuw uitvinden?
Weer wat geleerd vandaag
Ben benieuwd of dit in de Mono implementatie ook rekening houdt met de Linux style paden, Linux hanteert / als directory scheiding. Als deze path.combine hier rekening mee houdt is het helemaal mooi
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Het is een uiterst handige functie, alleen al die overloads zijn onnodig.
Je kan gewoon 1 Path.Combine maken welke een params string[] als argument krijgt, dan heb je geen overloads nodig.
Uiteindelijk heb ik hem zelf maar gemaakt:
Je kan gewoon 1 Path.Combine maken welke een params string[] als argument krijgt, dan heb je geen overloads nodig.
Uiteindelijk heb ik hem zelf maar gemaakt:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
| public static string Combine(params string[] paths) { List<string> pList = new List<string>(paths); if (pList.Count == 1) return pList[0]; pList[0] = Path.Combine(pList[0], pList[1]); pList.RemoveAt(1); return Combine(pList.ToArray()); } |
Dacht eerst dat het misschien was vanwege legacy, maar deze functie bestaat pas sinds 4.0. De constructie dat er een aantal overloads zijn met meerdere parameters zit vaker in .NET, geloof dat String.Format dat ook had. Maar daarna zit er inderdaad 1 bij die een param array ontvangt om de andere scenario's op te vangen. Had hem hier ook wel verwacht inderdaad, ik dacht al iets vreemds te zien, maar dacht dat het in eerste instantie ging om het bestaan van de functie (sommige mensen zullen allicht denken: waar heb ik dat nou weer voor nodig).CyCloneNL schreef op woensdag 05 januari 2011 @ 15:01:
Het is een uiterst handige functie, alleen al die overloads zijn onnodig.
Je kan gewoon 1 Path.Combine maken welke een params string[] als argument krijgt, dan heb je geen overloads nodig.
Uiteindelijk heb ik hem zelf maar gemaakt:
...
Ah well, ik heb vandaag in ieder geval weer een nieuwe functie uit de library geleerd (terwijl ik de laatste tijd weinig/niets meer doe in .NET, dan is het helemaal kunst om iets bij te leren
Aan de andere kant baal ik af en toe als ik weer zie wat voor moois .NET kan, want dan klik ik de browser weg en ben ik weer in de harde realiteit van Dynamics AX en de interne IDE van AX, mijn hemel wat voelt dat dan primitief aan
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Nee hoor, al sinds 1.1 (1.0?).Gertjan. schreef op woensdag 05 januari 2011 @ 15:16:
[...]
Dacht eerst dat het misschien was vanwege legacy, maar deze functie bestaat pas sinds 4.0.
Jouw functie ookCyCloneNL schreef op woensdag 05 januari 2011 @ 15:01:
Het is een uiterst handige functie, alleen al die overloads zijn onnodig.
C#:
1
| string mypath = Path.Combine("c:\\foo", Path.Combine("bar", "foobar")); |
c:\foo\bar\foobar
[ Voor 33% gewijzigd door RobIII op 05-01-2011 15:29 ]
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij
Ja, maar alleen met twee String-parameters en geen overloads. Die zijn pas in 4.0 toegevoegd.
[ Voor 20% gewijzigd door CodeCaster op 05-01-2011 15:28 ]
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
Vreemd

Mmm daar staan wel weer de andere versies in de dropdown "other versions". Vreemd, de overzichtspagina is er alleen voor 4.0, maar de detail pagina's bestaan wel voor de oudere versies...CodeCaster schreef op woensdag 05 januari 2011 @ 15:27:
Ja, maar alleen met twee String-parameters en geen overloads.
[ Voor 28% gewijzigd door .Gertjan. op 05-01-2011 15:29 ]
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Ja, hé hé, doe dat maar is 5 keer. Dan blijf je bezigRobIII schreef op woensdag 05 januari 2011 @ 15:24:
Jouw functie ook
C#:
1 string mypath = Path.Combine("c:\\foo", Path.Combine("bar", "foobar"));
c:\foo\bar\foobar
Bovendien zou je functie aanroep voor 2 parameters er heel anders uit zien dan voor 3 (etc), wat verwarring opbrengt.
[ Voor 15% gewijzigd door TJHeuvel op 05-01-2011 15:31 ]
Waarom maak je er eerst een list van waar je later weer een array van maakt? Om hem recursief aan te kunnen roepen?
Ik zou het zo gedaan hebben, is makkelijker en safer (wat doet jouw methode bij een lege array?):
Ik zou het zo gedaan hebben, is makkelijker en safer (wat doet jouw methode bij een lege array?):
C#:
1
2
3
4
5
6
7
8
9
| public static string Combine(string path, params string[] morePaths) { path = System.IO.Path.Combine(path); foreach(string subPath in morePaths) { path = System.IO.Path.Combine(path, subPath); } return path; } |
Dat ze hem er met twee argumenten hebben ingelaten voor backwards compatibility: soit. Dat ze een overload met array hebben toegevoegd: prima. Maar dan óók nog overloads voor 3 en 4 strings toevoegen...
Het gaat steeds meer op PHP lijken, voor elke scheet een functie maken, zodat je langer bezig bent met documentatie lezen met hoe het aan te roepen dan het zelf programmeren.
[/gechargeerd]. En ja, ik heb het stuk "it's harder to read code than to write it" gelezen.
Wat is er mis met
Als je drie of meer strings wil combineren tot een pad?


Wat is er mis met
C#:
1
| Path.Combine(new String[]{"foo", "bar", "baz"}); |
Als je drie of meer strings wil combineren tot een pad?
[ Voor 7% gewijzigd door CodeCaster op 05-01-2011 15:36 ]
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
Ik maak er een List van om een element te removen, en op dit moment gaat 'ie gigantisch op z'n smoel als je geen argumenten mee geeft. Om een of andere reden dacht ik dat dat niet kon...Davio schreef op woensdag 05 januari 2011 @ 15:35:
Waarom maak je er eerst een list van waar je later weer een array van maakt? Om hem recursief aan te kunnen roepen?
Ik zou het zo gedaan hebben, is makkelijker en safer (wat doet jouw methode bij een lege array?):
C#:
1 2 3 4 5 6 7 8 9 public static string Combine(string path, params string[] morePaths) { path = System.IO.Path.Combine(path); foreach(string subPath in morePaths) { path = System.IO.Path.Combine(path, subPath); } return path; }
Die overload zit er pas sinds .NET 3.5 in, wij werken nog met 2.0.Wat is er mis met
C#:
1 Path.Combine(new String[]{"foo", "bar", "baz"});
Als je drie of meer strings wil combineren tot een pad?
[ Voor 50% gewijzigd door TJHeuvel op 05-01-2011 15:45 ]
Zelfs vanaf 4.0 pas toch? Het was ook meer richting MS bedoeld, niet aan jouw adres.CyCloneNL schreef op woensdag 05 januari 2011 @ 15:43:
Die overload zit er pas sinds .NET 3.5 in, wij werken nog met 2.0.
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
Excuus, ik las het verkeerdCodeCaster schreef op woensdag 05 januari 2011 @ 15:46:
[...]
Zelfs vanaf 4.0 pas toch? Het was ook meer richting MS bedoeld, niet aan jouw adres.
In ieder geval, Davio heeft helemaal gelijk en ik doe te moeilijk
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| public static string Combine(params string[] paths) { if (paths.Count() <= 0) return ""; if (paths.Count() == 1) return paths[0]; for (int i = 1; i < paths.Count(); i++) { paths[0] = Path.Combine(paths[0], paths[i]); } return paths[0]; } Console.WriteLine(PathHelper.Combine(@"C:\", "Backups", @"Testfolder\", @"Somedirectory")); |
M'n testcase laat ook wel het probleem zien, sommige folders kunnen een backslash hebben, andere niet. Als je dit via strings aan elkaar gaat duct-tapen krijg je paden die niet kloppen.
[ Voor 12% gewijzigd door TJHeuvel op 05-01-2011 15:56 ]
int i = 1 had er moeten staan denk ik.CyCloneNL schreef op woensdag 05 januari 2011 @ 15:52:
[...]
C#:
1 2 3 4 5 6 7 8 9 10 11 12 public static string Combine(params string[] paths) { if (paths.Count() <= 0) return ""; for (int i = 0; i < paths.Count(); i++) { paths[0] = Path.Combine(paths[0], paths[i]); } return paths[0]; } Console.WriteLine(PathHelper.Combine(@"C:\", "Backups", @"Testfolder\", @"Somedirectory"));
@Edit: Ah, je hebt het al aangepast.
C#:
1
2
| if (paths.Count() == 1) return paths[0]; |
is overbodig. Ook zonder dat komt het juiste resultaat uit de functie.
[ Voor 11% gewijzigd door CoolGamer op 05-01-2011 15:58 ]
¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸
Ja, en moeilijk doen is vragen om problemen natuurlijk.CyCloneNL schreef op woensdag 05 januari 2011 @ 15:52:
[...]
Excuus, ik las het verkeerd
In ieder geval, Davio heeft helemaal gelijk en ik doe te moeilijk![]()
[..]
M'n testcase laat ook wel het probleem zien, sommige folders kunnen een backslash hebben, andere niet. Als je dit via strings aan elkaar gaat duct-tapen krijg je paden die niet kloppen.
Maar mijn methode klopte ook niet helemaal, omdat je geen Combine hebt met maar één string (ja, logisch).
Dit werkt in ieder geval:
C#:
1
2
3
4
5
6
7
8
9
| public static string Combine(string path1, string path2, params string[] morePaths) { string path = System.IO.Path.Combine(path1, path2); foreach (string subPath in morePaths) { path = System.IO.Path.Combine(path, subPath); } return path; } |
Resultaten:
Console.WriteLine(Combine(@"C:\", "Aep")); ==> C:\Aep
Console.WriteLine(Combine(@"C:\", "Backups", @"Testfolder\", @"Somedirectory")); => C:\Backups\Testfolder\Somedirectory
Collega/klasgenoot/teamgenoot vind autoincrement in databases lelijk omdat het dan niet "mooi" op volgorde blijft.
Ziehier de oplossing:
Ziehier de oplossing:
Java:
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
| public int getId(String table, String column) { int i = 0; int availableid = 0; int[] id = new int[1000]; for (int x = 0; x < 1000; x++) { id[x] = x; } int[] id2 = new int[1000]; for (int x = 0; x < 1000; x++) { id[x] = x; } try { String SQL_Query = "Select " + column + " FROM " + table + ""; ResultSet result = dbmanager.doQuery(SQL_Query); while (result.next()) { id2[i] = result.getInt(column); i++; } } catch (SQLException e) { System.out.println(Dbmanager.SQL_EXCEPTION + e.getMessage()); } for (int x = 0; x < 1000; x++) { if (id[x] != id2[x]) { availableid = x; break; } } return availableid; } |


Die is wel een tdwtf vermelding waard zeg!
Buiten het feit dat het zijn ' originele' probleem niet eens oplost zitten er zoveel wtf's in dat het eng wordt....
Wtf
Ook leuk als je tabel meer dan 1000 records bevat

Ook leuk als je tabel meer dan 1000 records bevat
[ Voor 40% gewijzigd door Bv202 op 05-01-2011 18:29 ]
My god 
Simpele vereenvoudiging van het algoritme:
Blijft over waarom je het überhaupt zo zou willen aanpakken
[list]• Waarom sorteert hij niet op column?
• Wat als meerdere users tegelijk een nieuw id willen hebben?
• Teruggegeven id wordt niet gereserveerd. 2x getId() aanroepen zonder daadwerkelijk inserten geeft hetzelfde id. Wellicht is dat wat je wil, maar het is natuurlijk vragen om problemen.
• Als er een exception optreedt dan wordt er alsnog een id teruggegeven.
• Als je meer delete dan insert dan hou je alsnog id's over die niet consecutive zijn, dus het lost niets op.

Simpele vereenvoudiging van het algoritme:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| public int getId(String table, String column) { int id = 0; try { String SQL_Query = "Select " + column + " FROM " + table; ResultSet result = dbmanager.doQuery(SQL_Query); while (result.next()) { if (result.getInt(column) != id) break; id++; } } catch (SQLException e) { System.out.println(Dbmanager.SQL_EXCEPTION + e.getMessage()); } return id; } |
Blijft over waarom je het überhaupt zo zou willen aanpakken

[list]• Waarom sorteert hij niet op column?
• Wat als meerdere users tegelijk een nieuw id willen hebben?
• Teruggegeven id wordt niet gereserveerd. 2x getId() aanroepen zonder daadwerkelijk inserten geeft hetzelfde id. Wellicht is dat wat je wil, maar het is natuurlijk vragen om problemen.
• Als er een exception optreedt dan wordt er alsnog een id teruggegeven.
• Als je meer delete dan insert dan hou je alsnog id's over die niet consecutive zijn, dus het lost niets op.
[ Voor 33% gewijzigd door .oisyn op 05-01-2011 18:58 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Juist in Java is dat handig, aangezien dat standaard platform onafhankelijk (moet | kan) draaien, waardoor je gebonden bent aan zowel Windows, Unix en Macintosh achtige filesystems..Gertjan. schreef op woensdag 05 januari 2011 @ 14:58:
[...]
Ben benieuwd of dit in de Mono implementatie ook rekening houdt met de Linux style paden, Linux hanteert / als directory scheiding.
Maar wees niet gevreest, Java heeft daar ook een systeem specifieke methode voor.
Java:
1
2
3
4
5
| File.pathSeparator(); OR System.getProperty("path.separator"); |
[ Voor 23% gewijzigd door RomeoJ op 05-01-2011 20:58 ]
You only need two tools in life: WD-40 and Duct-Tape, if it doesn't move and it should, use the WD-40. If it does move and it shouldn't, use the Tape.
In Java heb je:.Gertjan. schreef op woensdag 05 januari 2011 @ 14:58:
Zelfde verhaal met de regeleinden, gelukkig is daar Environment.NewLine voor in .NET, maar in bijvoorbeeld Java (vroeger op school) moest je daar toch altijd wel weer rekening mee houden, er was altijd wel weer iemand die met linux input text files kwam (en dus een andere newline had en je programma zijn nek brak).
Java:
En als je in Java input text files wil lezen, gebruik je toch gewoon java.io.BufferedReader of java.util.Scanner? Daarmee hoef je ook geen rekening te houden met regeleinden.1
| System.getProperty("line.separator") |
Je bedoeltRomeoJ schreef op woensdag 05 januari 2011 @ 20:57:
Maar wees niet gevreest, Java heeft daar ook een systeem specifieke methode voor.
Java:
1 2 3 4 5 File.pathSeparator(); OR System.getProperty("path.separator");
Java:
1
2
3
4
5
| File.separator(); OR System.getProperty("file.separator"); |
Je hebt hiervoor speciaal de string Environment.DIrectorySeparator in .NET..Gertjan. schreef op woensdag 05 januari 2011 @ 14:58:
[...]
Ben benieuwd of dit in de Mono implementatie ook rekening houdt met de Linux style paden, Linux hanteert / als directory scheiding. Als deze path.combine hier rekening mee houdt is het helemaal mooiZelfde verhaal met de regeleinden, gelukkig is daar Environment.NewLine voor in .NET, maar in bijvoorbeeld Java (vroeger op school) moest je daar toch altijd wel weer rekening mee houden, er was altijd wel weer iemand die met linux input text files kwam (en dus een andere newline had en je programma zijn nek brak).
Verder werken "/" paden ook op Windows (iig in .NET). Dus als je niet zeker bent kun je het het beste op die manier doen.
Meh dat is allemaal wel erg lang geleden. Wel onhandig dat je de getProperty moet aanroepen met een string parameter. Beter is gewoon een static/const in een class.terje7601 schreef op woensdag 05 januari 2011 @ 21:14:
[...]
In Java heb je:Java:En als je in Java input text files wil lezen, gebruik je toch gewoon java.io.BufferedReader of java.util.Scanner? Daarmee hoef je ook geen rekening te houden met regeleinden.
1 System.getProperty("line.separator")
[...]
Je bedoeltJava:
1 2 3 4 5 File.separator(); OR System.getProperty("file.separator");
Toen ik (vroegah) met java werkte was het geloof ik nog 1.3 of 1.4 ( > 5 jaar terug, JBuilder 4 enzo). Daarna nog 1x een project in een java spinoff gedaan (SilverStream, een of ander framework gebouwd op Java) puur omdat het nog onderhouden moest worden, gelukkig werd de hele handel herschreven naar .NET en ben ik zoveel mogelijk bij Java weggebleven. Sinds ik .NET heb ontdekt (v1) ben ik nooit meer terug gegaan, maar aan de andere kant kriebelt het wel weer omdat ik zo android spul kan maken.
Wij moesten destijds zeer basic tooltje bouwen, "correct" en netjes programmeren was niet nodig. We gingen nog net geen bytes van de hdd schrapen. Zelfs in de practica stonden de voorbeelden vol met "Regel1 \r\n Regel2, enz". Daarnaast moesten de eerste practica in JCreator, dat is gewoon een notepad met een compiler, er zat in de gratis versie namelijk geen code completion enzo. Echt een top programmeur werd je daar niet...
Waarom ik geen
I know, maar soms krijg je ook user input die je moet combineren. Maar goed de Environment class bevat wel meer handige dingenroy-t schreef op woensdag 05 januari 2011 @ 21:37:
[...]
Je hebt hiervoor speciaal de string Environment.DIrectorySeparator in .NET.
Verder werken "/" paden ook op Windows (iig in .NET). Dus als je niet zeker bent kun je het het beste op die manier doen.
Overigens vroeg ik me meer af of het in de combine automatisch werd meegenomen, het kan ook zijn dat daar een \ hardcoded staat opgenomen.
Misschien sowieso weer eens tijd om naar Mono te kijken, in het verleden wat mee zitten spelen en vond het toen wel grappig, maar was allemaal nog beta, inmiddels schijnt heb best leuk te werken.
[ Voor 7% gewijzigd door .Gertjan. op 05-01-2011 21:50 ]
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
.Gertjan. schreef op woensdag 05 januari 2011 @ 21:47:
[...]
I know, maar soms krijg je ook user input die je moet combineren. Maar goed de Environment class bevat wel meer handige dingenDat de paden met de andere slash ook werkte had ik ook al eens ontdekt, maar op het moment dat je ze door elkaar gebruikt gaat windows dat niet altijd leuk vinden.
Overigens vroeg ik me meer af of het in de combine automatisch werd meegenomen, het kan ook zijn dat daar een \ hardcoded staat opgenomen.
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
| public static string Combine(string path1, string path2) { if ((path1 == null) || (path2 == null)) { throw new ArgumentNullException((path1 == null) ? "path1" : "path2"); } CheckInvalidPathChars(path1); CheckInvalidPathChars(path2); if (path2.Length == 0) { return path1; } if (path1.Length == 0) { return path2; } if (IsPathRooted(path2)) { return path2; } char ch = path1[path1.Length - 1]; if (((ch != DirectorySeparatorChar) && (ch != AltDirectorySeparatorChar)) && (ch != VolumeSeparatorChar)) { return (path1 + DirectorySeparatorChar + path2); } return (path1 + path2); } |
Waarbij DirectorySeparatorChar, AltDirectorySeparatorChar en VolumeSeparatorChar zijn gedefinieerd als public static readonly char die in de constructor geïnitialiseerd worden:
C#:
1
2
3
4
5
6
7
| static Path() { DirectorySeparatorChar = '\\'; AltDirectorySeparatorChar = '/'; VolumeSeparatorChar = ':'; // etc. } |
Dus de waardes staan inderdaad hard-coded opgeslagen en er wordt een '\' gebruikt om paden aan elkaar te plakken.
Kater? Eerst water, de rest komt later
...maar de .NET-implementatie op een ander platform kan daar best een forward slash hebben staan.
We are shaping the future
Waarschijnlijk wel, maar ik had eigenlijk verwacht dat dit soort dingen in 1 class zit (en dat Path daarheen zou verwijzen) zodat bij een alternatief framework of een alternatieve versie van het framework slechts die ene class hoeft te worden aangepast. Meestal (tenminste zo heb ik het geleerd) plemp je die dingen bij elkaar. De Environment class zou een geschiktere plaats zijn in mijn ogen.Alex) schreef op woensdag 05 januari 2011 @ 23:30:
...maar de .NET-implementatie op een ander platform kan daar best een forward slash hebben staan.
Ben wel benieuwd hoe Mono het doet, iemand toevallig toegang tot de mono implementatie van dit verhaal?
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
In de rechterkolom: http://www.medicatieoverdracht.nl
Volgende keer even checken op 0 en dan gelukkig nieuwjaar laten ziennog - 5 dagen tot 2011
De hele wereld heeft toegang.Gertjan. schreef op donderdag 06 januari 2011 @ 07:28:
[...]
Ben wel benieuwd hoe Mono het doet, iemand toevallig toegang tot de mono implementatie van dit verhaal?
https://github.com/mono/m.../corlib/System.IO/Path.cs
Uiteindelijk kan je in MonoIO.cs zien dat het in de CLR geimplementeerd is
C#:
1
2
3
4
| public extern static char DirectorySeparatorChar { [MethodImplAttribute (MethodImplOptions.InternalCall)] get; } |
[ Voor 24% gewijzigd door Woy op 06-01-2011 14:40 ]
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Goed, het is knullig, maar men verliest er geen geld mee. Hier wel, de oude tarieven (2010) waren geldig TOT 31 december, en de nieuwe vanaf 1 januari.jip_86 schreef op donderdag 06 januari 2011 @ 14:16:
In de rechterkolom: http://www.medicatieoverdracht.nl
[...]
Volgende keer even checken op 0 en dan gelukkig nieuwjaar laten zien
Je raadt het al, de rapportage laat een piek zien op de 31e en de boekhouding is er alles behalve 'amused' van.
Zero SR/S 17.3kWh / 2.7 kWP PV / Xtend WP 5kW + HRSolar zonnoeboiler
Het is al een tijd geleden dat ik iets met bestanden deed in Java, maar waren er geen methodes in File waar je een pad op kon bouwen zonder handmatig separators in te hoeven voegen? Immers, aannemen dat een pad opgebouwd is met separators is alleen van toepassing op de nu gangbare OSen, als je het abstract bekijkt.RomeoJ schreef op woensdag 05 januari 2011 @ 20:57:
[...]
Juist in Java is dat handig, aangezien dat standaard platform onafhankelijk (moet | kan) draaien, waardoor je gebonden bent aan zowel Windows, Unix en Macintosh achtige filesystems.
Maar wees niet gevreest, Java heeft daar ook een systeem specifieke methode voor.
Java:
1 2 3 File.pathSeparator(); OR System.getProperty("path.separator");
Faux edit: Awel: hiero. Je zou iets kunnen maken als:
Java:
1
| File f = new File("bestandsnaam", new File("mapje 2", new File("mapje").getPath()).getPath()); |
Lelijk en waarschijnlijk inefficiënt, maar het zou moeten werken
Sja, heeft te maken met legacy code enzo. Ik vindt het ook gek dat de Java API's niet vaker bijgewerkt worden met nieuwe features - het is immers gewoon mogelijk om een nieuwe getProperty() functie in system te maken die een enum constante accepteert?quote: GertjanWel onhandig dat je de getProperty moet aanroepen met een string parameter. Beter is gewoon een static/const in een class.
Natuurlijk moet je ook rekening houden met het feit dat iedereen properties kan toevoegen, dwz dat de daadwerkelijke parameters niet beperkt zijn tot dingen als file.separator, maar ook bijv. nl.mijnzooi.instellingkje. Dat kun je weer afvangen door een SystemProperty interface te maken die de property interfaces kunnen implementeren, maar dan moeten wel al die libraries daar (uiteindelijk) gebruik van kunnen maken.
Als workaround zou je natuurlijk een library kunnen maken die wrapt om System.getProperty(), die een object dat een bepaalde interface implementeert en omzet naar een propere getProperty() parameter. Dan krijg je zoiets als (uit de losse pols):
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| public interface SystemProperty { public String getPropertyValue(); } public enum JavaSystemProperties implements SystemProperty { FILE_SEPARATOR("file.separator"); // woei boilerplate private final String propertyValue; private JavaSystemProperties(String propertyValue) { this.propertyValue = propertyValue; } public String getPropertyValue() { return this.propertyValue; } } public class SystemPropertyWrapper() { public static String getProperty(SystemProperty property) { return System.getProperty(property.getPropertyValue()); } // evt. overloaded methods om int enzo terug te geven. Verwacht type kan evt. ook in de SystemProperty gedefiniëerd worden. } |
[ Voor 19% gewijzigd door YopY op 06-01-2011 15:31 ]
Gezien hier bij ons op het werk:
Geen idee wat die a!=a moet doen...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| int compare_double( double a, double b) { if ((a != a) || (b != b)) { return memcmp( a, b, sizeof(double)); } else { if (a < b) return -1; else if (a > b) return 1; else return 0; } return 0; } |
Geen idee wat die a!=a moet doen...
Powermac G5 casemod. Mijn PV live output. | Ioniq 6 Style 77kWh Ultimate Metallic Red 18" RWD
Dat is voor wanneer een van de doubles een NaN waarde heeft? Er is een hele reeks beschikbaar voor NaNs en ze zijn altijd ongelijk aan elkaar, ook al hebben ze dezelfde binaire waarde.
Misschien is die a != a wel zijn vorm van in commentaar plaatsen, omdat hij erachter kwam dat de memcmp niet goed werkte?
Die laatste return is ook vrij nuttig...
Die laatste return is ook vrij nuttig...
Is die niet om compiler warnings (Function does not return a value) te voorkomen, in het geval dat de compiler niet ziet dat de if's alle cases afvangen?Davio schreef op donderdag 06 januari 2011 @ 16:05:
Die laatste return is ook vrij nuttig...
Zo scherp als een voetbal!
Sowieso moet je 2 floating point getallen niet op die manier vergelijken. Die laatste else zal als het tegenzit nooit bereikt worden.
wat is er mis mee dan?EddoH schreef op donderdag 06 januari 2011 @ 16:24:
Sowieso moet je 2 floating point getallen niet op die manier vergelijken. Die laatste else zal als het tegenzit nooit bereikt worden.
hoe moet je ze dan vergelijken?
Let op: Mijn post bevat meningen, aannames of onwaarheden
Meh, een goede compiler moet gewoon zien dat alle paden een return-value hebben.Reptile209 schreef op donderdag 06 januari 2011 @ 16:18:
[...]
Is die niet om compiler warnings (Function does not return a value) te voorkomen, in het geval dat de compiler niet ziet dat de if's alle cases afvangen?
Binnen Visual Studio met C# kan dat gewoon in ieder geval.
Omdat 0.5f intern niet gelijk hoeft te zijn aan 1.0 / 2.0 door afrondingsfouten.Gamebuster schreef op donderdag 06 januari 2011 @ 16:26:
[...]
wat is er mis mee dan?
hoe moet je ze dan vergelijken?
Je moet een functie schrijven die kijkt of 2 floating point getallen binnen een bepaalde marge X aan elkaar gelijk zijn.
edit: spelling + quote
[ Voor 32% gewijzigd door EddoH op 06-01-2011 16:30 ]
Afronding, heb je bij alle floating point getallen.Gamebuster schreef op donderdag 06 januari 2011 @ 16:26:
[...]
wat is er mis mee dan?
hoe moet je ze dan vergelijken?
Zo kun je bewerkingen doen met getallen waardoor er wiskundig hetzelfde uitkomt, maar op de computer niet.
Bijvoorbeeld 3 1/3 vs 3 1/3 (wiskunde) en 3,333333333333 vs 3,33333333333334 (computer).
Dat komt doordat zulke getallen binair niet goed kunnen worden weergegeven.
Die (x != x) gebruik ik ook soms om NaN's te detecteren. Mooier is om er ISNAN() macro van te maken, of isnan() uit math.h te gebruiken. De vraag is echter waar je die NaN's überhaupt wil sorteren want op de reële as passen ze niet.
Klik dan eens op het min-teken (A) als je in firefox zit krijg je een mooie error (IE niet)jip_86 schreef op donderdag 06 januari 2011 @ 14:16:
In de rechterkolom: http://www.medicatieoverdracht.nl
[...]
Volgende keer even checken op 0 en dan gelukkig nieuwjaar laten zien
Gamebuster schreef op donderdag 06 januari 2011 @ 16:26:
wat is er mis mee dan?
hoe moet je ze dan vergelijken?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| bool compare_double_equal( double a, double b, double crit) { equal = TRUE; if (fabs(a-b) > crit) { equal = FALSE; } return equal; } if (compare_double_equal( 0.5, 1.0/2.0, 1e-10) { /* TDB */ } |
Zo doe ik het altijd.
Dat van die NaN detecteren is nieuw voor me. Dat kan goed de reden zijn voor die code. Misschien toch nog een geldige reden voor if (a!=a). In het stuk code werd ook vaak NaN's gemaakt dmv 0.0/0.0 en Inf's dmv 1.0/0.0. Ik zie liever een bool om aan te geven of iets geldig is, dan er een NaN of Inf voor te gebruiken.
Powermac G5 casemod. Mijn PV live output. | Ioniq 6 Style 77kWh Ultimate Metallic Red 18" RWD
Onzin. Bijna alle operatoren levereren onder IEEE arithmetic gegarandeerd exacte resultaten op, die vervolgens afgerond moeten worden naar het dichstbijzijnde te representeren getal. Dat betekent concreet dat delingen met representabele getallen die ook een representabel resultaat opleveren (zoals 1/2) gegarandeerd exact het juiste resultaat opleveren. 0.5 is dus wel exact gelijk aan 1.0/2.0.EddoH schreef op donderdag 06 januari 2011 @ 16:28:
Omdat 0.5f intern niet gelijk hoeft te zijn aan 1.0 / 2.0 door afrondingsfouten.
Natuurlijk kun je in sommige gevallen wel fouten introduceren door het afronden dat noodzakelijk is bij het rekenen met niet-representable gatellen maar dat betekent niet dat je getallen niet kunt vergelijken. Een getal verandert niet magischerwijs van waarde.
Als dat niet zo was, zouden talen als JavaScript en Lua ook geen floating point getallen kunnen gebruiken als representatie voor alle getallen, omdat simpele operaties als x = x + 1 dan al onbetrouwbare resultaten zouden geven. In werkelijkheid zijn dit soort operaties echter exact zolang je je beperkt tot gehele getallen onder de 252 ofzoiets, wat in de praktijk voor for-lusjes enzo afdoende is.
[ Voor 19% gewijzigd door Soultaker op 06-01-2011 17:06 ]
1/2 was een verkeerd voorbeeld. Neem eens 1/10Soultaker schreef op donderdag 06 januari 2011 @ 17:02:
Onzin. Bijna alle operatoren levereren onder IEEE arithmetic gegarandeerd exacte resultaten op, die vervolgens afgerond moeten worden naar het dichstbijzijnde te representeren getal. Dat betekent concreet dat delingen met representabele getallen die ook een representabel resultaat opleveren (zoals 1/2) gegarandeerd exact het juiste resultaat opleveren. 0.5 is dus wel exact gelijk aan 1.0/2.0.
is 0.1f gelijk aan 1.0/10.0? En aan (2.0/5.0)/4.0?
Zolang je je beperkt tot gehele getallen hoef je niet met floats te klooien, lijkt me?Als dat niet zo was, zouden talen als JavaScript en Lua ook geen floating point getallen kunnen gebruiken als representatie voor alle getallen, omdat simpele operaties als x = x + 1 dan al onbetrouwbare resultaten zouden geven. In werkelijkheid zijn dit soort operaties echter exact zolang je je beperkt tot gehele getallen onder de 252 ofzoiets, wat in de praktijk voor for-lusjes enzo afdoende is.
Hier staat onderaan de pagina een mooi voorbeeldje van een algoritme waarin x + 1 significant betere resultaten oplevert dan x - 1 in een equivalent algoritme. Zo gek is het dus nog niet dat een simpele operatie al een "onbetrouwbaar" resultaat oplevert.
En ik ben dus databases tegengekomen waar bedragen in floats worden opgeslagen.
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
Wat Dido zegt dus. Ik heb inderdaad een verkeerd voorbeeld gebruikt.
Zo'n functie om doubles te vergelijken schrijf je per definitie niet om je te beperken tot gehele getallen lijkt me...
Als we dan toch bezig zijn:jip_86 schreef op donderdag 06 januari 2011 @ 14:16:
In de rechterkolom: http://www.medicatieoverdracht.nl
[...]
Volgende keer even checken op 0 en dan gelukkig nieuwjaar laten zien
http://www.medicatieoverdracht.nl/Logging/message.asp?MessageID=998&MessageStr=%3Cscript%3Ealert%28%27hoi%27%29%3C/script%3E&button=none&url=
Wel heel basic...
40D | 8 | 50 | 100 | 300
@CodeCaster: ik ook, helaas. Vergeet alleen niet dat je met een 32 bit float 'nooit' afrondingsfouten zult maken die een bedrag van bijv. 6 cijfers veranderen. Ik verwacht nu een stukje code van .iosyn ofzo waarin het wel gebeurt, maar ik denk dat het in 99,99% van de gevallen goed gaat, en in de 0,01% gevallen 1 cent scheelt.
@ppx: pas maar op, dadelijk wordt je opgepakt voor Hacken!
@ppx: pas maar op, dadelijk wordt je opgepakt voor Hacken!
[ Voor 9% gewijzigd door MBV op 06-01-2011 18:22 ]
Verwijderd
Mwah, ik ben databases tegengekomen waarin bedragen in floats en enkel incl BTW opgeslagen werden. Dus niet eens het BTW bedrag erbij.CodeCaster schreef op donderdag 06 januari 2011 @ 18:02:
En ik ben dus databases tegengekomen waar bedragen in floats worden opgeslagen.
Bij het aanspreken van de desbetreffende programmeur: "Hoezo? Je kunt toch altijd terugrekenen door te delen door 1.19f"




Getallen en talstelsels FAQGamebuster schreef op donderdag 06 januari 2011 @ 16:26:
[...]
wat is er mis mee dan?
hoe moet je ze dan vergelijken?
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij
Dat kan per definitie nooit voorkomen. Wat je nu beweert is dat een float een waarde kan hebben die nooit equal zal comparen met een andere float. Afgezien van NaN's kan dat helemaal niet voorkomen - als de ene float die waarde heeft, kan de andere float ook die waarde hebben, en zal a==b gewoon true opleveren.EddoH schreef op donderdag 06 januari 2011 @ 16:24:
Sowieso moet je 2 floating point getallen niet op die manier vergelijken. Die laatste else zal als het tegenzit nooit bereikt worden.
Bovendien gaat het hier om een ordering functie (de compare() ordert de twee floats, hij returnt -1 als a < b, 0 als a==b, en 1 als a>b). Bovenstaande posts over dat 1/10 wellicht niet hetzelfde is als 0.1f zijn dus compleet irrelevant.
Nee, want 0.1f is een float en 1.0/10.0 is een double. Daar 0.1 niet exact representeerbaar is zijn die twee dingen dus niet gelijk aan elkaar, door het simpele feit dat 1.0/10.0 meer significante cijfers heeft dan 0.1f. Als je 0.1 bedoelde dan zijn ze wél gelijk aan elkaar.Dido schreef op donderdag 06 januari 2011 @ 17:56:
[...]
1/2 was een verkeerd voorbeeld. Neem eens 1/10
is 0.1f gelijk aan 1.0/10.0?
Idem.En aan (2.0/5.0)/4.0?
Een goed voorbeeld was geweest: 20.0 * 0.3 != 20.0 * 3.0 / 10.0
Het idee is dat je de espilon af laat hangen van de orde van grootte en significantie van de input. 1e-10 is voor berekeningen met de orde van grootte van 1e100 of 1e-100 compleet nutteloos. Wat dat betreft geeft eps*abs(a+b) een beter resultaat, met 'eps' die correleert aan de significantie van je input (bijvoorbeeld 1e-5 bij 4 significante cijfers)zonoskar schreef op donderdag 06 januari 2011 @ 17:02:
[...]
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 bool compare_double_equal( double a, double b, double crit) { equal = TRUE; if (fabs(a-b) > crit) { equal = FALSE; } return equal; } if (compare_double_equal( 0.5, 1.0/2.0, 1e-10) { /* TDB */ }
Zo doe ik het altijd.
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ik was niet nauwkeurig genoeg, alle getallen waren als floats bedoeld. En dan zal uit 1/10 nog wel 0.1f komen, maar bij complexere berekeningen zou ik er niet te hard vanuitgaan dat float x gelijk is aan float y, zelfs als volgens de wiskunde x=y..oisyn schreef op donderdag 06 januari 2011 @ 18:33:
Nee, want 0.1f is een float en 1.0/10.0 is een double. Daar 0.1 niet exact representeerbaar is zijn die twee dingen dus niet gelijk aan elkaar, door het simpele feit dat 1.0/10.0 meer significante cijfers heeft dan 0.1f. Als je 0.1 bedoelde dan zijn ze wél gelijk aan elkaar.
Maar je hebt gelijk, als je gaat sorteren maakt het niet uit.
Ik kan je zonder te testen zeggen dat 1.0/10.0 en (2.0/5.0)/4.0 en 0.1 aan elkaar gelijk zijn, maar 0.1 is noch als float noch als double representabel, terwijl ik het specifiek over representabele waarden had.Dido schreef op donderdag 06 januari 2011 @ 17:56:
is 0.1f gelijk aan 1.0/10.0? En aan (2.0/5.0)/4.0?
Je voorbeeld onderschrijft mijn punt: dat je in bepaalde gevallen wél heel precies kunt zeggen wat het resultaat van een berekening is. Ik ageer tegen het fatalisme van programmeurs die niet begrijpen hoe floating point arithmetic werkt en er dus maar vanuit gaan dat floating point berekeningen of zelfs vergelijkingen om de een of andere reden altijd fuzzy of onbetrouwbaar zijn. Dát is onzin.
Floating point getallen zijn gewoon harde, exacte getallen, die een eindige deelverzameling van de reële getallen vormen en dus ook geordend zijn en aan elkaar gelijk kunnen zijn (en daarnaast zijn er nog wat speciale waarden als infinities en NaNs, die buiten de reële getallenlijn vallen).
Vertel dat de mensen die JavaScript en Lua verzonnen hebben.Zolang je je beperkt tot gehele getallen hoef je niet met floats te klooien, lijkt me?
Ik zie niet direct waar je aan refereert, maar ik ontken sowieso niet dat de beperkte precisie van floats in sommige gevallen problemen kan geven. Maar het feit dat de correcte werking van allerlei standaardoperatoren heel strict gedefinieerd is, is juist de reden dat er überhaupt over de stabiliteit van numerieke algoritmen geredeneerd kan worden.Hier staat onderaan de pagina een mooi voorbeeldje van een algoritme waarin x + 1 significant betere resultaten oplevert dan x - 1 in een equivalent algoritme
Ik doe vaak zoiets, met een constante epsilon:.oisyn schreef op donderdag 06 januari 2011 @ 18:33:
Het idee is dat je de espilon af laat hangen van de orde van grootte en significantie van de input.
C:
1
| abs(a - b) < eps || abs((a - b)/(a + b)) < eps |
Daarmee check je of het absolute óf relatieve verschil klein genoeg is, zodat getallen heel dicht bij 0 ook gelijk aan 0 zijn. Denormals worden vrij zinloos dan (die comparen allemaal gelijk aan elkaar en aan nul) maar vaak is dat gewenst.
Als je vaak dit soort vergelijkingen doet is het waarschijnlijk zinniger om code te verzinnen die een dure deling vermijdt.
[ Voor 14% gewijzigd door Soultaker op 06-01-2011 20:35 ]
Ik moet leren hier exacter te formuleren.oisyn schreef op donderdag 06 januari 2011 @ 18:33:
[...]
Dat kan per definitie nooit voorkomen. Wat je nu beweert is dat een float een waarde kan hebben die nooit equal zal comparen met een andere float. Afgezien van NaN's kan dat helemaal niet voorkomen - als de ene float die waarde heeft, kan de andere float ook die waarde hebben, en zal a==b gewoon true opleveren.
Uiteraard kunnen (en zullen) 2 floats die equal zijn gewoon true opleveren.
Dat bovenstaande functie een orderfunctie is zal ik ook niet ontkennen. Neemt niet weg dat ik in de praktijk de toepassing nog moet tegenkomen waarbij een compare tussen 2 floats alleen true zou moeten opleveren bij een exacte match.
Dat is echter een aanname en daarom kan mijn opmerking bij deze snippet inderdaad als irrelevant worden aangemerkt.
Waarom dat gedeelte vóór de ||Soultaker schreef op donderdag 06 januari 2011 @ 20:14:
Ik doe vaak zoiets, met een constante epsilon:
C:
1 abs(a - b) < eps || abs((a - b)/(a + b)) < eps
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Het eerste deel is zodat waarden vlakbij nul ook als nul geïnterpreteerd worden. Of je dat wil hangt wellicht af van je toepassing, maar als ik ergens tussendoor iets berekend heb als 12*0.1 - 1.2 wil ik dat dat gewoon als gelijk aan nul beschouwd wordt, maar (a - 0)/(a + 0) = 1, hoe groot of klein a ook is.
(Sowieso heeft de deling in het geval van twee nullen een ongedefinieerd resultaat; nog een reden om de vermenigvuldiging te prefereren, wat sowieso al een goed idee was.)
(Sowieso heeft de deling in het geval van twee nullen een ongedefinieerd resultaat; nog een reden om de vermenigvuldiging te prefereren, wat sowieso al een goed idee was.)
[ Voor 3% gewijzigd door Soultaker op 06-01-2011 23:41 ]
code:
1
2
3
4
5
6
| beschrijvingWatFunctieDoet() { <stuk code nr1> stringWaarde = !bool1 && !bool2 ? "hier tekst" : ""; <stuk code nr2> } |
Zover geen rare dingen.
Nu heeft een andere programmeur er een functie bijgemaakt.
code:
1
2
3
4
5
| beschrijvingWatAndereFunctieDoet() { <stuk code nr1> <stuk code nr2> } |
Voeg dan een bool toe aan de functie aanroep die je aan die !bool1 && !bool2 toevoegd en eventueel nog de functie zonder die extra bool behouden die dan alleen die met bool aanroept met de default waarde in plaats van een functie erbij maken die precies hetzelfde doet en dus bij een eventuele bug fix niet vergeten mag worden.



486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22
Ik snap hem ook niet helemaal... maar euhm
Voeg dan gewoon interpunctie toe aan het stuk tekst die je aan de zinnen toevoegt...Voeg dan een bool toe aan de functie aanroep die je aan die !bool1 && !bool2 toevoegd en eventueel nog de functie zonder die extra bool behouden die dan alleen die met bool aanroept met de default waarde in plaats van een functie erbij maken die precies hetzelfde doet en dus bij een eventuele bug fix niet vergeten mag worden.
[ Voor 0% gewijzigd door Webgnome op 14-01-2011 19:31 . Reden: typo... ]
Verwijderd
Altijd leuk als je aan het einde van een groepsproject voor de eindbespreking de code nog eens doorspit en dan dit soort dingen tegenkomt:
Blijkbaar gebruiken we deze methode niet, want de spelersnelheid vertoont geen bugs ingame. Het zou er i.i.g. zo uit moeten zien:
Java:
1
2
3
4
5
6
7
8
9
10
11
| public void setSpeed(int x, int z) { if(maze.maze[x][z] == 9) { setSpeed(NORMAL_SPEED); } else { setSpeed(NORMAL_SPEED); } } |
Blijkbaar gebruiken we deze methode niet, want de spelersnelheid vertoont geen bugs ingame. Het zou er i.i.g. zo uit moeten zien:
Java:
1
2
3
4
5
6
7
8
9
10
11
| public void setSpeed(int x, int z) { if(maze.maze[x][z] == 9) { setSpeed(SLOW_SPEED); } else { setSpeed(NORMAL_SPEED); } } |
Dat hij toevoegd schrijft betekent niet dat we het allemaal moeten doenWebgnome schreef op vrijdag 14 januari 2011 @ 16:23:
Ik snap hem ook niet helemaal... maar euhm
[...]
Voeg dan gewoon interpunctie toe aan het stuk tekst die je aan de zinnen toevoegd...

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
Blijft een slecht voorbeeld door het magic number 9Verwijderd schreef op vrijdag 14 januari 2011 @ 16:41:
Altijd leuk als je aan het einde van een groepsproject voor de eindbespreking de code nog eens doorspit en dan dit soort dingen tegenkomt:
Java:
1 2 3 4 5 6 7 8 9 10 11 public void setSpeed(int x, int z) { if(maze.maze[x][z] == 9) { setSpeed(NORMAL_SPEED); } else { setSpeed(NORMAL_SPEED); } }
Blijkbaar gebruiken we deze methode niet, want de spelersnelheid vertoont geen bugs ingame. Het zou er i.i.g. zo uit moeten zien:
Java:
1 2 3 4 5 6 7 8 9 10 11 public void setSpeed(int x, int z) { if(maze.maze[x][z] == 9) { setSpeed(SLOW_SPEED); } else { setSpeed(NORMAL_SPEED); } }
Battle.net - Jandev#2601 / XBOX: VriesDeJ
Wat bedoel je hier precies mee?Jan_V schreef op vrijdag 14 januari 2011 @ 17:55:
[...]
Blijft een slecht voorbeeld door het magic number 9
Dat je die 9 beter kan vervangen door een constante. Niet iedereen zal direct de betekenis herkennen van de 9, terwijl dat voor een constante als SLOW_TILE wel is.
¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸
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.