Programistyczne WTF jakie Was spotkały

3

Czasami wystarczy jedna linijka, żeby było WAT:

const auto b64 = base64::encode(json.str(), true);

Nieważne jaki byłby to język, jaki sens ma kodowanie JSon-a do base64? Co autor miał na myśli? Myślał w ogóle jak to pisał?

By mnie jeszcze bardziej dobić, klasa w której jest ten kwiatek nazywa się: MachineConfiguration

6

Witam na kolejnej lekcji programowania.

  1. Dzisiaj nauczymy się, że kod powinien mieć dokumentację i komentarze
// set title
setTitle(MSG_TITLE);
/**
 *
 * @param fromDate from date.
 * @param toDate to date.
 * @param reportType the report type.
 */
/* domain values */
/**
 * Get quantity domain
 *
 * @return domain DomainKey
 */
public DomainKey getQuantityDomain() {
  return quantityDomain;
}
/**
 * Set quantity domain
 *
 * @param number DomainKey
 */
public void setQuantityDomain(DomainKey quantityDomain) {
  this.quantityDomain = quantityDomain;
}
/* field values */
/**
 * Get quantity
 *
 * @return quantity
 */
public Double getQuantity() throws NumberFormatException {
  return quantityDef.getValue();
}
/**
 * Set quantity
 *

 * @return quantity
 */
public void setQuantity(Double quantity) {
  quantityDef.setPredefinedValue(quantity);
}```

2. Żeby przestrzegać single responsibility prinnciple. (pamiętajmy czego się nauczyliśmy w punkcie 1.)
  • @param string The value
  • @return The value
    */
    public String returnStringValue(String string) {
    return string;
    }

3. Trzeba również dobrze nazywać swoje zmienne

Enumeration<Object[]> enumx = request.getRequests();
Object[] oArray;


*Kwiatki wygrzebane z projektu
5

Bazodanowe WTF z dzisiaj:

Klient zrobił klaster z 3 serwerów ze współczynnikiem replikacji ustawionym na 3 tzn. każda informacja przechowywana w 3 egzemplarzach. Na każdym serwerze miał po 2 katalogi na dane czyli 6 łącznie. Klaster sobie hulał ładnie przez pewien czas, dane się ładnie zapisywały i odczytywały. W pewnym momencie klient doszedł do wniosku, że trzeba uporządkować struktury na dysku i jednak ładniej będzie mieć po jednym katalogu na dane, zamiast dwóch. Usunął więc po jednym katalogu na każdym węźle, zarówno z konfiguracji jak i z dysku. Tzn tak po prostu zalogował się na każdy serwer, usunął 50% danych i zrobił restart. Łącznie miał teraz 3 katalogi. Krótko się cieszył z porządku na dysku, bo jak się możecie spodziewać po tej rekonfiguracji system zaczął rzucać wyjątkami o niedostępności niektórych danych.

Klient zgłosił się do pomocy technicznej, że lecą "jakieś dziwne błędy" :D

Niestety zapomnieliśmy napisać w dokumentacji, że "usuwanie zbyt dużej liczby katalogów z danymi może powodować utratę danych". :D

8
if (environment.IsDevelopment())
      return (I)Activator.CreateInstance(proxyType, configuration);
else
      return (I)Activator.CreateInstance(proxyType, configuration);

Niedawno trafiłem na to we własnym kodzie. Nie pamiętam dlaczego popełniłem takie coś ale chyba jakiś większy refactoring robiłem i tak jakoś wyszło..

8

Dwa tygodnie siedziałem nad modułem komunikacji z jednym z urządzeń które plotło totalne bzdury po RS232C. Aplikacja była deployowana na zdalnego PC kilkaset kilometrów dalej, bo urządzenie było ciut za duże i testowana organoleptycznie. Klient zarzekał się że wszystko jest sprawne i dobrze podłączone.
Po dwóch tygodniach okazało się że facet z labu zamienił przewody - plus z minusem czy jakoś tak. Od tamtej pory działało :)

8

Programowanie w tle. Serwer pod bazę ma 128GB RAMu, to i tak dużo więcej niż potrzebne dla klienta, u którego toczy się akcja. Oddział zamorski firmy wyprodukował jakieś rozwiązanie i zdaje sobie sprawę, że zapytania bazodanowe nie są najwyższych lotów, jeden z zamorskich ziomków pisze "we should have to inform customer that the RAM size can be increased to 1TB"...

edited:
Drobna aktualizacja, po drążeniu tematu. Okazało się, że zapytania są słabe, bo developerzy nie mogą ich zmieniać... bo Hibernate im takie generuje :D

6

W Krakowie wiszą teraz takie plakaty: https://www.smlobzow.pl/?wpfb_dl=503
Sortowanie śmieci spoko, nie mam z tym problemu.
Widzę też Qr Code. Wyciągam telefon i próbuje zeskanować i nic.
Może to przez to, że Qr Code jest na czarnym tle i fragment kodu zlał się z tłem? Nie to nie to.
Ale coś jakiś dziwny ten Qr Code. Standardowe znaczniki jakoś mi nie pasują.
I nagle olśnienie, grafik wstawił Qr code odwracając kolory.
Po odwróceniu kolorów, telefon nie ma problemu z czytaniem Qr code: http://www.mpo.krakow.pl
W sumie adres też jest WTF, bo nie powinien prowadzić do strony głównej, ale jakiś sensownych materiałów na temat sortowania śmieci.

2

Nie do końca programistyczne ale WTF. W naszym oddziale był incydent bezpieczeństwa. Zrobiła się afera na poziomie korpo i teraz poza dodatkowymi szkoleniami dostaliśmy piosenkę o bezpieczeństwie danych. Muzyka Lady Gaga, słowa i wokal autorstwa jednej z dyrektorek z amerykańskiej centrali :D

9

Autentyczna sytuacja z dzisiaj, rekrutacja na stanowisko programisty Java, kandydat z polecenia, spóźniony 30 minut:
Rekrutujący: Wydawało się nam, że byliśmy umówieni na 14:00
Kandydat: Nie, ja umawiałem się na 14:30
R: Z CV wynika, że ma pan doświadczenie w języku C#, dlaczego ubiega się pan o stanowisko programisty Java?
K: Obejrzałem na Youtube filmik "Java Forever" i nie będę więcej programował w C#.
R: Częścią rekrutacji w naszej firmie jest wypełnienie testu
K: Takie testy, to ja rozwiązywałem na studiach. Mówiłem już, że jestem seniorem...

Do tej pory zastanawiamy się, czy facet tak na serio czy przyszedł sobie żarty porobić z okazji Prima Aprilis D:D

16
Optional.ofNullable(costam).orElse(null)
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

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.

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.

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)

}
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.

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?

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?

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

4

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

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

6

ReferenceError: undefinded is not defined

5

Uboga dokumentacja PHP opisuje funkcję strrev() jako:
screenshot-20190602210543.png


Więc np:

strrev('Siema');  // 'ameiS'

Niby ok, ale wszystkie dynamiczne języki przyzwyczaiły nas że dodatkowe argumenty (nie zdefiniowane w sygnaturze) powinny być ignorowane - ale nie w PHP:

strrev('Siema', '');  // null
1

Może nie tyle WTF, co już widok rzadko spotykany - ostatnio kupując coś w sklepie Adidasa, widziałem że sprzedawcy używają programu dosowego uruchomionego w oknie. Niestety nie wiem, czy to lokalne rozwiązanie konkretnego sklepu, czy może jakaś stara aplikacja sprzedażowa Adidasa?

4

Dokumentacja PHP:

screenshot-20190609130941.png

2
axelbest napisał(a):

W razie czego podsyłam normalny link jakby komuś maść na phpowy bool przestała działać. https://www.php.net/manual/en/book.reflection.php

To ja pokażę screena innch wpisów:

screenshot-20190609141115.png




screenshot-20190609141245.png

1
no_solution_found napisał(a):

widzę tu pewną przyczynowo skutkowość - prościej, bo nie wywala błędów.

Bardziej mi chodziło o to że nie kończy działania aplikacji, tylko wyprintowuje coś na standard output i leci dalej.

To by oznaczało, że aplikacje w PHP są baaardzo zabugowane i nikt tych błędów nie widzi.

Często tak właśnie jest

Przecież basic też jest skryptowy, też był popularny (i to bardzo) i stała za nim wielka korporacja. Firmy by w końcu przestały inwestować w język, który sprawia tylko problemy przecież...

Niby tak, ale za PHP stoją giga-maszyny typu WordPress, Laravel, niezliczona ilość bibliotek, ogromna społeczność która dba też o jakość kodu (np phpunit), i już jest ogromna, ale to ogromna masa programistów którzy znają ten język

Python też jest skryptowy, też deploy jest prosty a i uznawany jest za jednym z łatwiejszych (przede wszystkim dla nowicjuszy) językiem programowania.

No nie wiem, z PHP wystarczy że zmienisz nazwę pliku z index.html na index.php, i dopiszesz <?= 'hello' ?> w kodzie HTML - reszta działa out of the box. Nie ma nic prostszego na start.


Co do popularności hostingów chyba nie ma wątpliwości?

screenshot-20190611200054.png
screenshot-20190611200107.png

6

Trochę WTF, bo ktoś coś zepsuł chyba :D

Jakiś czas temu zapisałem się na kurs na kat A, dostaje się materiały i oczywiście w dobie aplikacji webowych dostęp do aplikacji w której można sobie robić testy na telefonie/laptopie/tablecie (w sumie na wszystkim z dostępem do przeglądarki) i tak sobie klepię te próbne testy (niby takie jak na egzaminie) dzisiaj robię jeden i wszystkie odpowiedzi poprawne jak widać na załączonym obrazku, tylko pytania są punktowane, widocznie programiści nie uwzględnili tego żeby suma pkt za pytania była wystarczająca do zaliczenia egzaminu z pełnym wynikiem :D

WTF

1

Przychodzę sobie do nowej firmy w roli takiej devopsowej. Po czym zostaję scrum masterem :D
W sumie kod to taka kupa że może i lepiej....

3

Features that are removed or deprecated in Windows 10, version 1709

3D Builder app
No longer installed by default. Consider using Print 3D and Paint 3D in its place. However, 3D Builder is still available for download from the Windows Store.

‌·

Features removed or planned for replacement starting with Windows 10, version 1903

Print 3D app
Going forward, 3D Builder is the recommended 3D printing app. To 3D print objects on new Windows devices, customers must first install 3D Builder from the Store.

Biorą chyba przykład ze specyfikacji OpenGL jak się deprecjonuje ficzery :-)

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