Pyxis

Pyxis
2019-05-06 00:13

Ciekawy patent na zmianę systemu z dziesiętnego na binarny w Bashu w nieco przewrotny sposób:

dec2bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
echo ${dec2bin[25]} # 00011001
echo ${dec2bin[255]} # 11111111
cerrato

a czy możesz wyjaśnić jak to działa? Bo bashem się bawiłem dawno temu i średnio jestem na bieżąco :(

Pyxis
2018-11-20 19:33

Zwykle gdy przetwarzamy dane, to wygodnie jest operować na tablicach dwuwymiarowych (np. gdy wczytujemy tabele z pliku). Ciekawymi obiektami są tablice maskowane (MaskedArray) w Pythonie. Czasem zachodzi potrzeba zapisania takiego obiektu do pliku. Oczywiście można go zapeklować, ale ja miałem potrzebę zrzucenia takiego obiektu z pominięciem zamaskowanych wierszy. W takim przypadku możemy użyć metody compressed. Problem w tym, że otrzymamy jednowymiarowy obiekt, który burzy nam wielokolumnową strukturę...

Otwórzmy najpierw taki obiekt:

import numpy as np
import numpy.ma as ma

tab = ma.arange(1,36).reshape(7,5)
tab.mask = ~np.asarray(tab, dtype=bool)
tab.mask[2] = tab.mask[5] = True

Wygląda to mniej więcej tak:

masked_array(
  data=[[1, 2, 3, 4, 5],
        [6, 7, 8, 9, 10],
        [--, --, --, --, --],
        [16, 17, 18, 19, 20],
        [21, 22, 23, 24, 25],
        [--, --, --, --, --],
        [31, 32, 33, 34, 35]],
  mask=[[False, False, False, False, False],
        [False, False, False, False, False],
        [ True,  True,  True,  True,  True],
        [False, False, False, False, False],
        [False, False, False, False, False],
        [ True,  True,  True,  True,  True],
        [False, False, False, False, False]],
  fill_value=999999)

Metoda compressed wywołana na tab, czyli tab.compressed() da nam nowy obiekt typu ndarray:

array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 31, 32, 33, 34, 35])

W zasadzie łatwo można to rozwiązać w ten sposób:

tab.data[~tab.mask].reshape(tab.shape[0] - len([_ for i in tab.mask if i.all()]), tab.shape[1])

by dostać:

array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25],
       [31, 32, 33, 34, 35]])

Po czym możemy zapisać taki obiekt do pliku tekstowego z zachowaniem struktury. tab.data[~tab.mask] zwraca to samo co metoda compressed. W zasadzie główna sprawa to wyznaczenie poprawnego wymiaru macierzy. Stosowanie maskowanej macierzy ma sens, na przykład kiedy chcemy wyróżnić pewną grupę punktów na wykresie. Oczywiście zastosowań jest więcej.

Pyxis
2018-06-25 12:29

Ciekawe wykorzystanie wyrażeń regularnych w Pythonie:

import re

def isprime(n):
    return re.compile(r'^1?$|^(11+)\1+$').match('1' * n) is None

print([x for x in range(100) if isprime(x)])

###########Output#############
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
cerrato

Nie rozumiem, ale podziwiam i szanuję :D

cerrato

@scibi92: dokładnie tak samo inteligentnie wyglądałem jak próbowałem zrozumieć, jak to działa. Po kilkunastu sekundach stwierdziłem, że szkoda czasu i lepiej zająć się czymś, co mi lepiej wychodzi - czyli dalej trollować na forum :D

vpiotr

To jest starsze od niektórych (większości?) użytkowników tego forum, jedno ze starszych wystąpień: http://diswww.mit.edu/bloom-picayune.mit.edu/perl/10138

Silv

A ja zapytam: po co jest tam to is None?

cerrato

@silv - nie interesuj się. Tego i tak nie da się zrozumieć, to są regexy ;)

jarekr000000

Ładne. Ta dodatkowa obsługa 0 i 1 to już niezła dbałość o szczegóły. @Silv is None jest dlatego, że de fakto regex łapie liczby niepierwsze i trzeba zanegować.

cerrato

@jarekr000000: A tak całkiem poważnie - czy mógłbyś wytłumaczyć mi (i podejrzewam,że dużej części forum) jak konkretnie podany przykład działa? Osobiście wiem, co to są regexy, kiedyś jak musiałem to parę prostych zrobiłem, ale ogólnie odrzuca i przeraża mnie sama świadomość, że one istnieją, a tutaj jestem mega ciekawy, w jaki sposób można regex'ami podejść do liczb pierwszych :o

jarekr000000

W sumie to nawet proste: 1 - liczba n jest zamieniana ('1' * n) na ciąg jedynek czyli 7 => 1111111 a 9 => 111111111. Potem najważniejsze jest to: (11+)\1+. (11+) złapie ciąg jedynek o długości 2 lub więcej (11 111 1111 11111 itd.). Z kolei \1 oznacza to co w ostatnim (pierwszym) nawiasie proszę (tzw. capturing group reference). I za nim jest jeszcze + czyli przynajmniej raz (może być więcej). I teraz jak mamy taką 9 -> 111111111 to najpierw wyrażenie w nawiasie dopasuje dwie jedynki (11) i będzie potem jeszcze raz te jedynki dopasowywał przez \1+, ale nijak się nie uda z pozostałych 7 jedynek zrobić X powtórzeń 11 żeby zakończyć w $ czyli na końcu ciągu. Nie bedzie dopasowania. No to wtedy kolejna próba dopasowania - wyrażenie (11+) złapie również 3 pierwsze 1 i wtedy łatwo widać, że pozostąłe 6 jedynek 111111 to dwukrotne powtórzenie tego co było w grupie ( wyrażenie \1+). Co robi: ^1?$ zostawiam do domyślenia, ale powiem, że to tylko kwiatek do kożucha.

cerrato

Dzięki za wyjaśnienia. Teraz rozumiem, dlaczego często chodzisz w stroju czarodzieja ;)

jarekr000000

@cerrato: to, że ogarniam przeczytanie regexpa nie oznacza, że wpadłbym na taki trik. Do głowy by mi nie przyszło :-)

cerrato

I tak jesteś poziom wyżej ode mnie - bo ja nawet tego przeczytać nie umiałem (pewnie jakbym musiał, to przez pól dnia, z manualami i how-to bym temat ogarnął) - ale na pewno nie tak, jak Ty - że paczę i wicę ;)

Pyxis

@cerrato: wczoraj pisałem wyjaśnienie podobne do tego, jakie przedstawił @jarekr000000. Jak już było gotowe, to powstrzymałem się przed wysłaniem, bo pomyślałem, że autentycznie trollujesz, prosząc o wyjaśnienie :)

cerrato

Nie, to co pisałem było całkiem na serio. Wiem, co to są regex'y, ale ich (na szczęście) nie używam, więc dla mnie podany przykład nie był wcale oczywisty. Mogłem poświęcić X czasu i to rozkminiać, ale szczerze mówiąc aż tak istotna ta kwestia dla mnie nie była. A jak ktoś (jak Jarek czy Ty) siedzi w tym i regularnie korzysta, to jest w stanie dość szybko i sprawnie wyjaśnić, w jaki sposób ta cała magia się odbywa.

jarekr000000

@cerrato: korzystam nieczęsto z regexpów. Przeważnie przy tym potrzebuję pomocy googla :-)

cerrato

i tak nieczęsto > (praktycznie) wcale

Silv

@cerrato: ale ja właśnie rozumiem wyrażenia regularne, tylko nie rozumiem Pythona. :(

Silv

@jarekr000000: no dobrze, tylko dlaczego to się pisze is None? Brzmi to dziwnie. Nie chciałbym szukać w Google całej składni pythonowej, dlatego pytam tutaj.

Pyxis

@Silv: jeśli wzorzec zostanie dopasowany, to zwracany jest obiekt dopasowania. W przeciwnym razie nie jest nic zwracane. Ponieważ funkcja isprime() ma zwracać True albo False, to trzeba sprawdzić, czy zwracany obiekt istnieje, czy jest None.

scibi92

@jarekr000000: @cerrato ja to z regexów to wiem tylko jak zrobić łańcuch zawierający liczby, cyfry jakieś znaki o danej długości np. [a-z,0-9]{3,9}

cerrato

@scibi92: no to mamy podobną wiedzę w tym zakresie :D

scibi92

Spoko, jeszcze zostane wizardem w tej materi :D

cerrato

@jarekr000000 - czy czujesz oddech konkurencji na plecach? ;)

scibi92

@cerrato: a może nauczę się regexów zarąbiśice i zrobie POTĘŻNY kurs na ich temat na udemy xD

cerrato

A za kilka lat na 4P będą wpisy w stylu "przyszedł do mnie junior po kursie regex'ów u jakiegoś Scibiego. Co to za ściema z tym Scibi? Ludzie po jego kursie niczego nie kojarzą" :P

scibi92

Wszystko będą wiedziec xD

scibi92

@cerrato: wątki, semaphory, synchronizacja, CountDownLatche - wszystko w 1 paluszku xD

Silv

@Pyxis: dziękuję! A czy None jest tym samym, co null w Javascripcie? A może tym samym co undefined?

nalik

Proste i piękne. Zamień liczbę na patyczki i sprawdź czy patyczki da się podzielić na co najmniej dwie grupy o takim samym rozmiarze.

enedil

PRIMES are in EXPTIME and EXPSPACE

nalik

@enedil tak, złożoność też ma "piękną", ale inaczej :D