Posts tagged ‘data formats’

Yummy YAML

2012-10-15 19:48

It won’t be a stretch to bet that you’ve heard of XML. The infamous markup format was intended to be easily parseable by machines, in addition to being readable by humans. Needless to say, it failed to deliver on either of these promises. Markup elements tend to obscure the actual data, while parsing it – with all its namespaces, !DOCTYPEs and ![CDATA[s – is convoluted and not exactly efficient.

Other formats have thus risen to popularity, out of which JSON is probably widest known and used. It also has excellent support on many platforms.

For the purpose of transporting data between Internet endpoints, or for various APIs offered by websites and services, it works pretty great. There are other applications, though, where it might be the obvious first choice – but not necessarily the best one.

What JSON does well is ease to read and parse: the syntax can be outlined and defined in few paragraphs. However, at the same it’s not that convenient to write.

Unlike actual JavaScript, it needs quotes around keynames, even if they would pass as identifiers. (And by quotes I mean double-quotes, also where apostrophes would be better). Furthermore, it requires keeping track of separators between key-value pairs or array elements, not allowing to have a handy trailing comma at the end.

And lastly, there is no good support for longer texts due to lack of multi-line string literals.

Enter YAML

There is another, lesser known format which addresses these concerns very well. It’s called YAML, recursively from YAML Ain’t Markup Language. Here’s a short sample:

  1. name: John Smith
  2. birth date:
  3.   day: 10
  4.   month: 11
  5.   year: 1982
  6. phone:
  7. - type: mobile
  8.   number: 1123581321
  9. - type: work
  10.   number: 0918237465
  11. friends:
  12. - Robert Jones
  13. - Jane Taylor

At first sight it probably appears as pythonic (or haskellish) counterpart to the C-like JSON. Indentation does indeed matter, at least in the most popular and powerful variant of YAML syntax.

However, giving this bit of significance to whitespace allows to substantially reduce syntactic clutter. There are no curly or square brackets, and no commas. For the most part, there’s not much use for quotes either: strings are easily recognized as both keys and values, even if they contain spaces. Arrays are also supported in a straightforward way: by listing their elements with a leading dash (-), including cases where they are key-value objects themselves.

There’s even support for long strings that span multiple lines:

  1. almost_limerick: |  
  2.     There once was a man from the sticks
  3.     Who liked to compose limericks.
  4.         But he failed at the sport,
  5.         For he wrote 'em too short.

Here, pipe character (|) instructs parsers to preserve newlines and most of the whitespace, excluding the leading indent. Were it replaced with greater-than sign (>), an HTML-like fold would be performed, converting chains of whitespace into a single space.

Parsing the thing

Simple YAML documents represent a tree of keys and values which is much the same as the one produced from JSON files. For some programming languages, this similarity extends to the parsing libraries, as they offer more or less the same interface:

  1. def parse_file(path, parser):
  2.     with open(path, 'r') as f:
  3.         return parser.load(f)
  4.  
  5. import json, yaml
  6. print parse_file('data.json', parser=json)
  7. print parse_file('data.yaml', parser=yaml)

Even if it’s not the case for your language, it’s quite likely there is a YAML parser readily available.

More features

Funny thing about YAML is that its glaringly simple syntax hides very powerful and flexible format.

For example, the values are actually typed. They can be strings or nulls, but also integers, floats or booleans. Syntactic rules make a very good job here at automatically detecting the types; for instance, the word Yes will be recognized as boolean truth if standing on its own, but a text starting with it will be correctly recognized as string.

The other nifty feature is referencing. Parts of YAML document tree can be given labels, while other parts can later use those labels to point back to specific nodes. The whole structure can therefore morph into something more general than just a tree:

  1. triangle_graph: &first_vertex
  2. - label: First vertex
  3.   adjacent_to:
  4.   - label: Second vertex
  5.     adjacent_to:
  6.     - label: Third vertex
  7.       adjacent_to:
  8.      - *first_vertex

With types (incl. custom ones) and references, YAML can actually serve pretty well as serialization format for persisting objects.

Uses?…

But besides that, what YAML is actually good for?

I have hinted in the beginning that it seems like a decent choice for structured text data which is meant to be hand-edited. Various configuration files fall into this category, as well as some datasets around the size of contact list. I used YAML as config format for my IRC bot and it worked very well for this purpose. I’m also using it to store initialization data for database used by another side project of mine.

So, if you are not exercising YAML in any of your current endeavors, I’m encouraging you to give it a try. It might not be the best thing since sliced bread, but it’s very pleasant format to work with.

Tags: , ,
Author: Xion, posted under Applications, Programming » 2 comments

Proste formaty tekstowe

2011-09-02 23:02

Wprawdzie dobry kod znaczy więcej niż tysiąc słów, ale czasami kawałek dokumentacji jest po prostu nieodzowny. Osobiście uważam, że w tym względzie liczy się prostota i zaprzęganie do pracy takich formatów jak .doc czy nawet .pdf jest niemal zawsze grubą przesadą. Jest o wiele łatwiej, jeśli dokument daje się edytować zwyczajnym edytorem tekstowym.

Ale nawet wśród czysto tekstowych formatów występuje całkiem spora różnorodność. Mamy chociażby kilka opartych na XML-u – takich jak DocBook – że nie wspominając o nieśmiertelnym \tau\epsilon\chi-u. Te i im podobne są językami znacznikowymi (markup languages) i poza sporymi możliwościami mają jedną wadę: są rozwlekłe. Stosunek “sygnału do szumu” nie jest w nich specjalnie wysoki, przez co w swojej surowej formie są one trudniejsze w czytaniu – a więc i w edycji.

Tej w wady są w dużym stopniu pozbawione formaty w stylu wiki, przypominające trochę różne spontaniczne pomysły na formatowanie czystego tekstu spacjami, myślnikami i gwiazdkami. Czasami nie mają one często zaawansowanych możliwości pozwalających na przykład na wstawianie tabel, ale w zakresie oferowanej funkcjonalności są zaskakująco często wystarczające. Z pewnością wystarczają chociażby do postów na forach czy ticketów w systemach do śledzenia błędów.

Jest tylko pewien szkopuł: jest ich mnóstwo. Poza kilkoma wariantami składni wiki, mamy też takie wynalazki jak Markdown albo reStructuredText. W sumie jednak stanowią one tylko część tych co bardziej znanych. Sytuacja przypomina tu trochę pewien szczególny komiks z xkcd. Skutkiem tego jest często konieczność sprawdzania, jakiej to składni używa akurat ta konkretna strona, na której piszemy post lub komentarz, jeśli tylko nie robimy tego regularnie.

Na szczęście przyswojenie sobie nowej składni tego rodzaju nie jest przeraźliwie wyczerpującym wysiłkiem umysłowym ;-) Niekiedy sprawę upraszcza też fakt wspierania przez dany serwis więcej niż jednego standardu – tak robi na przykład GitHub. I dlatego nawet istnienie kilkunastu podobnych formatów nie wydaje się być jakimś szczególnie wielkim problemem.
Porównajmy to chociażby z hipotetyczną sytuacją, gdy w użyciu jest kilka formatów podobnie rozbudowanych i skomplikowanych co XML… Brr :)

Tags: , ,
Author: Xion, posted under Applications, Programming » Comments Off on Proste formaty tekstowe

O kompatybilności wprzód i jej dziwactwach

2011-06-11 15:36

Oto proste zadanie. Proszę sobie przypomnieć dowolną funkcję z dowolnej platformy/biblioteki/frameworka/itp. posiadającą przynajmniej jeden parametr, który nigdy nie został przez nas użyty w żadnym jej wywołaniu. Idealnie by było, gdyby ów argument występował na innej pozycji niż ostatnia – tak, żeby jego pominięcie wymagało podania zera, NULL-a, nulla, nila, Nila, None-a, pustego napisu/tablicy/listy lub dowolnej innej, “neutralnej” wartości.
Jeżeli udało nam się uporać z tą łamigłówką, to mam kolejną w postaci prostego pytania: dlaczego takie funkcje w ogóle istnieją? Zadając to pytanie na głos, często doczekamy się odpowiedzi, które niewiele mają wspólnego z prawdą. Bo istnieją rzadkie sytuacje, gdy ów felerny parametr jednak się przydaje. Bo nie ma innego dobrego miejsca, gdzie można by go umieścić. Bo język programowania jest kiepski i tak już musi być. Bo w sumie co to za kłopot z tym jednym nullem więcej. Bo.. bo… – i tak dalej.

W rzeczywistości prawidłową odpowiedzią jest zazwyczaj brzydkie słowo na ‘k’, czyli kompatybilność :) Pół biedy, jeśli chodzi tutaj o kompatybilność wsteczną – ona jest codziennością co bardziej złożonych aplikacji i systemów oraz wszelkich bibliotek, które mają swoją własną historię. Nie da się jej uniknąć i zwykle nawet nie warto próbować, chociaż oczywiście okresowe jej porzucanie jest w gruncie rzeczy wskazane.
Jest jednak jeszcze kompatybilność wprzód. Dziwna to idea, mająca na celu przewidywanie przyszłych wymagań wobec systemu i ułatwiająca lub wręcz umożliwiająca sprostanie im. Należy więc ona do dziedzin z pogranicza prorokowania i prognoz pogody, zatem z miejsca wydaje się cokolwiek podejrzana. Co więcej, potrafi się ona wkraść do projektu tak podstępnie i niezauważenie, że nie musi być nawet świadomie stosowana, by zostawić w nim swoje ślady. Ślady zupełnie niepożądane, o czym jednak przekonujemy się zwykle dopiero dużo później.

Mniej więcej coś takiego zdarzyło mi się ostatnio podczas tworzenia wersji androidowej swojej gry sprzed paru lat, czyli Taphoo. Sprawa dotyczy formatu niewielkich (<1 kB) plików, w którym obie wersje przechowują poszczególne etapy gry. Nie należy on w żadnym razie do przesadnie skomplikowanych, gdyż jest prostym formatem binarnym, składającym się z trzech części:

  • stałego nagłówka o rozmiarze dwóch bajtów, równego zawsze 54 4C (w ASCII są to znaki TL, będące skrótem od Taphoo Level)
  • wymiarów etapu: szerokości i wysokości, zapisanych na dwóch bajtach każda
  • właściwej planszy, której każda komórka zajmuje dokładnie jeden bajt


Format etapów w Taphoo

Oryginalnie format ten służył jedynie windowsowej wersji gry, ale nie widziałem żadnych powodów, dla których nie mógłbym użyć go także w powstającym porcie na platformę Android. Z pewnością znaczącym czynnikiem było to, że razem z pierwotną wersją gry napisałem też do niej – nie chwaląc się – bardzo dobry edytor :) Rozsądne było więc, aby przepisać kod wczytujący poziomy na Javę i włączyć go do gry w wersji androidowej.
Intuicja każe przypuszczać, że wtedy właśnie pojawiły się kłopoty. Faktycznie tak było. W związku mam jeszcze jedną, ostatnią dzisiaj zagadkę, która powinna być stosunkowo łatwa do rozwiązania na podstawie informacji podanych wcześniej. Co mianowicie jest przykładem niepotrzebnej kompatybilności wprzód w opisanym wyżej formacie i jakie problemy może to stwarzać podczas portowania?…

JSON, czyli co dobrego dał światu JavaScript

2010-11-24 22:04

O języku JavaScript mogę powiedzieć mnóstwo złych rzeczy. Począwszy od tego, że powszechność stosowania anonimowych funkcji jako callbacków powoduje, że stężenie zagnieżdżonych nawiasów w kodzie osiąga często poziomy lispowe. Skończyć zaś mogę na koszmarnym wsparciu dla “normalnej” obiektowości, znającej chociażby pojęcie klasy i obiektu, który nie jest po prostu przypadkową kolekcją jakichś tam atrybutów.

Lecz co ciekawe, to właśnie takie traktowanie obiektów leży u źródła bardzo pożytecznego wynalazku wywodzącego się z okolic JavaScriptu – czyli formatu JSON (JavaScript Object Notation). Ponieważ w JS wszystko jest swego rodzaju hierarchicznym słownikiem, obiekt możemy zdefiniować podając po prostu listę nazw i definicji (wartości) jego składników:

  1. var foo = {
  2.     "first": "value",
  3.     "second": "another value",
  4.     "compound": { "hello": "world" },
  5.     "integer": 42
  6. }

A ponieważ JavaScript jest językiem interpretowanym, możliwe jest wykonanie kodu podanego jako tekst (funkcją eval). Stąd możliwość użycia składni samego kodu JS – a dokładniej jej podzbioru zaprezentowanego wyżej – jako formatu serializacji obiektów, a więc w praktyce do przechowywania dowolnych danych. I tym właśnie jest JSON.

Wśród zalet tego formatu, obok natywnej obsługi przez jeden z popularnych języków programowania, na pewno da się łatwo zauważyć prostotę połączoną ze sporymi możliwościami. JSON to co najmniej “hierarchiczna wersja INI” z kilkoma dodatkami, takimi jak obsługa tablic czy kluczy będących dowolnymi ciągami znaków. Format nie jest zaś ani tak rozwlekły jak XML, ani tak ścisły w swej składni jak YAML. Jest więc łatwy do czytania i pisania dla człowieka oraz nie daje dużego narzutu przy przesyłaniu przez sieć. Stąd zresztą bierze się jego popularność do takich zastosowań jak zdalne wywoływanie funkcji (RPC) jako alternatywa dla przyciężkiego, XML-owego standardu SOAP. Korzysta z niego chociażby jeden z wariantów API Facebooka.

Jak wygląda obsługa JSON-a w językach programowania poza JavaScriptem? Otóż całkiem dobrze, co też opisuję dokładniej poniżej. I tak:

  • Zwykła Java oferuje pakiet org.json, w którym potrzebne klasy (jak JSONObject i JSONArray) są dostępne do użycia.
  • W Pythonie mamy pakiet o nazwie simplejson (niektóre starsze wersje 2.x) lub po prostu json. Użycie JSON-a jest w tym języku bardzo proste ze względu na podobny do JavaScriptu model obiektowości.
  • Platforma .NET nie ma (o ile mi wiadomo) wbudowanych narzędzi do obsługi formatu JSON, ale istnieją oczywiście do tego zewnętrzne biblioteki takie jak JSONSharp czy CsJson.
    Update: Okazuje się, że serializator do formatu JSON jednak istnieje (od wersji 3.5) i stanowi go klasa JavaScriptSerializer.

Pełniejsza lista jest dostępna na oficjalnej stronie JSON-a i obejmuje chyba każdy choć trochę szerzej używany język. Niezależnie więc od tego, do czego zechcemy tego formatu użyć i na jakiej platformie pracujemy, powinniśmy być w stanie całkiem łatwo to zrobić.

Tags: , ,
Author: Xion, posted under Programming » 9 comments
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.