Tyle do wczoraj byłem już dni na świecie ;-)
Za teraz już 24 dni, czyli za trzy tygodnie będę miał 15 tysięcy dni :-)
Trochę to przerażające, ale i ciekawe.
De facto tą samą osobą jestem od jakichś ponad 10 tysięcy dni, czyli strasznie dużo czasu ;-)
Mój cel to jakieś 55 tysięcy dni, znanym rekordem jest 44695 dni czy jakoś tak ;-)
Na kolejne 22 tysiące dni życzę sobię:
- powrotu rządów prawa,
- ciekawej pracy,
- tego by do ludzi dotarło, że świat jest tak naprawdę dużo lepszy niż im się wydaje,
- odpowiednika Apple Watch z Androidem ;-)
I paru innych rzeczy ;-)
Podobne postybeta
Zabawy z Zoomem - ikonki ;-)
Freakonomia, czy jak kto woli Freakonomics
Windows....
Droga do celu..
Czy COVID-19 spowoduje powrót do identyfikacji przez odcisk palca? ;-)
środa, marca 20, 2019
poniedziałek, marca 18, 2019
Electron + Airly = wskaźnik jakości powietrza w pasku ;-)
Bawię się Electronem i Airly ;-) i właśnie popełniam aplikacyjkę*, która siedzi w zasobniku systemowym i wyświetla mi aktualne CAQI dla miejsca gdzie jestem ;-)
Wygląda to mniej więcej tak ;-)
Gdzie moja "aplikacja" to ta pomarańczowa czy bardziej żółta kropka i liczba 63.08 obok niej ;-)
Zmienia się to to co 15 minut.
Kolejnym krokiem będzie próba dodania pobierania lokalizacji, chociaż podobno nie jest to aż takie proste w Electronie.
Na razie kod głównym ma jakieś 30 linii. Pobieranie przez API Airly danych o jakości powietrza dla mojej lokalizacji, parsowanie (przy pomocy JSON.parse ;-)) odpowiedzi, zamiana indexes i values w mapy i pobranie AIRLY_CAQI i level, jedno ląduje jako dane liczbowe, drugie jako kod obrazka ;-)
Lubię Electrona bo w miarę szybko można zrobić zabawne rzeczy :-)
[Update po jakimś czasie ;-)]
Teraz wygląda to tak:
W końcu co przeszkadza mi dodać menu z informacjami o wartościach indeksów? :-)
* - aplikacyjka opisuje tylko funkcjonalność, nie rozmiar ;-) bo ponieważ to jest Electron to jest tego ponad 130 MB ;-)
Podobne postybeta
Electron + Airly = wskaźnik jakości powietrza w pasku ;-) - part 2, źródła ;-)
Moja własna akcja w Google Home ;-)
Airly + Python + Oczyszczacz Powietrza = lepsze oddychanie ;-)
Google Actions działają już w Google Assitant nie tylko na Google Home, ale i w innych jego inkarnacjach :-)
Symlink zamiast zmiany nazwy usera ;-)
Wygląda to mniej więcej tak ;-)
Gdzie moja "aplikacja" to ta pomarańczowa czy bardziej żółta kropka i liczba 63.08 obok niej ;-)
Zmienia się to to co 15 minut.
Kolejnym krokiem będzie próba dodania pobierania lokalizacji, chociaż podobno nie jest to aż takie proste w Electronie.
Na razie kod głównym ma jakieś 30 linii. Pobieranie przez API Airly danych o jakości powietrza dla mojej lokalizacji, parsowanie (przy pomocy JSON.parse ;-)) odpowiedzi, zamiana indexes i values w mapy i pobranie AIRLY_CAQI i level, jedno ląduje jako dane liczbowe, drugie jako kod obrazka ;-)
Lubię Electrona bo w miarę szybko można zrobić zabawne rzeczy :-)
[Update po jakimś czasie ;-)]
Teraz wygląda to tak:
W końcu co przeszkadza mi dodać menu z informacjami o wartościach indeksów? :-)
* - aplikacyjka opisuje tylko funkcjonalność, nie rozmiar ;-) bo ponieważ to jest Electron to jest tego ponad 130 MB ;-)
Podobne postybeta
Electron + Airly = wskaźnik jakości powietrza w pasku ;-) - part 2, źródła ;-)
Moja własna akcja w Google Home ;-)
Airly + Python + Oczyszczacz Powietrza = lepsze oddychanie ;-)
Google Actions działają już w Google Assitant nie tylko na Google Home, ale i w innych jego inkarnacjach :-)
Symlink zamiast zmiany nazwy usera ;-)
poniedziałek, marca 11, 2019
Go, a łatwość czytania kodu
Tak się teraz trochę bawię językim Go.
Biore proste zadanka z LeetCode, które już kiedyś napisałem w Java'ie (jak znajdę takie, którego nie zrobiłem to będzie jeszcze fajniej ;-)) i piszę je w Go.
Bez patrzenia na wersję w Java'ie, dopiero później wracam do wersji w Java'ie.
I ciekawa sprawa wydaje mi się, że kod w Go jest jakby sam z siebie czytelniejszy.
Tutaj wersja w Java'ie jednego z programików:
A tutaj w Go:
Mimo wszystko wydaje mi się, że wersja w Go jest jakby ciut bardziej czytelna.
Może chodzi o brak nawiasów w warunku if'a?
Chociaż cholery mogę dostać z tym ich umieszczaniem typu po zmiennej czy funkcji.....
OK, algo jest niby takie samo, ale ciut różne więc to jeszcze inna sprawa, ale wydaje mi się, że ten kod Go jest jakby mniej wymagający w czytaniu.
Podobne postybeta
Java i liczby pierwsze, odsłona druga
Słaby, ale wojujący ateizm - czyli "obiektywne" dziennikarstwo ;-)
Światełko w tunelu :-)
Deklaratywnie czy imperatywnie... oto jest pytanie ;-)
Plus dla Scala, minus dla Groovy ;-)
Biore proste zadanka z LeetCode, które już kiedyś napisałem w Java'ie (jak znajdę takie, którego nie zrobiłem to będzie jeszcze fajniej ;-)) i piszę je w Go.
Bez patrzenia na wersję w Java'ie, dopiero później wracam do wersji w Java'ie.
I ciekawa sprawa wydaje mi się, że kod w Go jest jakby sam z siebie czytelniejszy.
Tutaj wersja w Java'ie jednego z programików:
public int removeDuplicates(int[] nums) {
if (nums==null || nums.length==0) return 0;
int nextIdx = 0;
int prev = nums[nextIdx++];
for (int i:nums) {
if (i!=prev) {
nums[nextIdx++]=i;
prev=i;
}
}
return nextIdx;
}func removeDuplicates(nums []int) int {
if len(nums)==0 {
return 0
}
a:=1
b:=1
for a<len(nums) {
for a<len(nums) && nums[a-1]==nums[a] {
a++
}
if a==len(nums) {
break
}
nums[b]=nums[a]
a++
b++
}
return b
}Może chodzi o brak nawiasów w warunku if'a?
Chociaż cholery mogę dostać z tym ich umieszczaniem typu po zmiennej czy funkcji.....
OK, algo jest niby takie samo, ale ciut różne więc to jeszcze inna sprawa, ale wydaje mi się, że ten kod Go jest jakby mniej wymagający w czytaniu.
Podobne postybeta
Java i liczby pierwsze, odsłona druga
Słaby, ale wojujący ateizm - czyli "obiektywne" dziennikarstwo ;-)
Światełko w tunelu :-)
Deklaratywnie czy imperatywnie... oto jest pytanie ;-)
Plus dla Scala, minus dla Groovy ;-)
niedziela, marca 10, 2019
E! Gdzie jest mój następny smartwatch?
Moja Moto 360 V2 powoli acz skutecznie umiera.
Zajmuje jej to trochę więcej czasu niż Moto 360 w pierwszej wersji, ale jednak.
Bateria już ledwo, ledwo zipie.
Niby są jakieś modele z Qualcomm® Snapdragon™ Wear 3100, co powinno oznaczać więcej czasu na baterii i inne takie, ale w Polsce ich prawie nie można dostać.
Piszę prawie, bo mnie się nie udało, ale może jest jakiś sposób, tylko go nie znam.
Przez co coraz częściej myślę o szalonej drodze....
Kupnie Apple Watch'a, ale że Apple Watch'a nie można mieć bez iPhone'a to także o kupnie iPhone XR albo nawet X Max czy jak to się zowie.
Ale to jednak trochę przesada wydać tyle monet tylko przez to, że nie ma dobrych smartwatchy z Wear OS.
Google!?! Gdzie jest mój Pixel Watch? He? ;-)
Podobne postybeta
Ktoś ma pomysły na użycie tagów NFC?
Android Wear.... jaki zegarek po Moto 360 v2?
Moto 360 i Android Wear po paru godzinach używania....
Moto 360 i Android Wear po 3 dniach - zaczynam dostrzegać zalety ;-)
Piszę sobie...
Zajmuje jej to trochę więcej czasu niż Moto 360 w pierwszej wersji, ale jednak.
Bateria już ledwo, ledwo zipie.
Niby są jakieś modele z Qualcomm® Snapdragon™ Wear 3100, co powinno oznaczać więcej czasu na baterii i inne takie, ale w Polsce ich prawie nie można dostać.
Piszę prawie, bo mnie się nie udało, ale może jest jakiś sposób, tylko go nie znam.
Przez co coraz częściej myślę o szalonej drodze....
Kupnie Apple Watch'a, ale że Apple Watch'a nie można mieć bez iPhone'a to także o kupnie iPhone XR albo nawet X Max czy jak to się zowie.
Ale to jednak trochę przesada wydać tyle monet tylko przez to, że nie ma dobrych smartwatchy z Wear OS.
Google!?! Gdzie jest mój Pixel Watch? He? ;-)
Podobne postybeta
Ktoś ma pomysły na użycie tagów NFC?
Android Wear.... jaki zegarek po Moto 360 v2?
Moto 360 i Android Wear po paru godzinach używania....
Moto 360 i Android Wear po 3 dniach - zaczynam dostrzegać zalety ;-)
Piszę sobie...
niedziela, marca 03, 2019
A takie tam słowo na niedzielę ;-)
Pamiętam gdy zmieniłem zdanie o tym czy pary jednopłciowe* powinny mieć prawo do adopcji dzieci.
To było gdy czytałem w "Oto słowo czarne" w NIE fragmenty z gazet prawicowych i była wypowiedź Giertycha albo kogoś innego z LPR.
Było tam pełno nienawiści i wtedy do mnie dotarło, że jeśli miałbym dzieci i po mojej śmierci miałyby być adoptowane to wolę by adoptowało je dwóch kochających gejów niż pełen nienawiści członek LPR.
Momentalnie wyłączyła mi się cała niechęć, bo dotarło do mnie, że orientacja seksualna to tylko jeden z wymiarów człowieka i to wcale nie najważniejszy.
To samo mam teraz z osobami transpłciowymi.
Przyznam, że uprzedzenia tkwią we mnie głęboko.
Ale im więcej widzę nienawiście skierowanej w kierunku osób traspłciowych tym bardziej do mnie dociera, że płeć to znów tylko jeden z wymiarów.
No i przypominam sobie artykuł ze Świata Nauki "Nie tylko XX i XY" z października 2017 roku i tabelkę na stronach 44 i 45.
Często w sprawach gender czy osób traspłciowych pojawia się nawiązanie do genetyki i na tej stronie jest 13 przypadków, startując od XX, kończąc na XY.
9 z nich to stany transpłciowe.
Zespół Turnera, zaburzenie rozwoju płci z kariotypem XX, wrodzony przerost nadnerczy, mieszana dysgenezja gonad, zespół nadwrażliwości na androgeny (AIS), coś bez nazwy, zespół Klinefeltera, niedobór 5α-reduktazy, zespół przetrwałych struktur müllerowskich.
Sama grafika jest uproszczona, a nadal ma tyle strzałek i przejść między różnymi stanami, że struktura Unii Europejskiej, albo zasady odliczania VAT wyglądają przy tym jak dziecinne zabawki.
Wychodzi, że wcale nie jest tak, że każdy się rodzi chłopcem, albo dziewczynką. Niektórzy się rodzą będąc jeszcze kimś innym. Mogą mieć geny chłopca, a wyglądać jak dziewczynka.
A ty mówimy tylko o kawałku dotyczącym tylko zewnętrznych organów płciowych.
W ogóle nie dotykamy mózgu.
W którym hormony robią jeszcze więcej.
Tak, nie mogę zrozumieć jak można przez ileś tam lat życia być facetem i nagle twierdzić, że się od zawsze czuło jak kobieta i chcieć być kobietą.
Ale to, że ja tego nie mogę zrozumieć nie znaczy, że ktoś tak nie może czuć.
Kogoś kto ubóstwia disco-polo, albo jest głęboko religijny też nie rozumiem, a nie zabraniam im życia po swojemu (byle mnie nie wchodzili w szkodę).
Ciekawe czy jest więcej podobnych do mnie ludzi, którzy zmieniają swoją postawę do tak trudnych spraw jak gender czy transpłciowość przez to, że w kierunku tych tematów wylewa się tyle nienawiści.
U mnie podstawą jest to, że osoby transpłciowe czy pary jednopłciowe nikomu krzywdy nie robią będąc sobą, więc czemu mam być przeciwko nim?
* - głównie jednak takie mężczyzna z mężczyzną, co do par kobieta z kobietą nie miałem nigdy jakichś watpliwości**
** - co pewnie pokazuje, że we mnie stereotypy trzymają się mocno
Podobne postybeta
Nienawiść
Zaczął się nowy rok
Raj pro-life - czyli co oznacza konstytucyjna ochrona "życia poczętego"
Związki Partnerskie czyli Nienawistniki vs. Rozsądni - 1:0...
Uroki remote ;-)
To było gdy czytałem w "Oto słowo czarne" w NIE fragmenty z gazet prawicowych i była wypowiedź Giertycha albo kogoś innego z LPR.
Było tam pełno nienawiści i wtedy do mnie dotarło, że jeśli miałbym dzieci i po mojej śmierci miałyby być adoptowane to wolę by adoptowało je dwóch kochających gejów niż pełen nienawiści członek LPR.
Momentalnie wyłączyła mi się cała niechęć, bo dotarło do mnie, że orientacja seksualna to tylko jeden z wymiarów człowieka i to wcale nie najważniejszy.
To samo mam teraz z osobami transpłciowymi.
Przyznam, że uprzedzenia tkwią we mnie głęboko.
Ale im więcej widzę nienawiście skierowanej w kierunku osób traspłciowych tym bardziej do mnie dociera, że płeć to znów tylko jeden z wymiarów.
No i przypominam sobie artykuł ze Świata Nauki "Nie tylko XX i XY" z października 2017 roku i tabelkę na stronach 44 i 45.
Często w sprawach gender czy osób traspłciowych pojawia się nawiązanie do genetyki i na tej stronie jest 13 przypadków, startując od XX, kończąc na XY.
9 z nich to stany transpłciowe.
Zespół Turnera, zaburzenie rozwoju płci z kariotypem XX, wrodzony przerost nadnerczy, mieszana dysgenezja gonad, zespół nadwrażliwości na androgeny (AIS), coś bez nazwy, zespół Klinefeltera, niedobór 5α-reduktazy, zespół przetrwałych struktur müllerowskich.
Sama grafika jest uproszczona, a nadal ma tyle strzałek i przejść między różnymi stanami, że struktura Unii Europejskiej, albo zasady odliczania VAT wyglądają przy tym jak dziecinne zabawki.
Wychodzi, że wcale nie jest tak, że każdy się rodzi chłopcem, albo dziewczynką. Niektórzy się rodzą będąc jeszcze kimś innym. Mogą mieć geny chłopca, a wyglądać jak dziewczynka.
A ty mówimy tylko o kawałku dotyczącym tylko zewnętrznych organów płciowych.
W ogóle nie dotykamy mózgu.
W którym hormony robią jeszcze więcej.
Tak, nie mogę zrozumieć jak można przez ileś tam lat życia być facetem i nagle twierdzić, że się od zawsze czuło jak kobieta i chcieć być kobietą.
Ale to, że ja tego nie mogę zrozumieć nie znaczy, że ktoś tak nie może czuć.
Kogoś kto ubóstwia disco-polo, albo jest głęboko religijny też nie rozumiem, a nie zabraniam im życia po swojemu (byle mnie nie wchodzili w szkodę).
Ciekawe czy jest więcej podobnych do mnie ludzi, którzy zmieniają swoją postawę do tak trudnych spraw jak gender czy transpłciowość przez to, że w kierunku tych tematów wylewa się tyle nienawiści.
U mnie podstawą jest to, że osoby transpłciowe czy pary jednopłciowe nikomu krzywdy nie robią będąc sobą, więc czemu mam być przeciwko nim?
* - głównie jednak takie mężczyzna z mężczyzną, co do par kobieta z kobietą nie miałem nigdy jakichś watpliwości**
** - co pewnie pokazuje, że we mnie stereotypy trzymają się mocno
Podobne postybeta
Nienawiść
Zaczął się nowy rok
Raj pro-life - czyli co oznacza konstytucyjna ochrona "życia poczętego"
Związki Partnerskie czyli Nienawistniki vs. Rozsądni - 1:0...
Uroki remote ;-)
środa, lutego 27, 2019
Powiadomieniami w walce z uzależnienie od WhatsApp i Telegrama ;-)
Z zasady mam wyłączone praktycznie wszystkie powiadomienia na swoich urządzeniach.
Jedynie SMSy i nieodebrane połączenia przechodzące są wyświetlane.
To się jednak chyba zmieni ;-) i pozwolę na wyświetlanie powiadomień z WhatsApp i Telegrama.
Bo trzeba przyznać, mam lekki problem z WhatsApp i Telegramem.
Mam tendencję do uruchamiana ich żeby sprawdzić czy ktoś coś napisał, albo czy przeczytał moją wiadomość.
To jest strasznie uzależniające, bo dość często, ale nie zawsze jest ten mały pik dopaminy, że ktoś coś napisał, albo że przeczytał.
Już wywaliłem obie aplikacje z ekranu startowego, wyłączyłem sugerowane aplikacje... ale nadal umiem otworzyć każdą z nich w ciągu 2 sekund.
Stąd stwierdziłem, że spróbuję inaczej ;-)
Skoro zaglądam do tych aplikacji żeby sprawdzić czy ktoś do mnie coś napisał, to żeby to wyeliminować włączyłem powiadomienia ;-)
Nie dostaję setek wiadomości dziennie, więc nie powinno mi to jakoś szczególnie przeszkadzać, a z drugiej strony będę widział w razie ktoś napisze.
Nadal bez dźwięków i innych takich, ale już są powiadomienia.
Muszę jeszcze tylko sprawić by nie pokazywały mi się na zegarku.
Kto by pomyślał, że z jednej strony wszyscy próbują nas shackować i trzeba się samemu hackować żeby jakoś przetrwać? ;-)
Podobne postybeta
Telegram
&amp;quot;Odstawianie&amp;quot; telefonu ;-)
Pomodoro z positive reinforcement? ;-)
Przydatne narzędzia ;-)
Darmowy hosting JSP
Jedynie SMSy i nieodebrane połączenia przechodzące są wyświetlane.
To się jednak chyba zmieni ;-) i pozwolę na wyświetlanie powiadomień z WhatsApp i Telegrama.
Bo trzeba przyznać, mam lekki problem z WhatsApp i Telegramem.
Mam tendencję do uruchamiana ich żeby sprawdzić czy ktoś coś napisał, albo czy przeczytał moją wiadomość.
To jest strasznie uzależniające, bo dość często, ale nie zawsze jest ten mały pik dopaminy, że ktoś coś napisał, albo że przeczytał.
Już wywaliłem obie aplikacje z ekranu startowego, wyłączyłem sugerowane aplikacje... ale nadal umiem otworzyć każdą z nich w ciągu 2 sekund.
Stąd stwierdziłem, że spróbuję inaczej ;-)
Skoro zaglądam do tych aplikacji żeby sprawdzić czy ktoś do mnie coś napisał, to żeby to wyeliminować włączyłem powiadomienia ;-)
Nie dostaję setek wiadomości dziennie, więc nie powinno mi to jakoś szczególnie przeszkadzać, a z drugiej strony będę widział w razie ktoś napisze.
Nadal bez dźwięków i innych takich, ale już są powiadomienia.
Muszę jeszcze tylko sprawić by nie pokazywały mi się na zegarku.
Kto by pomyślał, że z jednej strony wszyscy próbują nas shackować i trzeba się samemu hackować żeby jakoś przetrwać? ;-)
Podobne postybeta
Telegram
&amp;quot;Odstawianie&amp;quot; telefonu ;-)
Pomodoro z positive reinforcement? ;-)
Przydatne narzędzia ;-)
Darmowy hosting JSP
sobota, lutego 23, 2019
Serializacja w Java'ie - revisited ;-)
Blisko 9 lat temu napisałem chyba najpopularniejszy wpis na moim blogu, o serializacji i relfeksji.
Dziś postanowiłem wrócić do tematu ;-)
Zacznę od tego, że Serializable był rzeczą, która mnie zachwyciła w Java'ie.
Do teraz mnie zachwyca, chociaż już nie tak bardzo ;-)
Czym jest serializacja?
To zamiana obiektu w strumień danych, dzięki czemu można obiekty zapisywać "na później" albo przesyłać.
Po drugiej stronie procesu jest deserializacja, czyli "zbudowanie" obiektu na podstawie tego co wcześniej zapisaliśmy.
Jakie obiekty są serializowalne?
Żeby obiekt był serializowalny w Java'ie MUSI implementować Serializable.
Sam interfejs Serializable jest interfejsem znacznikowym, nie wprowadza wymogu implementacji żadnych metod, a sygnalizuje tylko JVM, że dany obiekt obiecuje, że da się zserializować.
To jest tylko obietnica.
Kompilator w compile time nie jest w stanie stwierdzić czy to jest prawda.
JVM dopiero w runtime próbując dokonać serializacji, czy też deserializacji sprawdza czy jest to możliwe.
Jest to istotne o tyle, że fakt posiadania wśród przodków klasy, które implementuje Serializable i jest serializowalna nie oznacza wcale, że nasza klasa ładnie się zserializuje.
Samo implementowanie Serializable też nie znaczy, że jesteśmy z automatu serializowalni.
By to była prawda musimy zapewnić tą serializowalność.
Pola w nasze klasie, jak i superklasach muszą być serializowalne, oznaczone jako transient albo musimy dostarczyć mechanizmu serializacji.
Wszystkie pola niestatyczne i nie oznaczone jako transient są serializowane, niezależnie od ich widoczności.
Do tego to, że obiekt dało się zserializować nie oznacza od razu, że uda się go zdeserializować.
Czy konstruktory są używane w trakcie deserializacji?
I nie i tak ;-)
Ogólnie nie, jeśli klasa implementuje Serializable to jej konstruktor nie będzie wołany.
Ale, jeśli któryś z przodków po drodze nie implementuje Serializable i nie ma konstruktora domyślnego to mamy problem ;-)
Tutaj warto pamiętać, że jeśli nie napiszemy żadnego konstruktora dla naszej klasy, to Java sama doda bezparametrowy konstruktor domyślny.
Do tego gdy piszemy nasz konstruktor i nie zawołamy w naszym konstruktorze konstruktora klasy bazowej to Java dopisze nam super() jako pierwszą linię naszego konstruktora, czyli wywoła konstruktor domyślny superklasy.
Jeśli nie ma takiego konstruktora to kod nam się nie skompiluje, no chyba że sami zrobimy super z parametrami do jednego z istniejących konstruktorów.
W trakcie deserializacji JVM używa więc konstruktorów dla tych klas które są w hierarchii przed pierwszą klasą oznaczoną jako taka, która implementuje Serializable.
Jeśli ta klasa nie ma konstruktora domyślnego, a nasza klasa ma wywołanie któregoś z niedomyślnych (czyli kod się kompiluje) to choć mamy kompilowalny kod to deserializacja będzie niemożliwa.
Stąd rule of thumb jest, jeśli już musisz używać serializacji/deserializacji to upewnij się, że klasa bazowa na której budujesz swój obiekt implementujący Serializable ma konstruktor domyślny ;-)
Jak zserializować obiekt?
To jest akurat proste, trzeba skorzystać z ObjetOutputStream, tutaj przykład jak to wygląda gdy chcemy nasz obiekt zapisać do pliku:
To zapisze nam obiekt do pliku "toster.dat" (oczywiście trzeba jeszcze obsłużyć wyjątki, które mogą stąd polecieć).
To wszystko przy założeniu, że obj, które próbujemy zapisać jest serializowalne.
OK, czyli jak sprawić by obiekt był serializowalny?
Jak już było wyżej, by obiekt był serializowalny wymagania są takie:
Najpierw wołamy defaultWriteObject(), która to metoda zapisze za nas wszystkie pola niestatyczne i nietransient.
Oczywiście nie ma obowiązku wołania tej metody ;-)
Dalej dajemy kod, który zapisuje wartości które będziemy umieli później wykorzystać do zbudowania obiektu czy obiektów oznaczonych jako transient.
Jak zdeserializować obiekt?
Warto zwrócić uwagę na to rzutowanie w 2 linii, które jest ważne o tyle, że readObject() zwraca Object, który musimy zrzutować na to co wczytujemy.
Oczywiście wypadałoby wcześniej sprawdzić czy to co wczytujemy jest instancją naszego typu i dopiero wtedy rzutować.
Mamy też dla pól oznaczonych jako transient metodę readObject(), która najpierw przy pomocy defaultReadObject(), wczytuje standardowo zapisane pola i po tym implementujemy mechanizm wczytujący pola transient.
W przypadku methody readObjectNoData() napiszę to co napisałem 9 lat temu ;-)
Ostatnią metodą jest readObjectNoData(), której przyznam się nigdy nie musiałem używać :-) więc mogę się w jej opisie oprzeć tylko na opisie z JavaDoc'a. W skrócie metoda ta jest wołana wtedy gdy "podnoszonej" klasy nie ma w strumieniu, który próbujemy odczytać...... ale przyznam, że nie udało mi się tego teraz oprogramować :-(
Oczywiście mechanizm z writeObject/readObject można wykorzystać także do napisania własnego mechanizmu serializacji/deserializacji, nie ma przymusu używania tych wbudowanych w Java'ę.
Serializacja w Java'ie pozwala jeszcze na użycie metod writeReplace() i readResolve(), które służą temu by zapisać alternatywne obiekty.
Powiedzmy, że nasz obiekt jest serializowalny, ale nie chcemy go zapisywać całego, potrafimy zapisać go w "lepszy" sposób, wtedy implementujemy writeReplace() które zwróci inny obiekt, który zostanie zapisany przez domyślny mechanizm serializacji.
readResolve() zostanie użyte w trakcie deserializacji.
Przyznam, że nigdy nie musiałem używać tych 2 metod.
A co z wersjonowaniem?
No właśnie...
Nie jest dobrze z wersjonowaniem.
Obiekt implementujący Serializable powinien mieć statyczne finalne pole typu long o nazwie serialVersionUID, które mówi o wersji obiektu.
W trakcie serializacji wartość tego pola jest zapisywana, a w trakcie deserializacji wartość tego pola jest porównywalna z tą w klasie deserializowanego obiektu i jeśli się nie zgadzają JVM zgłasza wyjątek.
Jeśli nie stworzymy sami tego pola to kompilator zrobi to za nas. Ale jeśli zmienimy cokolwiek w naszej klasie, dodamy pole, usuniemy, albo nawet po prostu zrobimy dowolną edycję w pliku to kolejna skompilowana klasa z naszego pliku będzie miała inną wartość serialVersionUID....
Czyli chociaż mechanizm deserializacji powinien być w stanie odczytać nasz plik to nie będzie umiał.
Nawet nasza własna implementacja readObject nas tu nie uratuje....
Czy powinno się używać serializacji w Java'ie?
Nie do końca ;-)
Po pierwsze problem z wersjonowaniem jest poważny i mocno ogranicza możliwość pracy z Serializable.
Po drugie i chyba ważniejsze ;-) Oracle planuje wyłączenie serializacji w kolejnych wersjach Java'y.
To przez to, że serializacja i deserializacja są źródłem największej ilości błędów bezpieczeństwa w Java'ie.
Wszystko dzięki temu, że cały proces deserializacji to nic innego jak interpreter, a interpretery w samej swej naturze są niebezpieczne.
Stąd jeśli zdecydujesz się na używanie serializacji to z jednej strony ryzykujesz, że któraś z przyszłych wersji Java'y wyłączy ten mechanizm, ryzykujesz też otwarcie powierzchni do ataku swojej aplikacji.
Istnieją też mechanizmy alternatywne, które lepiej nadają się do serializacji i deserializacji obiektów.
Ale to już temat na kolejny wpis ;-)
Podobne postybeta
Refleksje i serializacja w Java'ie - podstawy i obalanie mitów ;-)
Wymiana obiektów między PC a Androidem... - użyj serializacji Luke ;-)
Lenistwo w działaniu, "piklujemy" Androida ;-)
Czemu trzeba pomagać Jacksonowi? ;-)
Konstruktory
Dziś postanowiłem wrócić do tematu ;-)
Zacznę od tego, że Serializable był rzeczą, która mnie zachwyciła w Java'ie.
Do teraz mnie zachwyca, chociaż już nie tak bardzo ;-)
Czym jest serializacja?
To zamiana obiektu w strumień danych, dzięki czemu można obiekty zapisywać "na później" albo przesyłać.
Po drugiej stronie procesu jest deserializacja, czyli "zbudowanie" obiektu na podstawie tego co wcześniej zapisaliśmy.
Jakie obiekty są serializowalne?
Żeby obiekt był serializowalny w Java'ie MUSI implementować Serializable.
Sam interfejs Serializable jest interfejsem znacznikowym, nie wprowadza wymogu implementacji żadnych metod, a sygnalizuje tylko JVM, że dany obiekt obiecuje, że da się zserializować.
To jest tylko obietnica.
Kompilator w compile time nie jest w stanie stwierdzić czy to jest prawda.
JVM dopiero w runtime próbując dokonać serializacji, czy też deserializacji sprawdza czy jest to możliwe.
Jest to istotne o tyle, że fakt posiadania wśród przodków klasy, które implementuje Serializable i jest serializowalna nie oznacza wcale, że nasza klasa ładnie się zserializuje.
Samo implementowanie Serializable też nie znaczy, że jesteśmy z automatu serializowalni.
By to była prawda musimy zapewnić tą serializowalność.
Pola w nasze klasie, jak i superklasach muszą być serializowalne, oznaczone jako transient albo musimy dostarczyć mechanizmu serializacji.
Wszystkie pola niestatyczne i nie oznaczone jako transient są serializowane, niezależnie od ich widoczności.
Do tego to, że obiekt dało się zserializować nie oznacza od razu, że uda się go zdeserializować.
I nie i tak ;-)
Ogólnie nie, jeśli klasa implementuje Serializable to jej konstruktor nie będzie wołany.
Ale, jeśli któryś z przodków po drodze nie implementuje Serializable i nie ma konstruktora domyślnego to mamy problem ;-)
Tutaj warto pamiętać, że jeśli nie napiszemy żadnego konstruktora dla naszej klasy, to Java sama doda bezparametrowy konstruktor domyślny.
Do tego gdy piszemy nasz konstruktor i nie zawołamy w naszym konstruktorze konstruktora klasy bazowej to Java dopisze nam super() jako pierwszą linię naszego konstruktora, czyli wywoła konstruktor domyślny superklasy.
Jeśli nie ma takiego konstruktora to kod nam się nie skompiluje, no chyba że sami zrobimy super z parametrami do jednego z istniejących konstruktorów.
W trakcie deserializacji JVM używa więc konstruktorów dla tych klas które są w hierarchii przed pierwszą klasą oznaczoną jako taka, która implementuje Serializable.
Jeśli ta klasa nie ma konstruktora domyślnego, a nasza klasa ma wywołanie któregoś z niedomyślnych (czyli kod się kompiluje) to choć mamy kompilowalny kod to deserializacja będzie niemożliwa.
Stąd rule of thumb jest, jeśli już musisz używać serializacji/deserializacji to upewnij się, że klasa bazowa na której budujesz swój obiekt implementujący Serializable ma konstruktor domyślny ;-)
Jak zserializować obiekt?
To jest akurat proste, trzeba skorzystać z ObjetOutputStream, tutaj przykład jak to wygląda gdy chcemy nasz obiekt zapisać do pliku:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("toster.dat")); oos.writeObject(obj);oos.close();To zapisze nam obiekt do pliku "toster.dat" (oczywiście trzeba jeszcze obsłużyć wyjątki, które mogą stąd polecieć).
To wszystko przy założeniu, że obj, które próbujemy zapisać jest serializowalne.
OK, czyli jak sprawić by obiekt był serializowalny?
Jak już było wyżej, by obiekt był serializowalny wymagania są takie:
- musi implementować Serializable (lub jedna z jego superklas musi),
- wszystkie pola muszą być albo:
- serializowalne (czyli implementować Serializable),
- byś typami prostymi,
- być oznaczone jako transient
- by je zapisać trzeba dostarczyć własny mechanizm serializacji, lub pole takie będzie zignorowane.
Pola, które są typów prostych, lub takich które implementują Serializable zostaną zserializowane przez wbudowane w JVM mechanizmy, pola transient zostaną przez te mechanizmy zignorowane.
Jak zserializować dane z pól oznaczonych jako transient?
Da się ;-)
W takim przypadku trzeba dostarczyć własny mechanizm, który to mechanizm opiera się o 3 metody:
W trakcie serializacji ważna jest pierwsza metoda, dwie pozostałe są istotne w trakcie deserializacji. private void writeObject(java.io.ObjectOutputStream out) throws IOException; private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException; Najpierw wołamy defaultWriteObject(), która to metoda zapisze za nas wszystkie pola niestatyczne i nietransient.
Oczywiście nie ma obowiązku wołania tej metody ;-)
Dalej dajemy kod, który zapisuje wartości które będziemy umieli później wykorzystać do zbudowania obiektu czy obiektów oznaczonych jako transient.
Jak zdeserializować obiekt?
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("toster.dat")); OurType object = (OurType)ois.readObject();ois.close();
Warto zwrócić uwagę na to rzutowanie w 2 linii, które jest ważne o tyle, że readObject() zwraca Object, który musimy zrzutować na to co wczytujemy.
Oczywiście wypadałoby wcześniej sprawdzić czy to co wczytujemy jest instancją naszego typu i dopiero wtedy rzutować.
Mamy też dla pól oznaczonych jako transient metodę readObject(), która najpierw przy pomocy defaultReadObject(), wczytuje standardowo zapisane pola i po tym implementujemy mechanizm wczytujący pola transient.
W przypadku methody readObjectNoData() napiszę to co napisałem 9 lat temu ;-)
Ostatnią metodą jest readObjectNoData(), której przyznam się nigdy nie musiałem używać :-) więc mogę się w jej opisie oprzeć tylko na opisie z JavaDoc'a. W skrócie metoda ta jest wołana wtedy gdy "podnoszonej" klasy nie ma w strumieniu, który próbujemy odczytać...... ale przyznam, że nie udało mi się tego teraz oprogramować :-(
Oczywiście mechanizm z writeObject/readObject można wykorzystać także do napisania własnego mechanizmu serializacji/deserializacji, nie ma przymusu używania tych wbudowanych w Java'ę.
Serializacja w Java'ie pozwala jeszcze na użycie metod writeReplace() i readResolve(), które służą temu by zapisać alternatywne obiekty.
Powiedzmy, że nasz obiekt jest serializowalny, ale nie chcemy go zapisywać całego, potrafimy zapisać go w "lepszy" sposób, wtedy implementujemy writeReplace() które zwróci inny obiekt, który zostanie zapisany przez domyślny mechanizm serializacji.
readResolve() zostanie użyte w trakcie deserializacji.
Przyznam, że nigdy nie musiałem używać tych 2 metod.
A co z wersjonowaniem?
No właśnie...
Nie jest dobrze z wersjonowaniem.
Obiekt implementujący Serializable powinien mieć statyczne finalne pole typu long o nazwie serialVersionUID, które mówi o wersji obiektu.
W trakcie serializacji wartość tego pola jest zapisywana, a w trakcie deserializacji wartość tego pola jest porównywalna z tą w klasie deserializowanego obiektu i jeśli się nie zgadzają JVM zgłasza wyjątek.
Jeśli nie stworzymy sami tego pola to kompilator zrobi to za nas. Ale jeśli zmienimy cokolwiek w naszej klasie, dodamy pole, usuniemy, albo nawet po prostu zrobimy dowolną edycję w pliku to kolejna skompilowana klasa z naszego pliku będzie miała inną wartość serialVersionUID....
Czyli chociaż mechanizm deserializacji powinien być w stanie odczytać nasz plik to nie będzie umiał.
Nawet nasza własna implementacja readObject nas tu nie uratuje....
Czy powinno się używać serializacji w Java'ie?
Nie do końca ;-)
Po pierwsze problem z wersjonowaniem jest poważny i mocno ogranicza możliwość pracy z Serializable.
Po drugie i chyba ważniejsze ;-) Oracle planuje wyłączenie serializacji w kolejnych wersjach Java'y.
To przez to, że serializacja i deserializacja są źródłem największej ilości błędów bezpieczeństwa w Java'ie.
Wszystko dzięki temu, że cały proces deserializacji to nic innego jak interpreter, a interpretery w samej swej naturze są niebezpieczne.
Stąd jeśli zdecydujesz się na używanie serializacji to z jednej strony ryzykujesz, że któraś z przyszłych wersji Java'y wyłączy ten mechanizm, ryzykujesz też otwarcie powierzchni do ataku swojej aplikacji.
Istnieją też mechanizmy alternatywne, które lepiej nadają się do serializacji i deserializacji obiektów.
Ale to już temat na kolejny wpis ;-)
Podobne postybeta
Refleksje i serializacja w Java'ie - podstawy i obalanie mitów ;-)
Wymiana obiektów między PC a Androidem... - użyj serializacji Luke ;-)
Lenistwo w działaniu, "piklujemy" Androida ;-)
Czemu trzeba pomagać Jacksonowi? ;-)
Konstruktory
piątek, lutego 22, 2019
Kiedy polecimy na Marsa?
Szczerze zawsze mi się wydawało, że Elon Musk i SpaceX są zbyt optymistyczni, bo Elon Musk ma taki sposób estymacji, że bierze najbardziej optymistyczną estymatę i skraca ją o 30-50% zakładając, że ludzie będą pracowali po 100 godzin tygodniowo.
Ale... po obejrzeniu Fist Man o Neilu Amstrongu pooglądałem ile trwał cały program Apollo.
Zaczęli w 1963 roku, a w 1969 wylądowali na Księżycu.
Pierwszy lot człowieka był w 1961 roku.
W 8 lat przeszli od wysłania człowieka w kosmos do lądowania na Księżycu.
Fakt, po stronie USA (które od początku to robiły bardziej planowo i profesjonalnie, Rosjanie robili to tak bardziej amatorsko i na "taśmę klejącą") w porywach wydawano chyba 4.5% rocznego budżetu USA na NASA, ale jednak potrzebowali tylko głupich 8 lat.
Stąd, skoro SpaceX ma jeszcze do 2030 roku 11 lat, to może z tym BFR (teraz zwanym SuperHeavy + Starship chyba) im wyjdzie? Może nawet do 2030 roku wylądujemy na Księżycu znowu?
Podobne postybeta
Dysonans poznawczy roku 2017 ;-)
A może by tak ukrywać sobie wszystkie artykuły czy video ze słowami Trump, Elon i Musk w tytule? ;-)
1 plus braku tramwaju ;-)
Marcowe książki
Świat disco polo...
Ale... po obejrzeniu Fist Man o Neilu Amstrongu pooglądałem ile trwał cały program Apollo.
Zaczęli w 1963 roku, a w 1969 wylądowali na Księżycu.
Pierwszy lot człowieka był w 1961 roku.
W 8 lat przeszli od wysłania człowieka w kosmos do lądowania na Księżycu.
Fakt, po stronie USA (które od początku to robiły bardziej planowo i profesjonalnie, Rosjanie robili to tak bardziej amatorsko i na "taśmę klejącą") w porywach wydawano chyba 4.5% rocznego budżetu USA na NASA, ale jednak potrzebowali tylko głupich 8 lat.
Stąd, skoro SpaceX ma jeszcze do 2030 roku 11 lat, to może z tym BFR (teraz zwanym SuperHeavy + Starship chyba) im wyjdzie? Może nawet do 2030 roku wylądujemy na Księżycu znowu?
Podobne postybeta
Dysonans poznawczy roku 2017 ;-)
A może by tak ukrywać sobie wszystkie artykuły czy video ze słowami Trump, Elon i Musk w tytule? ;-)
1 plus braku tramwaju ;-)
Marcowe książki
Świat disco polo...
niedziela, lutego 17, 2019
Gdzie popełniliśmy błąd?
Współczesne tworzenie aplikacji to ciągła walka z narzędziami i bibliotekami.
Dziś postanowiłem usunąć z mojej aplikacji do blogowania, czyli z Bloggeroida możliwość uploadowania obrazków.
Czemu to muszę zrobić?
Bo kiedyś zdecydowałem się używać 3rd party usługi, czyli Picasy od Google do przechowywania obrazków (używam też Bloggera, ale Bloggeroid to klient Bloggera ;-)).
A Google po wielu latach wspierania Picasy uznało, że już jej nie będzie wspierać, że Google Photos są lepsze.
To zabijają Picasę, proponując przejście do Google Photos. Które to Google Photos nie mają możliwości publikacji obrazków tak by były możliwe do osadzenia na innych stronach.
To usunąłem z Bloggeroida odpowiednie fragmenty kodu, a szczerze to nawet nie kod, a jego użycia.
Zrobiłem wersję z podpisem.... próbowałem wrzucić do Google Play Console, które mnie opluło, że nie, bo wersja targetApi jest 25, a powinna być najmniej 26....
To zmieniłem to, ale to wymagało zmienienia wersji narzędzi buildujących....
To znów zmianę wersji bibliotek.
Jak już niby wszystko było OK, to znów Gradle zaczął płakać, że Jack (kompilator który pozwalał używać ficzerów w Java 8) jest deprecated.
Gdy wyłączyłem Jacka to zaczęło płakać, że bez niego nie mogę używać ficzerów z Java 8.
Żeby móc ich używać zainstalowałem wtyczkę Androida do Gradle w wersji 3.0.0 lub wyższej.
To zaczęło płakać, że nie umie pobrać Kotlina z repozytorium od Google...
Zmieniłem wersję Android Studio (bo z IntelliJ i tak nie chciało działać).
Okazało się, że muszę zmienić wersję Gradle'a.
Zmieniłem wersję Gradle'a to okazało się, że moje pliki buildowe są niekompatybilne bo używam compile i testCompile, a powiniennem implementation i testImplementation....
To nie pomogło bo znów coś leci....
Jak rozumiem teraz dlatego, że gdzieś któryś kawałek kodu, którego nie używam, ale używa jakaś biblioteka jest niekompatybilny z najnowszym Gradle....
Gdzie popełniliśmy błąd?
Programiści mieli podobno rozwiązywać problemy przy pomocy kodu, a teraz głównie spędzają czas walcząc z narzędziami.
Wprowadzono narzędzia i biblioteki, które miały ułatwić nam pracę, miały sprawić, że nie będziemy marnować czasu na niepotrzebne zadania.
A w rezultacie dostaliśmy kolejne.
Gdy potrzebujesz zrobić coś bardzo typowego, powiedzmy stworzenie nowego projektu, to coś co zajęłoby Ci może 15 minut zajmie Ci 30 sekund, plus jakieś 30 minut polowania po internecie na instrukcję skąd co pobrać.
Gdy narzędzia przestaną działać spędzisz wiele, naprawdę wiele godzin walcząc z nimi.
Podobne postybeta
Rant po toolach w stylu Mavane, Gradle, Bowera i całej tej hałastry
Przebrzydłe lambdy ;-)
Tak Maven'ie, zbłądziłem ;-)
Kilka Androidów w domu... jak to jest?
Jak zmusić Gradle'a do używania ramdysku (na OS X)
Dziś postanowiłem usunąć z mojej aplikacji do blogowania, czyli z Bloggeroida możliwość uploadowania obrazków.
Czemu to muszę zrobić?
Bo kiedyś zdecydowałem się używać 3rd party usługi, czyli Picasy od Google do przechowywania obrazków (używam też Bloggera, ale Bloggeroid to klient Bloggera ;-)).
A Google po wielu latach wspierania Picasy uznało, że już jej nie będzie wspierać, że Google Photos są lepsze.
To zabijają Picasę, proponując przejście do Google Photos. Które to Google Photos nie mają możliwości publikacji obrazków tak by były możliwe do osadzenia na innych stronach.
To usunąłem z Bloggeroida odpowiednie fragmenty kodu, a szczerze to nawet nie kod, a jego użycia.
Zrobiłem wersję z podpisem.... próbowałem wrzucić do Google Play Console, które mnie opluło, że nie, bo wersja targetApi jest 25, a powinna być najmniej 26....
To zmieniłem to, ale to wymagało zmienienia wersji narzędzi buildujących....
To znów zmianę wersji bibliotek.
Jak już niby wszystko było OK, to znów Gradle zaczął płakać, że Jack (kompilator który pozwalał używać ficzerów w Java 8) jest deprecated.
Gdy wyłączyłem Jacka to zaczęło płakać, że bez niego nie mogę używać ficzerów z Java 8.
Żeby móc ich używać zainstalowałem wtyczkę Androida do Gradle w wersji 3.0.0 lub wyższej.
To zaczęło płakać, że nie umie pobrać Kotlina z repozytorium od Google...
Zmieniłem wersję Android Studio (bo z IntelliJ i tak nie chciało działać).
Okazało się, że muszę zmienić wersję Gradle'a.
Zmieniłem wersję Gradle'a to okazało się, że moje pliki buildowe są niekompatybilne bo używam compile i testCompile, a powiniennem implementation i testImplementation....
To nie pomogło bo znów coś leci....
Jak rozumiem teraz dlatego, że gdzieś któryś kawałek kodu, którego nie używam, ale używa jakaś biblioteka jest niekompatybilny z najnowszym Gradle....
Gdzie popełniliśmy błąd?
Programiści mieli podobno rozwiązywać problemy przy pomocy kodu, a teraz głównie spędzają czas walcząc z narzędziami.
Wprowadzono narzędzia i biblioteki, które miały ułatwić nam pracę, miały sprawić, że nie będziemy marnować czasu na niepotrzebne zadania.
A w rezultacie dostaliśmy kolejne.
Gdy potrzebujesz zrobić coś bardzo typowego, powiedzmy stworzenie nowego projektu, to coś co zajęłoby Ci może 15 minut zajmie Ci 30 sekund, plus jakieś 30 minut polowania po internecie na instrukcję skąd co pobrać.
Gdy narzędzia przestaną działać spędzisz wiele, naprawdę wiele godzin walcząc z nimi.
Podobne postybeta
Rant po toolach w stylu Mavane, Gradle, Bowera i całej tej hałastry
Przebrzydłe lambdy ;-)
Tak Maven'ie, zbłądziłem ;-)
Kilka Androidów w domu... jak to jest?
Jak zmusić Gradle'a do używania ramdysku (na OS X)
sobota, lutego 16, 2019
Skalowanie miernika jakości powietrza ;-)
Jakiś czas temu kupiłem sobie miernik jakości powietrza.
Ale, jak wykazało porównywanie jego odczytów z tym co mówiły bardziej oficjalne wyniki nie do końca to co pokazywał zgadzało się z rzeczywistością.
Zwykle drań mocno przesadza.
Więc w końcu zrobiłem to co każdy absolwent dowolnego kierunku technicznego czy ścisłego, postanowiłem sprawdzić jak wygląda funkcja opisująca zależność tego co pokazuje mój miernik z tym co pokazują "bardziej oficjalne" mierniki.
Jako bardziej oficjalnego użyłem Airly ;-)
To wrzuciłem wyniki do tabelki:
Podobne postybeta
Dobrze wyskalowałem te 7 lat temu mój czujnik czystości powietrza ;-)
Airly + Python + Oczyszczacz Powietrza = lepsze oddychanie ;-)
Algorytm - czemu w szkole nie uczą jak obliczyć pierwiastek? ;-)
Spektroskop z płyty CD :-)
3 Home w jednym domu ;-)
Ale, jak wykazało porównywanie jego odczytów z tym co mówiły bardziej oficjalne wyniki nie do końca to co pokazywał zgadzało się z rzeczywistością.
Zwykle drań mocno przesadza.
Więc w końcu zrobiłem to co każdy absolwent dowolnego kierunku technicznego czy ścisłego, postanowiłem sprawdzić jak wygląda funkcja opisująca zależność tego co pokazuje mój miernik z tym co pokazują "bardziej oficjalne" mierniki.
Jako bardziej oficjalnego użyłem Airly ;-)
To wrzuciłem wyniki do tabelki:
| miernik [PM2.5] | Airly [PM2.5] |
| 40 | 19 |
| 53 | 23 |
| 81 | 27 |
| 142 | 41 |
Później narysowałem wykres w Google Sheets:
Jak widać Google Sheets pokazały mi już nawet równanie ;-) [trzeba się pobawić w Series].
Głębsze oglądanie pokazało mi też, że R2=0.993.
Czyli teraz już wiem, że chcąc poznać rzeczywiste zanieczyszczenie PM2.5 gdy mój miernik coś pokazuje to powinienem wrzucić to do wzoru:
Albo po prostu podzielić wynik przez 5 i dodać 11 ;-)
Tutaj taka uwaga, mój miernik mierzy przy pomocy diody, pewnie nie używa rozproszenia Rayleigha, a patrzy pewnie tylko na ilość odbitego, albo przepuszczonego światła...
Więc możliwe, że np. PM10 też mocno wpływa na wzór, tego jeszcze nie wiem ;-)
Ale wszystko wskazuje, że jak mój miernik już panikuje i pokazuje:
Z podpisem Moderate, to tak naprawdę PM2.5 wynosi jakieś 18.5 µg/m3, a nie 35.9 µg/m3 ;-)
Czyli teraz już wiem, że chcąc poznać rzeczywiste zanieczyszczenie PM2.5 gdy mój miernik coś pokazuje to powinienem wrzucić to do wzoru:
Prawdziwe_PM2.5=0.21*wynik_PM2.5_z_miernika+10.9
Albo po prostu podzielić wynik przez 5 i dodać 11 ;-)
Tutaj taka uwaga, mój miernik mierzy przy pomocy diody, pewnie nie używa rozproszenia Rayleigha, a patrzy pewnie tylko na ilość odbitego, albo przepuszczonego światła...
Więc możliwe, że np. PM10 też mocno wpływa na wzór, tego jeszcze nie wiem ;-)
Ale wszystko wskazuje, że jak mój miernik już panikuje i pokazuje:
Z podpisem Moderate, to tak naprawdę PM2.5 wynosi jakieś 18.5 µg/m3, a nie 35.9 µg/m3 ;-)
Podobne postybeta
Dobrze wyskalowałem te 7 lat temu mój czujnik czystości powietrza ;-)
Airly + Python + Oczyszczacz Powietrza = lepsze oddychanie ;-)
Algorytm - czemu w szkole nie uczą jak obliczyć pierwiastek? ;-)
Spektroskop z płyty CD :-)
3 Home w jednym domu ;-)
Subskrybuj:
Posty (Atom)



