Co ten Pluton, nawet złotówki nie oddał. :P
Jednak wartość merytoryczna jest na dobrym poziomie. Kiedy dasz jakieś nowe? Chętnie pogłówkuje.
O, albo czy znasz jakąś stronę właśnie z takimi zadaniami/ćwiczeniami?
Wersja do druku
Część druga - podejmujemy decyzję:
Dowiedzieliśmy się już, czym są wyrażenia i instrukcję w języku programowania. Poznaliśmy definicję zmiennej - etykiety na szufladkę w pamięci. Dowiedzieliśmy się, że możemy w zmiennych przechowywać wynik każdego wyrażenia w programie.
Zauważmy jednak, że teraz nasze programy nie są zbyt ciekawe. Wykonują jakiś ciąg instrukcji, modyfikując zmienne. Jednak ten ciąg jest liniowy - nie możemy podjąć decyzji "wykonaj te instrukcje w tym przypadku, a w tamtym przypadku - inne". Oczywiście, brak tej możliwości bardzo ogranicza nasze programy - bardzo trudnym byłoby np. stworzenie programu, który wysyła SMS mamie Plutona, gdy jego dług przekroczy już granice zdrowego rozsądku. Poznamy teraz instrukcje, które pozwolą nam na sterowanie tzw. control flow - czyli które instrukcje będą w programie wykonywane, a które nie.
Na początek, króciutka powtórka z logiki. Wiemy, że wynik wyrażenia 2+2 to liczba - w tym wypadku 4.
Każda, najmniejsza nawet rzecz w matematyce ma swój typ. Nie uczą tego w szkole (niestety!), ale cały język matematyczny możemy traktować jak język programowania. Zastanówmy się więc, jaki jest typ takiego wyrażenia:
A takiego?:Kod:x > 2
Kod:x jest liczbą całkowitą
Nie jest to liczba. O tych trzech zdaniach możemy powiedzieć, że są prawdziwe, albo fałszywe. W logice istnieją takie zdania, które są zawsze prawdziwe - np. trzecie. Zwie się je tautologiami. Są też takie, tylko że zawsze fałszywe - te są formułami sprzecznymi.Kod:ZinC ogląda chińskie bajki.
A jakim zdaniem jest:
To zależy od wartości x, oczywiście.Kod:x > 2
Takie zdania nazywamy "formułami logicznymi". To uniwersalny język matematyki - na podstawie teoretycznej logiki istnieją języki programowania, które udowadniają wiele twierdzeń automatycznie. Niemniej jednak, w podstawowym stopniu możemy reprezentować formuły logiczne w naszych językach programowania. Takie typy zwracają True albo False (w Pythonie), lub też 1 albo 0 w C.
Odpal swój Pythonowy shell i odpal w nim następujący kod:
Sprawdź te odpowiedzi. Mamy tzw. operatory logiczne. W przypadku Pythona są to:Kod:x = 3
x > 2
x = 1
x > 2
Kod:>, <, >=, <=, ==, !=, and, or, not
>, <, >=, <= to typowe operatory z matematyki. x <= 2 oznacza "jeżeli x nie mniejsze od 2", analogicznie >=. and, or, not to operatory działające na zdaniach.Kod:>, <, >=, <=, ==, !=, &&, ||, !
Wyrażenie:
Zwróci True wtedy, gdy x > 2 zwróci True, oraz x < 2 zwróci True. W języku polskim jest to odpowiednik "i". Przy okazji - mała powtóreczka: Dla jakiego x jest spełnione wyrażenie na górze? Czy jest to tautologia, albo formuła sprzeczna?Kod:x > 2 and x < 2
Wyrażenie:Kod:ZinC ogląda chińskie bajki i Masaker jest gruby
Zwróci True wtedy, gdy x > 2 zwróci True, lub x < 2 zwróci True. Przy okazji, pytanie pozostaje podobne jak dla góry :) - to tautologia albo formuła sprzeczna? A może to zależy od x?Kod:x > 2 or x < 2
Warte odnotowania jest to, że te operatory są "leniwe". Zauważmy, że jakbyśmy łączyli:
Gdy x == 7, to program już nie sprawdzi następnych dwóch warunków, tylko od razu zwróci False. To jest przydatne, gdybyśmy np. mieli:Kod:x != 7 and x < 9 and x > 1
Jak wiadomo, to po prawej mogłoby zająć bardzo dużo czasu. Jeżeli warunek po lewej jest niespełniony, oszczędzimy mnóstwo pracy.Kod:<jakiś warunek> and sprawdzParzystoscCyckowWZakochaszSiePrzegrywasz()
Analogicznie, or przerywa swoją pracę gdy znajdzie już coś, co zwraca True.
!, lub not to operator unarny (bierze tylko prawą stronę), który neguje wartość formuły logicznej. Np.
Zwróci True, gdy x > 2 zwróci False, i odwrotnie. Jakbyś miał zapisać to bez not i !, jak by wyglądało to zdanie?Kod:!(x > 2) # python: not x > 2
Kontrolujemy nasz program!
W każdym języku imperatywnym (takim, w którym mówimy programowi JAK ma zrobić daną rzecz, a nie opisujemy jak wygląda rozwiązanie) takim jak C lub Python istnieje instrukcja warunkowa, oraz instrukcja pętli.
Taką instrukcję piszę się następująco:
C:
Python:Kod:if(<formuła logiczna>) {
// Instrukcje, które ma wykonać program, jeżeli formuła logiczna zwraca wartość 1
}
Do każdej z tych instrukcji istnieje odpowiednia instrukcja, która wykonuje kod, jeżeli dany warunek jest fałszywy:Kod:if <formuła logiczna>:
# Instrukcje, które ma wykonać program, jeżeli formuła logiczna zwraca wartość True
Python:Kod:if <formuła logiczna> {
}
else {
// jeżeli <formuła logiczna> zwraca 0, tutaj będą wykonane instrukcje.
}
W Pythonie bardzo ważne są te dwie spacje przed instrukcjami! Python wie, które instrukcje należą do if <formuła logiczna>: właśnie z pomocą tych spacji. W C nie jest to ważne - tutaj definiują to klamerki { i }.Kod:if <formuła logiczna>:
# ...
else:
# te instrukcje wykonają się, gdy formuła logiczna zwróci False.
Przykładowo, chcielibyśmy zrobić grę i wypisać wynik gracza, jeżeli gracz pobił najlepszy wynik. Możemy to napisać następująco:
Jeżeli chcielibyśmy zmienić zasady gry na bardziej Piła-like, możemy sprawić, że gracz który nie pobił poprzedniego najlepszego wyniku może spodziewać się wizyty Torg Usera:Kod:# zakładamy, że zmienna najlepszy przechowuje aktualny najlepszy wynik, a wynik - wynik gracza:
if wynik > najlepszy:
print(wynik)
najlepszy = wynik # najlepszy wynik się zmienił - teraz najlepszym wynikiem jest wynik gracza!
Oczywiście, proszę zadawać pytania jeżeli coś jest niejasne.Kod:if wynik > najlepszy:
print(wynik)
najlepszy = wynik # najlepszy wynik się zmienił - teraz najlepszym wynikiem jest wynik gracza!
else:
print("Pisz testament chłopcze.")
zadzwonPoTorg Usera()
Czasem chcielibyśmy, żeby nasz program wykonywał w kółko jakieś operacje, dopóki jakiś warunek jest spełniony. Zauważmy, że nasz if wykonuje instrukcje które ma w środku jedynie raz. My chcielibyśmy, żeby wykonywał je np. 100 razy, albo nawet w nieskończoność (jeżeli warunek zawsze jest spełniony). Myślisz sobie "co to za sens robić program, który nigdy się nie zatrzyma?". Odpowiadam - Windows jest takim programem. ;)
Aby takie instrukcje wykonywać, mamy instrukcję while:
Python:
C:Kod:while <formuła logiczna>:
# kod będzie wykonywany w kółko, dopóki <formuła logiczna> zwraca True
Przykładowo, jeżeli chcielibyśmy wypisać liczby od 1 do 100, możemy wykonać taki kod:Kod:while(<formuła logiczna>) {
// kod będzie wykonywany w kółko, dopóki <formuła logiczna> zwraca 1.
}
Zauważmy, że wewnątrz pętli modyfikujemy to i, które definiuje nam w formule logicznej jej wartość True lub False. To jest najczęstsza sytuacja - często obliczamy coś, wykonując kroki i chcemy ich wykonać dokładnie ileś..Kod:i = 1
while i <= 100:
print(i)
i = i + 1
Zapraszam do pytań i do zadań:
Zadania:
- <Kartka papieru>
Ściągnij mój skrypt z logiki na studiach: http://www.speedyshare.com/Pt3Qv/skrypt.pdf i spróbuj pomyśleć nad zadaniem 6 z "zadań na początek". To fajne, rozgrzewające mózg zadanie. Najprawdopowodniej będziesz chciał wiedzieć czym jest implikacja. Nazwana inaczej wynikaniem, jest to operator:
I jest fałszywa tylko wtedy, gdy pierwsza formuła jest prawdziwa, a druga fałszywa. To język matematyki, nei Python ani C - nie ma implikacji w programach w C i Pythonowych.Kod:<formuła logiczna> => <formuła logiczna>
- <C/Python>
W matematyce dosyć powszechnie stosowanym i prostym przykładem tzw. ciągu rekurencyjnego (czyli takiego, że wyraz 10-ty zależy np. od 9 i 8) jest ciąg Fibonacciego. Jego definicja jest następująca:
Napisz program, który pod zmienną nTyFib trzyma którą liczbę Fibonacciego ma policzyć, a pod zmienną wynik zwraca jej wartość. Przykład w C:Kod:Fib(0) = 0
Fib(1) = 1
Fib(2) = 1
Fib(n) = Fib(n-1) + Fib(n-2)
Dla wyjadaczy: Nie korzystaj z tablic i rekurencji.Kod:int nTyFib = 10;
// policz fibonacciego.
// Kolejne liczby fibonacciego:
// 0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55
printf("%d\n", wynik); // wypisze: 55
Dla początkujących: Przyda się zmienna, która trzyma poprzednią liczbę fibonacciego, musisz skorzystać z pętli.- <C/Python>
Przeczytaj o:
http://pl.wikipedia.org/wiki/Problem_Collatza#Definicja
Skorzystamy tutaj z operacji modulo - reszty z dzielenia (%). Wiemy, że liczba x jest podzielna przez y, jeżeli x dzieli się bez reszty (czyli x % y == 0) przez y. Liczby parzyste to te, które dzielą się przez 2 (x % 2 == 0), a nieparzyste to wszystkie inne - pomyśl jak to zapisać (możesz skorzystać z not, albo zauważyć, że reszta z dzielenia przez 2 to albo 0 albo 1).
Niech w zmiennej start będzie liczba startowa. Napisz program, który zliczy w ilu krokach po przekształceniach zdefiniowanych w definicji z Wikipedii dojdziemy do 1.
Wskazówka: zdefiniuj sobie zmienną licznik i zwiększaj ją o 1 co każdy obrót pętli.- <C/Python, łatwe>
Zmodyfikuj program, który obliczał dług Plutona tak, żeby po obliczeniu długu, jeżeli przekracza on wartość zmiennej cierpliwośćTorg Usera, wypisał na ekran link do tego filmiku.
http://www.youtube.com/watch?v=IIMs5fpLgOI
Program będzie używany do szkolenia bojówek w mafii Torg Usera.
Lista może być już troszeczkę bardziej skomplikowana, zapraszam do pytań ;). To żaden wstyd nie umieć zrobić, wstyd to nie próbować się dowiedzieć.
@Abe: Znam, nawet całkiem sporo. Jak tylko nauczę Was języka na tyle, żeby te zadania rozwiązywać, to podam linki i dodam proponowane przeze mnie zadania.
@Szantymen: Strasznie przepraszam, nie zauważyłem Twojego posta! Na razie nie przejmujemy się takimi rzeczami - nie chcemy, żeby zmienne były wprowadzane przez użytkownika, wpisujemy je w kod programu. Do tego dojdziemy, ale jeżeli jesteś niecierpliwy, to w Pythonie np. wczytanie liczby wygląda następująco:
Dzięki za miłe słowa, to bardzo zagrzewa do roboty. No to kodzić, panowie i panie! ;)Kod:line = input() # input() zwraca nam jedną linię wczytaną przez użytkownika. Opcjonalnie możesz dodać w argumencie komunikat dla użytkownika, np. input("Podaj liczbę")
liczba = int(line) # zamieni nam napis, który jest liczbą na prawdziwą Pythonową liczbę.
Pozdrawiam
Killavus
To zadanie 6 z .pdf strasznie zagmatwane, hmm... albo ja logicznie nie umiem myśleć.
Na początku zacząłem główkować i zrobiłem sobie na kartce takie coś:
$swiadekZastraszony = 0; $henrySamobojstwo == 1; $odnalezionoTestament = 1;
$swiadekZastraszony == 1; $henrySamobojstwo = 0; x
$odnalezionoTestament == 1; $henrySamobojstwo = 1; v
$henrySamobojstwo == 0; $odnalezionoTestament = 1; x
i już chciałem to robić w instrukcjach warunkowych... :)
Według mojego myślenia wygląda to tak:
Świadek nie był zastraszony.
Henry popełnił samobójstwo.
Testamentu nie odnaleziono.
Resztę dam w edit.
Dodam że javowe klamry są brzydkie i to bardzo ;d
Polecam pisać
zamiastKod:if (jakis fajny warunek)
{
// zrob cos
// zrob cos
// zrob cos
}
Kod:if (jakis fajny warunek) {
// zrob cos
// zrob cos
// zrob cos
}
Dziwnie wygląda pętla for w pythonie. Musiałem użyć while'a. Ciąg fibonacciego bez tablic i rekurencji, może komuś pomoże:
Kod:fib1=1
fib2=1
print("Który wyraz ciągu wyświetlić?")
n=int(input())
i=2
if n<3 and n>0:
print("1")
else:
if n<0:
print("Nie można wybierać liczb ujemnych.")
else:
while i!=n:
fib=fib2
fib2=fib2+fib1
fib1=fib
i=i+1
print("Wynik to:"+str(fib2))
Nie ma oficjalnego style-guide, ja lubię ten sposób - jedyne, co ważne to to, żeby być konsekwentnym w wyborze sposobu zapisu klamer.
http://eoghang.blogspot.com/2009/05/...tion-wars.html
@camile:
Pominąłeś jeden edge case, zobacz co Twój kod zrobi dla n = 0.
Pozdrawiam
Killavus
Jasne, spoko ;). Kwestia gustu - mi to bardzo burzy 'visual flow'. Ale wiem, że wiele osób klamerki umieszcza pod ifem. Ale np. Visual Studio 2012 wymusza bodajże taką stylówę, która niekoniecznie mi się podoba (a akurat coś tam dłubie w C#)...
można w ustawieniach wybrać konwencję - gray
Pozdrawiam
Killavus
Czekałem sporo na taki temat, jutro po pracy przeczytam go dokładnie. Ogółem to mam nadzieje ze będziesz go sukcesywnie rozwijał i zdołam się czegoś nauczyć.
Zadanie 6. to z tym policjantem, jestem ultra skołowany tym :D Ale lubie logiczne zagadki, napisz czy dobrze ;P
Jeśli testament odnaleziono - > samobójstwo. To jest fakt.
Jeśli nie popełnił, to i tak odnaleziono.
Ale jeśli odnaleziono to na pewno popełnił.
Więc: Testament odnaleziono, i on popełnił samobójstwo.
Pytanie czy był zastraszony.
Nie był zastraszony, bo gdyby był zastraszony to by nie popełnił samobójstwa, ale wiemy że popełnił.
Moje odpowiedzi:
Nie był zastraszony, Popełnij samobójstwo, testament odnaleziono.
Na razie wszystko znam ale i tak czekam na dalszy ciąg bo świetnie opisujesz, może są jakieś rzeczy banalne które mi umknęły. Z niecierpliwością czekam na OOP :D
@down
Ale dlaczego nie odnaleziono, sprawdź swoje wyniki, czy pojawia ci sie tam gdzies ze nie ma testamentu? ;P
Polecam zrobic tabelke z wartosciami prawda/falsza i strzalkami, jesli tutaj falsz to tutaj prawda, albo jesli tutaj prawda to tutaj prawda. Latwiej sie ogarnac. Ja zostaje przy swoim stanowisku :D
Nie przypadkowo jest tam slowo "LUB" żeby namieszać w głowie :D
@edit
Program z problemem Collatza, z komentarzami. Troszeczke wybiega za treść killavusa, bo stworzona odrębna funkcja do faktycznego liczenia. Polecam, Marcin Bazanowski :D
Kod:
#include <stdio.h>
#include <stdlib.h>
// utworzenie funkcji ze zmienna pobierana w trakcie wywolywania - typu integer
int collatza(int liczba)
{
//tworzenie licznika
int i=0;
//sprawdzenie warunku czy doszlismy do konca obliczen - liczby 1
while (liczba>1)
{
// sprawdzenie czy liczba parzysta - reszta z dzielenia przez 2 musi byc 0
if ( liczba%2 == 0 )
{
liczba=liczba/2; // wiadomo
}
else
{
liczba=(liczba*3)+1; // wiadomo
}
i++; // zwiekszenie licznika
// wyswietlenie aktualnej liczby
printf("\nLiczba aktualna: %d",liczba);
};
return i; // zwrocenie licznika czyli ilosci krokow
}
int main(int argc, char *argv[])
{
// utworzenie zmiennej do ktorej wpiszemy wlasna liczbe
int a;
printf("wpisz liczbe: "); //informacja dla uzytkownika
// wczytywanie z klawiatury - informacja dla kompilatora ze pobierzemy coś typu digit - liczbe
// ma ją przypisać do zmiennej a. Ważny znak & w C, killavus wiecej o tym napisze zapewne.
scanf("%d",&a);
// utworzenie zmiennej i , i przypisanie jej wartosci tego co sie wykona w funkcji collatza.
// Dla funkcji Collatza przekazujemy wczytana wartosc, dlatego zmienna int liczba bedzie miala wartosc a
int i=collatza(a);
// wyswietlenie wyniku. \n oznacza nowa linie, czysto dla wygladu programu.
printf("\n\nLiczba przeksztalcen dla liczby %d wynosi: %d\n\n",a,i);
system("PAUSE");
return 0;
}
Jutro dam rozwiązanie. Może być... zaskakujące ;).
Pozdrawiam
Killavus
heheszki, akurat zaczalem interesowac sie programowaniem :D (c#)
czekam na kolejne zadania ;P
btw jak juz tu jestem, to napisze mi ktos, jak zaslaniac text na czarno? dla niektorych moze obvious ale nie mam nigdy czasu tego poszukac (ta) ;p