Bylo oznámeno (cs) vydání Fedora Linuxu 40. Přehled novinek ve Fedora Workstation 40 a Fedora KDE 40 na stránkách Fedora Magazinu. Současně byl oznámen notebook Slimbook Fedora 2.
ČTK (Česká tisková kancelář) upozorňuje (X), že na jejím zpravodajském webu České noviny byly dnes dopoledne neznámým útočníkem umístěny dva smyšlené texty, které nepocházejí z její produkce. Jde o text s titulkem „BIS zabránila pokusu o atentát na nově zvoleného slovenského prezidenta Petra Pelligriniho“ a o údajné mimořádné prohlášení ministra Lipavského k témuž. Tyto dezinformace byly útočníky zveřejněny i s příslušnými notifikacemi v mobilní aplikaci Českých novin. ČTK ve svém zpravodajském servisu žádnou informaci v tomto znění nevydala.
Byla založena nadace Open Home Foundation zastřešující více než 240 projektů, standardů, ovladačů a knihoven (Home Assistant, ESPHome, Zigpy, Piper, Improv Wi-Fi, Wyoming, …) pro otevřenou chytrou domácnost s důrazem na soukromí, možnost výběru a udržitelnost.
Společnost Meta otevírá svůj operační systém Meta Horizon OS pro headsety pro virtuální a rozšířenou realitu. Vedle Meta Quest se bude používat i v připravovaných headsetech od Asusu a Lenova.
Společnost Espressif (ESP8266, ESP32, …) získala většinový podíl ve společnosti M5Stack, čímž posiluje ekosystém AIoT.
Byla vydána nová stabilní verze 3.5 svobodného multiplatformního softwaru pro editování a nahrávání zvukových souborů Audacity (Wikipedie). Přehled novinek také na YouTube. Nově lze využívat cloud (audio.com). Ke stažení je oficiální AppImage. Zatím starší verze Audacity lze instalovat také z Flathubu a Snapcraftu.
50 let operačního systému CP/M, článek na webu Computer History Museum věnovaný operačnímu systému CP/M. Gary Kildall z Digital Research jej vytvořil v roce 1974.
Byl zveřejněn program a spuštěna registrace na letošní konferenci Prague PostgreSQL Developer Day, která se koná 4. a 5. června. Na programu jsou 4 workshopy a 8 přednášek na různá témata o PostgreSQL, od konfigurace a zálohování po využití pro AI a vector search. Stejně jako v předchozích letech se konference koná v prostorách FIT ČVUT v Praze.
Po 48 letech Zilog končí s výrobou 8bitového mikroprocesoru Zilog Z80 (Z84C00 Z80). Mikroprocesor byl uveden na trh v červenci 1976. Poslední objednávky jsou přijímány do 14. června [pdf].
Ještě letos vyjde Kingdom Come: Deliverance II (YouTube), pokračování počítačové hry Kingdom Come: Deliverance (Wikipedie, ProtonDB Gold).
Pro jeden Pythoní projekt na kterém pracuji jsem potřeboval převést CRONový zápis (12 9 * * *) na "human readable" string, zde se chci podělit o výsledek.
Po chvilce hledání na google jsem zjistil že nic takového pro Python neexistuje (nebo je projekt ve velmi raném/nepoužitelném stádiu). Po prvních pokusech a zjištění ze to kvůli hromadě vyjímek nebude jen pár řádek kódu, mě napadlo že bych se mohl podívat zda li tohle již někdo neřešil pro jiné jazyky. Nakonec jsem narazil na celkem slušnou .NET implementaci (Rozluštění záhady proč někdo tvoří parser na UNIXový CRON v .NETu necháme pro Akta X) kterou jsem se rozhodl naportovat do Pythonu (+ pár menších vylepšení).
cron-descriptor je dostupný skrze pip:
(pokud zde mate velke bile misto, tak pokracovani je nize pod pravym sidebarem... nevim jak tento bug z me strany opravit)
pip install cron-descriptor
from cron_descriptor import Options, CasingTypeEnum, DescriptionTypeEnum, ExpressionDescriptor # Jednoduše print(ExpressionDescriptor("*/10 * * * *")) # Pokročilé nastavení (viz Options.py) descripter = ExpressionDescriptor("*/10 * * * *", throw_exception_on_parse_error = True, casing_type = CasingTypeEnum.Sentence, use_24hour_time_format = True) # get_description uses DescriptionTypeEnum.FULL by default: print(descripter.get_description()) # Nebo print("{}".format(descripter))
# 24 hodinový formát 17 * * * * -> At 17 minutes past the hour 25 6 * * * -> At 06:25 47 6 * * 7 -> At 06:47, only on Saturday 52 6 1 * * -> At 06:52, on day 1 of the month # 12 hodinový formát 17 * * * * -> At 17 minutes past the hour 25 6 * * * -> At 06:25 AM 47 6 * * 7 -> At 06:47 AM, only on Saturday 52 6 1 * * -> At 06:52 AM, on day 1 of the month
https://github.com/Salamek/cron-descriptor
PR's jsou vítány
Tiskni Sdílej:
Pristup prepsat existujici implementaci v jinem jazyce je urcite mnohem lepsi nez zacinat od nuly.Ale je to menší zábava (respekt autorovi).
Podpora Pythonu 2.7-3.4Jak je toho dosaženo? Dle zdrojaku mám dojem, že se prostě nepoužívá žádná kolizní syntaxe. Jak se to dá řešit?
#: ExpressionDescriptor.py:218 #, python-brace-format msgid "at {0}" msgstr "v {0}"Pokud by stejným stylem bylo udělaných vět více, může být v některých použita špatná předložka. Letmý pohled do slovníku rychle ukáže, kolik možností překladu podle kontextu se nabízí – úryvek ze slovnik.cz:
at - k at - na (místo, čas, stav, pohyb, cíl) at - po (cena, množství, např.o ceně k)s at - v (místo, čas, stav) at - z at - u (těsně) at - o (čas, stav) at - při (čas, stav, činnost) at - za (čas, stav) at - alespoň at - jak budete mít čas at - jak to je at - ke at - těsně u (2. p.) at - veSprávný přístup je mít jeden řetězec s celou větou se zástupnými symboly a tu přeložit. Nikoliv slepovat krátké samostatně překládané řetězce do věty s anglickým slovosledem. Naneštěstí v tomto případě to je tak trochu pointa celého toho programu. Dalo by se to zlepšit použitím delších fragmentů, ale ani to ideální nebude. Proto například Osmand má hlasovou navigaci implementovanou v Prologu a každý jazyk má vlastní pravidla, jak skládat věty pro různá oznámení. Pak můžeš mít správně slovosled podle daného jazyka, ale i skloňování, časování a další vymoženosti.
Nedávno som niečo podobné robil pre recurrence rule a podobných problémov je tam dosť veľa a časť z nich je rovnaká pre všetky projekty ktoré vyjadrujú čas/dátum v ľudsky zrozumiteľnom tvare (ak má ísť naozaj o tvar, ktorému majú bez problémov rozumieť ľudia).Vždycky když něco takového čtu, tak si říkám, že asi nejsem člověk. Nejlépe se mi používá tvar, který víceméně standardizuje ISO. Všechno vyjádřeno číselně. Všechna čísla doplněná zleva nulami do jednotného zarovnání. Všechna čísla seřazena podle váhy od největší po nejmenší. Paradoxně je takový způsob ze všech řetězcových zápisů nejvýhodnější i pro počítač.
To "on day 1 of the month", s prižmúrením očí, dáva v angličtine zmysel, ale český preklad "v 1 den v měsíci" má iný význam.To bude asi reakce na úplně jiný komentář.
PS: A len tak pre zaujímavosť, ako by vyzeralo vyjadrenie crontab v "ISO" formáte (a prípadne aj s príkladom pre recurrence rule).Oni definují formát data a času. Musel bys tam doplnit nějaké ty zápisy s crontab. Já osobně nemám problém používat crontab zápis tak jak je, bez nějakých přepisů.
""" Converts a Cron Expression into a human readable string """ class ExpressionDescriptor(object): m_special_characters = ['/', '-', ',', '*'] m_expression = '' m_options = None m_expression_parts = [] m_parsed = FalseProč jsi použil tyhle divné docstringy? V pythonu bývá zvykem používat jako docstring první řetězec v těle funkce. Ty používáš všechny před tělem funkce. Nápověda tak nefunguje:
bystrousak:~/Plocha/cron-descriptor,0$ python Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from cron_descriptor.ExpressionDescriptor import ExpressionDescriptor >>> help(ExpressionDescriptor)
Help on class ExpressionDescriptor in module cron_descriptor.ExpressionDescriptor: class ExpressionDescriptor(__builtin__.object) | Methods defined here: | | __init__(self, expression, options=None, **kwargs) | | __repr__(self) | | __str__(self) | | format_time(self, hour_expression, minute_expression, second_expression='') | | get_day_of_month_description(self) | | get_day_of_week_description(self) | | get_description(self, type=1) | | get_full_description(self) | | get_hours_description(self)Správně by to mělo vypadat takhle:
class ExpressionDescriptor(object): """ Converts a Cron Expression into a human readable string """ m_special_characters = ['/', '-', ',', '*'] m_expression = '' m_options = None m_expression_parts = [] m_parsed = FalseCož pak v help()u vypadá:
Help on class ExpressionDescriptor in module cron_descriptor.ExpressionDescriptor: class ExpressionDescriptor(__builtin__.object) | Converts a Cron Expression into a human readable string | | Methods defined here:Nejde o problém jen u interní funkce help(), ale i různých nápověd v IDE a generování dokumentace. Když už se s tou dokumentací píšeš, tak mi přijde docela škoda jí takhle „zahodit“. Pak taky vidím, že používáš vlastní Enum:
class DescriptionTypeEnum(object): FULL = 1 TIMEOFDAY = 2 SECONDS = 3 MINUTES = 4 HOURS = 5 DAYOFWEEK = 6 MONTH = 7 DAYOFMONTH = 8 YEAR = 9Což by pro budoucí úpravy bylo lepší zapsat spíš jako:
class DescriptionTypeEnum(object): _cnt = (x for x in range(100)) FULL = next(_cnt) TIMEOFDAY = next(_cnt) SECONDS = next(_cnt) MINUTES = next(_cnt) HOURS = next(_cnt) DAYOFWEEK = next(_cnt) MONTH = next(_cnt) DAYOFMONTH = next(_cnt) YEAR = next(_cnt)Není to sice nutnost, ale může ti to ušetřit nepříjemné bugy, protože se to stará o unikátnost hodnoty. Potom tohle
if type == DescriptionTypeEnum.FULL: description = self.get_full_description() elif type == DescriptionTypeEnum.TIMEOFDAY: description = self.get_time_of_day_description() elif type == DescriptionTypeEnum.HOURS: description = self.get_hours_description() elif type == DescriptionTypeEnum.MINUTES: description = self.get_minutes_description() elif type == DescriptionTypeEnum.SECONDS: description = self.get_seconds_description() elif type == DescriptionTypeEnum.DAYOFMONTH: description = self.get_day_of_month_description() elif type == DescriptionTypeEnum.MONTH: description = self.get_month_description() elif type == DescriptionTypeEnum.DAYOFWEEK: description = self.get_day_of_week_description() elif type == DescriptionTypeEnum.YEAR: description = self.get_year_description() else: description = self.get_seconds_description()By bylo asi elegantněji zapsáno jako:
choices = { DescriptionTypeEnum.FULL: self.get_full_description, DescriptionTypeEnum.TIMEOFDAY: self.get_time_of_day_description, DescriptionTypeEnum.HOURS: self.get_hours_description, DescriptionTypeEnum.MINUTES: self.get_minutes_description, DescriptionTypeEnum.SECONDS: self.get_seconds_description, DescriptionTypeEnum.DAYOFMONTH: self.get_day_of_month_description, DescriptionTypeEnum.MONTH: self.get_month_description, DescriptionTypeEnum.DAYOFWEEK: self.get_day_of_week_description, DescriptionTypeEnum.YEAR: self.get_year_description, } description = choices.get(type, self.get_seconds_description)()Nehledě tedy na to, že si tím názvem proměnné shadowuješ interní funkci type().
for i in range(0, len(hour_parts)):Range jede vždy od nuly. Sice to ničemu nevadí, ale ani to nic nepřidává.
if len(description) > 0:Obecně všechny tyhle kontroly se dají přepsat na elegantnější
if description:Tohle
return self.get_segment_description(self.m_expression_parts[0], _("every second"), lambda s: s.zfill(2), lambda s: _( "every {0} seconds").format(s), lambda s: _( "seconds {0} through {1} past the minute"), lambda s: _("at {0} seconds past the minute"))by asi vypadalo podstatně líp, kdybys to rozepsal takhle:
return self.get_segment_description( self.m_expression_parts[0], _("every second"), lambda s: s.zfill(2), lambda s: _("every {0} seconds").format(s), lambda s: _("seconds {0} through {1} past the minute"), lambda s: _("at {0} seconds past the minute") )Já vím, je to čistě otázka vkusu, ale fakt mi to přijde podstatně čitelnější a nemusíš pak zbytečně zalamovat ty výrazy, protože se ti nevešly na konec řádku. Asi by se toho našlo víc, tohle mě napadlo jen tak v rychlosti.
for i in range(0, len(hour_parts)): ... hour_parts[i] ...je lepší (pythoničtější) psát:
for i, hour_part in enumerate(hour_parts): ... hour_part ...
Jo a misto psani sem jsi mohl rovnou udelat fork a poslat PRNerad dělám stylistické pull requesty, protože nemusí být začleněny, protože se ti něco nemusí líbit. Pak je to kopa práce k ničemu. Tohle byly spíš rady, než že by šlo o něco podstatného.
Já se v takových případech zeptám Googlu, jsou stránky kde není problém naklikat si chování a vyplivne to zápis pro CRON. Nevím ale jistě jestli to jde i obráceně, tedy vložit a nechat si vypsat co se bude dít
Zrovna konfigurator CRONu se da napsat tak aby uzivatel nic nerozbyl... protoze se tam dostane jen to co tam sam v te aplikaci pustis...To ovšem pak není konfigurátor cronu, ale custom plánovač na vybrané akce. Jestli na spouštění úloh používá vlastní proces nebo cron je jen implementační detail. Webhosting tady asi řešit nebudeme. :)