Wątek przeniesiony 2014-02-13 18:14 z Off-Topic przez ŁF.

jednolinijkowce - tak czy nie?

5

Co jest nie tak z tym kodem?

#include <cstdio>
#include <cstring>
using namespace std;

int main()
  {
   unsigned T;
   scanf("%u",&T);
   while(T--)
     {
      static char A[1001],B[1001];
      scanf(" %1000s %1000s",B,A);
      char *a=A;
      for(char *b=B;(*a)&&((b=strchr(b,*a))!=0);++a) ++b;
      printf("%s\n",*a?"Nie":"Tak");
     }
   return 0;
  }

z http://4programmers.net/Forum/Newbie/156914-wyszukiwanie_podciagu_w_danymciagu-_kod_nie_zostaje_zaakceptowany_przez_sedziego_spoj

1) stosuje duże litery do zmiennych
2) zadanie polega na znalezieniu drugiego ciągu w pierwszym (a tu jest odwrotnie - szukamy a w b)
3) rozwiązanie sprowadzone do jednej linijki nie jest ładnym rozwiązaniem - i o tym jest dyskusja w ww wątku
4) w standardzie GNU explicite Richard Stallman pisze żeby takich kodów unikać:

GNU C/C++ Coding Standards, Richard Stallman
(avoid assignments inside if-conditions)
http://www.sourceformat.com/pdf/cpp-coding-standard-gnu.pdf

5) @_13th_Dragon powołuje się na Boost i STL (np. STLPort).
W Boost nie znalazłem ani jednego jednolinijkowego for-a z przypisaniem w warunku pętli.
W STLPort nie szukałem, ale chętnie zobacze jakiegoś.

I pytanie:

  • kto pisze takie kody i jak mu to usprawnia pracę?

Wersja poglądowa, rozpisana dla ludzi którzy nie mają czasu lub ochoty formatować i analizować jednolinijkowców:

#include <cstdio>
#include <cstring>
using namespace std;

int main() {
    unsigned cnt;
    scanf("%u", &cnt);
    while (cnt--) {
        static char atab[1001], btab[1001];
        scanf(" %1000s %1000s", atab, btab);
        char *a = atab;
        char *b = btab;
        while(*b) {
            a = strchr(a, *b);
            if (!a)
                break;
            ++a;
            ++b;
        }
        printf("%s\n", *b ? "Nie" : "Tak");
    }
    return 0;
}

(for zamieniony na while)

3

Lubie czytac posty @_13th_Dragon jezeli uzyje ciekawego algorytmu. Jezeli chodzi o takie zadania, przewaznie omijam posty. Z prostego wzgledu. Szkoda mi czasu na analizowanie dokladnie co tam sie dzieje.
Kazdy ma swoj styl pisania, ja takiego nie popieram, bo z mojego doswiadczenia.
1) dluzej sie analizuje
2) na pierwszy rzut oka NIE widac co to robi
3) gorzej sie utrzymuje.

osobiscie wole drugi kod.

Moge zrozumiec taki kod jezeli chodzi o wydajnosc , nie w innych przypadkach. Takze na SPOJ to jest calkiem dobre rozwiazanie.
A najladniejszy kod dal @Shalom. Ten kod mozna czytac i po 10 sekundach wiadomo o co chodzi w calym programie

nawet @vpiotr owi powiedzialbym zeby tego ifa obsluzyl w {} a zamaist a == 0 wpisac po prostu if (!a). Prinfta rozbic, if trojargumentowy tez nie jest fajny. Kod ma byc taki zeby dalo sie go czytac jak ksiazke. Szybko i wiedziec co dany kawalek kodu robi. Analizowanie kodu po kims dzieki takim zalozeniom jest wielokrotnie krotsze. Jezeli bedzie jakis bug. To bedziemy mogli go szybko odnalezc, gdyz bedziemy wiedziec dokladnie gdzie to moze wystepowac. Wole poprawiac bugi i rozszerzac kod latwo, niz przepisywac wszystko i rozszerzac trudno. Wystepowanie bugow/feature'ow przewaznie zawsze jest taka sama nie zaleznie jak "krotki" bedzie ten kod. A lepiej spedzic nad poprawieniem 4 min niz godzine

0

@_13th_Dragon: twierdziłeś, że Twój kod wzoruje się na K&R (C Programming Language, Brian W. Kernighan, Dennis M. Ritchie).

Cytuję:

"za samo przypisanie w warunku wieszałbym na suchej gałęzi ..."

  • to powinieneś zacząć od D.Ritchie, B.Kernighan poprzez B.Stroustrup'a na autorach współczesnych STL oraz boost'a kończąc.

Just-for-you przejrzałem jeszcze raz K&R.

W całej książce jest jeden for-a z przypisaniem w warunku:

5.2 Wskaźniki i argumenty funkcji (wydanie 2010)

for(*pn = 0; isdigit(c), c = getch())
  *pn = 10 * *pn + (c - '0');

W wydaniu z 1988 widać już lepiej o co chodziło autorom:

for(*pn = 0; c >= '0' && c <= '9'; c = getch())
  *pn = 10 * *pn + c - '0';

Jeśli coś przeoczyłem to i tak większość pętli wygląda tak:

  • for: pętla z inicjalizacją, czystym warunkiem i aktualizacją liczników
  • while: pozostałe pętle, w tym każda z przypisaniem w warunku

Kody K&R nie są specjalnie piękne (np. zmienne "fp", "fd", "nbp") ale i tak są super, jak na język C.
Po prostu mijasz się z prawdą, styl tego programu na pewno nie pochodzi z K&R.
Więc skąd?

0

Nie za bardzo widze co jest zlego w prostym przypisaniu w petli czy ifie, skoro calosc wykonuje sie, sprawdzajac warunek pojedynczej funkcji.
Example: [ http://beej.us/guide/bgnet/ou[...]age/syscalls.html#getaddrinfo ]

if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    exit(1);
}
0

Osobiście nie lubię jednolinijkowców, dla mnie są nieczytelne. Nie mam nic przeciwko prostym przypisywaniom w pętli czy if'ie choć sam tego nie praktykuję.

5

Moim zdaniem programowanie nie polega na napisaniu jak najkrótszego kodu pod względem liczby linijek czy znaków. Czytelność jest jedną z ważniejszych rzeczy, szczególnie, kiedy nad kodem pracuje wielu ludzi albo kod ma być używany przez wielu ludzi. To ostatnie to akurat są rzeczy tak oczywiste i podstawowe, że nie ma w ogóle o czym dyskutować. Taki potwór nigdy nie przejdzie przez normalne code review.

Podsuwanie takich kodów początkującym uważam za bardzo szkodliwe - zniechęca do nauki i uczy bardzo złych nawyków. Miejsce takich kodów jest na IOCCC.

Ten temat ponadto nie ma sensu. _13th_Dragon nie zmieni zdania, ani my nie zmienimy zdania, może zawczasu przenieście to do Flame.

Btw: Już dwa razy pokazywałem, że takie potwory są nie tylko nieczytelne ale też wolniejsze od czytelnego kodu.

0

@Endrju: Chcę się tylko upewnić że nie cyt. "obrosłem w łuski".
Bo może w dobie internetu od kołyski ludzie takie kody wciągają bez zastanowienia a ja tylko dramatyzuje.

13

Kod ma być przejrzysty i wydajny. W sensownie zorganizowanym zespole, w którym robi się review kodu, taki obfuskowany kod (zminifikowany?) zostałby zwrócony.
Nie ma czegoś takiego jak wydajność kosztem czytelności, ponieważ zawsze można napisać kod tak samo wydajny w sposób przejrzysty. Oszczędzanie na nazwach zmiennych, spacjach, enterach, wprowadzanie niestandardowego formatowania - to wszystko zemści się w pierwszym większym projekcie, nad którym trzeba będzie się pracować na tyle długo, że zapomni się o co chodziło w kodzie sprzed kilku miesięcy. A błyskawicznie wróci to w przypadku, kiedy nad projektem będzie pracować kilka osób, już widzę tę kłótnię po kilku pierwszych commitach (chociażby za formatowanie odległe od jakiegokolwiek standardu - vide przytoczony na samym początku wątku kod). No i kogo obchodzi oszczędność kilkunastu cykli procesora, albo nawet dwukrotne przyspieszenie kodu po miesiącu pracy, jeśli serwer jest obciążony w 5%? Optymalizuje się tylko wąskie gardła i to w taki sposób, żeby kod pozostał zrozumiały dla wszystkich.
Zwróćcie też uwagę na to, że programista jest drogi, dlatego powinien być możliwie wydajny. To oznacza, że nie powinien marnować czasu na próbach zrozumienia, co kolega miał na myśli (o ile nie zwolnili do tej pory tego kolegi za kod gównianej jakości - wtedy nawet nie można go spytać "wtf?!"). Z tego powodu też najpierw liczy się czytelność, a dopiero potem wydajność - sprzęt jest zwykle tańszy od programisty, więc można dokupić kolejny serwer, a zresztą słaba wydajność wyjdzie przy automatycznych testach wydajnościowych, a pomyślcie o ile trudniej robi się review takiego zobfuskowanego kodu i o ile trudniej wyłapać niewydajną logikę. To trochę, jakby Polak miał poprawiać błędy gramatyczne Czecha.
Moim zdaniem umiejętność napisania kodu w mniejszej ilości znaków nie świadczy dobrze ani o kompetencjach miękkich, ani twardych programisty.

0

Odwieczny problem - każdy programista ma inne zdanie co jest czytelne a co nie. Dla jednych klamerki w tej samej linijce są bardziej czytelne od klamerek w nowej linijce; jedni wolą Camel Case inni go nie cierpią; niektórzy wolą NULL'a od 0... Tak można by wymieniać. Coding style to idealny temat na marnowanie czasu zarówno prywatnego jak i tego w pracy. Nieraz widziałem code review, które skupiały się tylko i wyłącznie na "błędach" w stylu zamiast na realnych błędach w aplikacji. W sumie mnie to nie dziwi - łatwiej znaleźć "błąd" w stylu niż realnego buga. Do tego można pisać o tym kilometrowe wywody dowodzące swoich racji.
IMHO sprawa jest dosyć prosta:

  1. Jeżeli w projekcie jest ustalony coding style to bez gadania trzeba się go trzymać
  2. Jeżeli w projekcie nie ma ustalonego coding style'u to każdy wybiera styl jaki uważa za czytelny
    Oszczędza czas na jałowe dyskusje.
    Tak na prawdę problemem nie jest to, że ktoś pisze jednolinijkowce lub ich nie pisze. Problemem jest wiara Jeden Czytelny Styl, którego wszyscy powinni używać i zamknięcie się na inne na wszystko inne. Z tym warto by powalczyć.
0

A ja tam lubię jednolinijkowce. Nie ma co tracić czasu na rozbijanie na części prostego algorytmu. Jedna linijka, komentarz - co to robi. Jeśli przeszło unit testy to "fck off! this is my sit!".

A co do podrzucania takiego kodu początkującym. Powinni wiedzieć, że JavaScript z programowaniem ma niewiele wspólnego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0