Sa ma fut in politete

Posted in Regula 0 on September 18th, 2013 by Mihnea

retard-baby2Cum pula mea s-a ajuns sa fie mai important sa fii politicos decit sa stii despre ce vorbesti?

Este o chestie pe care o tot vad pe forumuri, liste de discutii etc. Sa-i spunem sindromul Marius Bancila. Vine un prost – sa-i spunem Silviu Ardelean – si emite o timpenie. Ii arati ca-i prost si-l rogi sa nu mai posteze imbecilitati. Apare un moderator – sa-i spunem tot Marius Bancila, ca sa rimeze cu sindromul – si te avertizeaza sa nu-i mai spui lui Silviu Ardelean sa-si tina gura, ca nu-i frumos. CUM SLOBOZ BA? In loc sa-i spuna Silviului ca e inacceptabil sa vorbesti timpenii (sau sa-l baneze direct), Mariusul e preocupat de mentinerea atmosferei de voie buna si cooperare tovaraseasca. Ca si retardatii e oameni, si are si ei inteligenta lor emotionala, nu?

Da, stiu. Daca iti antagonizezi interlocutorul, comunicarea se duce pulii, asa ca daca vrei sa fii constructiv trebuie s-o iei cu frumosul. Problema cu aceasta regula de cacat este ca presupune existenta unui interlocutor. Eu nu vorbeam de cazurile in care cineva greseste pur si simplu si il corectezi, ci de situatiile in care e implicat un Silviu, unde e evident de la inceput ca n-ai cu cine sa discuti. Presupusul interlocutor e atit de prost incit nu numai ca nu poate, dar nici nu vrea sa inteleaga argumentele pe care le aduci. In mod normal, Mariusul ar trebui sa-i stearga aberatiile. Daca n-o face, ceilalti participanti la discutie au obligatia morala de a face misto de retardat, pentru a se asigura ca viitorii cititori ai thread-ului nu sint indusi in eroare. Eu asa vad lucrurile.

Dar sa lasam numele generice si sa trecem la un exemplu practic. Un domn de la Valve a propus ca VC++ sa dea warning-uri cind dai parametri aiurea la functii care accepta format string-uri, asa cum fac deja diverse alte compilatoare. VC++ da si el warning-uri d-astea, dar doar cind ii dai cu /analyze, ceea ce dureaza inacceptabil de mult IRL. Validarea asta nu e costisitoare (dupa cum ne dicteaza atit bunul simt, cit si faptul ca nu incetineste semnificativ compilarea acolo unde e implementata deja), deci ar putea fi mutata din analizorul static in compilator.

In acest moment se amesteca in discutie Silviul de serviciu, cu numele de scena UnitUniverse, care nu vrea ca compilatorul sa faca “special process” pentru printf, care e o functie ordinara. Fiind foarte prost, el este de parere ca problema reala sta in faptul ca printf foloseste “extractie binara” si “masti binare” pentru a extrage parametrii, deci compilatorul n-are ce face. Ca si Silviul real, este preocupat de noile cuceriri ale tehnicii in materie de generat code bloat si incetinit compilatorul, asa ca face si el o Propunere: sa inlocuim printf cu template-uri variadice (sigur, nu inainte de a inlocui enumurile cu vectori).

Imboldit iar de spiritul civic, am considerat ca-i datoria mea sa-i spun boului ca nu e vorba de printf, ci de un mecanism pentru marcat format string-urile ca sa le poata verifica compilatorul. Care mecanism exista deja in VC++ sub forma macro-ului _Printf_format_string_. Ce a inteles retardatul (care stapineste limba lui Shakespeares la fel de bine ca omologul sau din Valea Jiului):

Yes, providen switchers to enable the detecting is an considerable idea. But, as i written previously, the printf extracting tail arguments with binary cutters, I’m doubt if they could implement such kind of checking mechanism.

I-au zis doi oameni ca e facut. I-am zis si cum e facut si i-am dat si link la cum fac alte compilatoare. De aici, el a concluzionat ca nu se poate face din cauza “taietoarelor binare”. In pula mea.

I-am raspuns ca nu stiu ce-s alea binary cutters si ca-s convins ca nici el nu stie, dar ca indiferent de ce crede el, mecanismul exista deja si trebuie doar mutat din analizor in compilator. De asemenea i-am recomandat sa nu-si mai dea cu parerea in probleme pe care nu le stapineste. Nu i-am zis sa nu-si mai dea IN PULA MEA cu parerea. I-am zis fara mui si puli. Rezultatul a fost ca s-a autosesizat Mariusul local si mi-a sters comentariul.

Lasind la o parte faptul ca-i urez cancer militianului care a facut asta, doresc sa insist un pic asupra unui model de comportament (ca nu pot sa-i spun gindire) ce este des intilnit printre Silvii. Cum ajunge imbecilul sa deduca cu mintea lui ca nu se poate face, dupa ce i-am aratat cum e facut, si i-am dat si link-uri?

Raspunsul e simplu si nesurprinzator: prostia. Silviul porneste cu o Opinie. Desi undeva adinc in fiinta lui licare ideea ca de fapt nu prea stie despre ce e vorba, odata ce-si formeaza si exprima Opinia, vocea interioara este sugrumata si Silviul se lanseaza cu toata forta intru sustinerea Opiniei. Nu conteaza daca ii dai argumente, link-uri sau bucati de cod pe care le-ar putea baga intr-un compilator ca sa verifice ca-i prost. Cind parcurge raspunsul tau, Silviul sare pur si simplu peste partile pe care nu le intelege. Nu le vede. Este un mecanism de aparare: faptul ca nu intelege ceva ar insemna ca e prost. El nu vrea sa fie prost, asa ca lucrurile pe care nu le pricepe trebuie sa fie irelevante. De la irelevant la inexistent este un pas foarte mic, pe care intelectul sau de batracian cu trisomie il face fara ezitare.

Pentru a vedea cum percepe un Silviu o discutie, iti poti sterge toate argumentele. Textul ramas pare o simpla Opinie. Aha! Silviul are si el o Opinie. De ce ar fi Opinia ta mai buna decit Opinia lui?

Revenind: e OK ca intr-o discutie despre compilatoare pe MSDN sa spui ca printf foloseste taietoare binare pentru extras argumente, dar nu e OK sa ii recomanzi unui bou sa nu vorbeasca despre lucruri pe care nu le intelege. Idiocracy.

PS: tag-urile pentru acest post s-au scris practic singure. Le-am luat direct de la ultimul post de pe blogul de atitudine al minerului.

PPS (adica post-post-scriptum, Ovidiu): in curind e ziua de nastere a minerului si i-am pregatit o surpriza.

EDIT: multumim Pintea:

yPuhX91

Tags: , , , , , , , , ,

Cele doua fete ale tirnacopului

Posted in Regula 0 on July 16th, 2011 by Mihnea

As vrea sa facem un exercitiu de imaginatie: inchipuiti-va Liceul de Informatica din Hunedoara intr-o dimineata de vara tirzie, la sfirsitul lui August 1999. E vacanta si liceul ar trebui sa fie pustiu, dar azi nu e, pentru ca a inceput a doua sesiune de bacalaureat. Alegeti o materie la intimplare – sa spunem informatica (merge si romana). Intrati cu ochiul mintii intr-una din salile de clasa si umpleti-va plaminii cu atmosfera de examen: susoteli, fituici, profesori care scriu rezolvarile pe tabla, elevi care se duc la celelalte sali sa vada daca acolo “s-a rezolvat subiectul 2”. Un singur om sta aplecat asupra foii sale, concentrat, superior, sclipitor, dar vizibil deranjat de forfota din jurul sau. Toti incearca sa copieze de la el, iar lui ii este din ce in ce mai greu sa ignore aceste agresiuni. Acest om este Silviu Ardelean.

Silviu se jura ca asa a fost. Saptamina trecuta a fost Sarbatoarea Bacalaureatului in Calendarul Datatorilor Cu Parerea si nu putea sa lipseasca tocmai el de la festivitati, asa ca a tinut sa-si proclame admiratia fata de camerele lui Funeriu si “adevarul, normalitatea, lucrurile frumoase, realitatea” pe care acestea le-au adus in viata romanilor. Noi am avea totusi niste obiectii…

La doar patru zile dupa ce l-a batut incurajator pe spate pe Funeriu, Silviu a decis ca a sosit timpul pentru a pune inca o data umarul la progresul programarologiei, asa ca a publicat un tratat despre functia _chkstk(). Articolul incepe in felul urmator:

A process starts with a fixed stack space. The top of a stack is pointed to by the ESP register (Extended Stack Pointer) and this is a decrementing pointer.

E ceva dubios aici, nu? Exprimarea curata, informatiile corecte, mentionarea cuvintului “registru” – toate acestea ii dau cititorului fidel un sentiment de alienare si-l fac sa verifice textul din address bar. Am intrat cumva din greseala pe o alta pagina? Nu, adresa e corecta, deci citim mai departe:

This is in contrast with the heap that can theoretically grow to a limit of 4 GB.

This is in contrast with“? Pe bune, dupa “electric power manufacture base on water“, “I’m acting into a C++ Romanian programming community” si “it depends on your’s algorithmic intellection, cleverness“? Ajuns aici am simtit nevoia sa-l intreb pe Google ce parere are despre alfabetizarea subita a lui Silviu, iar el mi-a raspuns fara sa pregete cu acest link de la codeguru. Pai ce facem Silviu? Iar copiem? Iar ne inspiram? Ce-ar fi sa punem niste camere d-alea de supraveghere si la calculatorul tau, pentru ca “rigoarea inpusă în această sesiune de examene să fie un nou început”? (“Inpusa”, mai gunoiule?)

Sigur, articolul nu e copy/paste in intregime. Putem determina unde incep contributiile originale ale minerului urmarind momentele in care fata gramaticii se intuneca brusc:

If you have an infinite recursion then you will gate same stack overflow error

I have started the study of _chkstk() function in the moment when I got few bugs with crashes with some similarly details.

I stopped to some trace function calls and I studied deeply.

Observam ca lucrarea minerului se incheie cu o lista de referinte, din care lipseste insa tocmai thread-ul de pe codeguru din care s-a inspirat. Deci:

Incheiem cu cuvintele directoarei liceului unde zice Silviu ca au copiat altii dupa el (si nu ne putem abtine sa ne intrebam cit de prosti erau aia):

Un mare filosof spunea că numai prin educaţie se poate asigura dominaţia minţii peste întuneric. Educaţia de care au avut parte atâtea generaţii care au trecut pragul acestei şcoli a însemnat colaborare, comunicare şi dialog, a asigurat elevilor libertatea să se întrebe şi să ne întrebe.

Sau, mai direct, cum cintau rapsozii aventurile lui Silviu in Piata Universitatii:

Minerul isi construieste singur cerul.
Minerul din mici lampase lucitoare isi face luna, stele, soare la fel ca si un vrajitor.
Minerul c-o mana poate s-atinga cerul
Si poate-n noapte-ntotdeauna s-aprinda stelele si luna.

Tags: , , , , , , , , , , , , , , ,

Pe urmele lui Silviu Ardelean

Posted in Codare cu premeditare, Premiul n00bel on April 1st, 2011 by jos8cal

LE3: Am mutat filmele la noi. Viva la Revolucion!

LE2: Gingerul Pop si-a facut private orgiile cu XCode. S-a saturat de lumea mirsava si rea care nu-i intelege invataturile despre curentul C++, asa ca i-a intors spatele pentru a nu mai putea fi la curent cu ultimele pozitii in C++. Speram ca urmatorul pas sa fie cel in care isi sterge blogul dupa care filmeaza o Introducere in Sinucidere.

LE: In timp ce echipa de suflet a lui Silviu Ardelean incerca in etapa a 23-a sa-i dapaseasca IQ-ul in Liga 1, chiar la el acasa, si pe programatorul Pop l-a trecut un Silviu Ardelean si si-a transhumat orgiile de pe youtube pe vimeo, asa ca ne-am conformat si noi si am tras apa prin link-uri.

Marius Pop trece prin momente grele de carierist in pix, tastatura, if, while, for, pointeri, matrici, limba romana, limba engleza, youtube, paypal si nu in ultimul rind 100m chitara garduri. Si-a pierdut increderea in sine si a decis ca e timpul sa riste totul, sa traiasca viata pe cont propriu asa ca a renuntat sa mai ceara donatii pe blog in schimbul muncii cinstite, blog care in acest scop i-ar fi servit si de mama si de tata, nu doar de amanta.

Faptul ca a riscat totul a inceput sa dea roade. A inceput Corectarea Posturilor, sport marketat pe piata de catre Silviu Ardelean inca din 2007. E un fel de curling, doar ca aruncatorul pietrei este acelasi cu cel care da cu mopu` in urma bilei, pentru a i se pierde urma. Iata o aruncare facuta dupa manualul Ardelean, editie revizuita:

ps. am avut o eroare datorită tastaturii mele care merge când și cum vrea iar o altă eroare că am scris codul inafara funcției main, asta din neatenție

Observati logica Ardeleana de a mopa aruncarea dezastruoasa. Aparent faptul ca tastatura s-a saturat de tine si nu te mai lasa sa o bati are un efect direct asupra limbii romane, engleze si C++.

Si iata si o aruncare in limba engleza demna de o Olimpiada Ardeleana:

Since I was a kid, I like strategies games. My (geek) cousin made me addicted to Heroes III, about 10 years ago. Since than, Heroes III is my favorite game. I played Heroes IV but it’s not the same thing. That Heroes III feeling is gone in greater versions.

Disclamer: Citate date din manualul Federatiei Internationale de Corectat Posturi (FICP) 2007-2011.

 

 

Tags: , , , , , , , , , , , , , , , , , , , , , , , , ,

Internetul, memoria si Ardeleanul

Posted in Premiul n00bel, Regula 0 on March 7th, 2011 by Mihnea

Azi e o zi importanta pentru Silviu Virgula Ardelean: in sfirsit a gasit un articol care explica pe intelesul sau ce-i cu pointerii si cu memoria. Surescitat de descoperirea sa, expertul ce duce-n spate nu mai putin de 9 ani de tras la saiba C++-ului si-a aruncat tirnacopul in zare, sa stie toata lumea:

A nice and simple tutorial of “C/C++ Memory Corruption and Memory Leaks”: http://bit.ly/jWwEd

Vreau sa subliniez “pe intelesul sau”. Articolul nu e in nici un caz pe intelesul oricui, ci doar al lui Silviu, asa cum discutiile intre doi boschetari beti nu-s pe intelesul oamenilor de rind. Sa spicuim:

char *oldString = "Old String";
char newStrig = strdup(oldString);
if(newString == ENOMEM) ... // Fail!!!!

...

free(newString);

Nu-i asa ca aveti un deja-vu? Cod care nu se compileaza, pentru ca “omul nu are un compilator in cap”, si pentru ca “tutorialele nu-s facute sa iei cu copy/paste din ele”? Bifat. Autor care e asa de prost incit crede ca malloc() returneaza ENOMEM cind nu mai are de unde da, dar posteaza totusi tutoriale pe net? Bifat. Utilizarea limbii lui Shakespeares pentru a ne asigura ca mesajul de pace si incompetenta este inteles si de oamenii din “India, Africa de Sud, Columbia, Rusia, etc”?

Memory allocated by copy constructors for pointer duplication. Check in destructor and delete if necessary. Memory allocated in passing class by value which invokes copy constructor.

Bifat.

Numarul de ineptii din articolul respectiv este aproximativ egal cu numarul de propozitii (doar daca socotim drept propozitii si enunturile alea fara predicat, altfel ineptiile cistiga), dar n-o sa stau acum sa fac analiza pe text. Mai interesant ar fi de aflat cum si de ce a ajuns minerul sa-si gaseasca sufletul-pereche in persoana acestui Greg Ippolito. “Cum” e simplu: a scris in google free memory tutorial si a dat pe primul link. “De ce” are legatura cu site-ul asta si cu utilizatorii sai.

Acum ceva vreme, minerul a postat un articol in care ataca spinoasa problema a convertirii numerelor in string-uri. La momentul creatiei l-am sarit pentru ca nu ni s-a parut ca ar avea suficient potential umoristic, dar un cititor fidel ne-a urecheat ca n-am semnalat faptul ca Silviu punea destructori virtuali in niste clase goale, ca un automaton constiincios ce este. Sigur pe textele invatate pe de rost de prin surse dubioase, Silviu (care, tineti minte, nu se ascunde dupa nick-uri pentru ca are singe in instalatie) a venit deghizat in Coco si a lasat urmatorul comentariu veninos:

Coco Says:
January 26th, 2011 at 4:32 pm
@thefatredguy: prima data trebuie sa scrie un FAQ special pentru tine despre destructori virtuali.

Dupa risetele ce au urmat, el si-a inmuiat intrucitva pozitia:

Coco Says:
January 26th, 2011 at 4:58 pm
Discutia cu destructor virtual / nevirtual e cu dus-intors oricum ai intoarce-o. Voie buna!

Vazind totusi ca voia buna nu inceteaza, a dat fuga la articol si a scos destructorii aia virtuali, ca nu se stie. A ramas totusi cu un ghimpe, ca n-a inteles de ce i-a scos, asa cum n-a inteles nici de ce i-a pus. Neintelegind ca e atit de prost incit nu va intelege niciodata, el a continuat sa caute raspunsuri sub forma de tutoriale si asa a dat peste Greg.

Un om de calibrul lui Silviu, care isi recunoaste greselile, nu putea dormi noaptea fara a scorni o justificare pentru faptul ca orice spune se dovedeste a fi gresit. El e un suflet nobil si mare, care vede dincolo de corecturi. Atita timp cit Adevarul iese la iveala, pe Silviu nu-l intereseaza cum se ajunge la asta. Cum ne-a obisnuit, minerul iar da cu tirnacopul in peretele gresit, crezind ca noi ne luam de el pentru ca isi corecteaza post-urile, asa ca ma voi preface ca incerc sa-l indrept pe calea cea buna, inainte sa-si darime abatajul in cap.

Nu, draga Silviule. Noi nu ridem de tine pentru ca iti corectezi scrierile, ci pentru ca trebuie s-o faci. Tot ce scrii este gresit si tu nu vrei sa vezi in asta un semn al incompetentei colosale care-ti caracterizeaza existenta. Post-urile tale ar trebui sa-i avertizeze pe cititori sa nu ia nimic de bun pina nu apare articolul corespunzator la noi pe site. Daca vrei, facem noi plug-in-uri de wordpress si phpbb care afiseaza un disclaimer in ce postezi si adauga automat link-ul catre noi in momentul in care publicam corecturile. Visez la ziua in care vei putea imprumuta de la cineva un sfert de creier si vei putea vedea ironia faptului ca ai invatat despre pointeri, constructori si destructori de la un idiot ca tine, care nu stie despre ce vorbeste, dar totusi vorbeste. Tu, in prostia ta, ai preluat prostia lui si o dai mai departe altora. Daca Fibonacci ar fi trait azi, i-ar fi dat pulii de iepuri si ar fi studiat pe tine rata de crestere a prostiei pe internet.

Sigur, incercarile acestea de a-l face pe Silviu un ortac mai bun sint nascute moarte. Un intelept ne-a lasat mai demult pe failbook urmatorul mesaj, ce ilustreaza cu mare concizie si absoluta precizie imposibilitatea comunicarii cu minerul-programator:

Cand Silviu-Marius Ardelean greseste si incerci sa ii spui, sunt trei variante:

1. Faci misto si nu se prinde;
2. Ii spui discret si nu intelege;
3. Ii spui direct si nu te crede.

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Mineriada de la pagina 5

Posted in Premiul n00bel, Stand-up philosophy on March 3rd, 2011 by jos8cal

Citeodata unele afirmatii ma bintuie! Intrebarile sau raspunsurile ma plictisesc, dar afirmatiile ma ustura pe creier. De ceva vreme tot dau cu nidoflor pe urmatoarea afirmatie, care chipurile ar explica poza de mai sus:

Dupa cum se poate observa, la câte aberaţii spun, sunt “ignorat” de întreaga audienţă.

Afirmatia apartine protagonistului pozei, adica Silviu Virgula Ardelean si ar deslusi misterul paralelismului dintre masa si membrul superior. Dar eu nu pricep! Nu inteleg ce face Silviu acolo de atrage privirea intregii crisme.

Asa ca ma aplec spre domniile voastre, stimati trei cititori, (who touched me?) si va chestionez cu privire la ce credeti ca se intimpla sau discuta in poza aia? Pentru spiritele artistice, accept si poze explicatorii, ca nu-i asa, pina si Lumea a inceput cu unii privind la altii explicind poze pe pereti.

Cele mai bune explicatii sau poze isi vor urma propriul destin!

Tags: , , , , , , , ,

Purely Fabricated Interview Expert Pattern

Posted in Slagare internationale, Stand-up philosophy on February 21st, 2011 by Mihnea

Am aflat de la Andrei Ignat ca Scott Hanselman a publicat o noua lista de intrebari de interviu pentru programatori. Cred ca Hanselman asta e un fel de Ovidiu Cucu international, ca vad ca tot publica liste d-astea. Ca orice programator care se respecta, si eu sint constient ca pot deveni somer peste noapte, deci fac eforturi mari sa ma tin la curent cu ultimele evolutii in domeniul intrebarilor de interviu. Atasez mai jos raspunsurile mele la intrebarile lui, pentru cei 3 cititori din totalul nostru de 5 care nu sint membri pe programare.org. Scuzati limba lu’ Shakespeares, am zis sa nu break character.

What is SOLID?

YABA.

Why are patterns important?

Patterns are important because people who cannot program must be able to project importance by wielding pompous words.

Who are the Gang of Four? Why should you care?

The Gang of Four, also known as The Alpha Wankers, are four non-programmers who understood what power words are and applied the concept to programming. I care because Aurelian Popa told me that today it is more important to be “social” than to know how to program, and using pretentious jargon like “singleton” instead of “global variable” is a guaranteed way of improving one’s social status. They are not to be confused with the Wang-Zhang-Jiang-Yao group, whose name they borrowed in a spectacularly ill-advised stab at self-irony.

Explain the concept of Separation of Concerns and it’s pros and cons.

Separation of Concerns means that when you concern yourself too much with design patterns, you can stop being concerned about grammar. No man can understand the singleton pattern AND remember the basic rules of languages with immensely complex grammars such as English, so once you embrace the teachings of the Gang of Four, grammar becomes Somebody Else’s Concern. The first sign of this transcendence is putting an apostrophe in the possessive pronoun “its”.

Discuss the concept of YAGNI and explain something you did recently that adhered to this practice.

YAGNI is something YAGN, as it’s related to XP.

Are you still writing code? Do you love it?

No, I’m too busy calling my global variables singletons and speaking at conferences about it.

What do you do to stay abreast of the latest technologies and tools?

Hahaha you said breast!

How do you react to people criticizing your code/documents?

I punch them, fire them and/or write inflammatory posts about them on forums or blogs.

Whose blogs or podcasts do you follow? Do you blog or podcast?

Are blogs and podcasts design patterns? Never heard of them. Anyway, I like the color fuchsia, I am an open-minded person focused on self-improvement and my hobbies include hiking, music, reading and taxidermy. I hope this helps you determine if I’m a good programmer or not.

What is the last programming book you read?

I only ever read one, “Design Patterns”. I memorized every word. I don’t need to know anything else.

What’s so great about <cool web technology of the day>?

<generic answer>

How can you stop your DBA from making off with a list of your users’ passwords?

I didn’t know such sexual deviationism is so common among DBAs and anyway, why is that my problem instead of HR’s? Oh wait, you said “making off”, not “making out”. My bad.

What do you do when you get stuck with a problem you can’t solve?

The Design Patterns book is a complete list of solutions which are just waiting for problems. Unenlightened people approach programming the wrong way: they see problems and look for solutions. I use the sure-fire method of picking solutions from The Book and inventing problems for them. That way, I’m never stuck. Any feature or system which cannot be implemented in this way is ill-defined and not worth my concern in the first place. See also the “Separation of Concern” principle.

What’s the difference between a web server, web farm and web garden?

Wait, what? Web garden?

When do you know your code is ready for production?

When I have at least 157 design patterns in it.

What’s YAGNI? Is this list of questions an example?

Didn’t you ask this already?

Noile mele cuvinte favorite: Information Expert (a nu se confunda cu Code Expert), Pure Fabrication, Protected Variations.

LE (adica Later Edit, Ovidiu): hahahaha am aflat ce-i ala web garden. Redefinirea cuvintelor limbii engleze, in pula mea.

LLE: GoF au incercat sa si cinte la un moment dat. Punk, pentru ca si la muzica se pricep la fel de bine ca la programare. Iata-i aici prezentind pattern-ul “Old Grey Whistle Test”:

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,