Początkujący: Dlaczego operacje nie są zawarte w poleceniach wyjściowych?

23

Przeglądam wstępną książkę programistyczną, która zawiera prosty przykład w pseudokodzie:

Start
  input myNumber
  set myAnswer = myNumber * 2
  output myAnswer
Stop

Dlaczego nie możemy pominąć tworzenia innej zmiennej o nazwie myAnsweri po prostu wstawić operację do polecenia wyjściowego, na przykład:

Start
  input myNumber
  output myNumber * 2
Stop

Dlaczego to pierwsze jest poprawne, a drugie nie?

użytkownik 1475207
źródło
39
Czy książka mówi, że nie możesz?
Tulains Córdova,
2
Książka nie mówi, że nie mogę; nic o tym nie mówi.
user1475207,
5
Myślę, że rozsądnie jest zacząć od krótszego drugiego bloku, a następnie, jeśli go potrzebujesz, przejść na pierwszy.
Mateen Ulhaq,
13
Krótka odpowiedź: możesz, autor robi to (próbując), aby było to jaśniejsze (chociaż szczerze mówiąc, prawdopodobnie wcale nie czyni go jaśniejszym ...).
Jules
1
Oba sposoby działają. Z większym doświadczeniem przekonasz się, że dla poważnego kodowania czytelność jest znacznie ważniejsza niż prostota lub oryginalność kodu. Twój kod powinien być łatwy do odczytania przez wiele osób go utrzymujących.
Frantisek Kossuth,

Odpowiedzi:

36

Mógłbyś, ale drugi jest po to, aby zobaczyć, co się dzieje i abyś mógł myAnswerpóźniej skorzystać z programu. Jeśli użyjesz drugiego, nie możesz go ponownie użyć myAnswer.

Więc później w programie możesz chcieć:

myAnswer + 5
myAnswer + 1
etc.

Możesz mieć różne operacje, do których chcesz go użyć.

Rozważ zamianę numerów:

Start
  input myNumber
  set myAnswerA = myNumber * 2
  output myAnswerA
  set myAnswerB = myNumber * 3
  output myAnswerB
  set temp = myAnswerA
  set myAnswerA = myAnswerB
  set myAnswerA = temp
  output myAnswerA
  output myAnswerB
Stop

Byłoby to trudne bez zmiennych. Książki komputerowe zaczynają się naprawdę proste, a większość programowania jest łatwa, dopóki nie zobaczysz złożoności. Większość wszystkiego jest trywialna w samouczkach i tylko w złożoności widzisz, gdzie rzeczy mają lub nie mają sensu.

Jasio
źródło
1
Więc to jest poprawna logika, ale nie jest to najlepsza praktyka, ponieważ nie pozwala mi na ponowne użycie operacji w innych częściach programu?
user1475207,
@ user1475207 Zobacz moją edycję. W tym małym programie nie ma to znaczenia. Autor wie, że będziesz robił znacznie więcej niż później generowanie wartości. Widzisz to tylko w złożoności. Trzymać się tego.
Johnny
ah ok, rozumiem. Pamiętam o tym, czytając książkę. Dzięki.
user1475207,
29
@ user1475207 Oba sposoby mają swoje miejsce. Czasami może być konieczne użycie dodatkowej zmiennej. Czasami możesz nie potrzebować dodatkowej zmiennej, ale i tak chcesz jej użyć, ponieważ w niektórych sytuacjach po prostu nadanie czegoś przemyślanej nazwy sprawia, że ​​jest to o wiele wyraźniejsze. Czasami nie chcesz używać dodatkowej zmiennej, ponieważ jest to tylko dodatkowy szum. I wiele razy różnica tak naprawdę nie ma znaczenia.
8bittree,
3
Myślę, że poprawne jest zwrócenie wyniku operacji bez uprzedniego przypisania go do zmiennej. Ale przyzwyczaiłem się do tworzenia resultzmiennej nawet dla krótkich funkcji, dzięki czemu debugowanie przez dodawanie print(result)jest naprawdę szybkie. Jest to jednak bardziej wygodne niż dobre praktyki.
Prawa noga
33

Kolejny powód: przypisanie set myAnswer = myNumber * 2nadaje wartości wynikowej nazwę . Osoba czytająca dwuwierszową wersję kodu wie tylko, że wypisuje wartość myNumber * 2. Osoba czytająca wersję trzywierszową może zobaczyć, że myNumber * 2to odpowiedź .

W tak trywialnym przykładzie może to nie wydawać się ważne, ale czasami przypisanie wartości wynikowej zmiennej o znaczącej nazwie może znacznie ułatwić innym programistom odczytanie i zrozumienie twojego kodu.

Solomon Slow
źródło
10
+1, chociaż ma to zastosowanie tylko wtedy, gdy nazwa ma znaczenie. Korzystanie tymczasowe vars tak nazwany i, resultlub jakiś inny identyfikator sensu nie robi nic, aby poprawić przejrzystość i tylko zaśmieca kodu
Alexander - dozbrojenie Monica
7
@Alexander: Bezsensowne nazwy mogą nadal mieć znaczenie. ilepiej być indeksem tablicowym. Jeśli istnieje result, funkcja powinna kończyć się return resultna równoważniku moralnym. I tak dalej ...
Kevin
6
@Kevin „Bezsensowne nazwy mogą wciąż mieć znaczenie” uhhh ... jesteś pewien? lol
Alexander - Przywróć Monikę
3
@Kevin Jeśli masz zamiar return result, możesz równie dobrze po prostu w linii zwrócić to, co przypisałeś do wyniku. Widzimy, że to wynik. Zwracasz to, rozumiemy.
Alexander - Przywróć Monikę
5
@Alexander: Oczywiście możesz wstawić zwrot, jeśli jest to proste wyrażenie, ale co, jeśli musisz zbudować go na wielu instrukcjach? Użycie spójnego schematu nazewnictwa wyjaśnia, co robisz w takich przypadkach.
Kevin
14

To pseudokod. Nie powinien to być żaden konkretny zaimplementowany język.

Niektóre języki programowania nie obsługują oceny wyrażenia, a następnie wykluczają wynik w tym samym wierszu kodu. Na przykład większość asemblerów tego nie obsługuje. Być może autor książki chciał pokazać rzeczy na niskim poziomie.

Tulains Córdova
źródło
2
A niektóre języki (na przykład C) pozwalają na oba w tym samym czasie - możesz na przykład pisać „wynik (odpowiedź = odpowiedź * 2)”, jeśli naprawdę chcesz! (ale uwaga niż „wynik (odpowiedź == odpowiedź * 2)” oznacza coś zupełnie innego ...
alephzero,
9

Inne odpowiedzi dotyczyły konkretnych szczegółów mechanicznych i przykładów, kiedy jedna lub druga forma byłaby lepsza, ale chcę wspomnieć o nieco dalszym tle, w pewnym sensie filozoficznym:

Uczysz się języka.

Język to coś, w czym można wyrażać i rozumieć (komunikować) idee. Komputerowy język programowania ma dodatkową właściwość polegającą na tym, że może być mechanicznie analizowany przez maszynę zaprojektowaną do podejmowania działań (wykonywania) na podstawie pomysłów (decyzji) określonych i wprowadzonych za pomocą tego języka.

W KAŻDYM języku, który w ogóle jest przydatny, istnieje więcej niż jeden sposób wyrażenia prawie każdego pomysłu wyrażalnego w tym języku.


Rozważ szeroką gamę niuansów dostępnych w języku angielskim. Nawet proste zdanie, takie jak

Kot wskoczył na pudło.

mogą być zmieniane, aby wyrazić nieco inne pomysły lub położyć nacisk na różne części sceny , odnosząc się do tej samej dokładnej akcji wszechświata fizycznego.

Najpierw są odmiany gramatyczne:

Na pudełko wskoczył kot.

Na pudło wskoczył kot.

Są coraz szersze odmiany, wciąż odnoszące się do tej samej akcji fizycznej:

Pudełko trzęsło się pod wpływem kota.

Kot upadł z hukiem na górną część pudła.

Koci wyskoczył lekko w powietrze i wylądował starannie na pobliskim pudełku.

Wystarczy spojrzeć na konsekwencje słowa „w pobliżu” w ostatnim zdaniu. Jego włączenie zawiera zupełnie nowy zakres pojęć, których inaczej nie ma.


Zawsze jest na to więcej niż jeden sposób, przeciwnie - Python Zen.


Oczywiście będzie JEDEN sposób, który doskonale wyraża Twoją intencję i jest najbardziej odpowiedni, tak jak wybrałbyś JEDEN z powyższych angielskich zdań, w zależności od tego, co chcesz komunikować. Właśnie o to chodzi w Zen Pythona.

Ale w trakcie wstępnego programowania lub wprowadzającym kurs angielskiego, trzeba najpierw nauczyć się różnych sposobów (sformułowań, fragmenty kodu), w którym można kanapa pomysł zanim opracuje osąd do wyboru , który jest najbardziej idealnie przylegające.

Dzika karta
źródło
3
Oczywiście Python łamie własną zasadę. Masz lambdy i funkcje zagnieżdżone; pętle, listy i wyrażenia generatora; zmiennoprzecinkowe, dziesiętne i ułamki; i __init__a __new__, żeby wymienić tylko kilka. Chodzi o to, że każdy jest odpowiedni dla subtelnie innego problemu. Nie wybrałbyś przypadkowo jednego z tych angielskich zdań, ani nie wybrałbyś przypadkowo jednej z tych funkcji języka Python.
Kevin,
1
@Kevin, tak, zgodził się. Chodzi o to, że dla kogoś zupełnie nowego w programowaniu dokładność wymaganej składni może sprawiać wrażenie, że jest tylko jeden sposób, w jaki można wszystko osiągnąć - tj. Kopiowanie dokładnego kodu z dosłownego tutoriala, podobnie jak problemy matematyczne w szkole średniej (573 x 247) mają tylko jedną poprawną odpowiedź. Zobacz także pytania typu „Co to jest program kurczyć pliki?” Jeśli przeczytacie moją odpowiedź, nie mówię, żebym robił coś losowo; Mówię, że ty zawsze dokonywania wyborów podczas programowania.
Wildcard
1
To z pewnością sprawiedliwe. Myślę, że problem polega na tym, że nieco upraszczasz / wprowadzasz w błąd w Zen of Python. Chodzi o to, że decyzje te są ostatecznie podyktowane konturami twojego problemu, a nie swobodnymi wyborami. Być może trzeba będzie przejść wiele iteracji i refaktoryzacji, aby znaleźć jeden sposób, aby to zrobić, ten, który idealnie pasuje do twoich wymagań, jest czytelny, zwięzły, a nawet elegancki. Ale w przypadku każdego problemu powinno istnieć takie idealne rozwiązanie, a dobrze zaprojektowany język poprowadzi Cię do niego. To właśnie oznacza Zen.
Kevin
4
Cynik może powiedzieć: „W Pythonie jest tylko jeden sposób, aby to zrobić, ale każda nowa wersja Pythona stosuje funkcję„ a teraz coś zupełnie innego ”niż w poprzedniej wersji”;)
alephzero,
3
cytat z PEP20: „Powinien istnieć jeden - a najlepiej tylko jeden - oczywisty sposób na zrobienie tego. Chociaż na początku taki sposób może nie być oczywisty, chyba że jesteś Holendrem”.
vaxquis
5

Pytasz tylko o myAnswerzmienną, która wydaje się zbędna. Inne odpowiedzi już wyjaśniają niektóre z powodów, dla których i kiedy warto je pominąć lub użyć, ale oto jeszcze jedno: co powiesz na to?

Start
  output input * 2
Stop

a nawet to

Start output input * 2 Stop

W większości języków to nadal działałoby, ale czy możesz to przeczytać? Jest to trudne, dlatego często używamy zmiennych pomocniczych , ponieważ komputery nie są jedynymi, które czytają kod. Musimy go utrzymywać i rozumieć za kilka miesięcy, a jeszcze trudniej jest napisać kod, którego będziesz w stanie zrozumieć później niż działający ... zwykle po kilku dniach nie będziesz wiedział, dlaczego zrobiłeś coś w określony sposób .

t3chb0t
źródło
2
... a nawet po prostu (*2). Chciałbym jednak sprzeciwić się temu, że wykonywanie danych wejściowych niekoniecznie musi być wyrażone w sposób bezpieczny tylko jako dostęp do zmiennej / wykonanie operacji arytmetycznej: może mieć zauważalne skutki uboczne.
leftaroundabout,
2

Możesz zrobić oba warianty (w tym prostym przypadku), ale pierwszy wariant staje się bardziej czytelny i ustrukturyzowany dla bardziej złożonych przypadków. Pierwszy wariant pokazuje model IPO z jedną linią dla każdego kroku (dwa z już o właściwej nazwie):

Start
  input myNumber                       // Input
  set myAnswer = myNumber * 2          // Process
  output myAnswer                      // Output
Stop
Raidri wspiera Monikę
źródło