#python

37
112
Napisałem sobie taki krótki program do robienia zdjęć z kamerki, gdzie potem sklejam z tego timelapse, ale nie rozumiem jednej rzeczy - zdjęcia zapisują się... z opóźnieniem. Musiałem dolać ukorzeniacza do awokado, więc zabierałem je sprzed kamerki. Po skończonej robocie (9:47) usiadłem do kompa i sprawdziłem poprzednie zdjęcia czy ustawiłem rośliny w miarę w tych samych miejscach. A tu się okazuje, że zdjęcie które powinno być zrobione w momencie skończenia, to tak naprawdę zdjęcie sprzed kilku minut. Łącznie zajęło mu 8 minut (5 zdjęć), zanim dotarł do momentu w którym skończyłem. Dlaczego tak jest? Czegoś tu nie rozumiem?
Kod:
import cv2
from time import sleep
from datetime import datetime

cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080.0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1920.0)
cam.set(cv2.CAP_PROP_AUTO_WB, 0.0)
cam.set(cv2.CAP_PROP_WB_TEMPERATURE, 7000)
cam.set(cv2.CAP_PROP_SATURATION, 75)
cam.set(cv2.CAP_PROP_CONTRAST, 100)
while True:
   retval, frame = cam.read()
   dt = datetime.now()
   ts = int(datetime.timestamp(dt))
   if retval != True:
      print(str(dt) + ": Can't read frame")
      sleep(5)
      continue
   cv2.imwrite(str(ts) + '.png', frame)
   print(str(dt) + ": saved img " + str(ts) + ".png")
   sleep(120)
#python #programowanie
9e52353b-adf4-4507-b0d0-c53a4af049de
298ca152-8de6-486d-ab2f-5cfddaf7e444
203129d3-d0a7-4a2a-94e6-ee680a320cc4
edbf2503-175a-452d-b48e-c86cd23ecdf2
50e6dc6b-50c7-4419-9057-a4faaeedf354
Prucjusz

@Bielecki cv2 działa bardzo wolno. Spróbuj z numpy.

Jesli dobrze pamiętam, z obiektu cv2 można wyciągnąć tablicę numpy i za jego pomocą to zapisać do pliku.

Bielecki

@markxvyarov dlaczego tak uważasz? Jeśli retval będzie false, to kontynuuję loop, żeby nie wywalać całego programu, ale nie zapisuję obrazu


@Prucjusz najwolniejsze w opencv w moim przypadku jest inicjalizowanie kamery przez cv2.VideoCapture(0). Ja loopuję się już po inicjalizacji, nie zwalniam kamery. Sam zapis odbywa się w ciągu ~0,1s, zakładając że sleep trwa równe 120s (takie mam różnice w timestampach).


@psalek dzięki, to mi wiele powiedziało. Wygląda na to że to właśnie bufor. Niby mogę zastosować te rozwiązania (choć porzucanie ramek przez opencv z tego co znalazłem odbywa się poprzez ustawianie odpowiednich properties kamery i nie jestem pewien czy 1. jest to wspierane przez mój model, 2. jest to nadal w opencv, bo gdzieś była wzmianka, że to usunęli), ale to w sumie byłaby sztuka dla sztuki - a w moim przypadku rozwiązanie się w sumie sprawdza. Zwyczajnie mnie ciekawiło dlaczego tak się dzieje i mam odpowiedź. Dzięki

GrindFaterAnona

@Bielecki czym to potem składasz w filmik?

Zaloguj się aby komentować

Jak to jest z tym Django w Pytonie? Warto poświęcić na to czas? Ktoś zna jakiś poradnik, który byłby przystępny dla nieogara(idealnie by było, gdyby był w języku polskim)?
#programowanie #django #backend #python
koszotorobur

@Prucjusz - bardzo lubię Pythona (co potwierdzają moje wpisy na tagu #python) ale od Django trzymam się z daleka bo to kobyła dla korposzczurów - i do tego zaczyna być przestarzały.

Do robienia stron to teraz SvelteKit lub Astro i deployment do Vercel na szybko przy minimum konfiguracji (lub jak ogarniasz, to wszystko skonteneryzowane i hostowane na jakiejś instancji z procesorem ARM w chmurze lub self-hosted po taniości).

Zrobiłem kilka wewnętrznych projektów gdzie frontend pisałem w SvelteKit a backend (REST API) z wykorzystaniem Pythonowego frameworka FastAPI - frontend i backend oczywiście śmigają w swoich osobnych kontenerach (gdzie base image do frontendu to Distroless Node.js a do backendu oficjalny Pythonowski Debian Slim) - i tak mi się robiło najlepiej i wszystko jest proste w utrzymaniu.

koszotorobur

@Prucjusz - naprawdę nie rozumiem dlaczego Django do swoich własnych projektów - jak już komentowałem to są o wiele prostsze rzeczy, w których można robić całkiem skomplikowane stronki.

Napisz coś więcej poza faktem, że się odbiłeś 2 razy od Django i teraz czujesz, że musisz go ogarnąć.

Zaloguj się aby komentować

W pracy, udało nam się przepisać celery z Pythona na nasz własny menedżer tasków w Rust.
Wydajność jest zauważalnie lepsza, bo korzystamy ze starych komponentów i tam różnice są o wiele bardziej widoczne, niż na zwykłym komputerze, gdzie oba rozwiązania przetwarzają zadania niemal natychmiast.

Zatem mamy część z kodem w Rust, ale ciągle część z obliczeń musimy wykonać w pojedynczym procesie pythona do którego wysyłamy resty z zapytaniami.
Jednak celery miało jeden duży plus - uruchamiało się jako osobne procesy(co wydłużało o kilka sekund proces uruchamiania programu), dzięki czemu operacje numpy/scipy na CPU, były ładnie rozdzielane po stronie pythona na wszystkie wątki(na urządzeniu są 4 rdzenie i tyle samo procesów celery było uruchamianych)

Operacje obliczania statystyk(mowa o powyższym zadaniu korzystającym z numpy/scipy) są często zlecane w większej ilości na raz, dlatego ważne jest by to zrównoleglić.
Próbowałem robić to przez proste rozdzielanie tasków na wiele wątków, jednak, czasy bywały nawet czasami gorsze, niż jak robiłem to w jednym wątku - domyślam się że to wina GIL i tego że nie działa zbytnio dobrze, gdy wątki wykonują masę rzeczy na cpu.
Drugim problemem jest to że w przypadku równoległych działań wyskakują dziwne ostrzeżenia, przez co myślę że np. matplotlib, nie jest przystosowany do działania z wielu wątków(mimo że zadania które wykonuję od początku do końca działają tylko w jednym wątku), bo przechowuje globalnie jakieś parametry ze swoim stanem.

Kojarzycie, w jaki sposób, mógłbym w miarę prosto, móc wykonywać te obliczenia po stronie pythona na wielu wątkach?
#python
markxvyarov

@qarmin jest standardowy moduł w Pythonie, nazywa się multiprocessing. W nim znajdziesz Pool i metody typu starmap i map. Najczęściej z tego korzystam gdy trzeba zrównoległość obliczenia.


https://superfastpython.com/multiprocessing-pool-map/

# SuperFastPython.com

# example of parallel map() with the process pool

from random import random

from time import sleep

from multiprocessing.pool import Pool

# task executed in a worker process

def task(identifier):

    # generate a value

    value = random()

    # report a message

    print(f'Task {identifier} executing with {value}', flush=True)

    # block for a moment

    sleep(value)

    # return the generated value

    return value

# protect the entry point

if __name__ == '__main__':

    # create and configure the process pool

    with Pool() as pool:

        # execute tasks in order

        for result in pool.map(task, range(10)):

            print(f'Got result: {result}', flush=True)

    # process pool is closed automatically


Na zamieszczonym zdjęciu znajdziesz wszystkie metody z klasy Pool które możesz wykorzystać.

eaab2cd3-50c4-480c-aa4f-b776373b7c0f

Zaloguj się aby komentować

Zostań Patronem Hejto i odblokuj dodatkowe korzyści tylko dla Patronów

  • Włączona możliwość zarabiania na swoich treściach
  • Całkowity brak reklam na każdym urządzeniu
  • Oznaczenie w postaci rogala , który świadczy o Twoim wsparciu
  • Wcześniejszy dostęp, do wybranych funkcji na Hejto
Zostań Patronem
Nie tak dawno temu dokonałem czegoś niemożliwego - znalazłem błąd który był w obcej bibliotece, a nie w moim kodzie.

Na jednym ze starych armów których używamy, odkryliśmy bład w pythonowym programie, gdzie podczas testowania punktów poza okręgiem o promieniu 30, niekiedy wartości wyskakiwały poza skalę.

W okręgu r<30 mamy ~60 punktów z wartościami, które im dalej od środka, tym bardziej się powinny zmniejszać. Dla punktów spoza okręgu r>30 musimy to ekstrapolować, bo do nich danych nie mamy.

Lokalnie na komputerze wszystko mi działało, choć metoda ekstrapolacji wartości RBFInterpolator(korzystamy ze starszej wersji scipy - nie możemy jej niestety łatwo podnieść na urządzeniu, by przetestować czy została naprawiona) dawała nieco niepoprawne i zawyżone wyniki.

Dla pewności ujednoliciłem wersje wszystkich pakietów(głównie zależności pośrednich, bo główne zależności były w tej samej wersji) pomiędzy urządzeniem i komputerem, jednak nie przyniosło to żadnej poprawy.

Przełożony na wieść że nie występuje problem lokalnie, zasugerował bym upewnił się że wszystko lokalnie sprawdzam z tymi samymi parametrami co na urządzeniu. Niezbyt wziął pod uwagę moje wątpliwości co do tego, że może jest to wina biblioteki - szczerze mówiąc się mu nie dziwię, bo z jego strony nie wyglądało to zbyt dobrze - gościu tylko od roku programujacy mówi że być może to nie jego wina i problem może występować w jednej z najpopularniejszych bibliotek pythona i w issues na githubie nie było nawet jednego podobnego wątku.

Ostatecznie udało mi się zilustrować wartości w siatce w kwadracie (od -100 do 100) przy użyciu matplotlib, gdzie widoczne było że na komputerze wartości w miarę regularnie zmniejszają w miarę oddalania od środka. W przypadku urządzenia ARM, wartości promieniście odchodzące z kątów 0,90,180,270 stopni poza okręgiem(r>30), są wybite poza wszelkie granice.

Wygląda więc że w przyszłości będziemy musieli, zainstalować na produkcyjnym sprzęcie pytest, by sprawdzić czy wszystko działa tak jak powinno na armowym urządzeniu, skoro nikomu już nie można wierzyć.

#python
#programowanie
b48a7301-09cf-499d-ab8f-77e27bef38f0
ZohanTSW

Niesamowite że ktoś pomyślał że może z tym nie być problemu - zawsze powinno się budować, uruchamiać testy na docelowym sprzęcie (przecież tam będzie to wszystko działać na nie na kompie programisty lol). Dobrym pomysłem jest nawet redundancja, macie joba który uruchomi testy na x86_64 i joba na ARM, oba muszą przejść. Gdybyście kompilowali, to również im więcej kompilatorów tym lepiej. W embedded trzeba spodziewać się niespodziewanego.

A już totalną ignorancją okazali się prowadzący ten projekt jeśli uruchamiacie testy na 64 bitowej platformie, a docelową platformą jest 32 bitowy ARM

Ilirian

Najgorzej jak znajdziesz buga w Firefoxie i okazuje się że podobny błąd został zgłoszony w 2006 roku i od 18 lat toczy się pod nim dyskusja. Co jakiś czas ktoś pyta kiedy to będzie naprawione, następnie ktoś z mozilli odpowiada że nad tym pracuje by za dwa lata znowu dostać pytanie o postępy xD


Zauważyłem np że firefox na androidzie bardzo często odświeża strony po powrocie do niego, tak jakby od razu po przeskoczeniu do innej apki czyścił dane strony z pamięci. Oczywiście zgłoszony bug wisi od paru lat w backlogu bo niby ważny błąd ale jakoś tak nie umieją go odtworzyć


(sorki za offtop xD)

sadamasin

Używacie biblioteki scipy i się dziwicie… zaciągnijcie normalnie z github a nie z jakiejś cipy…

Zaloguj się aby komentować

Powerful Python One-Liners

A z jakich jednolinijkowców Wy korzystacie?

#technologia #programowanie #python
24e4fc68-4929-4a23-96a5-695c3f34cd1b
wonsz

import itertools, more-itertools

def

Jedyne do czego używam pythona python3 -m http.server

koszotorobur

@def - to i tak dobrze - bo super wygodne

sebie_juki

@koszotorobur sudo cat /dev/random > /dev/sda1

koszotorobur

@sebie_juki - czy ty aby przypadkiem nie próbujesz wystrychnąć nas na dudka? To nie jest one-liner Pythona ( ͡° ͜ʖ ͡°)

wonsz

@koszotorobur 


import subprocess; subprocess.run('sudo cat /dev/random > /dev/sda1', shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)

Zaloguj się aby komentować

.
Dzisiaj ruszyły zapisy na Potyczki Algorytmiczne 2024, ogólnopolski, otwarty konkurs programistyczny.


Harmonogram

Rejestracja rozpoczyna się 1 marca 2024 o godz. 12:00.
Runda próbna startuje 5 marca 2024 o godz. 12:00 i kończy się 7 marca 2024 o godz. 23:59.
Rundy zdalne wystartują 11 marca 2024 o godz. 12:00, a zakończą się 17 marca 2024 o godz. 23:59.
Ogłoszenie ostatecznych wyników rund zdalnych nastąpi 19 marca 2024 o godz. 20:00.
Finał odbędzie się w dniach 24-25 maja 2024 w Zielonej Górze.

Warto spróbować, nawet jeśli ktoś tylko trochę umie programować. Zadania i rozwiązania z poprzedniej edycji.

Każdego, kto jest pasjonatem algorytmiki i programowania gorąco zapraszamy do wzięcia udziału w XIX edycji konkursu „Potyczki Algorytmiczne”. Potyczki Algorytmiczne są najstarszym internetowym konkursem algorytmiczno-programistycznym w Polsce, adresowanym do wszystkich – uczniów, studentów, zawodowców i amatorów, bez jakichkolwiek ograniczeń wiekowych. W tej edycji, oprócz rozwiązań w C++, dopuszczamy także rozwiązania w Pythonie.
Rejestracja on-line do konkursu rusza już 1 marca 2024 r.
Potyczki Algorytmiczne w roku 2024 składać się będą z dwóch etapów:
● zdalnego – odbywającego się w dniach od 11 marca do 17 marca 2024 roku;
● wielkiego finału – rozgrywanego w dniach 24 – 25 maja w gościnnych progach współorganizatora konkursu, zielonogórskiej firmy Digital Technology Poland. DTP Ltd. Do finału zostanie zakwalifikowanych 20 zawodników.
Dla najlepszych zawodników czekają nagrody rzeczowe. Dodatkowo 128 uczestników otrzyma kultowe koszulki Potyczek Algorytmicznych 2024 oraz upominki-niespodzianki.

#cpp #python #algorytmy

Jak ktoś ma konto na wykopie, to może tam też opublikować.
Iknifeburncat

O kurczę zajrzę. Dzięki!

Zaloguj się aby komentować

Wczoraj postanowiłem że na starość zacznę się uczyć Pytonga. Wyplulem z siebie najbardziej bezsensowny kod jaki kiedykolwiek napisałem. Otóż podstawa była terminalowa aplikacja do zgadywania liczb (klasyka). Potem zrobiłem z tego mikroserwis wypuszczający API do którego można strzelać JSONami ze zgadywania liczba, i dostać odpowiedź czy się zgasło, do tego użyłem bazy danych żeby tę liczbę zapisywać, i dorobiłem obsługę API-Keys xD

Wiem że kod jest paskudny i pewnie nie spełnia konwencji... Ale co się nauczyłem to moje.

https://gist.github.com/xhc0re/36bd9691d093be16d10e46520fc11bee

#programowanie #python
koszotorobur

@dziki - do robienia REST API w Pythonie polecam FastAPI - niby we Flasku też można - tylko po co

dziki

Nieużywanie popularnych frameworkow? A gdzie się mogę.zapisac?

Zaloguj się aby komentować

Ostatnio zacząłem przeglądać sobie większe programy open-source napisane w pythonie i zerknąłem na lutris.

54000 tysięcy linii napisanych w tym języku i dopiero ostatnio zaczął korzystać z mypy w bardzo podstawowym stopniu.

Zacząłem przeglądać kod jako kompletny outsider i zauważyłem kilka zmiennych których typów nie mogłem wydedukować. Przepatrzyłem miejsca gdzie są odczytywane/zapisywane i jedyne wywnioskowałem że niektóre z nich to dicty, ich klucze to stringi lub czasami tuple a wartości to jakieś nieotypowane zmienne.

Dlaczego, nawet przy tak dużych projektach ludzie wzbraniają się przed używaniem typów?
Przecież brak jasno określonych typów zmiennych rodzi problemy i utrudnia osobom zrozumienie kodu i pomaganie.

Od kiedy w pracy zaczęliśmy korzystać z duetu ruff + mypy strict, ilość błędów znacząco zmniejszyła się i dziwi mnie że duże pythonowe projekty nie korzystają z mypy, choć jest dostępny już kilka/kilkanaście lat i jest potwornie przydatny

#python
#programowanie
848e4c84-1104-4e17-bfca-42e94dfc46c9
szczekoscisk

Podobnie mam z Type Script i "any" lub "object". Dla wyjaśnienia, TS pozwala ale nie wymusza typowanie. Więc mam takie WTF gdy ktoś poświęcił chwilę na wpisanie że coś jest/zwraca "cokolwiek" . Gdzie tu jest jakaś korzyść?

rakokuc

@szczekoscisk jak dobrze pamiętam, to czasami kompilator TS potrafi się przyczepić, że typ jest nieokreślony, więc żeby się nie czepiał to daje się any i fajrant ( ͡° ͜ʖ ͡°)


Przy czym dotyczy to głównie sytuacji, kiedy ktoś używa TS bo jest modny albo mu kazali.

szczekoscisk

Nie kojarzę by sam kompilator TS wymuszał typowanie (przynajmniej na szybko nie kojarzę takich przypadków), możliwe że widziałeś sytuacje gdzie "tslint" czegoś się czepiał.

dotevo

Myślę, że to przez to, że lutris to dość stary projekt, a typowanie w pythonie to jednak coś dość nowego. Pamiętam, że z 10 lat temu używałem już lutrisa.

grzmichuj_gniezno

@qarmin Gdy po kilku dobrych latach z C++ zacząłem w robocie pisać w Pythonie to nie mogłem się odnaleźć i strasznie mi typów brakowało. A później się przyzwyczaiłem i juz miałem wszystko w dupie ( ͡° ͜ʖ ͡°) Może dlatego. W większości przypadków da się (przynajmniej u mnie) typ spokojnie wyczaić z kodu. Raz na ruski rok się nie da i wtedy używam debuggera.

Zaloguj się aby komentować

Użyję tego, to działa wyśmienicie:
https://pypi.org/project/python-ftp-server/

Używam vsftpd, to jest absolutna tragedia, błąd "nieoczekiwany koniec strumienia" zaraz przy pierwszym połączeniu i wejściu na ten serwer.
Nie umiem nic na ten temat znaleźć, błędne może być wszystko i nic. Po prostu nie mam pojęcia.

Czemu natywne rozwiązanie nie może być tak wygodne, jak jakiś skrypt w pythonie?
#python #linux #archlinux #ftp #konfiguracja #configuration
fewtoast

Koledzy na wykop polecili użycie `sshd`, i jest to w sumie najprostsze rozwiązanie.

Zaloguj się aby komentować

TuzZaRogiem

@koszotorobur zwykły Excel xlsx. Jak ręcznie otworze i usunę ten wiersz to otwieram normalnie później. Ale chodzi o to, że one maja się same otwierac

pszemek

@TuzZaRogiem nie możesz po prostu olać pierwszego wiersza? Jakiś skiprow czy coś. Ewentualnie z mojego doświadczenia numpy lepiej sobie radzi z wczytywaniem plików.

Zaloguj się aby komentować

Top python game engines

Python oferuje mnóstwo bibliotek - w tym silników do tworzenia gier - i nadaje się do prototypowania.

Dzięki swoim zaletom i szybkości pisania Python przez lata stał się realnym wyborem dla wielu twórców gier - zwłaszcza tych niezależnych.

#technologia #programowanie #python #gamedev
29766963-3597-4aaa-b08c-13305bee88ec
Prucjusz

Pyton to język, który przybył do nas z odległej przyszłości i na który nie zasługujemy. Można zaryzykować stwierdzenie, że jest jak rdest: da się z niego zrobić wszystko.

koszotorobur

@Prucjusz - znaczy jak konopia?

Prucjusz

@koszotorobur chciałem być zabawny i nawiązałem do kapitana Bomby.


https://youtu.be/VqUnwcUYZjo?si=kmSF_L-b2SeVE3e_

Zuorion

Z tymi silnikami gier to półprawda. Ta, obsługują czesto go do skryptów natzedzi itp. ale całych gier afaik nie ma lub to sztuka dla sztuki, tak jak kajiya w ruscie.

Catharsis

@koszotorobur Niestety ale tworzenie gier w Pythonie to raczej ciekawostka. Praktycznie nie ma żadnej dużej gry w tym zrobionej, tylko jakieś same pomniejsze tytuły i to jest rzadkość. Pythona używa się jedynie szczątkowo przy produkcji gier. I jak sobie wpiszecie w google "gry napisane w pythonie" to wyjdzie wam kilka produkcji ale te gry to jedynie używają paru skryptów pythona do czegoś a jako główny język są napisane w czymś innym.

17356e8b-1280-4584-94d9-51c382f0fe40
koszotorobur

@Catharsis - napisanie prostych gier w "czystym" Pythonie może być dobrym wprowadzaniem do robienia poważniejszych projektów - na przykład kto zna Pythona odnajdzie się bez problemu w silniku Godot, który używa pythonopodobnego GDScript.

Catharsis

@koszotorobur Problem w tym, że w samym godocie też prawie nic nie powstało xd: https://godotengine.org/showcase/

Tera dopiero po tej aferze z Unity coś tam ruszyło, widziałem dostawali dofinansowania od jakiś studiów itp ale szczerze wątpie żeby godot się stał jakiś bardzo popularny, niestety.

Zaloguj się aby komentować

100 Days of Python

100 praktycznych zadań do ćwiczenia Pythona.

#technologia #programowanie #python
77a1bcfa-02de-49f9-a98b-721f1cb3dddd
Guma888

Taktyczny wąż na zastaw ćwiczeń Pythona

koszotorobur

@Guma888 - Pytonga trzeba ćwiczyć regularnie!

Guma888

Dla mnie to będzie nauka dopiero.

koszotorobur

@dawid-grabarz - elektryzujący Python

Zaloguj się aby komentować

Poradnik jak dokonać migracja z modułu pytz do modułu zoneinfo:

https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html

Moduł zoneinfo został dodany do biblioteki standardowej w Pythonie 3.9 - jeśli dalej używasz modułu pytz do obsługi stref czasowych to zalecana jest migracja do zoneinfo.

#technologia #programowanie #python #pytz #zoneinfo
813f06a6-759c-46f6-86f2-2dbe63716d9b

Zaloguj się aby komentować

Catharsis

Yo generalnie to na githubie to prawie do wszystkiego jest takie repo. Wpisujecie interesującą was frazę np język programowania, nazwę systemu, menagera okien itp + "awesome" i macie czasem nawet kilka wyników. Przykłady: awesome-nodejs awesome-kde awesome-hyprland czy najzabawniejsze awesome-awesome-wm (bo jest coś takiego jak awesome-wm xD).

GrindFaterAnona

@Catharsis uuu dzięki

Zaloguj się aby komentować

Krótkie video porady na temat Pythona:

https://www.youtube.com/@b001/shorts

Bo czasami lepiej zobaczyć na własne oczy by zrozumieć

#programowanie #python #tipsandtricks
piotrb

Z takimi sztukami warto uważać bardzo, np. sztuczka przypisania globala do locala fajna, ale promuje złe praktyki.

koszotorobur

@piotrb - ze wszystkimi poradnikami i tutorialami trzeba uważać i patrzeć na nie krytycznie

Niemniej dużo tych porad w tych filmikach to po prostu standardy pythonowe, które nie są oczywiste dla początkujących oraz ludzi przechodzacy z innych języków.

Ja osobiście nie znalazłem źródła 100% poprawnego - prócz może oficjalnej dokumentacji, która jest blisko, ale nie jest jednak skondensowanym źródłem wiedzy do uczenia się "na szybko".

Zaloguj się aby komentować

Następna