Programistyczne WTF jakie Was spotkały

Odpowiedz Nowy wątek
rnd
2009-04-03 11:31
rnd

Rejestracja: 12 lat temu

Ostatnio: 8 lat temu

11

Dziś w pracy moim oczom ukazała się klasa na 30k linijek. W jednym pliku.
Jeszcze jestem w szoku :-D
A jakie Wy mieliście WTF?


#define TRUE FALSE
//Happy debugging suckers :D
edytowany 2x, ostatnio: Demonical Monk, 2011-12-04 00:47

Pozostało 580 znaków

2019-04-13 22:25

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

1

A ja dzisiaj chyba te kontrole straciłem :D Wyszukane w sieci niby standardowe ogłoszenie o pracę. Widać wymagania wśród rekruterów rosną
titlescreenshot-20190413222722.png

edytowany 1x, ostatnio: Sadik, 2019-04-13 22:28
kolega, mojego kolegi, który zajmuje się marketingiem internetowym, gdy opowiedział rekruterom czym się zajmuje usłyszał, że takie coś to oni se zautyomatyzujęąi niech wyp***. - Julian_ 2019-04-15 05:01

Pozostało 580 znaków

2019-04-23 09:43

Rejestracja: 1 rok temu

Ostatnio: 8 miesięcy temu

5

Ręcznie rzeźbione frameworki do walidacji zawsze dostarczają uciechy.

Dla dobra poszkodowanych, zmieniłem niektóre nazwy:

Condition.fromPredicate(
  new IfTrueCondition(jesliWybrano(ABC) || jesliWybrano(XYZ))
   .and(
     new NotNullCondition<>(encja.getKupa().getKupa2())
   )
)

Tam są polskie nazwy.

Jeśli myślicie, że IfTrueCondition, albo Condition reprezentują funkcję która odracza wykonanie lub inny trik z programowania funkcyjnego, to nie rozumiecie tego kodu. Te konstruktory pobierają booleana, żeby mieć fluent interfejs z metodą .and(). Zarówno Condition, jak i Predicate robią to samo - są alternatywą dla Booleana, natomiast nie są ze sobą kompatybilne. WTF.

Dzięki temu mamy nowy, bardziej enterprise, język programowania, gdzie zamiast (jesliWybrano(ABC) || jesliWybrano(XYZ)) && encja.getKupa().getKupa2() != null możemy wytworzyć ten piękny "bardziej czytelny" kod.

Widać, że programista nie dostosował się do obowiązującego wzorca: bo użył new IfTrueCondition(a || b) zamiast new OrCondition(a, b).

Tego typu frameworki widziałem już z 3 razy. Wydaje mi się, że oryginalnym problemem autorów było sprawdzenie wielu rzeczy na raz nie przerywając sprawdzania przy pierwszym błędzie. Rozwiązanie to notification pattern, a nie pakowanie wszystkich konstrukcji języka w obiekty.

Pierwsze słyszę o notification pattern :D Zawsze myślałem że to po prostu zdrowy rozsądek a nie pattern haha. No i współczuję ... - orchowskia 2019-04-24 09:57
@orchowskia: a czy patterny to nie zdrowy rozsądek? :) - WeiXiao 2019-05-04 02:20
@WeiXiao: owszem, ale czasami mam wrażenie, że każdy programista chce mieć swój pattern, albo coś tam driven bo fajnie brzmi. Widziałem już nawet takie coś jak puzzle driven. Nie mówię że nie mają sensu, ale nikomu nie wciśniesz do głowy dobrych praktyk, bo ten ktoś będzie wciskał patterny a nie praktyki co nie do końca jest zbieżne ze zdrowym rozsądkiem... - orchowskia 2019-05-04 10:14

Pozostało 580 znaków

2019-05-03 11:14

Rejestracja: 9 lat temu

Ostatnio: 13 godzin temu

6

Kiedy chcesz uchodzić za poważny bank, a testujesz na produkcji. Złożyłem wniosek o lokatę, dostałem takiego maila. Bank w polskim top15 co do wielkości.

  • bank.png (0.03 MB) - ściągnięć: 643
BOŚ bank + zwyczajnie skopane kodowanie znaków, nic więcej. Niekoniecznie wina testu na produkcji. Prędzej innej konfiguracji jakiegoś Stage od produkcji. - dzek69 2019-05-03 12:33
W każdym razie już zmieniłem zdanie, nie chcę lokaty u nich, jeśli o moje pieniądze mają dbać tak jak o swoje mailingi.. - okmanek 2019-05-03 16:52
Ale po co zakładać lokatę w banku, który prawie nie oferuje odsetek? - somekind 2019-05-03 18:33
Bieda obecnie z lokatami, ale 2,5% to przynajmniej minimalnie powyżej inflacji (pomijam podatek Belki). Zawsze lepiej niż trzymać na koncie 0%. Jakoś czuję dyskomfort gdy moje pieniądze są zjadane przez inflację i wolę wpłacać je na lokaty. - okmanek 2019-05-03 20:50
A, dobra, faktycznie mają coś na 2,5%, wtedy widziałem coś na 1,5%. Dla porównania kilka dni temu założyłem lokatę na 4%, no ale nie w BOŚ. - somekind 2019-05-04 01:23

Pozostało 580 znaków

2019-05-04 17:10

Rejestracja: 15 lat temu

Ostatnio: 1 godzina temu

8

Fińsko-angielski kod w Scali: https://github.com/Opetushallitus/hakurekisteri

package fi.vm.sade.hakurekisteri.oppija

import fi.vm.sade.hakurekisteri.{Oids, Config}
import fi.vm.sade.hakurekisteri.rest.support.Resource
import fi.vm.sade.hakurekisteri.opiskelija.Opiskelija
import fi.vm.sade.hakurekisteri.storage.Identified
import fi.vm.sade.hakurekisteri.suoritus.Suoritus
import fi.vm.sade.hakurekisteri.arvosana.Arvosana
import fi.vm.sade.hakurekisteri.opiskeluoikeus.Opiskeluoikeus

case class Oppija(oppijanumero: String,
                  opiskelu: Seq[Opiskelija],
                  suoritukset: Seq[Todistus],
                  opiskeluoikeudet: Seq[Opiskeluoikeus],
                  ensikertalainen: Option[Boolean]) extends Resource[String, Oppija] with Identified[String] {

  override val id = oppijanumero

  override def identify(identity: String): Oppija with Identified[String] = this
  override val source = Oids.ophOrganisaatioOid

  def newId = oppijanumero

  override val core: AnyRef = oppijanumero
}

case class Todistus(suoritus: Suoritus, arvosanat: Seq[Arvosana])

case class InvalidTodistus(suoritus: Suoritus, arvosanat: Seq[Arvosana], errors: Seq[String])

object InvalidTodistus {

  def apply(todistus: Todistus, errors: Seq[String]): InvalidTodistus = InvalidTodistus(todistus.suoritus, todistus.arvosanat, errors)

}

"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
Pokaż pozostałe 23 komentarze
@Azarien: +1. @Lubię Naleśniki z Dżemem: nie pamiętam takiej konwencji, ale skoro tak mówisz, to widać jest; w sumie każdy pies Ci przytaknie, że nie jest fałszem, tylko prawdą. - Silv 2019-06-10 15:23
Parafrazując @maszynaz: new Pies().getPies() :] - Wibowit 2019-06-10 15:24
PiesFactory.getFactory().createPies() - Azarien 2019-06-10 15:38
@Azarien: Co ty? Sam się pies nie zrobi. PiesFactory.getFactory().createPies(pies1, pies2) - PerlMonk 2019-06-10 15:40
@Lubię Naleśniki z Dżemem: +1. - Silv 2019-06-10 15:42

Pozostało 580 znaków

2019-05-07 12:08

Rejestracja: 9 lat temu

Ostatnio: 1 godzina temu

1

Postanowilem sobie poradzic z niedzialajcym updatem security Win 7, bo sprowadzalo sie to do tego, ze prawie kazde wlaczenie wymagalo kilku rebootow (tzn proba instalacji aktualizacji, reset, blad aktualizacji, reset, wycofywanie zmian itd. ) Bylo to dodatkowo uperdliwe ze wzgledu na dual boot.

Co sie okazalo? Windows nie radzil sobie z tym, ze mam dual boota i partycja windowsa nie byla ustawiona jako aktywna (Grub sobie z tym radzil i wszystko startowalo).
Kilka godzin szukania. Ustawienie partycji jako aktywna i wszystko dziala.

A mozna to bylo zalatwic w minute usuwajac windowsa :D - stivens 2019-05-07 12:58
Windows w ogóle się popsuł pod tym względem. Kiedyś (za czasów XP) jak w boot.ini było że ma startować z partycji tej to startował. A teraz jak z jajkiem: pod Linuxem przesuniesz partycję, albo przekopiujesz na większy dysk przy okazji zmieniając rozmiar - kupa, Windows 10 już nie wystartuje bo coś mu się zmieniło. I teraz szukaj/wypalaj płytkę/nagrywaj pena z Windowsem żeby dostać się do opcji naprawiania systemu. Nie wiem od czego to dokładnie zależy, ale już kilka razy miałem podobną sytuację. - Azarien 2019-05-07 19:25

Pozostało 580 znaków

2019-05-10 11:45

Rejestracja: 2 lata temu

Ostatnio: 1 godzina temu

1
HR::after

Działa różnie na różnych przeglądarkach, a nawet różnie na różnych wersjach Chroma, z czego w tych nowszych nie działa :P
Problemy z elementarnym CSS? Nadal? W 2019?


edytowany 1x, ostatnio: Freja Draco, 2019-05-10 11:46
Pokaż pozostałe 15 komentarzy
I działa tak jak u mnie. :P - Silv 2019-05-11 14:19
Ta druga strona pozwala zobaczyć wygląd dokumentu na różnych przeglądarkach. HR height potrzebowałam, bo one miały się układać jeden pod drugim, tworzą wykres słupkowy, ale już bez znaczenia - poszło na DIV-ach. - Freja Draco 2019-05-11 14:28
@Freja Draco: dzięki, teraz skojarzyłem. :) Ale te style, które poradziłem Ci usunąć, są ważne? - Silv 2019-05-11 14:33
Rozumiem, cóż poradzić. Dobrze, że umiesz sobie radzić bez stresu (mam nadzieję). :) - Silv 2019-05-11 14:37

Pozostało 580 znaków

2019-05-20 12:30

Rejestracja: 2 lata temu

Ostatnio: 1 godzina temu

1

importowany.js

function test() {
  document.getElementById("txt").value += "Poprawnie zaimportowano skrypt JS\n";
}

importujący.js

var skrypt_js = document.createElement("script");
skrypt_js.src = "importowany.js";
document.head.appendChild(skrypt_js);

skrypt_js.addEventListener("load", test);

Pod FF działa to normalnie, natomiast w Chrome wyskakuje:
import_JS.htm:35 Uncaught ReferenceError: test is not defined
Ale jak zrobię:

skrypt_js.addEventListener("load", funkcja_wywołująca_funkcję_test);
To już działa.

Czyli co? Podczas wystąpienia zdarzenia load elementu, element ten nie jest jeszcze załadowany? Czy może jest załadowany ale jeszcze nie sparsowany? Czy o co kaman?


Najwyraźniej Chrome domyślnie wczytuje wszystkie takie skrypty asynchronicznie (co ma sporo sensu, ponieważ nie blokuje to wykonywania innych JSów w trakcie ładowania skryptów). A że skrypt_js.addEventListener("load", test); zakłada, że element test istnieje zanim wykona się całe wczytywanie (w innym wypadku jaką wartość miałoby mieć test? Skąd przeglądarka miałaby widzieć, że to coś znajdującego się w skrypcie, skoro jeszcze go nie wczytało?) - no to się wykrzacza. - Patryk27 2019-05-20 12:36
Wyłącz cache i/albo dodaj throttling sieciowy. test musi być ewaluowany do wartości już w momencie wywołania addEventListener. W tym momencie test najpewniej nie ma wartości/referencji, chyba, że załadowanie i sparsowanie skryptu nastąpi zanim wywołasz addEventListener (i to najpewniej zdarza się w FF, masz importowany.js w cache i on jest ładowany natychamiast po appendChild). Funkcja jest zdefinionwaną wartością, więc zadziała zawsze. - dzek69 2019-05-20 12:39

Pozostało 580 znaków

2019-05-20 13:25
Moderator

Rejestracja: 13 lat temu

Ostatnio: 1 tydzień temu

Lokalizacja: Stacktrace

2

Zmiana technologii z Javy na Elixira nie spowodowała zmniejszenia ilości ciekawego kodu w projekcie. Po prostu sam go teraz więcej produkuję.

Mamy taki kod:

def update(conn, %{settings: settings}, %{user_id: id, platform_id: platform_id}) do
    user = User.get!(id)

    with {:ok, user} <- User.update_settings(user, settings),
         {:ok, platform} <- Platforms.get_platform(platform_id),
         {:ok, _} <- is_binary(settings[:password]) |> Service.queue_password_changed_email(user, platform)
      do
        render(conn, "show.json", user: user)
    end
  end

Jeżeli użytkownik zmienił hasło, to wyślij email. Niestety jest w tym kodzie mały babol, bo jeżeli użytkownik jest tworzony „za zaproszeniem”, to już w momencie wysłania maila z zaproszeniem tworzymy użytkownika i później, jak się rejestruje, to dostaje maila z informacją o zmianie hasła. Zatem zmieniam na:

  def update(conn, %{settings: settings}, %{user_id: id, platform_id: platform_id}) do
    user = User.get!(id)
    is_password_not_nil = !is_nil(user.encrypted_password)
    with {:ok, user} <- User.update_settings(user, settings),
         {:ok, platform} <- Platforms.get_platform(platform_id)
      do
      if (is_binary(settings[:password])) do
          Service.queue_password_changed_email(is_password_not_nil, user, platform)
      end
      render(conn, "show.json", user: user)
    end
  end

ale nie przechodzi CR, bo choć działa, to warunek w if jest rozbity na if-a i pierwszy, opcjonalny, parametr funkcji kolejkującej. W dodatku jakieś dodatkowe zmienne i w ogóle nie po elixirowemu. Zmieniam:

  def update(conn, %{settings: settings}, %{user_id: id, platform_id: platform_id}) do
    user = User.get!(id)

    with {:ok, user} <- User.update_settings(user, settings),
         {:ok, platform} <- Platforms.get_platform(platform_id)
      do
      if (!is_nil(user.encrypted_password) && is_binary(settings[:password])) do
          Service.queue_password_changed_email(user, platform)
      end
      render(conn, "show.json", user: user)
    end
  end

Przestało działać. noszkurwaface.jpg Debugger i jedziemy. Wchodzi w if-a, nawet jak pierwszy warunek jest false. Po chwili olśnienie:

  def update(conn, %{settings: settings}, %{user_id: id, platform_id: platform_id}) do
    user = User.get!(id)
    is_password_not_nil = !is_nil(user.encrypted_password)
    with {:ok, user} <- User.update_settings(user, settings),
         {:ok, platform} <- Platforms.get_platform(platform_id)
      do
      if (is_password_not_nil and is_binary(settings[:password])) do
          Service.queue_password_changed_email(user, platform)
      end
      render(conn, "show.json", user: user)
    end
  end

Elixir ma dwa rodzaje operatorów logicznych. Normalne tzn. && || itd. oraz „dla pascalowców” and, or, not. Te pierwsze przyjmą wszystko, a te drugie tylko wartości true i false. Rzecz w tym, że te pierwsze pozwalają na porównanie różnych typów i czasami wychodzą „głupoty”. Jednak jest tu cudowniejszy babol. W trzecim przypadku błąd powrócił, ponieważ sprawdzenie, czy zaszyfrowane hasło istnieje, odbywało się po zapisie do bazy danych. Uroki używania with :D


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
Akurat tutaj różnica między && oraz and nie powinna nic zmienić bo jedyna różnica to taka, że akceptuje jeszcze nil jako wartość fałszywą. Ogólnie można to zmienić na user.encrypted_password || settings[:password] zgodnie z DeMorganem (ale wtedy trzeba użyć || a nie or). - hauleth 2019-05-20 13:37
@hauleth: ale zauważ, że w with masz zapis do bazy User.update_settings, który powoduje, że user zmienia stan. - Koziołek 2019-05-20 14:13
No tak, ale zawsze można nie przesłaniać zmiennej user i osiągnąć ten sam wynik. Trochę przyzwyczajenia z Erlanga ;) - hauleth 2019-05-20 14:14

Pozostało 580 znaków

2019-05-20 14:08

Rejestracja: 6 lat temu

Ostatnio: 4 godziny temu

4

Ktoś z tymi aktualizacjami w M$ trochę przegiął.
screenshot-20190520140722.png

ile ty masz ramu xD? ze tylko 62% zuzycia a ja tu widze jakies 40 GB ? - Akihito 2019-06-05 20:25
O___o grubo, mógłbyś pół bloku obdarować ;-) Uchylisz rąbka tajemnicy do czego używasz takiej ilości pamięci? Jakiś konkretny projekt/program czy tak po prostu "by było"? - Marooned 2019-06-10 12:31
@Marooned: Pewnie to projekt "wszystkie hentaie do RAMu". - PerlMonk 2019-06-10 12:35
@Marooned: To jest serwer ML350 więc nici z rozdawania. Mam na nim kilka VMek. I w zależności jaki projekt to sobie odpalam inną. Do tego testowe środowiska win od 95 do 10. Bardzo przydatne gdy trzeba równocześnie mieć linuxa i winde włączone i kilka innych. - hzmzp 2019-06-10 13:02
Ok, czyli w sumie obdzielasz, ale wirtualki ;-) - Marooned 2019-06-10 13:04

Pozostało 580 znaków

2019-05-22 14:15

Rejestracja: 2 lata temu

Ostatnio: 1 godzina temu

1

Google znowu "ulepszył" wygląd swojej strony:

Google - głupie ikonki

W miejsce, gdzie od 20 lat było czytelne menu tekstowe, wpierdzielił ikonki, które:

  • zabierają skąpą tutaj przestrzeń użytkową,
  • są niespójne, bo pierwsza kolorowa, a pozostałe szarobure,
  • jak dla mnie, wszystkie te szarobure ikony niczego nie ułatwiają, bo trzeba się w nie wgapiać, żeby zobaczyć, co tam w ogóle nagryzmolili, a w omawianym przypadku wręcz zaciemniają spójną wcześniej listę.

Pominę już fakt, że Google stara się wiedzieć lepiej ode mnie czego szukam, w związku z czym kolejność i obecność takich pozycji jak "grafika" czy "mapy" bywa tu często (z mojego punktu widzenia) zwyczajnie losowa.

I niech mi ktoś jeszcze raz powie, że tak ma być, bo to duża firma zrobiła, a duże firmy wiedzą, co robią :P


edytowany 1x, ostatnio: Freja Draco, 2019-05-22 14:47
Pokaż pozostałe 13 komentarzy
@Azarien: Osobiście w lokalnym CSS mam ustawione filtry usuwające część takich bzdur: tabel sportowych, karuzel obrazków itp. Kiedyś, jak wpisałam "korona" i na pierwszej stronie miałam praktycznie baner reklamowy domu towarowego na pół ekranu, a drugie pół baner jakiejś drużyny sportowej, co to nawet nie wiedziałam wcześniej, że istnieje, to się wkurzyłam i napisałam filtry. - Freja Draco 2019-05-22 20:03
@V-2: chodzi Ci o wygląd gmaila? nadal możesz używać "starego" - WeiXiao 2019-05-22 20:23
@Freja Draco: twórcze takie wkurzenie. ;) - Silv 2019-05-22 22:24
https://4programmers.net/uploads/attachment/5c/5cfe31dc7f087.png u mnie nadal po staremu, ale przyznam rację, że bardzo wkurzające jest zamienianie kolejności (albo w ogóle usuwanie opcji) w tym menu.. często nie ma np. grafiki dla danego zapytania i muszę wracać na główną, klikać 'grafika' w prawym górnym roku i od nowa wklejać zapytania.. wtf - Marooned 2019-06-10 12:34
@Marooned: u mnie też po staremu, ale jakiś czas temu pamiętam, że wyglądało inaczej, tylko nie pamiętam, czy na tym systemie. - Silv 2019-06-10 13:42

Pozostało 580 znaków

Odpowiedz

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