Pretekst

Od jakiegoś czasu szukałem pretekstu, żeby pobawić się maszynkami z Ampere A1 od Oracle. Poza tym, w zadaniach przetestowanie Cloudflare na blogu wisiało… prawie 5 lat. I jeszcze na dodatek gorącym tematem jest AI, często reprezentowana ostatnio przez ChatGPT. Ale jakoś na nic nie było czasu i potrzeby.

Zatem wpadłem na pomysł, żeby postawić bloga, który będzie WordPressem, stojącym na VMce z arm64, za Cloudflare, a treść dostarczać będzie głównie AI. Trzy pieczenie na jednym ogniu. W sumie cztery, bo jeszcze sprawdzę indeksowanie tego tworu i zarobię miliony na reklamach. Poznajcie blog everything about coffee.

Przyznam, że było trudniej, niż się spodziewałem. Najpierw był problem z wyborem domeny. Stwierdziłem bowiem, że taki eksperyment wymaga stosownej separacji. W domenach raczej nie siedzę, więc znalezienie czegoś sensownego w niewielkich pieniądzach było trudne. Stanęło na tym, że analogicznie jak na głównej domenie niech się składa w jedno słowo. I tak powstał coffee express. Bez es. W sumie także bez e w środku, bo byłyby aż trzy kolejno, ale to już wybór, nie ograniczenie techniczne.

Domena

Wydawać by się mogło, że kupno domeny w 2023 jest proste, szybkie i przyjemne. Sprostuję, nie jest. A przynajmniej nie jest, jeśli korzysta się z TLD .es a kupuje w OVH. Rejestrator ma teraz dziwne wymagania, panel OVH ma dziwne pola i komunikaty. Ostatecznie udało się, po kontakcie z supportem OVH. Dwukrotnym.

Hosting

Jeśli chodzi o Ampere A1, to ostatecznie odpuściłem instalację Debiana, którego Oracle nie dostarcza i użyłem gotowca w postaci Ubuntu. Przynajmniej na podstawce AKA hypervisorze, bo sam blog stoi już w kontenerze LXC z Debianem. Za wiele się tam nie dzieje, ale – po krótkim obcowaniu – maszynka wygląda na wydajną i generalnie śmiga.

Cloudflare

Przepięcie domeny na Cloudflare – szybkie, łatwe i przyjemne. Podpowiadają co mają podpowiadać, autouzupełnianie działa. Panel przejrzysty, ustawienia domyślne sensowne. Opcji w wersji darmowej niewiele, ale wystarczają.

Oczywiście jest tricky part związana z certyfikatami SSL czy ustawieniami DNS, jeśli chce się mieć coś dostępne bezpośrednio, ale da się. No i wypada zablokować ruch HTTP(S) do serwera spoza Cloudflare. Jest wiele sposobów, wybrałem prawdopodobnie najprostszy i najgorszy, czyli iptables z wyjątkami na klasy adresowe Cloudflare na maszynie. Może kiedyś zmienię.

WordPress

Stawianie WordPressa także okazało się pewnym wyzwaniem. Może nie tyle samo postawienie, co doprowadzenie do działania. W każdym jakby ktoś wybrał wariant z ruchem nieszyfrowanym między blogiem a Cloudflare, czyli teoretycznie najprostszą opcję, to może się naciąć. W praktyce chyba prościej uruchomić to jako szyfrowane, z certyfikatem self signed. Nie obyło się bez grzebania w wp-config.php. Poza tym, raczej było prosto. Najwięcej czasu zeszło na wybór grafiki i ręczną instalację i konfigurację wszystkich wtyczek do WordPressa, których używam.

ChatGPT

No i na koniec część związana z AI. Jak łatwo można się domyślić, bawiłem się chatGPT przy porannej kawie i wtedy powstał pomysł na bloga generowanego przy pomocy AI. No właśnie nie przez AI, a przy pomocy. Co to znaczy? Ano to, że może się zdarzyć, że ingeruję w odpowiedzi zwrócone przez chatGPT. Łączę je, przycinam, albo dodaję coś od siebie. Ale nie jest to regułą i zwykle po prostu przeklejam wprost. Bez korekty, sprawdzania faktów itd. Błędy się zdarzają, o czym można przeczytać choćby w komentarzach do tego wpisu. Poza tym, nie podaję prompta i sam, ręcznie wybieram tytuł. Ot, powiedzmy taki asystent leniwego copywrightera w postaci AI. Co do zasady muszę zmieścić się z utworzeniem wpisu od początku do końca przy paru łykach porannej kawy.

Projekt nie jest skończony. Marzy mi się dorzucanie powiązanych obrazków do każdego wpisu. Najchętniej automatyczne. Brakuje detali typu favicona czy optymalizacja szybkości. Choć ten w zasadzie goły WordPress za Cloudflare działa wg GTmetrix podobnie szybko, co ten blog. Nad wyświetlaniem reklam nadal pracuję – chwilę to trwa już po stronie Google No i oczywiście wpisów na razie jest mało, a chciałbym dodawać około dwóch tygodniowo, przynajmniej przez najbliższych parę miesięcy.

DeepL

UPDATE: Do gromady dołączył jeszcze DeepL, a dokładnie Write. Coraz częściej zdarza mi się dodać coś od siebie, poza tym ChatGPT pisze dość sucho i encyklopedycznie. Nie używam domyślnie, raczej sporadycznie póki co. I uwzględniam tylko niektóre sugestie, ale warto wspomnieć i o tym narzędziu.

Recenzja słuchawek Mozos M700BT

Niby mam słuchawki, niby wolę na kablu. Ale od pewnego czasu chodzą za mną słuchawki na Bluetooth. Żona ma od lat Sony WH-CH510. To świetne słuchawki, funkcjonalne, wygodne, z bardzo dobrym czasem pracy na baterii (do 35h) i umiarkowaną ceną (ok. 150 zł normalnie, bywają 30-40 zł taniej w promocji). Kupiłbym je już dawno, ale brakuje mi w nich jednej rzeczy – możliwości podłączenia kabla i korzystania przewodowo.

Słuchawki Mozos M700BT
Mozos M700BT Źródło: https://mozos.pl/sklep/mozos-m700bt-sluchawki-nauszne-bezprzewodowe-bt5-0/

Po co kabel? Ano niektóre urządzenia nie mają BT. Choćby piecyk do gitary. Poza tym, jeśli siedzę w pracy przy komputerze, to wolę mieć wpięty kabel kabel, niż pamiętać o ładowaniu. Dodam jeszcze, że chodzi mi wyłącznie o słuchanie muzyki, w wersji na kablu nie potrzebuję mikrofonu. Zresztą w obecnie używanych do komputera Sony MDR-ZX110 też nie ma mikrofonu.

Dodatkowo niedawno w ręce wpadły mi przypadkiem jeszcze tanie słuchawki Bluetooth znane jako B39, kosztujące ok. 25-40 zł i o ile jakość materiałów, wykonania i parametry pozostawiały nieco do życzenia, to grały całkiem znośnie[1]. Dlatego gdy zobaczyłem pozytywne opinie o tytułowych Mozos M700BT, że grają poprawnie, ale jakość wykonania bardzo dobra w tej cenie, zacząłem się zastanawiać. Do 16h pracy na baterii może nie zachwyca, ale… dają możliwość podłączenia kablem.

Mozos M700BT na bluetooth

Zamówiłem słuchawki M700BT (60 zł), zamówiłem od razu kabel. Przyjechały. Rozpakowałem – jakość faktycznie na oko przyzwoita. Podłączyłem do komputera i telefonu, posłuchałem – grają OK. Zasięg również bez problemu. Dodatkowo dobrze przylegały i miło przytłumiały otoczenie[2]. Cecha przeze mnie pożądana, ale niewymagana. Generalnie jako słuchawki bluetooth – przyzwoite, do rozważenia.

Kabel do słuchawek

Stwierdziłem, że pora na podłączenie kablem i… tu zaczęły się schody. Niektórzy sprzedawcy piszą wprost o możliwości podłączenia kablem jack 3,5 mm, inni o możliwości podłączenia kablem. Sam producent na stronie produktu pisze tak:

Co warte odnotowania słuchawki mogą łączyć się również przewodowo za pomocą standardu jack 3.5 mm (przewód należy dokupić oddzielnie).

Tyle, że w słuchawkach nie ma gniazda jack! Jest USB C, to samo, które służy do ładowania. No dobra. Nie jestem szczęśliwy, ale jeszcze nie ma dramatu. Kabel można dokupić. Niestety, okazało się to nie takie proste, na jakie wygląda. Większość kabli to przejściówki z USB C na jack. Czyli źródłem jest np. telefon, a odbiornikiem np. radio z gniazdem mini jack. Jakoś nie wierzyłem w dwukierunkowość tego typu rozwiązań, tym bardziej, że wszyscy producenci i sprzedawcy pokazywali i opisywali jasno sugerując kierunek nadawania sygnału.

Zapytałem producenta i szybko uzyskałem odpowiedź, że należy dokupić kabel do słuchawek Bluedio. Zatem cytowany powyżej opis z jednej strony jest prawdziwy, z drugiej nie, Zależy na który koniec kabla spojrzeć. Szybko poszukałem co to takiego Bluedio i okazało się, że Mozos M700BT to rebrandowane Bluedio BT5, a przynajmniej wszelkie znaki na niebie i ziemi na to wskazują. Kabel był trochę drogawy, bo 30 zł to połowa ceny słuchawek. Stwierdziłem jednak, że dam szansę.

Mozos M700BT na kablu

Dałem i jestem głęboko rozczarowany. Jakość dźwięku na kablu jest tragiczna. Dźwięk jakby zniekształcony, totalny brak basów, wręcz trudno rozpoznać utwory. Sprawdzone na dwóch komputerach. Skojarzenia z rozmową przez telefon jak najbardziej na miejscu. Być może od biedy nada się to do telekonferencji, ale nie sprawdzałem, bo nie o to chodzi. Nie wiem, czy to kwestia egzemplarza, czy coś jest zepsute, czy to po prostu broken by design.

Cieszę się, że kupiłem ze Smart! na Allegro, bo do tej pory nie miałem nigdy problemów ze zwrotem[3]. Zastanawiałem się, czy oddać sam kabel, czy także słuchawki. Bowiem jako słuchawki bezprzewodowe oceniam je jako przyzwoite. Jednak po namyśle stwierdziłem, że jeśli mam kupować, to takie, które naprawdę pozwalają zarówno na działanie po bluetooth, jak i na kablu.

Jeśli więc czytelnicy są w stanie wskazać sprawdzone, niedrogie, nauszne słuchawki bluetooth, które potrafią zmienić się w przewodowe i grać na kablu, to poproszę.

[1] Odwołuję. Przymierzyłem i jest to jako-tako. Widocznie w pierwszym wrażeniu zachwyciłem się, że jest jakiś bas, a nie kartony. Bo jakiś jest, ale sztuczny i zbyt mocny. Ale to detal, w porównaniu z tym, że nie grają normalnego, oddzielnego stereo. Na testach, gdzie normalnie gra jeden głośnik, w nich grają oba. Nie przypuszczałem, że takie coś może w ogóle mieć miejsce.
[2] Niektórzy narzekali, że słabo wygłuszają, bo są przerwy między słuchawkami a głową. Jestem w stanie zrozumieć – to słuchawki z montażem „na sztywno”, bez żadnej swobody, więc może się zdarzyć, że komuś nie do końca przypasują do głowy.

UPDATE: [3] Zwroty bez problemu. Zapakowałem, odesłałem, po paru dniach pieniądze były z powrotem na koncie.

Podobieństwo i porównywanie zbiorów

Przy okazji projekciku[1] trafiłem na interesujący problem. Chodzi o porównywanie zbiorów, a dokładnie liczenie ich podobieństwa. Marzyło mi się, by wyrazić je w zakresie 0 do 1, gdzie 0 to zbiory rozłączne, a 1 zbiory identyczne[2].

Popełniłem następujący kawałek kodu, liczący, na ile set2 jest podobny do set1:

def count_similarity_percent(set1, set2):
    base_count = len(set1)
    if base_count == 0:
        base_count = 1
    matching = 0
    for element in set1:
        if element in set2:
            matching += 1
    perc = 100 * matching / base_count
    return perc

Niby działa, ale… Spójrzmy na przykłady.
Przykład 1:

A = [1, 2, 3, 4]
B = [3, 4, 5, 6]

Podobieństwo A do B wynosi 50% (2 z 4 elementów ze zbioru A występują w B).
Podobieństwo B do A także wynosi 50% (2 z 4 elementów ze zbioru B występują w A).
Wszystko fajnie. Podobieństwa są równe, niezależnie z której strony patrzeć.

Niestety, jeśli zbiory będą miały różną ilość elementów, to sprawa się komplikuje i podobieństwo A do B przestaje być równe podobieństwu B do A. Możemy to zobaczyć w kolejnym przykładzie.
Przykład 2:

A = [1, 2, 3, 4]
B = [3, 4]

Podobieństwo B do A to nadal 50%.
Podobieństwo A do B wynosi 100% – 2 z 2 elementów A występują w B.

Nie spodobało mi się to i zastanawiałem się, co można z tym zrobić. Z jednej strony chciałem, by wartości były przechodnie, tj. równe, niezależnie z które strony porównuję.

Przez głowę przeleciało mi szybko liczenie średniej z podobieństw i zapamiętywanie w obu przypadkach tego wyniku. Podobnie mógłbym zapamiętywać w obu wynikach większą – lub mniejszą – z wartości podobieństwa. Z drugiej strony kołatało mi się, że fajnie nie byłoby liczyć dwa razy.

Poszukałem, popytałem i okazało się, że są do tego miary. W tym przypadku miarą podobieństwa zbiorów jest indeks Jaccarda[3] . Jest prosta i „przechodnia”, tj. nie ma znaczenia, który zbiór z którym się porównuje.

Znalazłem taki wpis o indeksie Jaccarda dla Pythona, ale przyznaję, że nie spodobała mi się implementacja. Po pierwsze, bez sensu importowane jest numpy, które w tym przypadku niczego nie robi. Po drugie, implementacja jest poprawna, ale nieco zakręcona. Lepiej implementować na setach, nie listach. I jak najbardziej można skorzystać z wbudowanego union, a następnie liczyć wprost, wg definicji.

def jaccard_index_percent(set1, set2):
    intersection_count = len(set1.intersection(set2))
    union_count = len(set1.union(set2))
    if union_count == 0:
        union_count = 1
    return 100 * intersection_count / union_count

Zapewne użyję ww. wersji do porównywania zbiorów. Chyba, że pokuszę się jeszcze kiedyś o optymalizację pod kątem prędkości działania. O ile zauważę taką potrzebę.

[1] Jeśli coś się z tego wykluje sensownego, to niebawem opiszę dokładniej.
[2] Od 0 do 1, od 0% do 100%, bez znaczenia, wartość jest taka sama. Choć IMO ludzie lepiej rozumieją procenty, a łatwiej kodować na float. Ale to wszystko nieistotny detal.
[3] Linkuję we wpisie polską wersję, która jest lakoniczna, ale prostsza. Jeśli ktoś jest bardziej zainteresowany tematem, to polecam wersję angielską, wraz z see also.