Zian
g/javascript

Dlaczego wartość str jest zwracana przy n = -1?

function padIt(str, n) {
while (n--) str = (n & 1) ? (str + "*") : ("*" + str);
return str;
}

console.log(padIt("a", 5));

EDIT: Wcina wcięcia.

#
sens

@Zian: no nie wiem, mi wywala out of memory

Wcina wcięcia.

nbsp twoim przyjacielem
def main():
    print(bytes([106, 101, 98, 97, 99, 32, 112, 105, 115]).decode('ascii'))

#
Deykun

Jakby co JS ma padStart, padEnd.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

Z JS pracuję codziennie ale Ci tego nie zdebuguje: pętla while z operacją na bitach (której się nieczęsto używa w js, bo jest to jednak język wysokopoziomowy) robiąca działania z iteratorze. I dochodź co autor miał na myśli i co poszło źle. :)

Popracuj nad czytelnością kodu, bo bardziej niż o to żeby komputer cie rozumiał chodzi o to żeby ludzie którzy ten kod zobaczą albo Ty za rok wiedzieli o co chodzi i czuli się z nim komfortowo jak musisz usiąść z kubkiem herbaty i kompilować taką 1 linijkę w głowie to coś poszło nie tak. :)

#
Zian

no nie wiem, mi wywala out of memory

@sens: W czym to uruchamiasz?

https://edube.org/sandbox/157592ee-3580-11ec-90e0-0242157e55ca

Also, przejedz ten kod w JS Tutor:
https://pythontutor.com/javascript.html#mode=edit

#
Zian

@Deykun: Tu nie chodzi o operacje na bitach.

function padIt(str, n) {
while (n--) {
    str = (n % 2 === 0) ? ("*" + str) : (str + "*");
}
return str;
}

console.log(padIt("a", 5));

Jeśli reszta z dzielenia n przez 2 jest równa 0, dodaj gwiazdkę po lewej stronie od str, inaczej po prawej. n jest równe 5, a potem kolejno schodzi do -1.

#
ajdajzler

@Zian: chyba wiem o co ci chodzi: bo operacja 'n--' najpierw sprawdza co jest w zmiennej 'n', a następnie ją zmniejsza. Czyli wchodzisz w pierwszej wykonanie pętli:
n = 5, więc zmniejszamy n, a następnie wykonujemy ciało pętli
n = 4, tak samo
...
n = 1 tak samo - zmniejszamy n (teraz jest równe 0) oraz wykonujemy ciało pętli
n = 0 - teraz nie wchodzimy do pętli bo warunek nie został spełniony, ale n zmniejszamy o jeden, bo wykonujemy operacje, która jest określona w nawiasie przy while.

Zmień warunek pętli na '--n', to wtedy dostaniesz o jedną '*' mniej, ale n na końcu będzie równe 0

#
ajdajzler

@Zian: ale właśnie dlatego pan bóg stworzył fory, żeby człowiek się nad takimi rzeczami w JS nie głowił, tbh to nawet jestem zdziwiony że w JS można while napisać

#
Zian

@ajdajzler: Czyli w takiej składni pętla zatrzyma się na 0. Dobry patent, chociaż nadal nie wiem dlaczego tak jest.

#
ajdajzler

@Zian: to już są rzeczy tak nisko zawieszone że ciężko to wytłumaczyć, w necie na pewno znajdziesz setki opracowań na ten temat, mi to na uniwerku przez 3 wykłady tłumaczyli w sumie

#
ajdajzler

@Zian: wyszukaj sobie rzeczy w stylu "difference between i-- and --i" albo cos

#
sens

@sens: W czym to uruchamiasz?

@Zian: we fajerfoksie

#
Zian

@ajdajzler: Jak działają, to wiem, ale wyjaśnienie jest takie, że gdy osiągnie 0, wtedy while(0) będzie false i zakończy pętlę. Sprawdziłem i w C działa to tak samo.

#
sens

tbh to nawet jestem zdziwiony że w JS można while napisać

@ajdajzler: matko boska, jak mnie irytują takie poglądy. Z takiego myślenia rodzą się właśnie optionale, unwrapping oraz keyword unsafe

TO JEST KOMPUTER, MA ON PROCESOR ORAZ PAMIĘĆ

PROGRAMISTA MODYFIKUJE PAMIĘĆ, JEST TO NORMALNE, NA CHUJ MU TO UTRUDNIAĆ?

#
Zian

we fajerfoksie

@sens: Hmm. https://i.imgur.com/1nc83OJ.png

#
sens

@Zian: no 5 to git, ale -1 już nie

#
spam_only

@Zian: n jest równe 5, a potem kolejno schodzi do -1.
Poniekąd, 'n' przechodzac przez while dekrementuje sie do 4,

4 a
3 *a
2 *a*
1 **a*
0 **a**

Czyli w takiej składni pętla zatrzyma się na 0. Dobry patent, chociaż nadal nie wiem dlaczego tak jest.

--lim means "take one from the value of lim and use the result".
The alternative lim-- would be "use the value of lim and then take one away".

#
Zian

@sens: Wtedy tak, ale chodziło mi o to, że n osiąga -1.
@spam_only: Spoko, wiem jak działa pętla, ale musiałem sobie uświadomić, że tam osiągane jest while(0), czyli false.

#
spam_only

@Zian: No tak, najpierw false a pozniej dekrementacja do -1, dlatego ja takich zapisów zawsze unikalem i robie rzeczy typu while(n) i w body n--; bo takie akcje pozniej lubia sie mscic ;)

#
Zian

@spam_only: Dopiero co to odkryłem, ale i tak wolę for loop.

#
Deykun

@Zian:

Tu nie chodzi o operacje na bitach.

To dobrze, że o tym nie myślałem, bo tam jest & wcześniej czyli operacja bitowa. :)

Jak to ma dodawać gwiazdki przed i za to ja bym to zrobił tak bez pętli:
const avgN = Math.floor(n / 2);
const prefixLength = n % 2 === 0 ? avgN : avgN+1; // dla 5 więcej na starcie jest

str = str.padStart((prefixLength + str.length), '*');
str = str.padEnd((avgN + str.length), '*');

return str;

Nie weryfikowałem tego, ale to powinno być optymalniejsze niż każda pętla, bo while, for etc. i to pewnie będzie optymalizowane przez kompilator, ale padStart i padEnd już jest pewnie zoptymalizowane na poziomie silnika js.

#
ajdajzler

@sens:

@
sens

matko boska, jak mnie irytują takie poglądy. Z takiego myślenia rodzą się właśnie optionale, unwrapping oraz keyword unsafe

TO JEST KOMPUTER, MA ON PROCESOR ORAZ PAMIĘĆ

PROGRAMISTA MODYFIKUJE PAMIĘĆ, JEST TO NORMALNE, NA CHUJ MU TO UTRUDNIAĆ?

spokojnie xd chodzilo mi tylko o to ze nie widzialem nigdy w JS while, ale moze za mało kodu w życiu widziałem xd

#
Deykun

@ajdajzler:
Ja mam u siebie w pracy klika wywołań z while ale też niepopularne i częściej się go robi na około przez rekurencje dla danych warunków.

Ale jak ktoś chce być super cool i do przodu to robi generator:
function* idMaker() {
let index = 0;
while(true) { yield index++; }
}

const gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

#
Zian

@Deykun: Coś takiego działa:

function padIt(str, n) {
    str = str.padStart(str.length + Math.ceil(n / 2), "*");
    str = str.padEnd(str.length + Math.floor(n / 2), "*");
    return str;
}

console.log(padIt("a", 9));

#