Programistyczne WTF jakie Was spotkały

Odpowiedz Nowy wątek
2009-04-03 11:31
rnd
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-04 00:14
13
Optional.ofNullable(costam).orElse(null)

Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
typ zwracany z metody: List - danek 2019-04-04 00:18
Kumulacja :-) - jarekr000000 2019-04-04 00:19
Jest Optional? Jest. Jest wykorzystane nowe API? Jest. 10/10 - TomRiddle 2019-05-02 15:41

Pozostało 580 znaków

2019-04-13 22:25
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
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
5

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ęć: 272
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
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.
Za to w Finlandii pewnie wklejaja polski kod jako WTF :) - WhiteLightning 2019-05-04 19:11
Ale tam to jest prawdziwa publiczna kopalnia takiego kodu: https://github.com/Opetushallitus :] Ciekawe czy da się gdzieś znaleźć kod naszego USOSwebu? - Wibowit 2019-05-04 19:15
osobna klasa na "invalid" todistus (cokolwiek to znaczy) to chyba obiektowe przekombinowanie... nie wystarczyłby todistus z suoritusem i arvosanatem, ale z errorsami albo bez? ;-) /disclaimer: nie znam Scali/ - Azarien 2019-05-05 00:55
Nie, bo dzięki osobnej klasie możesz łatwo robić match po typie. Oraz nie przekażesz omyłkowo InvalidTodistus w miejsce, gdzie potrzebny jest dobry Todistus. Wow, czytam fiński kod! To nie takie trudne :) - Krolik 2019-05-06 18:01
Jak widać Finowie nie mają kompleksów. W odróżnieniu niektórych wyznawców angielszczyzny z niniejszego forum :> - Freja Draco 2019-05-07 14:38

Pozostało 580 znaków

2019-05-07 12:08
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
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
0

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
1

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

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
4

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

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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