"To twoja opinia"

0
somekind napisał(a):
._. napisał(a):

"Masz rację, tak samo jak Twoja opinia. Tylko że ja swoją podpieram doświadczeniem i ustalonymi w branży dobrymi praktykami. Zwolennikami tego są znacznie lepsi niż my specjaliści tacy jak X, Y, Z."

Argumenty w stylu, Ja swoją opinię podpieram doświadczeniem albo ustalonymi regułami i dobrymi praktykami, są dla mnie zawsze tak samo żałosne.

No, to fakt. Argumenty odwołujące się do doświadczenia są niezrozumiałe dla tych, którzy doświadczenia nie zdobywają.

Nie rozumiem, o czym ty prawisz, przecież argument "Ja wiem lepiej, bo ja mam doświadczenie w branży" to argument ad personam, który mówi w skrócie "Ja mam rację, bo ja jestem mądrzejszy" Doświadczenie zawodowe jest pojęciem szerszym niż staż pracy. A pomimo tego większość ludzi używa stażu pracy jako argument. Doświadczenie to "bodziec - inpuls" na który możesz zareagować, przeanalizować i wyciągnąć wnioski. Zwykle ma znaczenie tylko za pierwszym razem. Staż pracy nie jest dla mnie wymiernym wskaźnikiem twoich rad (w stylu jak wyżej). Ponieważ ja nie wiem jakiego rodzaju doświadczenia przeżyłeś i w jaki sposób na nie reagowałeś. Programowanie to logika tego nie trzeba podważać jakimiś autorytetami ani jakimiś wyższymi prawidłami. Zdanie autorytetów należy przeanalizować. Co niektórzy tego nie robią, bo są pracownikami fabryki obsługującymi maszyny produkcyjne i interesują ich proste regułki.

Jak widzę, to twoje zdanie odnośnie do co niektórych rzeczy strasznie ewoluowało. To bardzo dobrze, ponieważ ludzie, którzy uważają, że zawsze mają rację, wydają się strasznie zamknięci na wymierne wykorzystanie zdobytego doświadczenia.

1
._. napisał(a):

Nie rozumiem

No wiem, że nie rozumiesz. Przecież o tym właśnie napisałem. Żeby rozumieć na czym polega zdobywanie doświadczenia trzeba je zdobywać.

o czym ty prawisz, przecież argument "Ja wiem lepiej, bo ja mam doświadczenie w branży" to argument ad personam, który mówi w skrócie "Ja mam rację, bo ja jestem mądrzejszy"

To ad personam jest mocno naciągane, no ale niektórzy tak lubią. Na pewno jest niemerytoryczne. I ja takiego argumentu nie stosuję.

Doświadczenie zawodowe jest pojęciem szerszym niż staż pracy. A pomimo tego większość ludzi używa stażu pracy jako argument.

A skąd teraz staż pracy się nagle urodził?! Ja nic o żadnym stażu nie wspominałem.

Ja pisałem o tym, że dobre praktyki biorą się ze zdobywanego doświadczenia. Ktoś kiedyś rozwiązał problem X w sposób A i miał z tego powodu jakieś inne problemy. Ktoś inny rozwiązał ten sam problem w sposób B i nie miał potem problemów będących konsekwencjami wyboru sposobu rozwiązania. Dlatego można powiedzieć, że B jest lepszym sposobem rozwiązywania problemów rodzaju X. Gdy taka wiedza dotrze do jakiejś większej grupy ludzi, to uznaje się ją za dobrą praktykę.
I tyle, nie trzeba tu dopowiadać sobie opowieści o mądrzeniu się ani stażu pracy.

Programowanie to logika

Na poziomie pisania kodu owszem. Tylko ta dyskusja dotyczy wytwarzania oprogramowania, czyli inżynierii, która to opiera się w znacznej mierze na doświadczeniu.

Jak widzę, to twoje zdanie odnośnie do co niektórych rzeczy strasznie ewoluowało.

Być może. Ale nie w kwestii omawianej tutaj.

2

Mówienie 'bo ktoś mądry tak powiedział' jest samo w sobie błędem logicznym. Dopiero mówienie 'ktoś mądry tak powiedział bo <jakiś powód>' ma sens

0

Na początek, to nie moja opinia, to opinia ludzi "much smarter than I am". Software engineering może być zrobione dobrze na więcej niż jeden sposób.
Dlatego takie dyskusje mogą się ciągnąć w nieskończoność. I tyle.

2
._. napisał(a):

"Masz rację, tak samo jak Twoja opinia. Tylko że ja swoją podpieram doświadczeniem i ustalonymi w branży dobrymi praktykami. Zwolennikami tego są znacznie lepsi niż my specjaliści tacy jak X, Y, Z."

Argumenty w stylu, Ja swoją opinię podpieram doświadczeniem albo ustalonymi regułami i dobrymi praktykami, są dla mnie zawsze tak samo żałosne.

To pokaż mi cwaniaku jak zrefaktoryzujesz tą metodę.
Tak żeby było mniej ifów i mniej linijek.

Jezu aż oczy bolą. W życiu nie spotkałem osoby pracującej w branży, która napisała by kod aż tak niskiej jakości. Jest tak źle, że podejrzewam prowokację!
Jakbym dostał, współpracownika, który pisałby coś takiego, to omówiłbym z nim na stronie, wszystkie problemy tego kodu.
Jeśli taka osoba okazała by się odporna na argumentację i byłaby przekonana, że to jest super, to nie widziałbym wyjścia, tylko przedyskutować to ze zwierzchnikiem, bo taki pracownik nie rokuje. Może taka osoba zrealizuje parę zadań, ale za parę miesięcy trzeba będzie naprawiać bugi, po takim artyście poświęcając na to 2 razy więcej własnego czasu.
Każdy robi bugi, ale w tym wypadku poprawianie kodu byłoby to wyjątkowo bolesne.

Podstawowe problemy opisała katelx:

katelx napisał(a):

ten kod to tragedia, testy jeszcze gorsze ;)

  1. potrzebne sa ze 2 metody - jedna dajaca nowy rozmiar obrazka, druga robiaca krojenie
  2. przeskalowanie rozmiaru to krotka formulka, nie trzeba zadnych ifow i pincet zmiennych
  3. to rzutowanie do decimala jest bezsensowne i bezuzyteczne
  4. uzywanie mutowalnych pol (i to statycznych) to patola level 99
  5. ten wyjatek to taki se

nie chce mi sie juz wiecej wymieniac, w sumie to nie wiem o co chodzi z tym pytaniem, wiem ze nie chcialabym pracowac z kims kto pisze taki kod

A problemów jest dużo więcej z tym kodem.

Disclaimer: jestem bardziej C++/Swift/ObjC niż C# więc pewnie będą niedoróbki językowe, albo złe użycie bibliotek, ale generalnie chodzi o pokazanie, że da się zrobić lepiej. Ograniczając się jedynie do punktowania wszystkich kwiatków, autor odbierze(rał) to personalnie i nie zrozumie, że naprawdę coś jest źle.
Jest tak źle, że lepiej zacząć od zera, bo naprawdę nie ma sensu poprawiać iteracynie:

interaface ImageTransformator
{
       Image transform(Image image);
}

class ThumbnailGenerator : ImageTransformator
{
    private final System.Drawing.Size size;
    public ThumbnailGenerator(System.Drawing.Size expectedSize)
    {
          size = expectedSize;
    }

    public override Image transform(Image image)
    {
           if (doNotHaveToResize(image.Size))
           {
                 return image;
           }
           return scaleToSize(image, thumbnailSizeFrom(image.Size));
    }

    public static Image scaleToSize(Image image, System.Drawing.Size size)
    { // przeróbka z tego: https://stackoverflow.com/a/2001462/1387438 więc mogłem coś popsuć, nie testowałem
        Bitmap bmPhoto = new Bitmap(size.Width, size.Height, image.PixelFormat);
        bmPhoto.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using(Graphics graphics = Graphics.FromImage(bmPhoto)) {
            graphics.Clear(Color.Red);
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

            graphics.DrawImage(imgPhoto, 
                       new Rectangle(0, 0, size.Width, size.destHeight),
                       new Rectangle(0, 0, image.Width, image.Height),
                       GraphicsUnit.Pixel);
        }
        return bmPhoto;
    }

    private bool doNotHaveToResize(System.Drawing.Size actualSize)
    {
          return actualSize.Width <= size.Width && actualSize.Height <= size.Height
    }

    private Size thumbnailSizeFrom(Size actualSize)
    {
          if (actualSize.Width / (double) size.Width >= actualSize.Height / (double) size.Height)
               return new Size(size.Width, size.Width * actualSize.Height / (double) actualSize.Width);
          return new Size(size.Height * actualSize.Width / (double) actualSize.Height, size.Height);
    }
}

class ImagesConverter
{
    private ImageTransformator transformation;
    MapImages(ImageTransformator transform)
    {
          transformation = transform;
    }

    List<Image> transform(List<Image> images)
    {
          return images.Transform(image => transformation.transform(image));
    }

    void TransformFiles(String fromDir, String toDir, String prefix)
    {
          Directory.EnumerateFiles(fromDir, "*.jpg")
               .Transform(file => (Image.FromFile(file), file.Substring(fromDir.Length + 1)))
               .Transform((image, name) => (transformation.transform(image), prefix + name))
               .Where((image, name) => image != null)
               .Do((image, name) => image.SaveTo(toDir + name);
    }

    // inne api operowania na zbiorze obrazów
}

Nazwy klas mi się nie podobają, w takich wypadkach zostawiam do poprawy podczas code review z komentarzem prowokującym do sugesti innej nazwy.
Nie chce mi się pisać części odpowiedzialnej za zapis i odczyt z plików, ale jak widać można to ładnie odizolować od części generującej miniatury od iterującej po obrazach zapisanych w różnych formatach.
Jeden algorytm może obsługiwać nie tylko generowanie miniatur, ale też zmianę balansu bieli, kowersje na obraz czarno biały itp itd.
Tak samo klasa do generowania miniatur może być użyta winnym kontekście.
Pisanie testów do tego też nie jest problemem.
Widać też, że przeczytanie i poprawienie tego kodu jest dużo łatwiejsze niż oryginał.

0

Ty coś "poprawiłeś".? Gdzie?

2
._. napisał(a):

Ty coś "poprawiłeś".? Gdzie?

Widzisz użycie pół statycznych?
Czy kod działa można użyć tylko w jednym kontekście?
Czy funkcje są mają wysoką złożoność cykliczną (dużo ifów forów …)?
Czy kod jest trudny w czytaniu i poprawianiu?
Czy widzisz definicję zbędnych klas/struktur tak ja te twoje ThumbnailSize?

Tak jak zaznaczyłem, zapewne to co napisałem ma kupę błędów, bo C# nie używałem z 8 lat, a UI w .net nie dotykałem od +10 lat, a Windowsa używam, gdy mnie zmuszają okoliczności. Nie mam nawet narzędzi, by dokonać weryfikacji składni. Chodziło o pokazanie, że da się inaczej czytelniej i zmienić tek kod by był bardziej uniwersalny (uczynić go bardziej abstrakcyjnym).

Jeśli naprawdę nie widzisz tych różnic, no to mi przykro. Mam wrażenie, że krytykę kodu, przyjąłeś jako atak personalny, a to oznacza, że trudno będzie cię przekonać do czegokolwiek.

0

Czy kod działa tylko w jednym kontekście?

Kod zawsze powinien działać w jednym kontekście, po to są konteksty, chyba że jest współdzielony np. w module Common albo Base etc. No chyba, że projektujesz bibliotekę albo frameworka.

Czy funkcje są mają wysoką złożoność cykliczną (dużo ifów forów …)?

Nie, bo zmieniłeś pierwotne założenia kodu.

Czy kod jest trudny w czytaniu i poprawianiu?

Zdecydowanie, w testowaniu, też.

Czy widzisz definicję zbędnych klas/struktur tak ja te twoje ThumbnailSize?

A co z paradygmatem OOP w ogólności?

Jeśli naprawdę nie widzisz tych różnic, no to mi przykro. Mam wrażenie, że krytykę kodu, przyjąłeś jako atak personalny, a to oznacza, że trudno będzie cię przekonać do czegokolwiek

Nie czuję się atakowany, raczej rozczarowany. Staram się również nie być arogancki. :-|

2

bez zmieniania sygnatury:

public static void GenerateThumbnailFromImage(ThumbnailSize size) {
    Thumbnail = new Thumbnail(Image.FromStream(Image.Stream).GetThumbnailImage(size.Width, size.Height, null, IntPtr.Zero), Image.Name);
}

ale lepiej by bylo:

public static Thumbnail GenerateThumbnail(MyImage image, ThumbnailSize size) {
    return new Thumbnail(Image.FromStream(image.Stream).GetThumbnailImage(size.Width, size.Height, null, IntPtr.Zero), image.Name);
}

a jeszcze lepiej jakby MyImage mial np. metode:

public Thumbnail ExtractThumbnail(ThumbnailSize size) {
    return new Thumbnail(Image.FromStream(stream).GetThumbnailImage(size.Width, size.Height, null, IntPtr.Zero), name);
}

mam nadzieje ze o taka redukcje kodu chodzilo ;)

0

Jak masz pdejście funkcyjne i widzisz to jako stream, który porusza się po jakiejś szynie. No to okey, tyle że wolał bym dwie funkcje.

return imageStream.SacaleSize(h, w).DrawImage();


Ja bym zrobił tak:

public Thumbnail Thumbnail(IDrawImageService imageService, int height, int width)
{
   //Assercja
   //Wywołanie strategi skalowania.
   //Rysowanie
   //Tworzenie obiektu.
   //Return
}

1

nie mam podejscia funkcyjnego, widze ze nie ogarniasz frameworka, podstaw programowania ani nawet wlasnego kodu co jest dosc smutne, bo twardo (i arogancko) dyskutujesz na te tematy.
GetThumbnailImage i FromStream to dosc stare kwiatki, jeszcze sprzed wynalezienia extension methods.

0

GetThumbnailImage nie spełnia wymagań pierwotnej implementacji, czego sama nie jesteś świadoma i to jest smutne, nie potrafisz nawet zrozumieć prostego algorytmu i zmniejszyć ziarnistość metody, która go wykonuje. Specjalnie wam podsunąłem ten kod, który jest zły i jestem tego świadomy. A co niektórzy dalej nie kumają tego, że wychodzą na ekspertów, którzy nie potrafią przedstawić rozwiązania problemu. Jest tylko krzyk, bo to, bo tamto, a ja bym to zrobił najlepiej a ty jesteś głupi bo nie ogarniasz własnego kodu. W rzeczywistości ci eksperci nie umieją nic zrobić. Z tego wszystkiego @Afish okazał się najbardziej rzetelny i ogarnięty. Nawet nie wiedziałem, że tacy fajni ludzie tutaj są.

1

Jeżeli wymagania dotyczące pierwotnej implementacji są bez sensu, to należy je zmienić i tyle. A nie na siłę wciskać okrągły klocek w kwadratowy otwór.
Źle zaprojektowane API często uniemożliwia wydajną i elegancką implementację.

3
Krolik napisał(a):

A nie na siłę wciskać okrągły klocek w kwadratowy otwór.

Coś wam napiszę propos wciskania i głupoty, miałem kiedyś w aucie do wymiany tłoki zacisku hamulcowego (uszczelniacze puściły, porobiły się wżery i hamulce się blokowały-felga się nagrzewała).
No i mechanik kupił nowe tłoki, z racji, że wróciłem wcześniej po auto to trafiłem jak je wymieniał, no i wciska je do zacisku, ciężko idzie na prasie, gościu kiwa głową cały czerwony, ewidentnie widać, że rozmiar inny, pewnie do innego modelu, tak czasami bywa.
Mechan zamiast odpuścić, idzie jak po swoje, chyba liczył, że w połowie samo się naprawi, jak sie popieści to sie zmieści itp. :)
Finalnie na swój koszt kupił nowe zaciski i tłoki, jakieś 800 w pape.
Niech to będzie dla wszystkich lekcja (jeszcze nie zdecydowałem jaka).

1

Wietrzę zaczątki nowego wątku -> "Jak przyjmować krytykę" ;)

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