Programistyczne WTF jakie Was spotkały

1

@msm, @ShookTea, a co powiecie na to:

$array = (array) json_decode('{"12":"1"}');

var_dump($array);

// array(1) {
//   "12" =>
//   string(1) "1"
// }


var_dump(array_key_exists("12", $array)); // false
1
$array2 = array("12" => "1");
var_dump($array2);
var_dump(array_key_exists("12", $array2));

To z kolei zwraca:

array(1) {
  [12]=>
  string(1) "1"
}
bool(true)

To się już robi dziwne, ale jestem blisko powodu: json_decode() coś psuje.

6

Label248.

5

Krótki wpis @Azarien powyżej przypomniał mi jak wyglądał nasz support/devop w pewnym bankowym projekcie. By to lepiej zrozumieć należy wiedzieć, że tego typu usługi kupuje się w Indiach „na masę”. Firma zgłasza zapotrzebowanie do dostawcy, a ten ma już ustalone wszelkie protokoły, regulaminy, plany. Efektywnie sprowadza się to do utworzenia dużej liczby kont użytkowników dla pracowników dostawcy na bazie arkusza w excelu.

Nasz dostawca operował w regionie gdzie miejscowy „J. Kowalski”, nazywał się „A. Gupta”. Przy czym „A” było zarówno od imion męskich jak i żeńskich. Zatem niczym niezwykłym było, że rozmawiałeś z delikwentem podpisującym się agupta154. Jednak nie to było niezwykłe. Wysoka rotacja u dostawcy powodowała, że nie opłacało się zakładać nowych kont. Z jednego konta korzystali pracownicy na różnych zmianach. Było to łatwe do namierzenia, bo każdy z nich pisał w swój sposób (ulubione konstrukcje językowe, słowa, błędy).

Jednego jednak nie można im było odmówić. Reset serwera trwał tylko godzinę :)

15

Tytuł JIRA:
"User is not able to register if server IP address given in any different language other than english"

Tester wpisał do apki coś takiego: १३५.६०.८४.२४४:5061

6

W aplikacji Instagram na iPhone w filtrach mamy "Shadows" i "Highlights". Polska wersja? "Cienie" i "Najważniejsze wydarzenia" :D

1

Zgłoszenie błędu:

Unexpected Exception with duplicated DocId. needs better error handling (see attached log)

1
$call = array();
$notes = array();
$next = array();
$meeting = array();
$task = array();
$email = array();

foreach ($_POST as $key => $value) {
    if ($key[0] == 'c') {//call
        $new_key = substr($key, 5, strlen($key) - 5);
        $call[$new_key] = $value;
    }
    if ($key[1] == 'o') {//notes
        $new_key = substr($key, 6, strlen($key) - 6);
        $notes[$new_key] = $value;
    }
    if ($key[1] == 'e') {//next
        $new_key = substr($key, 5, strlen($key) - 5);
        $next[$new_key] = $value;
    }
    if ($key[0] == 'm') {//meeting
        $new_key = substr($key, 8, strlen($key) - 8);
        $meeting[$new_key] = $value;
    }
    if ($key[0] == 't') {//task
        $new_key = substr($key, 5, strlen($key) - 5);
        $task[$new_key] = $value;
    }
    if ($key[0] == 'i') { //email - zaczyna sie od index_ z powodu takiej nazwy kontrolera
        $new_key = substr($key, 6, strlen($key) - 6);
        $email[$new_key] = $value;
    }
}
2

Jak zamienić liczbę w część ułamkową po jedności w Ruby? Otóż pewni francuzi myślą, że tak:

eval("1.#{precision}")

Dodam tylko, że precision to parametr funkcji, już nawet nie miałem siły sprawdzić czy jest on gdziekolwiek pobierany od użytkownika.

2
std::wstring s;
s.resize(size);
memcpy(&*s.begin(), szStr, size*2)

Przez kawałek czasu miałem rozkminę czy to się na pewno nie wypier*oli w jakichś skrajnych sytuacjach. Cały kod można zapisać tak:

std::wstring s(szStr, size);
8

Wejdźcie sobie na http://smyk.pl - przekierowuje z automatu na:
dc0ea67711.png
:D

(w sumie to nie wiem czy to bardziej humor, czy wtf, także wrzucam tutaj.)

0

W pewnym systemie odziedziczonym po anglikach trzeba ręcznie odpalać updaty na bazie dla numerów kart otrzymanych plaintekstem, ale z szumem, bo ten tekt zawiera też inne dane.

Numerów może być dużo, a update się tylko numerem różni więc postanowiłem napisać prosty skrypt wyłuskujący z danego tekstu bez określonego schematu numery kart i robiący te updaty.

Okazuje się jednak, że numer karty jest Varcharem(24), i w bazie faktycznie poza numerami w stylu 6275980153133061195 są też numery tekstowe mające 10 znaków, więc znalezienie ich w bloku tekstu jest problematyczne.

9

anuluj.png

4

Oczom moim właśnie się ukazało coś takiego (wewnątrz metody na pięćset cztery linijki):

                        switch ((ContactType) contactType)
                        {
                            case ContactType.Email:
                                notifyAction = NotifyActions.Email;
                                break;
                            default:
                                notifyAction = NotifyActions.Email;
                                break;
                        }
2

Mimo mojej chęci pokazania tego kodu mogę to tylko opisać.
Singleton z okresowo 3 instancjami.
Tj. singleton tworzył dodatkowo instancję by stworzyć nową instancję i nadpisać na starą instancję za pomocą tej pośredniej - straciłem ponad tydzień by zrozumieć ten master piece kodowania...
Jak mój manager dowiedział się jaki kod przejeliśmy od orłów z za granicy (ich rodak) witki mu opadły ...

3

PHP, klasa na 1.6k linii służąca do zarządzania produktami w systemie (taki god object), gdzie 3/4 metod nazwanych jest w stylu temp_moveProduct, tak jak gdyby autor chciał zasugerować, że "ta metoda to tak tylko na chwilę".

Wszystkie one są oczywiście publiczne, robią w cholerę rzeczy i w większości przypadków okraszone są jedynie PHPDocem w stylu Dodawanie produktu (dla metody o nazwie temp_insertProductsData to naprawdę bardzo pomocne).

Coby nie być gołosłownym, oto screenshot z paska przewijania w PhpStormie ukazujący skalę problemu:1b90b4241c.png
(odwróciłem go o 90 stopni - normalnie jest oczywiście pionowy)

Biały kolor - literówki, pomniejsze złe praktyki programistyczne (typu ręcznie wklepana tablica mająca ponad 40 elementów ( :) )).
Czerwony - potencjalne błędy związane ze złym typowaniem (wina przede wszystkim braku PHPDoców), odwołanie przez dereferencję do klasy statycznej etc.

I, cholera, to działa od kilku lat!

1
  public DataTable dbQuery(string queryString)
        {
            SqlDataAdapter dataAdapter = new SqlDataAdapter();
            DataTable dataTable = new DataTable();

            dbConnection = new SqlConnection(connectionString);
            dbConnection.Open();

            try
            {
                dataAdapter.SelectCommand = new SqlCommand(queryString, dbConnection);
                dataAdapter.SelectCommand.CommandTimeout = 120;
                dataAdapter.Fill(dataTable);
                dataAdapter.Dispose();
                return dataTable;
            }
            catch (Exception)
            {
                return null;
            }
            finally
            {
                dbConnection.Close();
                dataTable.Dispose();
                dataTable = null;
            }
        }

w całym programie jest ok. 30 catchy i wszystkie puste.. pomijając fakt, że Open() jest przed blokiem try i wywala gdzieś wyżej :S

1

Jeden z naszyc klientow poprosil nas o wsparcie w realizowanym projekcie bo deadline sie zblizal (1 miesiac na zamkniecie projektu) i sie lekko nie wyrabiaja.. pomijam fakt ze to co zostalismy to rozpizdziel taki jakby projekt dopiero startowal (trwal rok).. no ale coz...

Na obecnej produkcji klienta spotkalam funkcje, ktora JEST uzywana do przpisywania wartosci pewnej zmennej globalnej na uzytkownika .. a wewnatrz tej funkcji taki kwiatek :

for(var i = 0; i < jakastablica.length; i++);
/*
{
   jakies przypisanie    jakastablca[i] 
}
*/
if(jakas_tablica[0] != null) {
zmienna_docelowa = jakas_tablica[0];
} else {
zmienna_docelowa = jakas_tablica[1];
}

To chodzilo na produkcji... pisane przez jak to okreslil nasz klient "SENIOR DEVELOPPERA" bo tam pracuja TYLKO SENIOR DEVELOPPERZY

7
$isFinished = $webapi->finishItem($auctionNumber);

if ($isFinished) {
	zwróć sukces
} else {
	zwróć błont
}

Jest to luźno przytoczony fragment z kodu kontrolera, który odbiera id aukcji i zakańcza (wyłącza) ją na Allegro (bo na przykład już nie opłaca się sprzedawać danego produktu).

Dzisiaj dostałem informację, że od ósmej rano próbują zakończyć jakąś aukcję, lecz nie daje ona za wygraną i w dalszym ciągu wisi aktywna.
Patrzę tak na ten kawałek kodu i patrzę... no skoro allegro zwraca, że aukcja zostaje zakończona, lecz faktycznie jej nie zakańcza, to problem po ich stronie.

Ale, coby być pewnym, zerknąłem jeszcze na kod metody finishItem (klasa, której instancja znajduje się w zmiennej webapi, to proxy między interfejsem SOAP od Allegro, a naszym kodem).

public function finishItem($item) {
	$this->_client->doFinishItem([
		'sessionHandle' => $this->_session['sesid'],
		'finishItemId' => (float)$item
	]);
	
	return true;
}

Bezwarunkowe optymistyczne return true; :) (doFinishItem to już soapowa metoda, która nie rzuca wyjątku, a zwraca wynik działania)

15

Edukowanie waszych przyszłych konkurentów w ramach szkolnictwa wyższego wygląda obecnie następująco:

(kod w Javie, przepisany żywcem z tablicy)
Mamy klasę Data, która przechowuje datę (no wai!) w postaci trzech intów:

class Data {
    private int dd;
    private int mm;
    private int rr;

    public Data() {
        dd = 28;
        mm = 10;
        rr = 2016;
    }

    public Data(int d, int m, int r) {
        dd = d;
        mm = m;
        rr = r;
    }

Na razie spoko. To teraz zróbmy metodę, która wykrywa, czy dany rok jest przestępny.

boolean czyRokPrzest(int r) {
    if (((r%4==0)&&(r%100!=0))||(r%400==0)){
        return true;    
    }
    else {
        return false;
    }
}

Yyyyy... ok. Nie jest źle. Nie mam co prawda pojęcia, czemu podajemy rok jako argument, skoro metoda jest częścią obiektu i może sobie pobrać. Ani czemu zwyczajnie nie zwrócimy warunku (co później ktoś poprawił). Ani nie zapiszemy krócej jako return r % 100 == 0 ? r % 400 == 0 : r % 4 == 0; Mogło być gorzej, prawda?

Mogło.

Korzystając z wiedzy na temat tego, czy rok jest przestępny, pobierzmy maksymalną liczbę dni w miesiącu.

int ileDniMiesiac(int m, int r) {
    int ld;
    switch(m) {
        case 1: case 3: case 5: case 7: case 8: case 10: case 12: ld = 31; break;
        case 4: case 6: case 9: case 11: ld = 30; break;
        case 2: czyRokPrzest(r) ? ld = 28 : ld = 29; break;
        default: ld = 0; break;
    }
    return ld;
}

Aha.
Pomijając pewne drobiazgi, jak zapisywanie wartości w zmiennej i zwracanie na koniec (prowadzący powiedział, że tak, jak jest teraz, będzie prościej i łatwiej czytać. Aha.), albo bezsensowny default z break, zastanawia mnie jedna rzecz: czy w linijce z case 2 nie będzie błąd? Tu akurat naprawdę pytanie do was, bo chwilowo nie mam dostępu do kompilatora, żeby sprawdzić. O operator ?: mi chodzi. Na pewno zadziałałoby ld = czyRokPrzest(r) ? 28 : 29, ale czy zapisanie tego w formie takiej, jak jest wyżej, nie wywali błędu?

No i znowu wsadzenie miesiąca i roku w argumentach, bo tak.

Ale po co to wszystko? Żeby sprawdzić, czy data jest poprawna, tj. czy może istnieć. Zostało to zrealizowane w sposób następujący (tak, znowu z wartościami w argumentach):
UWAGA, zachowano oryginalne wcięcia i użycie klamer (a raczej ich brak):

boolean sprawdzDate(int d, int m, int r) {
    if (r > 0)
        if (m > 0 && m <= 12)
            int d1 = ileDniMiesiac(m, r);
            if (d > 0 && d <= d1)
                return true;
    return false;
}

Jakby ktoś nie ogarniał (ja się na to patrzę i nie ogarniam), śpieszę z pomocą i dodam klamry tak, aby można było wczuć się w sytuację z perspektywy biednego kompilatora:

boolean sprawdzDate(int d, int m, int r) {
    if (r > 0) {
        if (m > 0 && m <= 12) {
            int d1 = ileDniMiesiac(m, r);
        }
    }
    if (d > 0 && d <= d1) {
        return true;
    }
    return false;
}

Czyż to nie wygląda pięknie? Ja na miejscu kompilatora z chęcią wywaliłbym wielki czerwony napis, zwłaszcza przy if (d > 0 && d <= d1), gdzie występuje porównanie do nieistniejącej zmiennej.

No dobra, ale pytanie: po co to wszystko? Bo chcemy przy tworzeniu obiektu klasy Data sprawdzać jej poprawność. To po części wyjaśnia, czemu dajemy wartości w argumentach. Dopisujemy więc dodatkowy konstruktor, w którym - jeśli warunek nie zostanie spełniony - wywalimy wyjątek.

public Data(int d, int m, int r) {
    if (sprawdzDate(d, m, r) {
        dd = d;
        mm = m;
        rr = r;
    }
    else
        throw new IllegalArgumentException() {};
}

(niech mi ktoś wyjaśni, po kiego grzyba klamry po konstruktorze wyjątku)

Po czym nagłe olśnienie. Zaraz, zaraz! Dopisaliśmy nowy konstruktor, który ma takie same argumenty, jak starszy!
Co więc trzeba zrobić?
Trzeba wykonać coś, co pan prowadzący określił mianem chwyt programistyczny.
Dorzucił do konstruktora dodatkowy argument, z którego nie korzysta.

public Data(int d, int m, int r, int k) {
    if (sprawdzDate(d, m, r) {
        dd = d;
        mm = m;
        rr = r;
    }
    else
        throw new IllegalArgumentException() {};
}

Na koniec dowiedzieliśmy się, że w ramach porównań dwóch obiektów nie zwraca się typu boolean, tylko int: 0, jeżeli obiekty są równe, 1, jeżeli pierwszy obiekt jest większy od drugiego, -1, jeżeli pierwszy jest mniejszy od drugiego. Postanowiono więc: robimy taką metodę do naszej cudownej klasy. Oczywiście jako argument nie przyjmujemy obiektu Data, tylko trzy liczby określające tę datę.

int ktoraDataWczesniejsza(int d, int m, int r) {
    int a = 0;
    if (rr < r) a = -1;
    else if (rr == r) {
        if (mm < m) a = -1;
        else if (mm == m) {
            if (dd < d) a = -1;
            else if (dd == d) a = 0;
            else a = 1;
        }
        else a = 1;
    }
    else a = 1;
    return a;
}

Kurtyna, temat "Programowanie obiektowe" zakończone sukcesem. Za tydzień tablice. Nie mogę się doczekać.

PS: Jeżeli ktoś nie będzie wykonywał zadań w tego rodzaju sposób, dowie się, że można prościej, zaś użycie w pętli słowa kluczowego return lub - NIE DAJ BOŻE! - break to tragedia. Jeżeli ktoś był na PWrze, to chyba będzie kojarzyć, o kim mowa :P

2
   if(this.SampleCollection.HasElements ){
      this.SampleCollection.each( \ element -> {
        if(element.SecondCollection.HasElements) {
          add.SecondCollection.each( \ secondElement ->{
			
			// Do something here
			
          } )
        }
      })
    }
14
ShookTea napisał(a):

Za tydzień tablice. Nie mogę się doczekać.

Zgodnie z zapowiedzią :)

Robimy sobie klasę Tablica, która według prowadzącego będzie "namiastką tablicy dynamicznej" (choć IMHO to raczej "namiastka listy", wtf, wszystkie tablice w Javie są dynamiczne).

class Tablica {
    int[] t;
    Tablica(int rozm) {
        t = new int[rozm];
    }

    void wypelnij(int max) {
        Random rnd = new Random();
        for (int i = 0; i <= t.length(); i++) {
            t[i] = rnd.nextInt(max);
        }
    }

Co mamy?
Mamy konstruktora
Mamy metodę, która ma wypełnić tablicę losowymi wartościami
Mamy klasę Random, która przez większość grupy jest nieogarniana, bo nie umieją obiektowości
Mamy błąd kompilacji przy t.length()
Mamy ArrayIndexOutOfBoundsException przy i <= t.length()

Lecimy dalej! Metoda, która wyświetli zawartość tabeli.

void wyswietl() {
    for (int i = 0; i < t.length; i++)
    System.out.print(t[i] + " ");
    System.out.println();
}

Zachowane oryginalne wcięcia. Brzydko to wygląda, ale działa!

Teraz zaczyna się robić wesoło. Metoda do szukania wartości w tablicy - zwraca pierwszy indeks, pod którym pokaże się dana wartość, lub -1, jeśli takiej nie będzie.

int znajdz(int w) {
    for (int i = 0; i < t.length; i++) {
        if (t[i] == w) {
            return i;
        }
    }
    return -1;
}

Wydawałoby się, że dobrze, prawda? Prawda, wszystkim się tak wydawało. Z wyjątkiem prowadzącego, dla którego pojawienie się dwóch return (jeszcze w dodatku jeden z nich jest w pętli!) to zbrodnia. Trzeba to naprawić. Żeby było weselej, break też jest nieuznawany i może być użyty TYLKO w switch. Jasne, że break jest brzydki, ale w niektórych, rzadkich przypadkach dobrze go użyć i nie psuje kodu (według tego, co znalazłem na StackOverflow).

Zrobimy więc ładniejszą wersję tej metody.

int znajdz1(int w) {
    int ret = -1;
    for (int i = 0; i < t.length; i++) {
        if (t[i] == w) ret = i;
    }
    return ret;
}

Ten kod realizuje już potrzeby prowadzącego, ale nie realizuje potrzeb zadania. Mieliśmy znaleźć pierwszy indeks, pod którym występuje zmienna, a to zwraca ostatni. Jeszcze gorzej: nawet, jeśli dana liczba jest zaraz na początku tabeli, i tak będziemy iterować do samego końca.

Kolejna wersja!

int znajdz2(int w) {
    int i = 0;
    while (i < t.length && t[i] != w) {
        i++;
    }
    return i < t.length ? i : -1;
}

Teraz już wszyscy są zadowoleni. Pan prowadzący zauważył jednak, że część z nas może nie wiedzieć, jak dokładnie działa operator trójargumentowy i zapisał go obok w ramach przykładu w postaci ifów:

if (i < t.length) {
    return i;
}
return -1;

Po czym uświadomił sobie, że złamał swoją własną zasadę Tylko Jednego Returna i przepisał to jeszcze raz:

int r;
if (i < t.length) {
    r = i;
}
else {
    r = -1;
}
return r;

Pan Robert C. Martin leży i płacze.

Na koniec napisaliśmy dwie metody: do szukania wartości w tablicy posortowanej (mniejsza, że nie robiliśmy sortowania) oraz do usuwania danego elementu, gdzie argumentem nie jest indeks, tylko wartość, a usunąć mamy jej pierwsze wystąpienie, podobnie do ArrayList.remove(Object o). Tych dwóch jednak nie będę przepisywać, bo napisały je na tablicy studentki, które pięknie pokazały swoją siłę i zdolność ogarniania tematu lepiej od prowadzącego.

6

LOL
user image

13

Podstawy Programowania na PWr, lekcja 3.
Tablice wielowymiarowe

Mieliśmy wcześniej klasę tablicy jednowymiarowej Tablica, która wypełniała się losowymi wartościami i tak dalej. Teraz pora na klasę reprezentującą tablicę dwuwymiarową, którą nazwiemy - a jakże! - Tablica2. Tym razem mamy głęboko gdzieś grzeczny podział na konstruktora i uzupełnianie: od razu w konstruktorze walnijmy wypełnianie tablicy losowymi wartościami.

class Tablica2 {
    private int[][] tab;
    
    public Tablica2(int m, int n, int z) {
        tab = new int[w][k];
        Random r = new Random;
        for (int i = 0; i < m; i++) {
            for (int l = 0; l < n; l++) {
                tab[i][l] = r.nextInt(z);
            }   
        }
    }
}

Poza błędem kompilacji przy new Random; raczej wszystko w porządku. Nie podoba mi się tylko użycie małej litery L jako samodzielnej nazwy zmiennej, zbytnio podobne do cyfry 1.

Następnie, tradycyjnie, metoda wyświetlania zawartości tablicy.

wyswietl() {
    for (int i = 0; i < tab.length; i++) {
        for (int l = 0; l < tab[0].length; l++) {
            System.out.print(tab[i][l] + " ");
        }
        System.out.println();
    }
}

Znowu paskudne L, teraz jeszcze brak void przed nazwą metody. Na szczęście ktoś (nie ja, ja dawno przestałem zwracać uwagę na kod na tablicy i go po prostu przepisuję, żeby się nim pochwalić tutaj :P) zwrócił na to uwagę i zostało naprawione.

Teraz najpiękniejsze. Metoda zwracająca największą wartość o nazwie int[] Max(). M wielkie jak ta wartość, ale czemu zwraca tablicę? Bo zgodnie z nazwą metody, metoda Max zwraca największą wartość która nie zmieści się w jednym elemencie wraz z położeniem X i Y w tablicy. Logiczne. Chyba.
Po napisaniu funkcji znaleźliśmy kilkanaście byków, które zostały poprawione na tablicy i funkcja stała się znośna. Przed poprawkami jej pierwsza wersja wyglądała tak: (komentarze moje)

void Max() { //zły typ
    max = tab[0][0]; m = 0; n = 0; //brak typów
    for (int i = 0; i < tab[].length; i++) { //wtf tab[]
        for (int j = 0; j < tab[].length; j++) { //znowu wtf tab[]
            if (tab[i][j] > max) {
                max = tab[i][j];
                m = i;
                n = j;
            }   
        }
        int t2[3]; //dlaczego tu, a nie na zewnątrz pętli? i co to za deklaracja?
        t2[1] = max; //w kimś odezwała się dusza humanisty
        t2[2] = i;
        t2[3] = j; //j nie istnieje
    }
    //nie ma return
}

Następnie chcemy wyliczyć sumę elementów w każdym wierszu i zwrócić jako tablicę jednowymiarową. Robimy to tak:

int[] suma() {
    int[] t2 = new int[tab.length];
    for (int i = 0; i < tab.length; i++) {
        t2[i] = 0;
        for (int j = 0; j < tab[0].length; j++)
            int t2[i] = t2[i] + tab[i][j];}
    return t2;
}

Błąd przy int t2[i] = t2[i] + tab[i][j], powodzenia w szukaniu, gdzie kończą się i zaczynają klamry.

Teraz prowadzący mówi:
Tablice wielowymiarowe już wiecie, jak robić, przyszła pora na tablicę tablic.
Co? To tablice wielowymiarowe nie są de facto tablicami tablic (co widać zwłaszcza przy tablicach nieregularnych)?
Otóż nie. Tablica wielowymiarowa to tablica wielowymiarowa, a tablica tablic to jednowymiarowa tablica obiektów reprezentujących inne tablice.

Mamy więc zrobić klasę reprezentującą tablicę tablic, korzystając z utworzonej powyżej klasy Tablica2. Dla zmyłki nową tablicę nazwiemy Tab.

public class Tab {
    Tablica2[] tab1; //"nie może być samo tab, bo się pomyli z tab w klasie Tablica2"
    public Tab(int elem, int m, int n, int z) {
        tab1 = new Tablica2[elem];
        for (int i = 0; i < elem; i++) {
            tab1[i] = new Tablica2(m, n, z);
        }
    }
    
    public void wyswietl() {
        for (int i = 0; i < tab1.length; i++) {
            tab1[i].wyswietl();
        }
    }
}

Zaraz, zaraz... wszystko działa? Jak to możliwe?
Może dlatego, że zgłosiłem się do tablicy i ten kod powyżej jest mojego autorstwa. Boli mnie trochę, że w metodzie wyswietl nie skorzystałem z pętli foreach, ale:

  • pewnie większość grupy go nie zna i nie będą wiedzieli, o co chodzi
  • z jakiegoś powodu prowadzący nie lubi foreacha równie mocno, jak dwóch returnów i breaków w pętli. Ma być zwykły for i koniec.

Później nagle przeszliśmy na tematy obiektowości (które podobno mieliśmy parę tygodni temu, ciekawe). Zrobiliśmy prostą klasę Osoba, bez żadnych kostruktorów, z dwoma polami: String imie i String nazwisko. Mieliśmy do niej napisać metodę equals.

boolean equals(Osoba x) {
    return imie.equals(x.imie) && nazwisko.equals(x.nazwisko);
}

Boli mnie strasznie, że w argumencie jest Osoba, a nie Object, i że nagle prowadzący uparł się na użycie angielskiej nazwy equals. ArrayListy i inne takie na tym padną. Dobrze chociaż, że użyli String.equals, bo niektórych kusiło porównywanie ==. Szkoda, że nie użył @Override, byłoby weselej.

Na koniec, złota myśl:

Dla obiektów typu String jest zadeklarowana metoda equals. Dla pozostałych obiektów trzeba ją napisać.

1

https://github.com/Microsoft/vscode/commits/master
przeglądam sobie teraz kod/commity programistów/ Visual Studio Code i w szoku jestem jak słabej jakości jest kod. Niestety przykryty jest on grubą warstwą overengineeringu, więc mam wrażenie, że ludzie z Microsoftu pewnie nawet nie wiedzą, że jest on zły (ale niezliczone raporty o bugach i różnego rodzaju regresjach mówią same za siebie - poznasz ich po owocach, sam zgłosiłem niedawno buga, plus parę dodatkowych rzeczy w VSCode mi nie działa, ale nie wiem dlaczego dokładnie, więc tego już nie zgłosiłem, bo nie wiem czy to bug, czy może tak zawiła konfiguracja).

a tak bardziej konkretnie:

  • długie pliki,czasem po tysiąc linijek,
  • kod ten w większości nic nie robi, tylko jest to kod klasy enterprise, czyli kod, który wygląda "mądrze", ale nic nie robi tylko deklaruje ileś klas, metod, interfejsów, które są jedynie wrapperami na inne klasy, metody czy interfejsy.
  • słaby decoupling, jeden plik potrafi importować z 20 różnych modułów
  • ifologia stosowana też się zdarza
  • naruszanie zasady DRY, logika jednej rzeczy jest rozsiana po iluś plikach albo to z nadmiaru warstw/wrapperów albo po prostu z niechlujności.
  • wydaje mi się, że refaktoring jaki wprowadzają w commitach to często zmiany na gorsze pod kątem jakości kodu czy architektury. Zamiast spłacać dług technologiczny, zaciągają go jeszcze bardziej.

etc.

Co ciekawe na poziomie bardziej "z lotu ptaka" to ludzie od VSCode mają parę faktycznie dobrych pomysłów na temat rozwiązań architektury edytora (akurat mnie to interesuje, bo sam zacząłem robić własne IDE niedawno), problem w tym, że jak się schodzi na poziom implementacji to jest kasza. Najpierw myślałem, że to kod jakichś juniorów, ale patrzę, że to jacyś wyjadacze Microsoftowi, może po prostu takie są skutki programowania w korpo zbyt długo.

Cóż, zastanawiam się poważnie czy dalej korzystać z VSCode i być królikiem doświadczalnym Microsoftu czy się przenieść na jakieś Sublime. Albo po prostu doprowadzę swój własny edytor do stanu używalności.

4

agar.png

Patrzcie na górę okienka :]

1

Tragedii ciąg dalszy:

1.png2.png

0

Na rekrutacji napisalem taki kod. Pozniej w domu sprawdzilem ,ze...dziala..:),...ale jest troche dziwny...Pracy nie dostalem

 
class MainClass
	{
		int[] tab;
		public static void swap(int[] tab, int index)
		{
			int temp = tab[index];
			tab[index] = tab[index - 1];
			tab[index - 1] = temp;

		}

		public int[] sort(int[] tab)
		{
			for (int i = 0; i < tab.Length; i++) {
				for (int j = 1; j < tab.Length; j++) {
					if (tab [j] < tab [j - 1]) {

						swap (tab, j);

					}
				}
			}

		    return tab;
		}

		public void print(int[] tab)
		{
			for (int i = 0; i < tab.Length; i++) 
			{
				Console.Write (tab[i] + " ");
			}
			
		}


		public static void Main (string[] args)
		{
			MainClass obj = new MainClass ();
			obj.tab = new int[10]{5, 4, 2, 8, 11, 31, 67, 23, 9, 45};


			obj.print(obj.sort (obj.tab));


			Console.WriteLine ();
			Console.ReadKey ();
		}
	}
0

A o co dokładnie chodzi? Bo to wygląda na klasyczny https://en.wikipedia.org/wiki/Bubble_sort (poza tym że słaby algorytm poza wartościami edukacyjnymi to jeszcze dośc słabo zaimplementowany. No i kto pisze własne sortowania).

Chodzilo o dowolna implementacje sortowania. W pamieci mam tylko sortowanie babelkowe, wiec tak to zrobilem. Startowalem na Junior dev.

0

Ja to tu tylko zostawię...
http://wklej.org/id/2945074/

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