Aquest és el segon llibre de la serie del "Libro de los caidos". Segueix la trama del llibre anterior, "Los jardines de la luna".
L'acció es situa en el continent de "Seven Cities" on hi ha 7 ciutats-estat que els Malazans ja han conquistat. Però donada la cultura del continent i la profecia de "Dryjhna la Apocaliptica" les ciutats es rebel·len fins que només queden dues fidels als malazans, Hissar i Aren. Coltaine, cap del 7e exercit ha d'escortar a 50.000 civils, fugint de Hissar travessant 1.500 milles de desert fins Aren. Aquesta gesta es coneix com la "Chain of Dogs", on Coltaine mor al final a les portes d'Aren.
Al llibre també passen moltes altres coses, el Kalam Meklar vol trobar la casa d'Azath del continent per viatjar fins a Unta i liquidar l'emperadriu, juntament amb al Fiddler (ex-Bridgeburner). I més coses...
A vegades perdia una mica qui estava fent que i on, ja que hi ha moltes accions paral·leles, però el llibre està molt bé! I m'hen quedaven 8 més!
Ja fa molts anys que vaig muntar un HTPC, quan encara teníem una televisió de tub Sanyo, aleshores tenia un Logitech diNovo Mini (un teclat petit amb un touchpad) per controlar-los. Els HTPCs han anat canviant però el diNovo aguantava, fins fa poc que ja comença a acusar l'edat, a nivell de tecles, de botons i de bateria.
També al llarg de tots aquests anys amb HTPC he pogut veure què faig servir i que no, realment teclejar textos no ho faig gairebé mai. Fa uns mesos vam comprar un teclat inalàmbric Rapoo per la meva dóna però a mi no m'agrada gaire el touchpad que porta, així que vaig seguir fent servir el diNovo, pensant que fer per substituir-lo. Finalment veient que si necessito un teclat ja en tinc he decidit comprar algo que faci de ratolí, i el més precís, més que un tochpad, és un trackball.
Per això he arribat al Logitech Wireless trackball M570. El cert és que és força car (suposo que en venen pocs) però penso que ha valgut la pena (si dura temps). És molt anatòmic i s'adapta molt bé a la meva mà, té rodeta (OMG! rodeta!) i boto dret i esquerra diferenciats (que amb el diNovo estan junts, has d'apretar una tecla FN per canviar el significat de botó dret, cosa que et fa ser contorsionista de mans i en els touchpads el boto dret no existeix). El cert és que he guanyat un munt! Ara és més còmode fer servir el HTPC.
Aquest és el primer llibre de la serie de "Malazan Book of the Fallen", aquesta serie de llibres està composta per 10 llibres! És enorme, tan en llibres com en pàgines . He trigat uns anys en llegir-los. Una cosa que crida l'atenció al llarg dels llibres és la forma en que estan escrits. Primer, hi ha un nombre molt gran de personatges i per tan uns mateixos fets es veuen des de perspectives diverses, potser hi ha unes desenes de pàgines dedicades a un personatge, hop! canvia i ja està. Segon, aquesta profusió de personatges fa que l'autor canvii d'uns a altres molt sovint i ràpid, sense preliminars, a vegades t'adones que has canviat de personatge quan portes ja unes frases llegides. Tercera, a vegades els personatges més poderosos no són els protagonistes, normalment són soldats rasos, personatges secundaris els que expliquen el que passa.
Hi ha tres línies argumentals, cada una pot avarcar varis llibres, confluint les 3 en el llibre desè. Aquest primer llibre està situat al continent de Genabackis on els exèrcits de l'imperi Malazà (humans) està assetjant les ciutats-estat de Pale i Darujhistan. Aconsegueixen conquistar Pale i forçar la retirada de l'Anomander Rake i la seva fortalesa flotant Moon's Spawn. Les unitats d'elit que ho aconsegueixen són els "Bridgeburners" comandades per el High Fist Dujek one Arm, i el sergent Whiskeyjack. Dins del propi imperi hi ha l'assassinat de l'emperador Kellavend i la neteja de les unitats que li eren fidels, entre elles els "Bridgeburners" i per això el setge de Darujhistan fracassa. L'adjunta Lorn allibera un tirà jaghut de fa milers d'anys per tal de forçar la retirada d'Anomander. Al llibre van apareixent els personatges que formaran part de l'historia dels següents. El fet és que al ser el primer llibre obre moltes línies argumentals i té molts personatges, és complicat de llegir però em va agradar molt.
Ahir va anar d'excursió al Rasos de Peguera. Anàvem full-equip amb botes de muntanya i abrigats per resistir al pol nord, però ha fet molt bon temps i al final jo anava només amb la camisa. Hem portat un trineu de plàstic per llançar-nos pel pendent. Els nens s'ho han passat molt bé, jo no m'he llançat per que ja tinc prou amb la meva esquena tal com està, no cal que l'empitjori. Hem trobat que la neu estava estupenda, ni molt desfeta ni gelada.
Quan ha sigut l'hora de dinar hem baixat a una zona de pícnic que hi ha més abaix on em menjat les truites de patata que portàvem en tupers. Després de dinar hem pujat al Santuari de Queralt per gaudir de les vistes. També hem coincidit amb uns nois que portaven unes motxilles molt grosses, però no anaven d'excursió, eren parapents! Allí al costat hi ha un lloc que serveix per llançar-se amb parapent i amb les corrents d'aire ascendents estan volant molta estona.
A vegades fent un webservice m'he trobat amb la necessitat d'enviar objectes, o en interfaces JSON fer objectes per enviar-los. En ambdós casos és necessari convertir un DataRow a un objecte. O un DataTable a una llista d'objectes.
Com sempre he afegit a la clsDades les funcions pertinents. El primer que cal entendre és la reflection que és obtenir informació d'objectes (propietats, tipus de dades, longituds) en temps d'execució i actuar en conseqüència.
La primera funció que converteix una taula a una llista d'objectes és molt restrictiva, ja que els noms de les columnes dels registres han de coincidir amb el nom de les propietats del objecte. També el tipus ha de coincidir, encara que el més recomanable és que ambdós siguin cadenes de text (strings).
publicList<T> ToList<T>(DataTable tbl) where T : new()
{
List<T> theList = newList<T>();
T item;
List<PropertyInfo> properties = typeof(T).GetProperties().ToList();
foreach (DataRow DR in tbl.Rows)
{
item = CrearItem<T>(DR, properties);
theList.Add(item);
}
return theList;
}
/// <summary>/// Crea un objecte a partir d'un DataRow. /// L'objecte destí ha de tenir els mateixos noms a las propietats i tipus que els camps a la BBDD./// </summary>/// <typeparam name="T">El tipus de l'objecte a crear</typeparam>/// <param name="row">El DataRow</param>/// <param name="properties">Les propietats de l'objecte</param>/// <returns>L'objecte</returns>public T CrearItem<T>(DataRow row, List<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (PropertyInfo property in properties)
{
property.SetValue(item, row[property.Name], null);
}
return item;
}
Aquesta funció és molt limitada, llavors he fet una altra que inclou els Mappings. Es a dir que les columnes de la taula poden tenir un nom diferent del de les propietats de l'objecte que es crea. Aprofitant la informació que es dels camps es pot fer una conversió de tipus, sempre i quan siguin tipus compatibles el de la columna i el de la propietat de l'objecte. El codi canvia força:
/// <summary>/// Converteix una taula a una llista d'objectes/// </summary>/// <typeparam name="T">El tipus de l'objecte a crear</typeparam>/// <param name="tbl">La taula a convertir</param>/// <param name="Mappings">Mapeig entre nom de propietat i camp del registre</param>/// <returns>La llista d'objectes</returns>publicList<T> ToList<T>(DataTable tbl, Dictionary<string, string> Mappings) where T : new()
{
List<T> theList = newList<T>();
T item;
List<PropertyInfo> properties = typeof(T).GetProperties().ToList();
foreach (DataRow DR in tbl.Rows)
{
item = CrearItem<T>(DR, properties, Mappings, true);
theList.Add(item);
}
return theList;
}
/// <summary>/// Crea un objecte a partir d'un DataRow./// L'objecte destí ha de tenir els mateixos tipus que els camps a la BBDD donat el mapping o bé strings./// </summary>/// <typeparam name="T">El tipus de l'objecte a crear</typeparam>/// <param name="DR">El DataRow</param>/// <param name="properties">Les propietats de l'objecte</param>/// <param name="Mappings">Mapeig entre nom de propietat i camp del registre</param>/// <param name="UseCampInfo">Parametre per distingir la sobrecàrrega</param>/// <returns></returns>public T CrearItem<T>(DataRow DR, List<PropertyInfo> properties,
Dictionary<string, string> Mappings, bool UseCampInfo) where T : new()
{
T item = new T();
DateTime ValorData;
Decimal ValorDecimal;
clsCamp Camp;
foreach (PropertyInfo property in properties)
{
if (Mappings.ContainsKey(property.Name))
{
Camp = BuscaCamp(Mappings[property.Name]);
if (Camp == null)
{
thrownewException("Camp " + Mappings[property.Name] + " no trobat");
}
else
{
if (!DR.IsNull(Camp.NomCamp))
{
switch (Camp.Tipus)
{
case Tipus.date:
if (property.PropertyType == Type.GetType("System.String"))
{
ValorData = (DateTime)DR[Camp.NomCamp];
if (string.IsNullOrEmpty(Camp.Format)) property.SetValue(item,
ValorData.ToShortDateString(), null);
else property.SetValue(item, ValorData.ToString(Camp.Format), null);
}
else
{
property.SetValue(item, DR[Camp.NomCamp], null);
}
break;
case Tipus.datetime:
if (property.PropertyType == Type.GetType("System.String"))
{
ValorData = (DateTime)DR[Camp.NomCamp];
if (string.IsNullOrEmpty(Camp.Format)) property.SetValue(item,
ValorData.ToString("dd/MM/yyyy HH:mm"), null);
else property.SetValue(item, ValorData.ToString(Camp.Format), null);
}
else
{
property.SetValue(item, DR[Camp.NomCamp], null);
}
break;
case Tipus.time:
if (property.PropertyType == Type.GetType("System.String"))
{
ValorData = (DateTime)DR[Camp.NomCamp];
if (string.IsNullOrEmpty(Camp.Format)) property.SetValue(item,
ValorData.ToString("HH:mm"), null);
else property.SetValue(item, ValorData.ToString(Camp.Format), null);
}
else
{
property.SetValue(item, DR[Camp.NomCamp], null);
}
break;
case Tipus.dec:
if (property.PropertyType == Type.GetType("System.String"))
{
ValorDecimal = (Decimal)DR[Camp.NomCamp];
if (string.IsNullOrEmpty(Camp.Format)) property.SetValue(item,
ValorDecimal.ToString(), null);
else property.SetValue(item, ValorDecimal.ToString(Camp.Format), null);
}
else
{
property.SetValue(item, DR[Camp.NomCamp], null);
}
break;
default:
if (property.PropertyType == Type.GetType("System.String"))
property.SetValue(item, DR[Camp.NomCamp].ToString(), null);
else property.SetValue(item, DR[Camp.NomCamp], null);
break;
}
}
}
}
}
return item;
}
private clsCamp BuscaCamp(string pCamp)
{
for (int i = 0; i < CampsResultat.Length; i++)
{
if (CampsResultat[i].NomCamp == pCamp)
{
return CampsResultat[i];
}
}
returnnull;
}
#06/03/2014 11:46 Programació C# Autor: Alex Canalda
Al 2013 s'han venut 195 milions de tablets a tot el món segons Gartner. Al 2012 iOS era majoritari, al 2013 ha perdut aquesta posició i ara és Android el sistema operatiu dominant. El curiós és que Apple ha venut més iPads en 2013 que en 2012 però el que ha passat és que Android ha tingut un creixement brutal.
Unitats 2013
% 2013
Unitats 2012
% 2012
Android
121 milions
61,9%
53,3 milions
45,8%
iOS
70,4 milions
36,0%
61,5 milions
52,8%
Windows
4,0 milions
2,1%
1,2 milions
1%
Si es mira en detall el mercat separat per fabricants, es veu clarament que Samsung a quadruplicat el nombre de tauletes venudes i que Apple segueix sent el fabricant individual que ven més tauletes. I tots en conjunt han augmentat la producció. També és espectacular el nombre de tauletes clóniques amb Android que hi ha.
Unitats 2013
% 2013
Unitats 2012
% 2012
Apple
70,4 milions
36,0%
61,5 milions
52,8%
Samsung
37,4 milions
19,1%
8,6 milions
7,4%
Asus
11 milions
5,6%
6,3 milions
5,4%
Amazon
9,4 milions
4,8%
7,7 milions
6,6%
Lenovo
6,5 milions
3,3%
2,2 milions
1,9%
Altres
60,6 milions
31%
30,1 milions
25,8%
#04/03/2014 12:10 Hardware Android Autor: Alex Canalda
Un sitemap és un llistat de URLs que té un format definit per la Sitemap.org i que s'envia als motors de cerca per tal que les indexin. El seu format és el següent:
He fet un petit programa en C# que genera aquest XML, he vist exemples on es fan servir objectes XMLDocument i es van afegint nodes fills etc... Donat que no és gaire complicat jo ho fet en cadenes de text directament. Apart d'això només s'ha de posar el Content-Type que toca: text/xml El codi a continuació
Hi ha moltes maneres de fer això, la normal és fer servir una collation (ordre alfabètic) diferent al de la BBDD i l'altra fent servir "[" i "]" (expressions regulars).
La collation fa que les consultes quedin algo com:
SELECT *
FROM Begudes
WHERE
Name COLLATE Latin1_general_CI_AI Like'%cafe%'COLLATE Latin1_general_CI_AI
Això trobarà "cafè", "café"... Però a mi no m'agrada gaire. Prefereixo un altra mètode.
Es tracta de substituir totes les vocals de la cerca per [aàáAÀÁ], [eèéEÈÉ]... quedaria:
SELECT *
FROM Begudes
WHERE
Name Like'%c[aàáAÀÁ]f[eèéEÈÉ]%'
No he trobat dades de rendiment ni recomanacions, tampoc en els llocs on ho he necessitat he vist que funcionés malament. El que sí he necessitat és una funció que em substitueixi les vocals per l'expressió regular. L'he afegit a la clsDades.
/// <summary>/// Donat un string que formarà part d'un LIKE el torna ACCENT INSENSITIVE/// </summary>/// <param name="Valor">L'string a convertir</param>/// <returns>L'string convertit</returns>privatestring FerAccentInsesitive(string Valor)
{
string Result = Valor;
string a = "[aàáAÀÁ]";
string e = "[eèéEÈÉ]";
string i = "[iìíIÌÍïÏ]";
string o = "[oòóOÒÓ]";
string u = "[uùúUÙÚüÜ]";
Result = Result.Replace("a", "_a_");
Result = Result.Replace("e", "_e_");
Result = Result.Replace("i", "_i_");
Result = Result.Replace("o", "_o_");
Result = Result.Replace("u", "_u_");
Result = Result.Replace("à", "_à_");
Result = Result.Replace("è", "_è_");
Result = Result.Replace("ì", "_ì_");
Result = Result.Replace("ò", "_ò_");
Result = Result.Replace("ù", "_ù_");
Result = Result.Replace("á", "_á_");
Result = Result.Replace("é", "_é_");
Result = Result.Replace("í", "_í_");
Result = Result.Replace("ó", "_ó_");
Result = Result.Replace("ú", "_ú_");
Result = Result.Replace("A", "_A_");
Result = Result.Replace("E", "_E_");
Result = Result.Replace("I", "_I_");
Result = Result.Replace("O", "_O_");
Result = Result.Replace("U", "_U_");
Result = Result.Replace("À", "_À_");
Result = Result.Replace("È", "_È_");
Result = Result.Replace("Ì", "_Ì_");
Result = Result.Replace("Ò", "_Ò_");
Result = Result.Replace("Ù", "_Ù_");
Result = Result.Replace("Á", "_Á_");
Result = Result.Replace("É", "_É_");
Result = Result.Replace("Í", "_Í_");
Result = Result.Replace("Ó", "_Ó_");
Result = Result.Replace("Ú", "_Ú_");
//----------------------------------------
Result = Result.Replace("_a_", a);
Result = Result.Replace("_e_", e);
Result = Result.Replace("_i_", i);
Result = Result.Replace("_o_", o);
Result = Result.Replace("_u_", u);
Result = Result.Replace("_à_", a);
Result = Result.Replace("_è_", e);
Result = Result.Replace("_ì_", i);
Result = Result.Replace("_ò_", o);
Result = Result.Replace("_ù_", u);
Result = Result.Replace("_á_", a);
Result = Result.Replace("_é_", e);
Result = Result.Replace("_í_", i);
Result = Result.Replace("_ó_", o);
Result = Result.Replace("_ú_", u);
Result = Result.Replace("_A_", a);
Result = Result.Replace("_E_", e);
Result = Result.Replace("_I_", i);
Result = Result.Replace("_O_", o);
Result = Result.Replace("_U_", u);
Result = Result.Replace("_À_", a);
Result = Result.Replace("_È_", e);
Result = Result.Replace("_Ì_", i);
Result = Result.Replace("_Ò_", o);
Result = Result.Replace("_Ù_", u);
Result = Result.Replace("_Á_", a);
Result = Result.Replace("_É_", e);
Result = Result.Replace("_Í_", i);
Result = Result.Replace("_Ó_", o);
Result = Result.Replace("_Ú_", u);
return Result;
}
#03/03/2014 11:27 Programació C# SQLServer Autor: Alex Canalda
Aquesta peli, com totes, té coses bones i coses dolentes. Lo bo és l'ambientació, el futur té pinta de ser així. Contaminació a tope, mediambient a 0, persones tractades com a merda, rics molt rics i pobres molt pobres. M'ha recordat molt a District 9 (també recomanable), després mirant resulta que el director és el mateix.
[Spoilers] L'argument és el següent, un accident laboral fa que el protagonista es vagi a morir, i ha d'anar on estan els rics a curar-se. En el procés salva a tot el món però mor al final. Salvar a tothom vol dir que els rics molt rics envien a les ambulàncies a curar a tothom, que si es pensa una mica ja podrien haver-ho fet abans i estalviar-se problemes.
La part que menys encaixa en el guió és que el protagonista és un bo, molt bo (amb un passat una mica delinqüent), sembla una mica un Robin Hood. I la dolenta és molt, molt dolenta. I també hi ha un error on el protagonista té el dolent estabornit a terra i no el liquida.
Apart d'això la peli es deixa veure molt bé, un bon ritme i bons efectes. A mi m'agradat molt.