-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
2076 lines (1812 loc) · 66.5 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# plik poświęcony kursowi na YT
import smtplib
import time
# pętla while
'''
name = None # ewentualnie dajemy ""
while not name: # ewentualnie gdy warunek wyżej, to sporawdzamy długość len(name) == 0
name = input("Podaj swoje imię: ")
print("Hello "+name)
'''
# pętla loop
# for "zmienna" in range("start","end","step")
'''
for i in range(10):
print(i)
for i in range(50,100+1):
print(i)
for i in "Bro Code":
print(i) # wypisanie każdej litery w podanej sekwencji
for seconds in range(10,0,-1):
print(seconds)
time.sleep(1)
print('Happy New Year!!!')
# nestled loops - pętla w pętli
rows = int(input("How many rows?: "))
columns = int(input("How many columns?: "))
symbol = input("Enter a symbol to use?: ")
for i in range(rows):
for j in range(columns):
print(symbol, end="") # end="" zapobiega przejściu do nowej linii
print() # nowa linia
'''
# loop control statements
# break = zatrzymuje pętle
# continue = przechodzi do następnej iternacji w pętli
# pass = do nothing, acts as a placeholder / symbol zastępczy?
'''
while True:
name = input("Enter your name: ")
if name != "":
break
phone_number = "123-456-7890"
for i in phone_number:
if i == "-":
continue
print(i, end="") # end="" zapobiega nowym liniom
for i in range(1, 21):
if i == 13:
pass
else:
print(i)
'''
# list = used to store multiple items in a single variable
'''
food = ["pizza", "hamburger", "hotdog", "spaghetti", "pudding"]
food[0] = "sushi"
# print(food[0])
# food.append("ice cream")
# food.remove("hotdog")
# food.pop() # usuwa ostatni element
# food.insert(0, "cake")
# food.sort()
# food.clear() # usuwa wszystko
for x in food:
print(x)
'''
# 2D list
'''
drinks = ["coffee", "soda", "beer"]
dinner = ["pizza", "hamburger", "hotdog"]
dessert = ["cake", "ice cream"]
food = [drinks, dinner, dessert]
print(food[1][2])
'''
# tuple = collection which is ordered and unchangeable used to group together related data
'''
student = ("Bro", 21, "male")
print(student.count("Bro"))
print(student.index("male"))
for x in student:
print(x)
if "Bro" in student:
print("Bro is here! ")
'''
# set - collection which is unordered, unindexed. No duplicate value
'''
utensils = {"fork", "spoon", "knife"} # set jest szybszy od list
# nie pozwala na duplikaty oraz nie ma indeksowania ( jak worek )
dishes = {"bowl", "plate", "cup", "knife"}
# utensils.add("napkin")
# utensils.remove("fork")
# utensils.clear()
# utensils.update(dishes) # mozna łączyc sety
dinner_table = utensils.union(dishes) # łączenie
for x in dinner_table:
print(x)
print(utensils.difference(dishes)) # co ma utensils a nie ma dishes
print(utensils.intersection(dishes)) # to co mają wspólne
'''
# dictionary = A changeable, unordered colection of unique key: value pairs
# Fast because they use hashing, allow us to access a value quickly
'''
capitals = {'USA': 'Washington DC',
'India': 'New Dehli',
'China': 'Beijing',
'Russia': 'Moscow'}
capitals.update({'Germany': 'Berlin'})
capitals.update({'USA':'Las Vegas'})
capitals.pop('China') # usunięcie danej wartości
capitals.clear() # wyczyszczenie słownika
# print(capitals.get('Germany')) # sprawdzanie czy dana wartośc się znajduje w słowniku
# print(capitals.keys())
# print(capitals.values())
# print(capitals.items()) # wypisanie par
for key, value in capitals.items():
print(key, value)
'''
'''
# index operator [] = gives access to a sequence's element (str, list, tuples)
name = "bro Code!"
if(name[0].islower()):
name = name.capitalize() # capitalize zmienia pierwszą literę na dużą
first_name = name[:3].upper() # gdy zaczynamy od początku to nie potrzebujemy podawać 0 na początku
last_name = name[4:].lower() # gdy nie podam jak długie jest nazwisko tylko zostawie miejsce to oznacza że do końca
last_character = name[-1]
print(first_name)
print(last_name)
print(last_character)
'''
# function = a block of code which is executed only when it is called
'''
def hello(first_name, last_name,age):
print("Hello " + first_name + " " + last_name)
print("You are "+ str(age) + " years old.")
print("Have a nice day! ")
# hello("Bro", "Code", 21)
# liczba parametrów musi się zgadzać !
'''
# return statment = Function send Python values/objects bact to the caller.
# These values/objects are know as the function's return value
'''
def multiply(n1, n2):
return n1 * n2
x = multiply(6,2)
print(x)
'''
# keywords arguments = arguments preceded by an identifier when we pass them to a function
# The order of the arguments doesn't matter, unlike positional arguments
# Python knows the names of the arguments thet uor function receives
'''
def hello(first, middle, last):
print("Hello "+first+" "+ middle+" "+last)
hello(last="Code",middle="Dude",first="Bro")
# chodzi po porstu o kolejność jeśli jest wpisywana inaczej
'''
# nested functions calls = function calls inside other function calls innermost function calls are resolved first
# returned value is used as argument for the next outher function
'''
print(round(abs(float((input("Enter a whole positive number: "))))))
# nested functions calls - funkcje zagnieżdżone - nie są rozbijane
'''
# scope = The region that a variable is recognized
# A variable is only avilable form inside the region it is created
# A global and locally scoped versions of variable can be created
name = "Andrzej " # global scope (available inside & outside functions # zmienna globalna
'''
# global scope - zasięg globalny
def display_name():
name = "Code" # local scope ( available only inside this functon ) # zmienna lokalna xD
print(name)
display_name()
print(name)
'''
# *args = parameter that will pack all arguments into a tuple useful so that a function can accept
# a varying amount of arguments
# podajemy po prostu listę argumentów a w funkcji to uwzględniamy
# trzeba pamiętać że podajemy tuple (krotkę) więc chcąc na niej działać trzeba ją zamienić na liste
'''
def add(*stuff):
sum = 0
stuff = list(stuff)
stuff[0]=0
for i in stuff:
sum += i
return sum
print(add(1,2,3,4,5,6))
'''
# **kwargs = parameter that will pack all arguments into a dictionary
# useful so that a function can accept a varying amount of keyword arguments
# czyli podajemy słownik zamiast tuple
'''
def hello(**kwargs): # pamiętać że muszą być te dwie gwiazdki bo potem nazwa może być różna
# print("Hello " + kwargs['first'] + " " + kwargs['last'])
print("Hello" , end=" ")
for key, value in kwargs.items():
print( value, end= " ")
hello(title = "Mr.", first="Bro",middle = "Dude", last="Code")
'''
# str.format() = optional method that gives users more control when displaying output
# sposób zapisania inaczej printa - bardziej estetyczny
'''
# animal = "cow"
# item = "moon"
# print("The "+animal+" jumped over the " + item)
# print("The {} jumped over the {}".format(animal, item))
# print("The {1} jumped over the {1}".format(animal, item)) # positional argument
# print("The {animal} jumped over the {item}".format(animal="cow", item="mood")) # keyword argument
# text = "The {} jumped over the {}"
# print(text.format(animal,item))
# name = "Bro"
# print("Hello, my name is {}".format(name))
# print("Hello, my name is {:10}. Nice to meet you".format(name)) # {:10} to oznacza 10 spacji po
# print("Hello, my name is {:<10}. Nice to meet you".format(name)) # {:10} to oznacza 10 spacji po
# print("Hello, my name is {:>10}. Nice to meet you".format(name)) # {:10} to oznacza 10 spacji przed
# print("Hello, my name is {:^10}. Nice to meet you".format(name)) # {:10} to oznacza 10 spacji a napis wyśrodkowany
number = 1000
print("The number pi is {:.3f}".format(number)) # zaokrągla do 3 miejsc po przecinku
print("The number pi is {:,}".format(number)) # dzieli na tysiące
print("The number pi is {:b}".format(number)) # zamiana na binarny
print("The number pi is {:o}".format(number)) # zamiana na ósemkowy
print("The number pi is {:X}".format(number)) # zamiana na szestnastkowy
print("The number pi is {:E}".format(number)) # format matematyczny
'''
# liczby pseudo-randomowe
'''
import random
x = random.randint(1,6)
y = random.random()
myList = ['rock', 'paper', 'scissors']
z = random.choice(myList) # losowanko z papier kamień nożyce
cards = [1,2,3,4,5,6,7,8,9,"J","Q","K","A"]
random.shuffle(cards) # losowe przelosowanie xD
print(cards) # karty po przelosowaniu
'''
# exception = events detected during execution that interrupt the flow of a program
# wyjątki...
'''
try:
numerator = int(input("Enter a number to divide: "))
denominator = int(input("Enter a number to divide by: "))
result = numerator/denominator
except ZeroDivisionError as e:
print(e)
print("You can't divide by zero! Idiot! ")
except ValueError as e:
print(e)
print("Enter only numbers plz")
except Exception as e:
print(e)
print("Something went wrong :(")
else:
print(result)
finally: # to zawsze się wykonuje
print("This will always execute")
'''
# file detection - sprawdzenie czy plik istnieje
'''
import os
path = "C:\\Users\\andrz\\Desktop\\test.txt"
if os.path.exists(path):
print("That location exists!")
if os.path.isfile(path):
print("That is a file")
elif os.path.isdir(path):
print("That is a directory!")
else:
print("That location doesn't exists!")
'''
# reading a file - czytanie pliku
'''
try:
with open('C:\\Users\\andrz\\Desktop\\test.txt') as file:
print(file.read())
except:
print("That file was not found :(")
# print(file.close()) # sprawdzenie czy plik został zamknięty
'''
# Zapisywanie do pliku
'''
# text = "Yooooooo\nThis is some text\nHave a good one!"
text = "This text was overwritten"
with open('C:\\Users\\andrz\\Desktop\\test.txt','w') as file: # otwieramy w trybie do zapisu 'w'
file.write(text) # pamiętać że plik jest nadpisywany
'''
# copy file() = copies contents of a file
# copy() = copyfile() + permission mode + destiantion can be a directiory
# copy2() = copy() + copies metadata (file's creation and modification times)
# kopiowanie plików
'''
import shutil
shutil.copyfile('C:\\Users\\andrz\\Desktop\\test.txt','copy.txt')
'''
# moving files
# by to działało to musi być to robione na jednym dysku
'''
import os
source = "copy.txt"
destination = "D:\\Do_nauki\\copy.txt"
try:
if os.path.exists(destination):
print("There is already a file there")
else:
os.replace(source, destination)
print(source+" was moved")
except FileNotFoundError:
print(source+" was not found")
'''
# delete files - usuwanie plików i folderow
'''
import os
import shutil
path = "test.txt"
# os.remove(path) # usuwa plik
try:
# os.remove(path) # delete a file
# os.rmdir(path) # delete an empty directory
# shutil.rmtree(path) # delete a directory containing files
except FileNotFoundError:
print("That file was not found")
except PermissionError:
print("You do not have premission to delete that")
except OSError:
print("You cannot delete that using that function")
else:
print(path+" was deleted")
'''
# module = a file containing python code. May contain functions, classes, etc
# Used with modular programming, which is to separate a program into parts
# można też dać from messages import * ale może to w większych programach spowodować kolizje nazw
'''
# import messages as msg
from messages import hello, bye
# msg.hello()
# msg.bye()
hello()
bye()
help("modules")
# Jest też strona z bibliotekami standardowymi chyba "Python Module Index"
'''
# gra papier kamień nożyce
'''
import random
while True:
choices = ["rock", "paper", "scissors"]
computer = random.choice(choices)
player = None
while player not in choices:
player = input("rock, paper, or scissors?: ").lower() # zamieniamy na małe
if player == computer:
print("computer: ",computer)
print("player: ",player)
print("Tie!")
elif player == "rock":
if computer == "paper":
print("computer: ", computer)
print("player: ", player)
print("You lose!")
if computer == "scissors":
print("computer: ", computer)
print("player: ", player)
print("You win!")
elif player == "scissors":
if computer == "rock":
print("computer: ", computer)
print("player: ", player)
print("You lose!")
if computer == "paper":
print("computer: ", computer)
print("player: ", player)
print("You win!")
elif player == "paper":
if computer == "scissors":
print("computer: ", computer)
print("player: ", player)
print("You lose!")
if computer == "rock":
print("computer: ", computer)
print("player: ", player)
print("You win!")
play_again = input("Play again? (yes/no): ").lower()
if play_again !="yes":
break
print("Bye!")
'''
# quiz game
# gra na A, B, C, D
# -------------------------
'''
def new_game():
guesses = []
correct_guesses = 0
question_num = 1
for key in questions:
print("------------------------")
print(key)
for i in options[question_num-1]:
print(i)
guess = input("Enter (A, B, C, or D): ")
guess = guess.upper()
guesses.append(guess)
correct_guesses += check_answer(questions.get(key),guess)
question_num += 1
display_score(correct_guesses, guesses)
# -------------------------
def check_answer(answer, guess):
if answer == guess:
print("CORRECT!")
return 1
else:
print("WRONG!")
return 0
# -------------------------
def display_score(correct_guesses, guesses):
print("----------------------------")
print("RESULT")
print("----------------------------")
print("Answers: ", end="")
for i in questions:
print(questions.get(i), end=" ")
print()
print("Guesses: ", end="")
for i in guesses:
print(i, end=" ")
print()
score = int((correct_guesses/len(questions))*100)
print("Your score is: "+ str(score)+"%")
# -------------------------
def play_again():
response = input("Do you want to play again? (yes/no): ")
response = response.upper()
if response == "YES":
return True
else:
return False
# -------------------------
questions = {
"Who crated Python?: ": "A",
"What year was Python created?: ": "B",
"Python is tributed to which comedy group?: ": "C",
"Is the Earth round?: ": "A"}
# pytania zostały tu zrobione za pomocą słownika
options = [["A. Guido van Rossum", "B. Elon Musk", "C BIll Gates", "D. Mark Zuckerburg"],
["A. 1989", "B. 1991", "C. 2000", "D. 2016"],
["A. Lonely Island", "B. Smosh", "C. Monty Python", "D.SNL"],
["A. True", "B. False", "C. Sometimes xD ", "D. What's Earth?"]]
# Do opcji została wykorzystana lista w liście
new_game()
# pętla do nowych gier
while play_again():
new_game()
print("------------------------------\nBYE!!!!")
'''
# -------------------------------------------------------
# PYTHON OBJECT ORIENT PROGRAMMING (POOP)
# PATRZ PLIK car.py
'''
from car import Car
car_1 = Car("Chevy","Corvette",2021,"blue")
car_2 = Car("Ford", "Mustang",2022, "red")
# print(car_2.make)
# print(car_2.model)
# print(car_2.year)
# print(car_2.color)
car_1.drive()
car_2 .stop()
'''
# differences between class and instant variables
'''
from car import Car
car_1 = Car("Chevy","Corvette",2021,"blue")
car_2 = Car("Ford", "Mustang",2022, "red")
car_1.wheels = 2 # jeśli np. to motocykl
# print(car_1.wheels)
# print(car_2.wheels)
# print(Car.wheels)
Car.wheels = 2 # można zmieniać stałą wartość dla wszystkich obiektów klasy w głównym programie i będzie to działać
print(car_1.wheels)
print(car_2.wheels)
'''
# inheritance in python
# czyli chodzi o dziedziczenie
'''
class Animal:
alive = True # class variable
def eat(self):
print("This animal is eating")
def sleep(self):
print("This animal is sleeping")
# by stworzyć klasę która ma klasę-matkę to w nawiasie podajemy klasę z której dziedziczymy
class Rabbit(Animal):
def run(self):
print("This rabbit is running")
class Fish(Animal):
def swim(self):
print("This fish is swimming")
class Hawk(Animal):
def fly(self):
print("This hawk is flying")
rabbit = Rabbit()
fish = Fish()
hawk = Hawk()
print(rabbit.alive)
fish.eat()
hawk.sleep()
rabbit.run()
fish.swim()
hawk.fly()
'''
# multi-level inheritance = when a derived (child) class inherits another derived (child) class
# dziedziczenie pochodne - dziedziczenie z klasy która także coś dziedziczy już
# to jest podobne do drzewa rodzinnego (family tree)
'''
class Organism:
alive = True
class Animal(Organism):
def eat(self):
print("This animal is eating")
class Dog(Animal):
def bark(self):
print("This dog is barking")
dog = Dog()
print(dog.alive)
dog.eat()
dog.bark()
'''
# multiple inheritance = when a child class is derived from more than one parent class
# dziedziczenie po więcej niż jednym rodzicu
'''
class Prey: # prey to ofiara
def flee(self): # flee to uciekać
print("This animal flees")
class Predator: # Predator - drapieżnik
def hunt(self): # hunt - polować
print("This animal is hunting")
class Rabbit(Prey):
pass
class Hawk(Predator):
pass
class Fish(Prey, Predator):
pass
rabbit = Rabbit()
hawk = Hawk()
fish = Fish()
# rabbit.flee()
# hawk.hunt()
fish.flee()
fish.hunt()
'''
# method overriding in python
# chodzi o nadpisywanie
'''
class Animal:
def eat(self):
print("This animal is eating")
class Rabbit(Animal):
def eat(self):
print("This rabbit is eating a carrot")
# no i ogólnie tak wygląda nadpisanie - czyli ta sama nazwa w klasie która już coś dziedziczy
rabbit = Rabbit()
rabbit.eat()
'''
# method chaining = calling multiple methods sequentially
# each call performs an action on the same object and return self
# wywołanie wielu metod na tym samym obiekcie sekwencyjnie?
'''
class Car:
def turn_on(self):
print("You start the engine")
return self
def drive(self):
print("You drive the car")
return self
def brake(self):
print("You step on the brakes")
return self
def turn_off(self):
print("You turn off the engine")
return self
car = Car()
# car.turn_on().drive()
# car.brake().turn_off()
# ten "\" oznacza kontynuowanie komendy w nowej linii
car.turn_on()\
.drive()\
.brake()\
.turn_off()
# ten methon chaining polega na tym że można dane funcje z klasy wywoływać zaraz po sobie
# trzeba tylko pamiętać by zwrócić w klasie "self" w każdej funkcji
'''
# super() = Function used to give access to the methods of the parent class.
# Returns a temporary object of a parent class when used
# służy do dostania się do klasy nadrzędnej
# chodzi o wykorzystnie funkcji klasy nadrzędnej wraz z jej parametrami jeśli mają coś wspólnego
'''
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
class Square(Rectangle):
def __init__(self, length, width):
super().__init__(length,width)
def area(self):
return self.width * self.length
class Cube(Rectangle):
def __init__(self, length, width, height):
super().__init__(length,width)
self.height = height
def volume(self):
return self.width * self.length * self.height
square = Square(3, 3)
cube = Cube(3, 3, 3)
print(square.area())
print(cube.volume())
'''
# !!! całkiem ważne
# Prevents a user from crating an object of that class # coś ala ghost class - szablon
# + compels a user to override abstract methods in a child class
# abstract class = a class which contains one more abstract methods
# abstract method = a method that has a declaration but does not have an implementation.
# abstract class ma zapobiec możliwości stworzenia przez użytkownika obiektu tej klasy
'''
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def go(self):
pass
@abstractmethod
def stop(self):
pass
class Car(Vehicle):
def go(self):
print("You drive the car")
def stop(self):
print("This car is stopped")
class Motorcycle(Vehicle):
def go(self):
print("You ride the motorcycle")
def stop(self):
print("This motorcycle is stopped")
# vehicle = Vehicle() - abstract ma zapobiec możliwości stworzenia obiektu tej klasy - wyrzuci błąd po prostu
car = Car()
motorcycle = Motorcycle()
# vehicle.go() - nie można korzystać z abstrakcyjnych funkcji/ metod
car.go()
motorcycle.go()
car.stop()
motorcycle.stop()
# ogólnie rzecz mówiąc to abstract class i abstract method są jakby szablonem który trzeba nadpisać by program działał
# Car jest pojazdem typu Vehicle i musi mieć nadpisane takie metody jak "go" czy "stop" bo takie są w szablonie
# bo każdy pojazd dziedziczony po Vehicle powinien mieć takie metody - zapobiega to wkradaniu się błędów i programista
# też będzie pamiętał by to nadpisać bo inaczej będzie wyrzucało błąd
'''
# pass objects as arguments
# przekazywanie obiektów jako argumenty
# gdy podajemy parametry to muszą one się zgadzać w funkcji którą piszemy - piszemy funkcję zmieniającą paramtery klasy
# którą chcemy przekazać to musimy pamiętać by w funckji paramter tej klasy się zgadzał z stanem faktycznym
'''
class Car:
color = None
class Motorcycle:
color = None
def change_color(car, color):
car.color = color
car_1 = Car()
car_2 = Car()
car_3 = Car()
bike_1 = Motorcycle()
change_color(car_1,"red")
change_color(car_2,"white")
change_color(car_3,"blue")
change_color(bike_1,"black")
print(car_1.color)
print(car_2.color)
print(car_3.color)
print(bike_1.color)
'''
# Duck typing = concept where the class of an object is less important than methods/attributes
# class type is not checked if minimum methods/attributes are present
# "If it walks like a duck, and it quacks like a duck, then it must be a duck."
'''
class Duck:
def walk(self):
print("This duck is walking")
def talk(self):
print("This duck is quacking")
class Chicken:
def walk(self):
print("This chiken is walking")
def talk(self):
print("This chicken is clucking")
class Person():
def catch(self, duck):
duck.walk()
duck.talk()
print("You cauth the critter")
duck = Duck()
chicken = Chicken()
person = Person()
person.catch(chicken)
# w skrócie to funkcja catch zadziała gdy klasa "duck" W NIEJ OPISANA będzie posiadała dane metody wktóre są wymagane
# chodzi o "walk" i "talk" wtedy np. kurczak może być uznany za "kaczkę" chodź nią nie jest, jakby np. nie chodził to
# zwróci nam ta funckja error gdyż nie będzie klasa "chiken" nie będzie miała atrybutu "walk" i nie będzie
# wtedy kurczakiem
'''
# walrus operator := # operator morsa?
# net to Python 3.8
# assignment expression aka walrus operator
# assigns values to variables as part of a larger expression
'''
# happy = True
# print(happy)
# print(happy = True) # to zwróci błąd
# print(happy := True) # tak będzie to działało oraz dana zmienna zostanie utworzona
# prosty program :
# foods = list()
# while True:
# food = input("What food do you like: ")
# if food == "quit":
# break
# foods.append(food)
# ----------------------------------
# teraz drugi sposób za pomocą operatora ":=" (czyli tego walrus operator) - będzie mniej linii kodu
foods = list()
while food := input("What food do you like?: ") != "quit":
foods.append(food)
'''
# assign function to a variable
# przypisanie funkcji do zmiennej
'''
def hello():
print("Hello")
# print(hello) # coś takiego spowoduje wyświetlenie adresu funckji w pamięci komputera
# hi = hello # przypisanie adresu funkcji (bez nawiasów "()") do zmiennej
# print(hi) # wyświetlenie zawartości zmiennej (czyli adresu funckji hello)
# hello()
# hi() # coś takiego spowoduje wykonanie funkcji hello() ale pod inną nazwą (coś ala alias)
say = print
say("Whoa!! I can't believe this works! :o")
# czyli stworzyliśmy coś ala kopię funckji print ale pod inną nazwą i możemy wykonywać teraz daną funckję
# ale pod różnymi nazwami jakimi chcemy
'''
# Higher Order Functions = a function that either:
# 1. accepts a function as an argument
# or
# 2. returns a function
# (In python, functions are also treated as objects)
# czyli funkcja która przyjmuje jako argument funkcję albo zwraca funkcję
'''
# def loud(text):
# return text.upper()
#
# def quiet(text):
# return text.lower()
#
# def hello(func):
# text = func("Hello")
# print(text)
#
# hello(loud)
# hello(quiet())
def divisor(x):
def divident(y):
return y/x
return divident
divide = divisor(2)
print(divide(10))
print(divide) # do zmiennej divide przypisaliśmy adres funkcji
# chodzi o to że najpierw wowołujemy zewnętrzną funkcję (divisor) która zwraca nam funkcję którą ma wewnątrz, a tą
# z kolei wywołujemy dodając nawias i wpisując liczbę bo inaczej ona sama by była zmienną
'''
# lambda function = function written in 1 line using lambda keyword accepts any number of arguments, but only has
# one expression. (think of it as a shortcut) (useful if needed a short period of time, throw-away)
# W skrócie to jakoś funckja z dowolną ilością argumentów, jednym wyrażeniem, gdy jest potrzebna na chwilę
# lambda parameters:expression
'''
# normalny sposób:
# def double(x):
# return x * 2
# print(double(5))
# za pomocą lambdy:
double = lambda x:x * 2
print(double(5))
multiply = lambda x, y: x * y
print(multiply(5,6))
add = lambda x, y, z: x + y + z
print(add(1,2,3))
full_name = lambda first_name, last_name: first_name+" "+last_name
print(full_name("Bro","Code"))
age_check = lambda age: True if age >=18 else False
print(age_check(29)) # czyli to są takie skróty
'''
# sort() method = used with lists
# sort() function = used with iterables
'''
# students = ("Squidward","Sandy","Patrick","Spongebob","Mr.Krabs")
# students.sort(reverse=True) # reverse = True oznacza w odwrotnej kolejności i to działa na listy
# sorted_students = sorted(students, reverse=True)
# for i in students:
# print(i)
# for i in sorted_students:
# print(i)
students = [("Squidward", "F", 60),
("Sandy", "A", 33),
("Patrick", "D", 36),
("Spongebob", "B", 20),
("Mr.Krabs", "C", 78)
]
grade = lambda grades:grades[1] # to spowoduje wybranie drugiej kolumny - jest to skrót funkcji w której to dostajemy
# się do drugiej kolumny
age = lambda ages:ages[2]
students.sort(key=age)
# jeśli zamiast listy mielibyśmy tuple to wykorzystalibyśmy :
# sorted_students = sorted(students,key=age)
for i in students:
print(i)
'''
# map() = applies a function to each item i na iterable (list, tuple, etc)
#
# map(function, iterable)
# mapuje - zmienia wartości każdej iteracji w danej liście/tupli itp za pomocą podanej funkcji
'''
store = [("shirt", 20.00),
("pants",25.00),
("jacket",50.00),
("socks",10.00)]
to_euros = lambda data: (data[0],data[1]*0.82)
to_dollars = lambda data: (data[0], data[1]/0.82)
store_euros = list(map(to_euros, store))
store_dollars = list(map(to_dollars, store))
for i in store_dollars:
print(i)
'''
# filter() = create a collection of elements from an iterable for which a function returns true
# filtruje dane
# filter(function, iterable)
'''
friends = [("Rachel",19),
("Monica",18),
("Phoebe",17),
("Joey",16),
("Chandler",21),
("Ross",20)]
age = lambda data:data[1] >= 18
drinking_boddies = list(filter(age,friends))
for i in drinking_boddies:
print(i)
'''
# reduce() = apply a function to an iterable and reduce it to a single cumulative value.
# performs function on first two elements and repeats process until 1 value remains
# tak jakby zmniejsza ilość elementów - z kilku łączy w jeden (literki w słowa itp)
# reduce(function, iterable)
'''
import functools
# letters = ["H","E","L","L","O"]
# word = functools.reduce(lambda x, y: x + y,letters)
# print(word)
factorial = [5,4,3,2,1]
result = functools.reduce(lambda x, y: x * y,factorial) # coś ala silnia # będzie to wymnażać wartości w liście
print(result)
'''
# list comprehension = a way to create a new list with less syntax can mimic certain lambda functions, easier to read
# lista z mniejszą ilością składni?
# 1 lista = [expression for item in iterable]
# 2 lista = [expression for item in iterable if conditional]
# 3 lista = [expression if/else for item in iterable]
'''
# squares = [] # create an empty list
# for i in range(1,11): # create a for loop
# squares.append((i*i)) # define what each loop iteration should do
# print(squares)
# teraz za pomocą list comprehension # 1
# squares = [i * i for i in range(1,11)]
# print(squares)
# --------------------------------------------------------------------------------------------------
students = [100,90,80,70,60,50,40,30,0]
passed_students = list(filter(lambda x: x >=60, students))
print(passed_students)
# teraz za pomocą list comprehension # 2
passed_students = [i for i in students if i >= 60]
print(passed_students)
# teraz za pomocą list comprehension # 3
passed_students_v2 = [i if i >= 60 else "FAILED" for i in students]
print(passed_students_v2)
'''
# dictionary comprehension = create dictionaries using an expression can replace for loops and certain lambda functions
# tworzenie słowników za pomocą wyrażenia może zastąpić pętle lub funkcje lambda
# 1 # dictionary = {key: expression for (key,value) in iterable}
# 2 # dictionary = {key: expression for (key,value) in iterable if conditional}
# 3 # dictionary = {key: (if/else) for (key,value) in iterable}
# 4 # dictionary = {key: function(value) for (key,value) in iterable}
# zamiana Farenhaita na Celcius za pmocą metody # 1
'''
# cities_in_F = {'New York': 32, 'Boston': 75, 'Los Angeles': 100, 'Chicago': 50}
#
# cities_in_C = {key: round((value-32)*(5/9)) for (key,value) in cities_in_F.items()}
# print(cities_in_C)
# -------------------------------------------------------------------------------------------------------
# za pomocą metody # 2
# weather = {'New York': "snowing", 'Boston': "sunny", 'Los Angeles': "sunny", 'Chicago': "cloudy"}