One of my favorite misconceptions to set straight for readers is that once I shoot in something I'm done wearing it… Completely wrong! I'm the type of person where I will wear something once and then style it differently and wear it as many various ways as possible. Then I sometimes alter, dye, or hem a garment just so I can continue getting more use out of it! So one of my new features on the blog I will begin to post regularly will be the wardrobe remix – taking one garment and styling it three different ways and throwing in a few styling suggestions here and there.
This feature I'm wearing the Yellow floral chiffon kimono from TORRID (Shop Here) .
Jean shorts with lace embellishment paired with a red bra for an extra hint of color and of course this floral beauty (All items from this look shopped from Torrid)! No accessories but a high ponytail and minimum makeup to complete this stay at home host look.
The second styled look we have is just the right amount of professional mixed with summer appeal – perfect for a picnic and day spent at the park with the family or luncheon out with the ladies. I love rompers but if I know I'm going to be in the sun for awhile I like to have a little something extra to cover up with to keep my sensitive skin from getting sunburned and this light weight kimono is perfect for just this reason!
Paired with the kimono I'm wearing a one piece romper and simple suede flats, high ponytail and Michael Kors sunglasses. Now I might add an oversized purse and understated necklace to this ensemble to step it up that extra notch. And when showing this much leg I'm always a fan of anklets.
Keeping with the simple low key theme for these looks I paired black leggings with the kimono, black pumps, swept my hair in to a messy bun and added bangles and black faux diamond studs to complete this look. Simple, summery, with a dash of elegance. (All items for this look shopped from Torrid.) Now for this look I would probably throw in a chic clutch and maybe add a little extra hair flower to my hair to bring that low key look up to a little something extra!
I hope you Loves enjoyed this wardrobe remix and stay tuned for future sets!


text:
Sept. 14, 2017 / 4:15 PM
Conor McGregor: UFC star obsessed with $480M yacht owned by Russian billionaire
Alex Butler
Conor McGregor posted several photos of Sailing Yacht A Tuesday on his instagram account. Photo courtesy of Conor McGregor/Instagram
Sept. 14 (UPI) -- MMA star Conor McGregor spotted a humungous yacht this week while lounging in the Mediterranean Sea.
McGregor has been enjoying his time off since losing his boxing super-bout against Floyd Mayweather on Aug. 26 in Las Vegas. He has spent most of the time with his family, including Conor McGregor Jr.
While most of his Instagram posts have been about his lavish lifestyle and baby boy, McGregor has recently been awed by a mega yacht owned by Russian billionaire Andrey MeInichenko.
"The 360 million dollar "sailing yacht A" pulls up out the back garden this morning . "Sailing yacht A" its called," McGregor posted on Instagram Tuesday, along with a photo of the massive vessel.
RELATED Conor McGregor shows off massive yacht, adorable baby on Instagram
"That's how you know the owner doesn't need to give a bollox about anything. Sailing yacht A. Most expensive sailing yacht in the world. 360mill. Owned by a Russian billionaire. Google it. Crazy!"
A Google search results in finding out that the yacht is one of the biggest - and priciest - boats in the world.
The 360 million dollar "sailing yacht A" pulls up out the back garden this morning . "Sailing yacht A" its called. That's how you know the owner doesn't need to give a bollox about anything. Sailing yacht A. Most expensive sailing yacht in the world. 360mill. Owned by a Russian billionaire. Google it. Crazy!
RELATED Mayweather vs. McGregor: Study breaks down earnings, social reach for fight
A post shared by Conor McGregor Official (@thenotoriousmma) on Sep 12, 2017 at 11:00am PDT
McGregor jumped on a jet ski for a closer look.
"Quick scope of it before I depart like a pirate," McGregor wrote on Instagram Tuesday, while looking through a scope.
RELATED Mayweather vs. McGregor: Celebrities flood fight, 'Notorious' gets respect
"To an even bigger yoke," he wrote on the next photo.
He then took some amazing photos, capturing the size of the vessel from multiple angles.
"Zoom in little super boat comes out the side camouflaged with the yacht like something out of a bond film. Can't believe this just pull up," McGregor wrote on Instagram.
That was a mad scene. I only posted "race to the next yacht" two days ago and then this one pulls up right out my back garden. The biggest one of all. This is an eye opening level of opulence to witness first hand. To me, it is truly motivating. I'm starting to think I don't have a wealth belly just yet. I'm more just rich fat now. I must keep eating. I wonder if my lunch is ready. Happy Tuesday
A post shared by Conor McGregor Official (@thenotoriousmma) on Sep 12, 2017 at 3:02pm PDT
McGregor later posted a photo of himself speeding away from the impressive yacht.
"That was a mad scene," he wrote. "I only posted "race to the next yacht" two days ago and then this one pulls up right out my back garden. The biggest one of all. This is an eye opening level of opulence to witness first hand. To me, it is truly motivating. I'm starting to think I don't have a wealth belly just yet. I'm more just rich fat now. I must keep eating. I wonder if my lunch is ready. Happy Tuesday."
Sailing Yacht A was built by Nobiskrug and designed by Philippe Starck, according to BoatInternational.com. It has a crew of 54 according to the website. The yacht measures out at 142 meters, or 468 feet.
McGregor, 29, was worth about $34 million before fighting Mayweather, according to Forbes. Celebrity Net Worth now estimates his net worth as $85 million.
A. Most
Women's World Cup: Team USA defeats Netherlands for second title

redpajama_set_name: RedPajamaCommonCrawl


text:
Command line scripts, ``scripts/``, and ``sandbox/``
====================================================

.. note::

   This document applies through khmer/oxli 2.0/3.0 (see
   :doc:`../roadmap`) - we will revisit when the Python API falls
   under semantic versioning for oxli 4.0.

khmer has two conflicting goals: first, we want to provide a reliable
piece of software to our users; and second, we want to be flexible and
enable exploration of new algorithms and programs.  To this end,
we've split our command line scripts across two directories,
``scripts/`` and ``sandbox/``.  The former is the staid, boring, reliable
code; the latter is a place for exploration.

As a result, we are committed to high test coverage, stringent code
review, and `Semantic Versioning <http://semver.org/>`__ for files in
``scripts/``, but explicitly *not* committed to this for files and
functionality implemented in ``sandbox/``.  So, putting a file into
``scripts/`` is a big deal, especially since it increases our maintenance
burden for the indefinite future.

We've roughed out the following process for moving scripts into ``scripts/``:

* Command line scripts start in ``sandbox/``;
* Once their utility is proven (in a paper, for example), we can propose to
  move them into ``scripts/``;
* There's a procedure for moving scripts from ``sandbox/`` into ``scripts/``.

Read on!

Sandbox script requirements and suggestions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

All scripts in ``sandbox/`` must:

* be importable (enforced by ``test_import_all`` in
  ``test_sandbox_scripts.py``)
* be mentioned in ``sandbox/README.rst``
* have a hash-bang line (``#! /usr/bin/env python``) at the top
* be command-line executable (``chmod a+x``)
* have a Copyright message (see below)
* have lowercase names
* use '-' as a word separator, rather than '_' or CamelCase

All *new* scripts being added to ``sandbox/`` should:

* have decent automated tests
* be used in a protocol (see khmer-protocols) or a recipe (see khmer-recipes)
* be pep8 clean and pylint clean-ish (see ``make pep8`` and ``make_diff_pylint``).

Command line standard options for scripts/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

All scripts in scripts/ should have the following options, if they could apply:

* ``--version`` - should always apply
* ``--help`` - should always apply
* ``--force`` - override any sanity checks that may prevent the script from running
* ``--loadtable`` and ``--savetable`` - where appropriate (see khmer_args.py)

Copyright message
~~~~~~~~~~~~~~~~~

Our current Copyright message is::

   #
   # This file is part of khmer, https://github.com/dib-lab/khmer/, and is
   # Copyright (C) Michigan State University, 2009-2015. It is licensed under
   # the three-clause BSD license; see doc/LICENSE.txt.
   # Contact: khmer-project@idyll.org
   #

The beginning year should be the first year that this file existed in
the repo; the end year should be the last year a coding change was
made in the file.

Upgrading a script from 'sandbox' to 'scripts'
----------------------------------------------

First, everything needed (all library support code) should be already
committed to khmer master after the usual review process; the relevant
script(s) should be in ``sandbox/``.

Second, an issue should be started explicitly to discuss whether the
script(s) should be moved from ``sandbox/`` into ``scripts/``.  This issue
should discuss the general need for this script, outside of a particular
paper pipeline.  (Note that there is no imperative to move a script
out of ``sandbox/``; if we think it's useful code to have around and
want to keep it functioning, we should just add in automated tests and
otherwise level it up.)

Third, assuming we reach general agreement about moving the script(s)
into ``scripts/``, start a pull request to do so, referencing the
issue and containing the following checklist.  The PR should start by
moving the script from ``sandbox/`` into ``scripts/``, and moving the
tests out of the ``test_sandbox_scripts.py`` file.

Last but not least, intensive code review may raise more general
issues that could apply to the entire code base; if contentious or
needing discussion, these issues may be punted to general issues so as
to not block a merge.

A checklist for moving a script into the scripts/ directory from sandbox/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Copy or paste this checklist into the PR, in addition to the normal
development/PR checklist::

   - [ ] most or all lines of code are covered by automated tests (see output of ``make diff-cover``)
   - [ ] ``make diff_pylint`` is clean
   - [ ] the script has been updated with a ``get_parser()`` and added to doc/user/scripts.txt
   - [ ] argparse help text exists, with an epilog docstring, with examples and options
   - [ ] standard command line options are implemented
   - [ ] version and citation information is output to STDERR (`khmer_args.info(...)`)
   - [ ] support '-' (STDIN) as an input file, if appropriate
   - [ ] support designation of an output file (including STDOUT), if appropriate
   - [ ] script reads and writes sequences in compressed format
   - [ ] runtime diagnostic information (progress, etc.) is output to STDERR
   - [ ] script has been removed from sandbox/README.rst

redpajama_set_name: RedPajamaGithub


Hikvision has achieved a U.S. Government Federal Information Processing Standard (FIPS) 140-2 certification, marking another important milestone in its cybersecurity program. Hikvision's encryption module (HIKSSL) received level 1 FIPS 140-2 certification to be used in both IP cameras and NVR products.
FIPS 140-2 is a U.S. government encryption standard created by the National Institute of Standards and Technology (NIST), which is a division of the U.S. Department of Commerce. Used by federal government agencies in the U.S. and Canada, FIPS 140-2 is also widely used in regulated industries such as finance, healthcare, legal and utilities, as well as commercial businesses.
One of the most recognized security standards worldwide, FIPS 140-2 is used and referenced by numerous standards bodies and international testing organizations including the ISO standard. Global tech companies such as Apple, Mi – Microsoft, Cisco, and Google have achieved FIPS 140-2 validation.
The FIPS 140-2 validation process is comprehensive and includes a series of rigorous tests by an independent and accredited U.S. security laboratory and NIST compliance confirmation.
Hikvision takes cybersecurity seriously and abides by all laws and regulations in the countries in which it operates. With a record of strict regulatory compliance, Hikvision products meet industry leading standards for safety and security that include ISO 270001, ISO 9001:2008, CMMI Level 5, and AICPA SOC, organizations.


text:
Paris1972-Versailles2003
Travel and my anecdotes
1) All rights reserved.
2) My hommage to my late dear Frenchie Martine, RIP
My introduction to USA!
My life in Madrid, Spain!
My life in my belle France!
3) Blog roll , my favorite sites other than my blog ::)
Havana, message to La Habana
Vannes, the gateway to the Gulf of Morbihan!!!
Bretagne, Morbihan, roads and waterways transports bits and pieces….!
The river Loc'h, Auray and Brec'h!
The Tour Solidor at Saint Malo!
City Hall of Redon!!!
So , short title, indeed. Do I need to tell you more? For me the name means France, there are a few more but none as high as Victor Hugo. From time of my early life I read his books first in Spanish, then in English, and finally in French all good. When we speak fo traditions and literary mind set, he probably means France more than anyone else. For me ,the men is huge.
I cannot find photos but so what, I need to tell you about my France, the deep France, the ones known by others on books and me on beliefs and the thank you to be here, and the many thank you's to my dear late wife Martine, who show me all about France. I remember.
For me a lousy writer to write about Victor Hugo is a monumental task, one I am not up to it, but will do my best to tell you a bit about the men and France or is it France and then the men, Victor Hugo.
Victor Hugo born at Besançon, February 2, 1802. He married Adéle Foucher in 1822, very early. He went into battle with his work of Hernani in 1830. Entered the Académie Française in 1841 ,entered the City council of Paris in 1845. In 1851 exile to Brussels, return from exile 1868, Senator in 1876, death in Paris and national funeral on May 22 1885 to be entered into the Panthéon. Indeed well deserve all of it.
Victor-Marie Hugo is the son of the Empire General Joseph Leopold Sigisbert Hugo , reaching Count status himself, according to the family tradition, by Joseph Bonaparte, King of Spain, and garrisoned in the Doubs at the time of the birth of his son, and Sophie Trebuchet, young woman from the bourgeoisie of Nantes.
On October 12, 1822, he married his childhood friend, Adéle Foucher, born in 1803, in the Church Saint-Sulpice in Paris, she gave birth to five children: Leopold ; Leopoldine ; Charles , François – Victor; and Adele, the only one who survives her illustrious father, but whose mental state, very soon failing, will earn her long years in a health home.
Beginning of February 1804 and the family elects domicile at 76 rue Neuve-des-Petites-Champs. It will remain for almost five years in this apartment of the 2éme arrondissement which unfortunately remains nothing and which today corresponds to no. 20 rue Danielle-Casanova. The couple lives with Adele's parents. They moved to 90, rue de Vaugirard; then the family moved the following year into a house at 11 rue Notre-Dame-des-Champs. In May 1830, the family moved again to the Rue Jean-Goujon; where Adele, had their last child. They will live on Rue Jean-Goujon until October 1832. In 1832, Victor Hugo settled in an apartment of the Hôtel de Rohan-Guémené, at no 6 Place Royale, which became Place des Vosges in 1848. For sixteen years, the author of Notre-Dame-de-Paris will write several of his major works here.
At the end of November 1878, Victor Hugo moved to 130, Avenue Eylau, in a mansion in the 16éme arrondissement that belonged to the Princess of Lusignan. It is here that on 27 February 1881, more than 600 000 people will parade under its windows to celebrate its entry into its 80th birthday! Later that year, Avenue Eylau will be renamed Avenue Victor-Hugo , the house is now at 124 Avenue Victor Hugo.
In 1837, Victor Hugo, the journalist Anténor Joly and the writer Alexandre Dumas, committed the creation of a theater that will leave its full place to the romantic dramaturgy, of which Victor Hugo is one of the most illustrious representatives: the Theatre de la Renaissance settled in the premises of the Salle Ventadour, a few steps from the Rue des Petites-Champs where, as a child, the young Victor Hugo had discovered Paris. The theater did not managed to cover its costs and ceases its activity in May 1841. The new Renaissance Theater will be inaugurated on March 8, 1873 at 20, Boulevard Saint-Martin, 10éme arrondissement of Paris.
He is considered one of the most important French-language writers, indeed. He is, also a political figure and a committed intellectual who played a major role in the history of the 19C. It occupies a prominent place in the history of French letters in the 19C, in genres and fields of a remarkable variety. In the theater, Victor Hugo manifests himself as one of the leaders of French romanticism when he exposes his theory of romantic drama in the prefaces that introduce Cromwell in 1827 then Hernani in 1830 which are real manifests, then by his other dramatic works: Ruy Blas in 1838, but also Lucréce Borgia and the Le Roi s'amuse (king has fun). Victor Hugo is also a lyric poet with collections such as Odes and Ballades (1826), Les Feuilles d'Automne (Autumn Leaves 1831) or Contemplations (1856), but he is also a poet committed against Napoleon III in Les Châtiments (Punishment 1853) or even an epic poet with the La Légende des siècles (legend of Centuries 1859 and 1877). His novels also met with great popular success, including Notre-Dame de Paris (1831), and even more with the Les Misérables (wretches of 1862). His multiple work also includes political speeches in the House of Peers, the Constituent Assembly and the legislature, including the death penalty, school or Europe, travel accounts like the Rhine, 1842, or things seen, posthumous, 1887 and 1890, an abundant correspondence, as well as numerous sketches and drawings in pen and wash.
Victor Hugo was a poet, drama writer, romance novel writer that also had a political career. The humanistic message on the speech of 9 july 1849 in the National Assembly of France (Assamblée Générale) and entered in conflict with Louis Napoléon Bonaparte future Napoleon III. To defend their rights of authors and prove that they live off their writing he found the societe of people of letters or sociéte des gens de letters in 1838 initial members included Honoré Balzac Alexandre Dumas, Théophile Gautier, George Sand, and Victor Hugo etc
In 1852 Louis Napoléon Bonaparte propose change in the constitution of the 2nd Republic and Victor Hugo oppose them, the National Assembly refuses the changes ,but his family goes in danger by the police more friendly to Louis Napoléon Bonaparte. His son Charles Hugo is arrested and put in the Conciérgerie, other son Francois-Victor joined him a few weeks later. The coup d'état comes on the night of Dec 2 1851 Victor Hugo tries to get the people of Paris to raise up in arms but the repression is huge, even his friend Alexandre Dumas suggested for him to go into exile and he does. Napoleon III is firmly in his coup d état and the police searched for Victor Hugo. The mistress of Victor Hugo in Sept 1852 was Juliette Drouet and she helped him hide and escape. There is another important mistress at the time name Léonie d'Aunet wife of painter Francois-Auguste Biard who with the knowledge of his formal wife Adéle for seven years, Juliette does not know this. Victor and Leonie are caught by the police she goes two months in jail but not him as adultery was not condemn then and until 1975!!!
In 1843 during a vacation trip to Spain coming back by La Rochelle , he takes the news that his oldest daughter Léopoldine and husband drown in a boat ride in the Seine river. From this date and for a long while until his exile he stop all ,no theater, no novels, not a poem,nothing, as the shock of his daughter death is huge.
Exile in Brussels in 1851 he lived at No 16 Grand Place in the Maison du Moulin à Vent then, No. 27 Grand Place in the Maison du pigeon , and he writes a small journal Napoleon le petit or little napoleon. Juliette Drouet, does not live far away from him, while here, she is in an apartment in the Galeries Saint Hubert where today there is a library call Librairie Tropismes . Victor Hugo patronized the places in the gallery and one today rename the Tavern du Passage where he meets with other writers exile in Brussels such as Rimbaud, Verlaine, etc all in Brussels to able to think freely.
Eventually, he goes to the island of Jersey to lived with Adéle and family. Here while they settle down at Saint Helier in the neighborhood of Marine Terrace, his mistress Juliette comes in at Havre des Pas. In the 1860's upon returning from Jersey , his wife Adéle and children lived at a house in the Place des Barricades in Brussels. In 1862, he is back in Brussels and settled in a house at the rue des Colonies.
Victor Hugo writes here the Les Contemplations, les Châtiments etc. Eventually he is force to leave the island and goes to Guernsey followed by Juliette. Victor Hugo acquired a house in Hauteville House and rent a house for Juliette a few meters away, his sons Charles and François Victor do visits and in 1863 Adéle dedicates a book to Juliette ;Victor Hugo raconte par un temoin de sa vie (Victor Hugo Tells by a Witness of his life).
In 1871 ,he finds refuge during 3 months and half at the Grand Duché Luxembourg. He stayed there successively in Luxembourg city , Vianden , Diekirch , and Mondorf, where he takes thermal bath cures
Adéle Hugo died 27 august 1868 and Juliette do not come together right away for fear of bad press but in sept 1870 when the second empire is ended and Vctor Hugo come back in triumph to France, Juliette is at his side. She died of cancer on May 11 1883 and from then on Victor Hugo stops writing altogether. He died in 1885 in his mansion or hôtel particulier « La Princesse de Lusignan », that was at no 50 Avenue Victor-Hugo, now it is no 124. The funeral goes under the Arc de Triomphe in May 31 1885 and exposed there, covered in black; a 21 gun salute is given from the Invalides , and on june 1, 1885 the funeral processesion goes by the Avenue des Champs Elysées, Place de la Concorde, then bd Saint Germain and bd Saint Michel to arrives at rue Soufflot and his body is transferred to the Panthéon where he lies today he was 83 yr s old, and it is estimated 2 million folks in person participated in the funeral!
He was the most popular writer of his time; It is already for several decades considered as one of the monuments of French literature.
There are several webpages that traces his life, I just put some official ones here
The Association of Friends of Victor Hugo: http://victor-hugo.org/fr/
The maison de Victor Hugo (house museum) is a monographic museum, located at 6 Place des Vosges, in the 4éme arrondissement, which preserves the former Hôtel de Rohan-Guémené where Victor Hugo rented the apartment on the second floor for sixteen years, from 1832 to 1848. More info here: http://www.maisonsvictorhugo.paris.fr/fr
In French , a bit on the house where he was born in Besançon: http://www.bm-besancon.fr/index.php?p=1328
Vacquerie in Seine et Marne dept 77 the resting place of his wife Adéle and oldest daughter Léopoldine near the spot where she drown with her husband in 1843 while on a Seine boat ride. Info here: http://www.museevictorhugo.fr/en/presentation-2/
And I have been too ,in Vianden Luxembourg where his rental house is a museum today , more info: http://www.victor-hugo.lu/cgi-bin/baseportal.pl?htx=/accueil
Info on the houses he lived in the British isles of Jersey and Guernsey: http://hautevillehouse.com/
Victor Hugo in Guernsey
There you go , good reading , I did my duty to write at least this post on this great men, and hope it helps you understand the French a bit more, and do come to check these places out, awesome. Salut
And remember, happy travels, good health ,and many cheers to all!!!
Posted in Europe, France, Paris, Versailles | 1 Comment »
Tags: Europe, France, Paris, Versailles
Some news from France CXCXVIIII
So back to my column self made of news from my belle France! The time here is 15h12 and cloudy, cool a bit breezy but no rain temps are in 15C or about 57F and in Paris is 59F cloudy. Just a wonderful Autumn day in my belle France and beautiful Morbihan.
Now for the latest that I pick up from various sources on the news of France according to yours truly are
The Argonaut submarine, in the Parc de la Villette , 19éme, rediscovers itself through a new exhibition that plunges us into the depths of the ocean. This great black submarine, installed since 1989 a few steps from the Géode, in the Parc de la Villette. How does a submarine work, what is oceanography, what species are found in the abyss, what are the political, economic, and climatic stakes of the seas?. Finally discover the gear used to observe the depths, beacons, robots that scrutinize the oceans and advance scientific research. Clou de l'Expo (Nail of the Expo) a simulator where we go to the gamepads, as a true commander of a submarine. You know that 80 to 90% of world trade traffic are done by the sea? The deepest known point of the Earth's crust, the Mariana Trench, in the Pacific, more than 11 000 meters deep. You know that sound propagation is much better in water 1 500 meters per second, than in air at 350 meters per second?. The Argonaut has carried out 24 years of good and loyal services to travel the seas of the globe. From 1958 to 1982, it accumulated more than 32 000 hours of diving and traveled a distance equivalent to ten times the circumference of the Earth. See it Sous l'océan (under the ocean), at the Argonaut, Parc de la Villette, 19éme, every day except Mondays from 10h. to 18h. and on Sundays until 19h; admission between 9 and 12 Euros.
Christmas comes back to the parvis of the La Defénse from November 22nd. While the 250 chalets are being installed, for the 2018 edition. And as a good Frenchman, we have charitable associations participating this year. This is the Maison de l'amitié (house of Friendship), located near the Place Carpeaux square, which welcomes in daytime the homeless people of the Parisian association the La Cloche ( Bell) which mobilizes local businesses by encouraging them to make small services to persons in precariousness. There will also be the online platform Entourage, which federates the solidarity initiatives, and the missing link, which fights the food waste by retrieving the unsold ones from the shops to redistribute them immediately to the structures of reception.
The Satory-West Concerted Development Zone (ZAC), Versailles! on the horizon of 2035, will completely change the physiognomy of this area of 330 ha that is not used today, except by the military. The arrival of the train station of Line 18 of the Metro in 2030 which will act as a trigger and make this sector more virtuous in matters of transport and the environment. Located a few steps from the present Bir-Hakeim roundabout, on the road D91, this station should meet the needs of the thousands of inhabitants expected at its doorstep. To the North, 3 500 housing units facing South towards a tree park. The army will retain its stranglehold on this sector along the road N12. A new exchanger is in the works for 2025 between the D91 and N12. The transport agency DIRIF works on this subject in order to eliminate the influx of cars during peak hours on the ramp of the N12 and facilitate access to Satory without thwarting the flow going towards Versailles. Eventually, the huge current roundabout of the D91, which serves Satory west today, is simply called to disappear to give way to a bypass traffic near the subway station. To relieve the traffic coming from St Cyr l'école by the creation, by 2025, of a bus line on own site in the direction of Gare de Saint-Cyr. It will be based on the military railway, which joins the site of Matelots at Versailles. Just a bit of road transport news, which will remind me and those road warriors readers!
The farm or La ferme de Saint-Cyr-l'École in the Yvelines my old dept 78, offers individuals the right to pick up fruit and vegetables directly in the fields for years and something we used to do; great for the family and real good stuff direct from mother earth.
The Maison du Vietnam, ( Vietnam House), the quintessential Vietnamese deli, organizes two free and exceptional days that will water your mouths. On the program: exhibitions, concerts, tastings of local produce, savory and sweet dishes, and discovery of the Asian Dragon crafts. The opportunity to (re) discover the culinary, artistic and cultural traditions of this incredible country. Saturday 17 and Sunday 18 November 2018 from 9h to 19h at 4, rue du Bourg l'Abbé 3éme Paris
Ok so it rains in Paris so what, the city is even more gorgeous in the rain ,and here are some tips to do otherwise : Rain in Paris is good news: This is a first advantage to rain: You no longer need to water your plants (at least those that survived without water for 3 weeks). We don't need to wash the car anymore. You're late all the time. So for once, enjoy the rain to have a good excuse to cancel an appointment or to arrive late at the party'. "I'm Singin' ' in the rain, just Singin' ' in the Rain." Finally a good excuse to sing in the rain without being ridiculous. What could be more romantic than rain? Enjoy it to slip under the umbrella of your crushing mate… And why not try a rapprochement? The rain is charged with negative ions that limit pathologies such as asthma. Roughly speaking, it renews the air we breathe! It rains heavily, and you want to go outside to smoke? No, I can't. Stay warm and use a good coffee. You can finally take out its finest wax and plastic boots; Since the time you bought it, we were really wondering when you were going to wear it! A sad advantage of the rain is to clean the Parisian streets of all their cigarette butts in the sewers. Next time, instead of throwing your butt on the floor, put it in the trash! Otherwise it's 68€ fine. Are you having trouble falling asleep? Listen to the rain. Are you stressed? Listen to the rain. Are you melancholy? Listen to the rain. You…well anyway, you got it!. It's time to react to enjoy the winds and tides of our beautiful city , dry of course. Reflex number one, the cinema. Second option: Expos or shopping. With the rain everything becomes super comforting. Do not be gloomy in the face of the boredom of rainy days. Yes, rain is a great reason to stay in bed in good company.lol! So enjoy the rain in Paris!!!
Know that there are 27 aerial stations, especially on métro lines 2 and 6, where you can discover incredible monuments, all without making any effort. And as said in my blog many times you come here whether visiting or in country because you want to see Paris above ground so do as I do use aerial metro stations or the bus! Here are something to make you change if not already!
13.6 km long, of which 6 km in above ground (or 45% of its route), Métro line 6 is the sixth busiest line of the network. It offers unique viewpoints on several monuments such as : the Pont de Bir-Hakeim, you can distinguish the Eiffel Tower dominating the Seine and l'île aux Cygnes (Swan Island). The Palais de Chaillot; the bell tower of the Church of Saint Augustine; the top of the canopy of the Grand Palais; the famous tour Montparnasse; the Invalides dome, the Francois Mitterand Library, the Notre-Dame Cathedral, the Maison de Radio France, before the Cambronne station, you can see the Invalides, then the Avenue de Breteuil on the Invalides before plunging back underground.
The Métro line 2 offers to a lesser extent points of view on Paris thanks to an aerial section between the stations Antwerp and Colonel Fabien. You can therefore observe, the Bassin and the rotunda of La Villette, the canal Saint-Martin, the Sacré-Coeur, the train station of Austerlitz, the National Museum of Natural History, the train station of Lyon, La Cité de la mode et du design ( city of fashion and design) , or the Cathedral of Notre-Dame.
As said enjoy Paris above ground, simply the best most beautiful city in the world!
And to finish this short post …..ha ha ha. Let me tell you about a nice story and wonderful resto of my eternal Paris;really nice.
The story goes that after a career in agri-food, Alexandra Lepage founded, five years ago, the fine grocery store/restaurant Papa Sapiens. She is from the old Berry region but grew up in Kaysersberg, a small village of winegrowers, in Alsace. She first worked for eleven years at Kraft Foods, a huge group that is now called Mondelez (includes brands such as Côte d'Or, Suchard, Milka, Carte Noire, Jacques Vabre, Philadelphia, Carambar, Lu). And then she spent a year in the United States, where she discovered Mac and cheese, instant sauces, ultratransformed products. And realized that all of this was downright disgusting, she was really struggling to defend these products. It was the end of a cycle. On her return to France, she left her salaried job, and started organizing evenings, Alexandra's dinners: Twelve Diners, a chef and an expert to talk about a topic. It was great, and not profitable at all. She ,then, partnered with her husband and two friends, and launched Papa Sapiens in 2013. Papa, for the unifying, paternalistic and somewhat outdated side. Sapiens, because we have the will to know, to transmit and to tell stories. This is what I like, in the kitchen and the good things: they are always beautiful stories. Papa Sapiens, Grocery-restaurant, at 24, rue Feydeau, 2éme Paris. More info here: Papa Sapiens
Stay tune, Paris , France has always more and more and more! It's eternal you know, and we love it , even if for living will say preferred Versailles lol! Cheers
And remember, happy travels, good health, and many cheers to all!!!
Posted in Europe, France, Paris, Versailles | Leave a Comment »
We have a military school in Paris!
Oh yes we have Fall here already with mild temps and cooler nights, some rain even today, light, and the season is getting white in spirit at least. No snow here in years in my neck of the woods , the Morbihan Breton.
I like to tell you a bit more on the military school of Paris, yes I agree, it doesn't sound the same in English, the French gives it a cache to it, école militaire de Paris! One of my favorite hangout places in Paris indeed. For the memories ,right by Ave Bosquet there is a resto Séptime Vin, I brought some friends from an old travel forum once there for a get together of many nations! And of course, one of my favorites too. Also, another of my favorite spots here is the La Terrasse du 7ème with nice views over the square! Great on my eternal Paris!
Now let me tell you a bit more on this school and square place de l'école Militaire. Actually , written on the school before so briefly, will concentrate here on my tour of streets of Paris with the square ok
The Place de l'école-Militaire is a square in the 7éme arrondissement. It lies on the northeast section of the école Militaire. There are six avenues eminating from it such as Avenue de La Bourdonnais in the north; Avenue Bosquet in the northeast; Avenue de La Motte-Picquet in the east; Avenue Tourville in the South east; Avenue Duquesne in the south; Place Joffre in the west. The neighborhood of the école-Militaire is the 27th of Paris in the 7éme arrondissement or district. The place de l'école Militaire is served by: Metro line 8, bus RATP lines 28 80 82 87 and 92, as well as a taxi stand. The 82 is a dandy for me from Montparnasse and see Paris above ground sublime! There is parking above ground at Place Joffre.
ch st François Xavier passing bus 82
Before its creation, in 1912, it was part of the Avenue Duquesne, between the avenues of La Motte-Picquet and Tourville, Avenue Tourville, between the avenues of La Motte-Picquet and Duquesne. On the here:east side, the square is served by several bars brasseries with large terraces, and in the east with the entrance of the vehicles of the école militaire. More info is given on the military school from the Paris tourist office:
Https://en.parisinfo.com/paris-museum-monument/71338/Ecole-Militaire
The école militaire was built between 1751 and 1768 in the plain of Grenelle during the reign of king Louis XV. The main entrance is the Avenue de la Motte Piquet, facing the Champ de Mars ; the Eiffel Tower at the other end. In 1787, the military school was closed and it was planned to transfer to the Hôtel-Dieu which would never took place.
The buildings are abandoned and then looted in the French revolution. The building serves as a depot, and then barracks, especially for the Imperial Guard. After various assignments, it is enlarged, to acquire the aspect that is now known today. In 1878 the École supérieure de guerre (high School of War) was opened, and in 1911 the centre des hautes études militaries opened (Center for Advanced Military Studies).
Nearby a popular stop for my family and meet friends at Rue de Grenelle is the wonderful market held there on Wednesdays and Sundays; and the wonderful fleas trinkets section on Sunday mornings. More here from the tourist office of Paris: Https://en.parisinfo.com/shopping-paris/73878/Marche-Grenelle
The main thing of course is the école militaire and not much is written on the square that carries its name. However, take it from me , it is a very chic nice neighborhood where I visit several friends, and the area has the allures of upper class, not that Paris does not have enough of these.
However, there is a nice small square with a statue nearby, Place Joffre, on the side of Avenue de la Motte-Picquet. Joseph Jacques Cesaire Joffre, often known just as Jacques Joffre, was a French General during WWI. He is most well known for regrouping the retreating allied armies in order to defeat the Germans at the strategically decisive First Battle of the Marne, which happened in 1914. And with this triumph, plus other strategies that Joffre put in place, he gained further popularity and became referred to with a nickname of Papa Joffre. Joseph Joffre had been awarded the title of Marshal of France, and he was the first person to receive this title and rank under the Third Republic, even though he also received other honors including knighthood.
Another interesting square in this neighborhood or quartier is the Place de Fontenoy–UNESCO, formerly Place de Fontenoy . This place near the military school bears the name of the Battle of Fontenoy won by the French in 1745 and UNESCO whose headquarters occupies most of it. Drawn up in 1770, the square is ceded by the state to the city in 1838. In the same square, you see the Ministry of Social Affairs. At No. 3, the building, adjoining the former Ministry of posts (Avenue of Saxe), was built at the beginning of the 1930's for the Ministry of the Merchant Navy. Following its restoration, it has been occupied since September 2016 by the National Commission of Informatics and Freedoms and the Defender of Rights. The military school occupies the entire west side of the square by Avenue de Lowendal.
And you have an idea of the neighborhood just my sublime Paris , eternal gorgeous and always wanting more. Enjoy it
Posted in Europe, France, Paris | Leave a Comment »
Tags: Europe, France, Paris
Africa Americas Asia Bretagne Cuba Europe Florida Food and Wine France Madrid New Jersey Paris Real Madrid Spain Versailles
40 Millions Automobilistes
Basilica of Saint Denis, Tourism 93
Brittany lovers, the Bretagne
Chateau de Versailles official site
Independant winegrowers in France
la Fourchette or the Fork, resto reservation online in France
La Revue du Vin de France, French wine magazine
Real Madrid FC official site
Trippit
wine bodegas in Spain (Spanish)
Yelp for help


text:
Historian Contact Info
Nicole Kelly
Darien Center, New York 14040
The history of the Town of Darien was updated for the Terquasquicentennial celebration in 2007; and is for all those interested in how Darien has progressed and prospered over the last 175 plus years. Darien is a small community with good local government, modern improvements and fine highways. Its religious heritage has been sustained over the years, as evidenced by three early churches still in existence. The history book is a tribute to all residents, elected and appointed officials, and early settlers who, over the years, have given many hours of their time to help make Darien the town that it is today.
In 1803, Orange Carter arrived from Vermont to become the town's first permanent resident in the southern part of town. Early settlers followed rapidly. Stephen Parker kept the first inn, in 1808, in Darien City. Amos Humphrey started the first saw mill in 1809 on Eleven Mile Creek in Darien. Stephen King opened the first store at Darien Center in 1815, giving the name King's Corners to the Settlement. Until 1832, the area that is now the Town of Darien was the southern part of the Town of Pembroke and often referred to as South Pembroke. By an Act of the State Legislature, dated February 10, 1832, Darien was established as a separate township. The first annual town meeting was held April 3, 1832 at the tavern of Stephen King. Two major streams with countless tributaries flow across town. Eleven Mile Creek was so named because it crossed the old Buffalo Road eleven miles from Buffalo, as tradition has it. In 1861, Murder Creek was moved 16 rods east during the building of the road. A culvert built of flat stones forming an arch was then added. Two versions of how the Creek got its name are widely accepted. The population of the Town of Darien in 1840 was 2406; in 1870 Darien was the smallest with a population of 2054; and in the 2000 Census Darien's population was 3061. And soon we will know how our population has changed again, although, Darien will always be Just Right. For more on the history of Darien, a history book can be purchased from the Town Clerk for $5.00.
1908 Perrys Home
1930s Barber Shop
1940s Darien Baseball Team
Alleghany Street
Darien General Store
Erie Station Rt77
Firemans Carnival Parade 1954
Greiner Home 1912
Griswold Pond
Home on Tinkham Road
Joseph Linsey Saloon
Post Office Firemans Hall
Rt20 77 road
School House 5 1927


text:
Q: mysql concat sub query results as a subquery itself this is a bit tough, i guess.
what i'm trying to achieve is to generate a string via group_concat and then run it as a query. my query return the
numCustomers as a query i would like to run.
is it possible to run this as a query inside the main query?
my query is as follows:
SELECT
lastSent,tblmailinglistgroups.addDate,title, tblmailinglistgroups.active, tblmailinglistgroups.id,groupType,
CASE
WHEN (groupType='s') THEN (SELECT COUNT(id) FROM tblmailinglistgroupscusts WHERE groupID=tblmailinglistgroups.id)
WHEN (groupType='d') THEN (
CONCAT('SELECT COUNT(tblcustomers.id) FROM tblcustomers INNER JOIN tblcustomersextension ON tblcustomers.id=tblcustomersextension.customerID WHERE 1=1 ',
(SELECT GROUP_CONCAT(filterAndOr,' ',openBrackets,' ',filterBy, ' ',(
SELECT
CASE
WHEN filterOperator='ne' THEN '!=' WHEN filterOperator='e' THEN '=' WHEN filterOperator='be' THEN '>=' WHEN filterOperator='se' THEN '<=' WHEN filterOperator='b' THEN '>' WHEN filterOperator='s' THEN '<' WHEN filterOperator='in' THEN 'in' WHEN filterOperator='ni' THEN 'not in' WHEN 'nu' THEN 'IS NULL'
END AS operator),' \'',filterValue,'\' ',closeBrackets SEPARATOR ' ') AS x
FROM `tblmailinglistgroupsrules1`
WHERE groupID=tblmailinglistgroups.id
)
)
) END AS numCustomers
FROM
tblmailinglistgroups
LEFT JOIN tblmailinglistgroupscusts ON (tblmailinglistgroupscusts.groupID = tblmailinglistgroups.id)
GROUP BY tblmailinglistgroups.id
ORDER BY tblmailinglistgroups.id DESC

the table structes are:
CREATE TABLE IF NOT EXISTS `tblmailinglistgroups` (
`id` bigint(12) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL DEFAULT '',
`addDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` enum('on','off') NOT NULL DEFAULT 'on',
`lastSent` date NOT NULL DEFAULT '0000-00-00',
`groupType` enum('s','d') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=67 ;

CREATE TABLE IF NOT EXISTS `tblmailinglistgroupscusts` (
`id` bigint(12) NOT NULL AUTO_INCREMENT,
`groupID` bigint(12) NOT NULL DEFAULT '0',
`custID` int(5) NOT NULL,
`email` varchar(200) NOT NULL DEFAULT '',
`phone` varchar(20) NOT NULL,
`comments` varchar(250) NOT NULL,
`addDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `groupID` (`groupID`),
KEY `custID` (`custID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7813 ;

CREATE TABLE IF NOT EXISTS `tblmailinglistgroupsrules1` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`groupID` int(5) NOT NULL,
`filterAndOr` enum('AND','OR') NOT NULL,
`openBrackets` enum('','(','((','(((','((((') NOT NULL,
`filterBy` varchar(40) NOT NULL,
`filterOperator` varchar(40) NOT NULL,
`filterValue` varchar(40) NOT NULL,
`closeBrackets` enum('',')','))',')))','))))') NOT NULL,
`showOrder` int(5) NOT NULL,
`addDate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=415 ;

A: You could use stored procedures to execute a query from the concat. There is no way to do this inside a simple SQL Query.
A good explanation could be found here: http://www.it-iss.com/mysql/mysql-stored-procedures-and-dynamic-sql/
DANGER: If this is a web-application, it may be possible for attackers to manipuate the result of the concat statement to execute own, bad statements like DROP DATABASE.

redpajama_set_name: RedPajamaStackExchange


Yay! You made it to the travelling bloggers' home page! Since you're here, you know us well enough to understand that, yup, we're on our way to Mexico again. It is less than 24 hours after setting out, this time via Honda CR-V, and David is handing me the first blog. Note that I realize that it is the "first" , which means that I expect several more during our journeys this time around.


After ordering any one of our products from our Amazon Store you are eligible to receive one free bottle on us!
You may visit DrTobiasRewards.com with your Amazon Order # and fill out the form to receive your free bottle. The form will not work for you until you have had your product for at least 14 days and will expire 60 days past your order.


text:
Posted on June 5, 2019 by mike
New PPL Plaza owners detail plans for property improvements
ALLENTOWN, Pa. – The PPL Plaza in Allentown is headed in a new direction and preparing for a new name.
The new owners invited media inside for a tour Wednesday after purchasing the property in a sheriff's sale last month.
The building, though 16 years old, was way ahead of its time and offers a lot of modern features.
The biggest change up is the plaza. The new owners want to make it more of a communal space. The water fountains go, but they'll add more places for people to sit and beef up entertainment.
The PPL Plaza has a spectacular lobby skylight, rooftop gardens and countless eco-friendly features.
The PPL Plaza building was sold at a sheriff's auction to Somera Road for 16 million, a fraction of what it cost to build it. It most recently was home to Talen Energy, a PPL spinoff.
The owners aim to make the building once again attractive to tenants, who recently have gone for newer, cheaper builds thanks to the Neighborhood Improvement Zone.
The old PPL Plaza Is in the NIZ, and the new owners could be eligible for NIZ benefits for new improvements like upgrading the lobby and revamping the plaza space.
Ian Ross says there's a lot of vendor interest in the vacant restaurant space, especially with 2,000 ADP employees soon to move in just down the street.
"A lot of vendors want to play into that and be accessible from a street front perspective," Ross said.
About a half a dozen companies have already expressed interest in moving into the building.
"Companies are saying I want to be downtown," Ross said.
The new owners aren't naming those companies, but they say they expect tenants will start moving in by the end of the summer.
Original post: https://www.wfmz.com/news/lehigh-valley/new-ppl-plaza-owners-detail-plans-for-property-improvements/1081928942
CategoriesAcquisitions, Management, Wealth
Previous PostPrevious New PPL Plaza owner shows off building, expects tenants this year
Next PostNext PPL Plaza is 'hands down the best office space in the market,' new building owner says


text:
The Party Posse
From Rocklopedia Fakebandica
Revision as of 16:21, 4 May 2011 by Alan (Talk | contribs)
After taking on rock, country and barbershop, The Simpsons finally get around to manufactured boy bands in the "New Kids on the Blecch" episode (first aired 25 Feb. 2001). In the episode, Classified Records producer L.T. Smash (who put together Boyneudo and New Kids In a Ditch) turns Bart Simpson, Milhouse Van Houten, Nelson Muntz, and Ralph Wiggum into a quartet of preteen crooners, thanks to studio magic and songs like "You're My Special Girl" and "I Gotta Spell Out What I Mean." Unfortunately, as Lisa Simpson discovers, the band is really part of the U.S. Navy's Project Boy Band, and has subliminal messages and backward masking (Yvan Eht Nioj) in their songs ("Drop Da Bomb" and "Let's Re-Up Tonight") to brainwash the youth of America to join the Navy. The band ends when the Navy tries to stop the project before a planned Mad Magazine spoofing, only to have L. T. Smash (really Navy Lt. L.T. Smash) go nuts and kidnap the band and destroy the Mad offices. Real group N'Sync guest starred as themselves.
Retrieved from "http://www.fakebands.com/wiki/index.php?title=The_Party_Posse&oldid=1925"
Content is available under Attribution-Noncommercial-Share Alike 3.0 Unported unless otherwise noted.
About Rocklopedia Fakebandica


Predictive maintenance software. Longer lifecycles for machines.
Predictive Maintenance (PdM) with VBASE.
Better machine life and lower wear with Predictive Maintenance.
Increased life cycle, optimized downtime.
Maintenance with VBASE: predictive instead of reactive.
Reactive maintenance is expensive, because it leads to unplanned machine downtimes, increased attrition and shorter machine lifetime. And we can find this method way to often in the field.
Repair your equipment before they fail unplannable by a defect.
With VBASE we integrate measures for predictive maintenance directly in your machine or system. In particular MES function blocks we encapsulate functions that constantly monitor the status and the number of state changes of individual units and entire plants. We constantly calculate the time until the next maintenance on the basis of specified MTBF parameters.
Request our latest VBASE price list now.
With the right combination to "Smart Maintenance"
In addition to this basic functionality we can include further individual parameters into this calculation. For example, a power factor can be taken into account for machines which are not permanently operated with the same power. If additional sensor signals from condition monitoring (e.g. vibration and temperature monitoring) are available that represent the current "state of health" of individual system components, these signals can also be included in the prediction. With the consistent and comprehensive combination of all data from predictive maintenance and condition monitoring we can achieve a smart maintenance system.
Status notifications by email, text message, etc.
Automatic entries in database-based maintenance books, protocols, etc.
All messages are logged and can be written into a digital "maintenance book" (database). The performed maintenance is recorded and also logged. All maintenance data are permanently available for analyzes, reporting and future optimization approaches.
Do you need individual consulting?
A machine-specific summary of the maintenance information can help easily keeping track. In a central shopfloor display for several machines, a general status indicator can show the maintenance information for each individual machine.
The "maintenance book" for each machine shows the details of the next maintenances. For example, which aggregate needs necessary actions at a expected time.
Beside the predictive maintenance information, VBASE can integrate and display more key values parallel to the maintenance data. For example, permanent overall productivity (OEE) or smart meter information to optimize the usage of energy and other resources.
Mobile access to your service data with Web-Remote.
Each VBASE system has an integrated web interface based on HTML5. This means that all machine, production and service data can be easily displayed on any mobile device (smartphone, tablet, etc.), and can also be operated after approval. Thus, the data can be made available on a worldwide basis, in real time.
In addition to mobile access, notifications can also be set up which notify the responsible employee or the responsible department by e-mail or text message when the predefined thresholds are reached.
Predictive Maintenance is only one aspect of Industry 4.0 and SmartFactory that VBASE covers. Further functions such as efficiency monitoring (OEE), smart metering, operating data acquisition, MES and more can be individually integrated and combined.
Many functions are available in VBASE as function blocks and can be quickly and easily integrated and parameterized. VBASE can be adapted to any industry and includes a variety of drivers for systems from different manufacturers. Thus, Industry 4.0 can also be retrofitted for older production plants.


text:
import io
import ipaddress
import time
from unittest import mock

from absl.testing import absltest
import humanize
from IPython.lib import pretty

import grr_colab
from grr_colab import representer
from grr_response_proto import jobs_pb2
from grr_response_proto import sysinfo_pb2
from grr_response_proto.api import client_pb2

class StatEntryPrettyTest(absltest.TestCase):

  def testFile(self):
    entry = jobs_pb2.StatEntry()
    entry.pathspec.path = '/foo/bar'
    entry.st_size = 42
    entry.st_mode = 33188

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.stat_entry_pretty(entry, pp, cycle=False)

    expected = '📄 bar (-rw-r--r-- /foo/bar, {})'
    expected = expected.format(humanize.naturalsize(42))

    self.assertEqual(out.getvalue(), expected)

  def testDirectory(self):
    entry = jobs_pb2.StatEntry()
    entry.pathspec.path = '/foo/bar'
    entry.st_size = 42
    entry.st_mode = 16877

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.stat_entry_pretty(entry, pp, cycle=False)

    expected = '📂 bar (drwxr-xr-x /foo/bar, {})'
    expected = expected.format(humanize.naturalsize(42))

    self.assertEqual(out.getvalue(), expected)

class BufferReferencePrettyTest(absltest.TestCase):

  def testAsciiData(self):
    ref = jobs_pb2.BufferReference()
    ref.pathspec.path = '/foo/bar'
    ref.offset = 42
    ref.length = 6
    ref.data = b'foobar'

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.buffer_reference_pretty(ref, pp, cycle=False)

    expected = '/foo/bar:42-48: b\'foobar\''
    self.assertEqual(out.getvalue(), expected)

  def testNonAsciiData(self):
    ref = jobs_pb2.BufferReference()
    ref.pathspec.path = '/foo/bar'
    ref.offset = 42
    ref.length = 3
    ref.data = b'\xff\xaa\xff'

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.buffer_reference_pretty(ref, pp, cycle=False)

    expected = '/foo/bar:42-45: b\'\\xff\\xaa\\xff\''
    self.assertEqual(out.getvalue(), expected)

class NetworkAddressPrettyTest(absltest.TestCase):

  def testIPv4(self):
    ipv4 = ipaddress.IPv4Address('42.0.255.32')
    address = jobs_pb2.NetworkAddress()
    address.address_type = jobs_pb2.NetworkAddress.INET
    address.packed_bytes = ipv4.packed

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.network_address_pretty(address, pp, cycle=False)

    expected = 'inet 42.0.255.32'
    self.assertEqual(out.getvalue(), expected)

  def testIPv6(self):
    ipv6 = ipaddress.IPv6Address('2001:db8::1000')
    address = jobs_pb2.NetworkAddress()
    address.address_type = jobs_pb2.NetworkAddress.INET6
    address.packed_bytes = ipv6.packed

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.network_address_pretty(address, pp, cycle=False)

    expected = 'inet6 2001:db8::1000'
    self.assertEqual(out.getvalue(), expected)

class InterfacePrettyTest(absltest.TestCase):

  def testNoAddresses(self):
    iface = jobs_pb2.Interface()
    iface.mac_address = b'\xaa\x12\x42\xff\xa5\xd0'
    iface.ifname = 'foo'

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.interface_pretty(iface, pp, cycle=False)

    expected = """\
foo (MAC: aa:12:42:ff:a5:d0):
"""
    self.assertEqual(out.getvalue(), expected)

  def testSingleAddress(self):
    ipv4 = ipaddress.IPv4Address('42.0.255.32')
    address = jobs_pb2.NetworkAddress()
    address.address_type = jobs_pb2.NetworkAddress.INET
    address.packed_bytes = ipv4.packed

    iface = jobs_pb2.Interface()
    iface.mac_address = b'\xaa\x12\x42\xff\xa5\xd0'
    iface.ifname = 'foo'
    iface.addresses.extend([address])

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.interface_pretty(iface, pp, cycle=False)

    expected = """\
foo (MAC: aa:12:42:ff:a5:d0):
    inet 42.0.255.32
"""
    self.assertEqual(out.getvalue(), expected)

  def testMultipleAddresses(self):
    ipv4 = ipaddress.IPv4Address('42.0.255.32')
    address1 = jobs_pb2.NetworkAddress()
    address1.address_type = jobs_pb2.NetworkAddress.INET
    address1.packed_bytes = ipv4.packed

    ipv6 = ipaddress.IPv6Address('2001:db8::1000')
    address2 = jobs_pb2.NetworkAddress()
    address2.address_type = jobs_pb2.NetworkAddress.INET6
    address2.packed_bytes = ipv6.packed

    iface = jobs_pb2.Interface()
    iface.mac_address = b'\xaa\x12\x42\xff\xa5\xd0'
    iface.ifname = 'foo'
    iface.addresses.extend([address1, address2])

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out)
    representer.interface_pretty(iface, pp, cycle=False)

    expected = """\
foo (MAC: aa:12:42:ff:a5:d0):
    inet 42.0.255.32
    inet6 2001:db8::1000
"""
    self.assertEqual(out.getvalue(), expected)

class ProcessPrettyTest(absltest.TestCase):

  def testFitWidth(self):
    process = sysinfo_pb2.Process()
    process.pid = 1
    process.username = 'admin'
    process.nice = 10
    process.VMS_size = 42
    process.RSS_size = 43
    process.status = 'sleeping'
    process.cpu_percent = 1.5
    process.memory_percent = 2.5
    process.exe = '/foo/bar'

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out, max_width=55)
    representer.process_pretty(process, pp, cycle=False)

    expected = '     1 admin      10   42B   43B S  1.5  2.5 /foo/bar'

    self.assertEqual(out.getvalue(), expected)

  def testExceedMaxWidth(self):
    process = sysinfo_pb2.Process()
    process.pid = 1
    process.username = 'longusername'
    process.nice = 10
    process.VMS_size = 42
    process.RSS_size = 43
    process.status = 'sleeping'
    process.cpu_percent = 1.5
    process.memory_percent = 2.5
    process.exe = '/foo/bar/baz'

    out = io.StringIO()
    pp = pretty.PrettyPrinter(out, max_width=55)
    representer.process_pretty(process, pp, cycle=False)

    expected = '     1 longusern  10   42B   43B S  1.5  2.5 /foo/bar/baz'

    self.assertEqual(out.getvalue(), expected)

class StatEntryListTest(absltest.TestCase):

  def testEmptyResults(self):
    sts = representer.StatEntryList([])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)
    self.assertEqual(out.getvalue(), 'No results.')

  def testCycle(self):
    sts = representer.StatEntryList([])

    out = io.StringIO()
    with self.assertRaises(AssertionError):
      sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=True)

  def testSingleDirectory(self):
    entry = jobs_pb2.StatEntry()
    entry.pathspec.path = '/foo/bar'
    entry.st_size = 42
    entry.st_mode = 16877

    sts = representer.StatEntryList([entry])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo
    📂 bar (drwxr-xr-x /foo/bar, {})
"""
    expected = expected.format(humanize.naturalsize(42))

    self.assertEqual(out.getvalue(), expected)

  def testSingleFile(self):
    entry = jobs_pb2.StatEntry()
    entry.pathspec.path = '/foo/bar'
    entry.st_size = 42
    entry.st_mode = 33188

    sts = representer.StatEntryList([entry])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo
    📄 bar (-rw-r--r-- /foo/bar, {})
"""
    expected = expected.format(humanize.naturalsize(42))

    self.assertEqual(out.getvalue(), expected)

  def testCommonImplicitRoot(self):
    entry1 = jobs_pb2.StatEntry()
    entry1.pathspec.path = '/foo/bar'
    entry1.st_size = 42
    entry1.st_mode = 33188

    entry2 = jobs_pb2.StatEntry()
    entry2.pathspec.path = '/foo/baz'
    entry2.st_size = 43
    entry2.st_mode = 16877

    sts = representer.StatEntryList([entry1, entry2])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo
    📄 bar (-rw-r--r-- /foo/bar, {})
    📂 baz (drwxr-xr-x /foo/baz, {})
"""
    expected = expected.format(
        humanize.naturalsize(42), humanize.naturalsize(43))

    self.assertEqual(out.getvalue(), expected)

  def testDifferentRoots(self):
    entry1 = jobs_pb2.StatEntry()
    entry1.pathspec.path = '/foo1/bar'
    entry1.st_size = 42
    entry1.st_mode = 33188

    entry2 = jobs_pb2.StatEntry()
    entry2.pathspec.path = '/foo2/baz'
    entry2.st_size = 43
    entry2.st_mode = 16877

    sts = representer.StatEntryList([entry1, entry2])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo1
    📄 bar (-rw-r--r-- /foo1/bar, {})
/foo2
    📂 baz (drwxr-xr-x /foo2/baz, {})
"""
    expected = expected.format(
        humanize.naturalsize(42), humanize.naturalsize(43))

    self.assertEqual(out.getvalue(), expected)

  def testNestedDirectories(self):
    entry1 = jobs_pb2.StatEntry()
    entry1.pathspec.path = '/foo/bar'
    entry1.st_size = 42
    entry1.st_mode = 16877

    entry2 = jobs_pb2.StatEntry()
    entry2.pathspec.path = '/foo/bar/baz'
    entry2.st_size = 42
    entry2.st_mode = 16877

    entry3 = jobs_pb2.StatEntry()
    entry3.pathspec.path = '/foo/bar/baz/quux'
    entry3.st_size = 42
    entry3.st_mode = 16877

    sts = representer.StatEntryList([entry1, entry2, entry3])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo
    📂 bar (drwxr-xr-x /foo/bar, {size})
        📂 baz (drwxr-xr-x /foo/bar/baz, {size})
            📂 quux (drwxr-xr-x /foo/bar/baz/quux, {size})
"""
    expected = expected.format(size=humanize.naturalsize(42))

    self.assertEqual(out.getvalue(), expected)

  def testCommonExplicitRoot(self):
    entry1 = jobs_pb2.StatEntry()
    entry1.pathspec.path = '/foo/bar'
    entry1.st_size = 42
    entry1.st_mode = 16877

    entry2 = jobs_pb2.StatEntry()
    entry2.pathspec.path = '/foo/bar/baz'
    entry2.st_size = 42
    entry2.st_mode = 33188

    entry3 = jobs_pb2.StatEntry()
    entry3.pathspec.path = '/foo/bar/quux'
    entry3.st_size = 42
    entry3.st_mode = 33188

    sts = representer.StatEntryList([entry1, entry2, entry3])

    out = io.StringIO()
    sts._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo
    📂 bar (drwxr-xr-x /foo/bar, {size})
        📄 baz (-rw-r--r-- /foo/bar/baz, {size})
        📄 quux (-rw-r--r-- /foo/bar/quux, {size})
"""
    expected = expected.format(size=humanize.naturalsize(42))

    self.assertEqual(out.getvalue(), expected)

  def testSlice(self):
    entry1 = jobs_pb2.StatEntry()
    entry2 = jobs_pb2.StatEntry()

    sts = representer.StatEntryList([entry1, entry2])
    sts = sts[:1]

    self.assertLen(sts, 1)
    self.assertIsInstance(sts, representer.StatEntryList)

class BufferReferenceListTest(absltest.TestCase):

  def testEmptyResults(self):
    brs = representer.BufferReferenceList([])

    out = io.StringIO()
    brs._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)
    self.assertEqual(out.getvalue(), 'No results.')

  def testCycle(self):
    brs = representer.BufferReferenceList([])

    out = io.StringIO()
    with self.assertRaises(AssertionError):
      brs._repr_pretty_(pretty.PrettyPrinter(out), cycle=True)

  def testMultipleItems(self):
    ref1 = jobs_pb2.BufferReference()
    ref1.pathspec.path = '/foo/bar'
    ref1.offset = 42
    ref1.length = 6
    ref1.data = b'foobar'

    ref2 = jobs_pb2.BufferReference()
    ref2.pathspec.path = '/quux'
    ref2.offset = 42
    ref2.length = 4
    ref2.data = b'quux'

    brs = representer.BufferReferenceList([ref1, ref2])

    out = io.StringIO()
    brs._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
/foo/bar:42-48: b\'foobar\'
/quux:42-46: b\'quux\'
"""
    self.assertEqual(out.getvalue(), expected)

  def testSlice(self):
    ref1 = jobs_pb2.BufferReference()
    ref2 = jobs_pb2.BufferReference()

    brs = representer.BufferReferenceList([ref1, ref2])
    self.assertIsInstance(brs[:1], representer.BufferReferenceList)

class InterfaceListTest(absltest.TestCase):

  def testEmptyResults(self):
    ifaces = representer.InterfaceList([])

    out = io.StringIO()
    ifaces._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)
    self.assertEqual(out.getvalue(), 'No results.')

  def testCycle(self):
    ifaces = representer.InterfaceList([])

    out = io.StringIO()
    with self.assertRaises(AssertionError):
      ifaces._repr_pretty_(pretty.PrettyPrinter(out), cycle=True)

  def testMultipleItems(self):
    ipv4 = ipaddress.IPv4Address('42.0.255.32')
    address1 = jobs_pb2.NetworkAddress()
    address1.address_type = jobs_pb2.NetworkAddress.INET
    address1.packed_bytes = ipv4.packed

    ipv6 = ipaddress.IPv6Address('2001:db8::1000')
    address2 = jobs_pb2.NetworkAddress()
    address2.address_type = jobs_pb2.NetworkAddress.INET6
    address2.packed_bytes = ipv6.packed

    iface1 = jobs_pb2.Interface()
    iface1.mac_address = b'\xaa\x12\x42\xff\xa5\xd0'
    iface1.ifname = 'foo'
    iface1.addresses.extend([address1])

    iface2 = jobs_pb2.Interface()
    iface2.mac_address = b'\xaa\x12\x42\xff\xa5\xd1'
    iface2.ifname = 'bar'
    iface2.addresses.extend([address2])

    ifaces = representer.InterfaceList([iface1, iface2])

    out = io.StringIO()
    ifaces._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
foo (MAC: aa:12:42:ff:a5:d0):
    inet 42.0.255.32

bar (MAC: aa:12:42:ff:a5:d1):
    inet6 2001:db8::1000
"""
    self.assertEqual(out.getvalue(), expected)

  def testSlice(self):
    iface1 = jobs_pb2.Interface()
    iface2 = jobs_pb2.Interface()

    ifaces = representer.InterfaceList([iface1, iface2])
    self.assertIsInstance(ifaces[:1], representer.InterfaceList)

class ClientListTest(absltest.TestCase):

  class _MockClient(grr_colab.Client):

    class MockInnerClient(object):

      def __init__(self):
        self.data = client_pb2.ApiClient()

    def __init__(self, client_id='', hostname='', last_seen_at=0):
      self._summary = None
      self._client = ClientListTest._MockClient.MockInnerClient()
      self._client.data.client_id = client_id
      self._client.client_id = client_id
      self._client.data.knowledge_base.fqdn = hostname
      self._client.data.last_seen_at = last_seen_at

  def testEmptyResults(self):
    cs = representer.ClientList([])

    out = io.StringIO()
    cs._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)
    self.assertEqual(out.getvalue(), 'No results.')

  def testCycle(self):
    cs = representer.ClientList([])

    out = io.StringIO()
    with self.assertRaises(AssertionError):
      cs._repr_pretty_(pretty.PrettyPrinter(out), cycle=True)

  def testMultipleItems(self):
    current_time_secs = 1560000000
    last_seen1 = (current_time_secs - 1) * (10**6)
    last_seen2 = (current_time_secs - 4 * 60 * 60 * 24) * (10**6)

    client1 = ClientListTest._MockClient('foo', 'host1', last_seen1)
    client2 = ClientListTest._MockClient('bar', 'host2', last_seen2)

    clients = representer.ClientList([client1, client2])
    out = io.StringIO()

    with mock.patch.object(time, 'time', return_value=current_time_secs):
      clients._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)

    expected = """
🌕 foo @ host1 (1 seconds ago)
🌑 bar @ host2 (4 days ago)
"""
    self.assertEqual(out.getvalue(), expected)

  def testSlice(self):
    client1 = ClientListTest._MockClient()
    client2 = ClientListTest._MockClient()

    clients = representer.ClientList([client1, client2])
    self.assertIsInstance(clients[:1], representer.ClientList)

class ProcessListTest(absltest.TestCase):

  def testEmptyResults(self):
    ps = representer.ProcessList([])

    out = io.StringIO()
    ps._repr_pretty_(pretty.PrettyPrinter(out), cycle=False)
    self.assertEqual(out.getvalue(), 'No results.')

  def testCycle(self):
    ps = representer.ProcessList([])

    out = io.StringIO()
    with self.assertRaises(AssertionError):
      ps._repr_pretty_(pretty.PrettyPrinter(out), cycle=True)

  def testMultipleItems(self):
    process1 = sysinfo_pb2.Process()
    process1.pid = 1
    process1.username = 'admin'
    process1.nice = 10
    process1.VMS_size = 42
    process1.RSS_size = 43
    process1.status = 'sleeping'
    process1.cpu_percent = 1.5
    process1.memory_percent = 2.5
    process1.exe = '/foo/bar'

    process2 = sysinfo_pb2.Process()
    process2.pid = 2
    process2.username = 'admin'
    process2.VMS_size = 40
    process2.RSS_size = 41
    process2.status = 'zombie'
    process2.exe = '/foo/baz/quux'

    ps = representer.ProcessList([process1, process2])

    out = io.StringIO()
    ps._repr_pretty_(pretty.PrettyPrinter(out, max_width=55), cycle=False)

    expected = """
   PID USER       NI  VIRT   RES S CPU% MEM% Command
     1 admin      10   42B   43B S  1.5  2.5 /foo/bar
     2 admin       0   40B   41B Z  0.0  0.0 /foo/baz/q
"""
    self.assertEqual(out.getvalue(), expected)

  def testSlice(self):
    process1 = sysinfo_pb2.Process()
    process2 = sysinfo_pb2.Process()

    ps = representer.ProcessList([process1, process2])
    self.assertIsInstance(ps[:1], representer.ProcessList)

if __name__ == '__main__':
  absltest.main()


text:
Next: Searching Up: Data-Oriented Design Previous: Component Based Objects Contents
Online release of Data-Oriented Design :
This is the free, online, reduced version. Some inessential chapters are excluded from this version, but in the spirit of this being an education resource, the essentials are present for anyone wanting to learn about data-oriented design.
Expect some odd formatting and some broken images and listings as this is auto generated and the Latex to html converters available are not perfect. If the source code listing is broken, you should be able to find the referenced source on github. If you like what you read here, consider purchasing the real paper book from here, as not only will it look a lot better, but it will help keep this version online for those who cannot afford to buy it. Please send any feedback to support@dataorienteddesign.com
JIT mementos
Alternative axes
Beyond space
Collective LOD
Hierarchical Level of Detail and Implicit-state
Consoles and graphics cards are not generally bottlenecked at the polygon rendering stage in the pipeline. Usually, they are bandwidth bound. If there is a lot of alpha blending, it's often fill-rate issues. For the most part, graphics chips spend a lot of their time reading textures, and texture bandwidth often becomes the bottleneck. Because of this, the old way of doing level of detail with multiple meshes with decreasing numbers of polygons is never going to be as good as a technique which takes into account the actual data required of the level of detail used in each renderable. The vast majority of stalls when rendering come from driver side processing, or from processing too much for what you want to actually render. Hierarchical level of detail can fix the problem of high primitive count which causes more driver calls than necessary.
The basic approach for art is to make optimisations by grouping and merging many low level of detail meshes into one single low level of detail mesh. This reduces the time spent in the setup of render calls which is beneficial in situations where driver calls are costly. In a typical very large scale environment, a hierarchical level of detail approach to game content can reduce the workload on a game engine by an order of magnitude as the number of entities in the scene considered for processing and rendering drops significantly.
Even though the number of polygons rendered may be exactly the same, or maybe even higher, the fact that the engine usually is only handling roughly the same number of entities at once on average increases stability and allows for more accurately targeted optimisations of both art and code.
Existence from Null to Infinity
If we consider that entities can be implicit based on their attributes, we can utilise the technique of hierarchical level of detail to offer up some optimisations for our code. In traditional level of detail techniques, as we move further away from the object or entity of interest, we lose details and fidelity. We might reduce polygon count, or texture sizes, or even the number of bones in a skeleton that drives the skinned mesh. Game logic can also degrade. Moving away from an entity, it might switch to a much coarser grain time step. It's not unheard of for behaviours of AI to migrate from a 50hz update to a 1hz update. In a hierarchical level of detail implementation, as the entity becomes closer, or more apparent to the player, it might be that only at that point does it even begin to exist.
Consider a shooter game where you are defending a base from incoming attacks. You are manning an anti-air turret, and the attackers come in squadrons of aircraft, you can see them all coming at once, over ten thousand aircraft in all, and up to a hundred at once in each squadron. You have to shoot them down or be inundated with gunfire and bombs, taking out both you and the base you are defending.
Running full AI, with swarming for motion and avoidance for your slower moving ordnance might be too much if it was run on all ten thousand ships every tick, but you don't need to. The basic assumption made by most AI programmers is that unless they are within attacking range, then they don't need to be running AI. This is true and offers an immediate speedup compared to the naïve approach. Hierarchical LOD provides another way to think about this, by changing the number of entities based on how they are perceived by the player. For want of a better term, collective lodding is a name that describes what is happening behind the scenes a little better. Sometimes there is no hierarchy, and yet, there can still be a change in the manner in which the elements are referenced between the levels of detail. The term collective lodding is inspired by the concept of a collective term. A murder of crows is a computational element, but each crow is a lower level of detail sub-element of the collective.
In the collective lodding version of the base defender game, there are a few wave entities which project squadron blips on the radar. The squadrons don't exist as their own entities until they get close enough. Once a wave's squadron is within range, the wave will decrease its squadron count and pop out a new squadron entity. The newly created squadron entity shows blips on the radar for each of its component aircraft. The aircraft don't exist yet, but they are implicit in the squadron in the same way the squadron was implicit in the wave. The wave continues to pop Squadrons as they come into range, and once its internal count has dropped to zero, it can delete itself as it now represents no entities. As a squadron comes into even closer range, it pops out its aircraft into their own entities and eventually deletes itself. As the aircraft get closer, traditional level of detail techniques kick in and their renderables are allowed to switch to higher resolution and their AI is allowed to run at a higher intelligence setting.
When the aircraft are shot at, they switch to a taken damage type. They are full health enemy aircraft unless they take damage. If an AI reacts to damage with fear, they may eject, adding another entity to the world. If the wing of the plane is shot off, then that also becomes a new entity in the world. Once a plane has crashed, it can delete its entity and replace it with a smoking wreck entity that will be much simpler to process than an aerodynamic simulation, faked or not.
If things get out of hand and the player can't keep the aircraft at bay and their numbers increase in size so much that any normal level of detail system can't kick in to mitigate it, collective lodding can still help by returning aircraft to squadrons and flying them around the base attacking as a group, rather than as individual aircraft. In the board game Warhammer Fantasy Battle, there were often so many troops firing arrows at each other, that players would often think of attacks by squads as being collections of attacks, and not actually roll for each individual soldier, rat, orc or whatever it was, but instead counted up how many troops they had, and rolled that many dice to see how many attacks got through. This is what is meant by attacking as a squadron. The aircraft no longer attack, instead, the likelihood an attack will succeed is calculated, dice are rolled, and that many attacks get through. The level of detail heuristic can be tuned so the nearest and front-most squadron are always the highest level of detail, effectively making them roll individually, and the ones behind the player maintain a very simplistic representation.
This is game development smoke and mirrors as a basic game engine element. In the past we have reduced the number of concurrent attacking AI5.1, reduced the number of cars on screen by staggering the lineup over the whole race track5.2, and we've literally combined people together into one person instead of having loads of people on screen at once5.3. This kind of reduction of processing is commonplace. Now consider using it everywhere appropriate, not just when a player is not looking.
Reducing detail introduces an old problem, though. Changing level of detail in game logic systems, AI and such, brings with it the loss of high detail history. In this case, we need a way to store what is needed to maintain a highly cohesive player experience. If a high detail squadron in front of the player goes out of sight and another squadron takes their place, we still want any damage done to the first group to reappear when they come into sight again. Imagine if you had shot out the glass on all the aircraft and when they came round again, it was all back the way it was when they first arrived. A cosmetic effect, but one that is jarring and makes it harder to suspend disbelief.
When a high detail entity drops to a lower level of detail, it should store a memento, a small, well-compressed nugget of data that contains all the necessary information in order to rebuild the higher detail entity from the lower detail one. When the squadron drops out of sight, it stores a memento containing compressed information about the amount of damage, where it was damaged, and rough positions of all the aircraft in the squadron. When the squadron comes into view once more, it can read this data and generate the high detail entities back in the state they were before. Lossy compression is fine for most things, it doesn't matter precisely which windows, or how they were cracked, maybe just that about of the windows were broken.
Another example is in a city-based free-roaming game. If AIs are allowed to enter vehicles and get out of them, then there is a good possibility you can reduce processing time by removing the AIs from the world when they enter a vehicle. If they are a passenger, then they only need enough information to rebuild them and nothing else. If they are the driver, then you might want to create a new driver type based on some attributes of the pedestrian before making the memento for when they exit the vehicle.
If a vehicle reaches a certain distance away from the player, then you can delete it. To keep performance high, you can change the priorities of vehicles that have mementos so they try to lose sight of the player thus allowing for earlier removal from the game. Optimisations like this are hard to coordinate in object-oriented systems as internal inspection of types isn't encouraged. Some games get around it by designing in ways to reset memento data as a gameplay element. The game Zelda: Breath of the Wild resets monsters during a Blood Moon, and by doing so, you as a player, are not surprised when you return to camps to find all the monsters are just as you left them.
If a vehicle that has been created as part of the ambient population is suddenly required to take on a more important role, such as the car being involved in a firefight, it needs to gain detail. This detail must come from somewhere and must be convincing. It is important to generate new entities which don't seem overly generic or unlikely, given what the player knows about the game so far. Generating that data can be thought of as providing a memento to read from just in time. Just in time mementos, or JIT mementos, offers a way to create fake mementos that can provide continuity by utilising pseudo-random generators or hash functions to create suitable information on demand without relying on storing data anywhere. Instead, they rely only on information provided implicitly by the entity in need of it.
Instead of generating new characters from a global random number generator, it is possible to seed the generator with details about the thing that needs generation. For example, you want to generate a driver and some passengers, as you're about to get close enough to a car to need to render the people inside it. Just creating random characters from a set of lookup tables is good, but if you drive past them far enough for them to get out of rendering range, and then return, the people in the car might not look the same anymore as they had to be regenerated. Instead, generate the driver and passengers using some other unique attribute, such as the license plate, as a seed. This way, while you have not affected the result of generating the memento, you have no memory overhead to store it, and no object lifetime to worry about either, as it can always be reproduced from nothing again.
This technique is used all the time in landscape generators, where the landscape is seeded from the x,y location in the map, so why not use it when generating the weather for day 107 of the game? When generating Perlin noise, many algorithms call upon a noise function, but to have a reproducible landscape, the noise function must be a repeatable function, so it can create the same results over and over again. If you're generating a landscape, it's preferred for the noise function to be coherent, that is, for small variances in the input function, only small changes should be observed in the output. We don't need such qualities when generating JIT mementos, and a hash function which varies wildly with even the smallest change in the input will suffice.
An example of using this to create a JIT memento might be to generate a house for a given landscape. First, take any normal random number generator and seed it with the location of the building. Given the landscape the house is on, select from a building template and start generating random numbers to answer questions about the house the same way loading a file off disk answers questions about the object. How large is the house? Is it small, medium, large? Generate a random number and select one answer. How many rooms does it have based on the size? 2 or 3 for small, or (int)(7 + rand * 10) for large. The point is, once you have seeded the random number generator, you're going to get the same results back every time you run through the same process. Every time you visit the house at {223.17,-100.5}, you're going to see the same 4 (or more) walls, and it will have the same paint job, broken windows, or perfect idyllic little frog pond in the back garden.
JIT mementos can be the basis of a highly textured environment with memento style sheets or style guides which can direct a feel bias for any mementos generated in those virtual spaces. Imagine a city style guide that specifies rules for occupants of cars. The style guide might claim that businessmen might share, but are much less likely to, that families have children in the back seats with an older adult driving. It might declare that young adults tend to drive around in pairs. Style guides help add believability to any generated data. Add in local changes such as having types of car linked to types of drivers. Have convertibles driven by well-dressed types or kids, low riders driven almost exclusively by their stereotypical owner, and imports and modded cars driven by young adults. In a space game, dirty hairy pilots of cargo ships, well turned out officers commanding yachts, rough and ready mercenaries in everything from a single seater to a dreadnought. Then, once you have the flavour in place, allow for a little surprise to bring it to life fully.
JIT mementos are a good way to keep the variety up, and style guides bias that so it comes without the impression that everyone is different so everyone is the same. When these biases are played out without being strictly adhered to, you can build a more textured environment. If your environment is heavily populated with completely different people all the time, there is nothing to hold onto, no patterns to recognise. When there are no patterns, the mind tends to see noise or consider it to be a samey soup. Even the most varied virtual worlds look bland when there is too much content all in the same place. Walk along the street and see if you can spot any identical paving slabs. You probably can, but also see the little bits of damage, decay, dirt, mistakes, and blemishes. To make an environment believable, you have to make it look like someone took a lot of effort trying to make it all conform.
As with all things, take away an assumption and you can find other uses for a tool. Whenever you read about, or work with a level of detail system, you will be aware that the constraint on what level of detail is shown has always been some distance function in space. It's now time to take the assumption, discard it, and analyse what is really happening.
First, we find that if we take away the assumption of distance, we can infer the conditional as some kind of linear measure. This value normally comes from a function which takes the camera position and finds the relative distance to the entity under consideration. What we may also realise when discarding the distance assumption is a more fundamental understanding of what we are trying to do. We are using a single runtime variable to control the presentation state of the entities of our game. We use runtime variables to control the state of many parts of our game already, but in this case, there is a passive presentation response to the variable, or axis being monitored. The presentation is usually some graphical, or logical level of detail, but it could be something as important to the entity as its own existence.
Distance is the measure we normally use to identify what level of detail something should be at, but it's not the metric we really need, it's just very closely related. In fact, it's inversely related. The true metric of level of detail should be how much of our perception an entity is taking up. If an entity is very large, and far away, it takes up as much of our perception as something small and nearby. All this time we have talked about hierarchical level of detail the elephant in the room has been the language used. We had waves on our radar. They took up as much perception attention as a single squadron, and a single squadron took up as much perceptual space as a single aircraft when it was in firing range.
Understand this concept: level of detail should be defined by how the player perceives a thing, at the range it is at. If you internalise this, you will be on your way to making good decisions about where the boundaries are between your levels of detail.
Let's now consider what other variables we can calculate that present an opportunity to remove details from the game's representation. We should consider anything which presents an opportunity to no longer process data unnecessarily. If some element of a game is not the player's current concern, or will fade from memory soon enough, we can dissolve it away. If we consider the probability of the player caring about a thing as a metric, then we begin to think about recollection and attention as measurable quantities we can use to drive how we end up representing it.
An entity that you know has the player's attention, but is hidden, maintains a large stake on the player's perception. That stake allows the entity to maintain a higher priority on level of detail than it would otherwise deserve. For example, a character the player is chasing in an assassination game, may be spotted only once at the beginning of the mission, but will have to remain at a high consistency of attribute throughout the mission, as they are the object the player cares about the most, coming second only to primitive needs such as survival. Even if the character slips into the crowd, and is not seen again until much later, they must look just like they did when you first caught sight of them.
Ask the question, how long until a player forgets about something that might otherwise be important? This information will help reduce memory usage as much as distance. If you have ever played Grand Theft Auto IV, you might have noticed that the cars can disappear just by not looking at them. As you turn around a few times you might notice the cars seem to be different each time you face their way. This is a stunning use of temporal level of detail. Cars which have been bumped into or driven and parked by the player remain where they were, because, in essence, the player put them there. Because the player has interacted with them, they are likely to remember they are there. However, ambient vehicles, whether they are police cruisers or civilian vehicles, are less important and don't normally get to keep any special status so can vanish when the player looks away.
At the opposite end of the scale, some games remember everything you have done. Kill enemies in the first few minutes of your game, loot their corpses, and chuck items around, then come back a hundred hours later and the items are still wherever you left them. Games like this store vast amounts of tiny details, and these details need careful storage otherwise they would cause continual and crushing performance degradation. Using spatially mapped mementos is one approach that can attempt to rationalise this kind of level of attention to player game interaction.
In addition to time-since-seen, some elements may base their level of detail on how far a player has progressed in the game, or how many of something a player has, or how many times they have done it. For example, a typical bartering animation might be cut shorter and shorter as the game uses the axis of how many recent barters to draw back the length of any non-interactive sections which could be caused by the event. This can be done simply, and the player will be thankful. Consider allowing multi-item transactions only after a certain number of single transactions have happened. In effect, you could set up gameplay elements, reactions to situations, triggers for tutorials, reminders, or extensions to gameplay options all through these abstracted level of detail style axes. Handling the idea of player expertise through axes of level of detail of gameplay mechanic depth or complexity.
This way of manipulating the present state of the game is safer from transition errors. These are errors that happen because going from one state to another may have set something to true when transitioning one direction, but might not set it back to false when transitioning the other way. You can think of the states as being implicit on the axis. When state is modified, it's prone to being modified incorrectly, or not modified at the right time. If state is tied to other variables, that is, if state is a function of other state, then it's less prone to inconsistency.
An example of where transition errors occur is in menu systems where all transitions should be reversible, sometimes you may find that going down two levels of menu, but back only one level, takes you back to where you started. For example, entering the options menu, then entering an adjust volume slider, but backing out of the slider might take you out of the options menu altogether. These bugs are common in UI code as there are large numbers of different layers of interaction. Player input is often captured in obscure ways compared to gameplay input response. A common problem with menus is one of ownership of the input for a particular frame. For example, if a player hits both the forward and backward button at the same time, a state machine UI might choose to enter whichever transition response comes first. Another might manage to accept the forward event, only to have the next menu accept the back event, but worst of all might be the unlikely, but seen in the wild, menu transitioning to two different menus at the same time. Sometimes the menu may transition due to external forces, and if there is player input captured in a different thread of execution, the game state can become disjoint and unresponsive. Consider a network game's lobby, where if everyone is ready to play, but the host of the game disconnects while you are entering into the options screen prior to game launch, in a traditional state-machine like approach to menus, where should the player return to once they exit the options screen? The lobby would normally have dropped you back to a server search screen, but in this case, the lobby has gone away to be replaced with nothing. This is where having simple axes instead of state machines can prove to be simpler to the point of being less buggy and more responsive.
Collective lodding - or how to reduce your instance count.
It's an ugly term, and I hope one day someone comes up with a better one, but it's a technique that didn't need a name until people stopped doing it. Over the time it has taken to write this book, games have started to have too many instances. We're not talking about games that have hundreds of enemy spacecraft, battling each other in a desperate fight for superiority, firing off missile after missile, generating visual effects which spawn multiple GPU particles. We're talking about simple seeming games. We're talking about your average gardening simulator, where for some reason, every leaf on your plants is modeled as an instance, and every insect going around pollinating is an instance, and every plot of land in which your plants can grow is an instance, and every seed you sew is an instance, and each have their own lifetimes, components, animations, and their own internal state adding to the ever-growing complexity of the system as a whole.
I have a fictional farming game, where I harvest wheat. I have a field which is 100 by 100 tiles, each with wheat growing. In some games, those wheat tiles would be instances, and the wheat on the tiles would be instances too. There's little reason for this, as we can reduce the field down to some very small data. What do we actually need to know about the field and the wheat? Do we need to know the position of the wheat? We don't, because it's in a tiled grid. Do we need to know if the tile has wheat or not? Yes, but it doesn't need an object instance to tell us that. Do we need an object to render the wheat? It needs to blow in the wind, so don't we need to have it keep track of where it is to blow around and maintain momentum? No, because in almost all cases, cheating at this kind of thing is cheap and believable. Grass rendering works fine without an instance per blade of grass. The right data format for a field full of wheat could be as simple as 10,000 unsigned chars, with zero being no wheat, and values from 1 to 100 being how grown it is. The wheat doesn't have positions. The positions have wheat.
If you have a stack of blocks in Minecraft, you don't have 64 instances in your inventory slot, you just have a type, and a multiple. You have a stack. If you have a stack of plates in a restaurant sim, you don't have 10 plate instances, you have a stack of plates object with an int saying how many plates there currently are.
The underlying principle of this is making sure you have slots in the world, whether hand placed, or generated in a pattern, and keeping track of what's in them, rather than placing things in the world directly. Refer to things by how a stranger would name them. When you ask someone what is in a room, they won't say a sofa, a bookshelf, an armchair, another armchair, a coffee table, a TV stand, more bookshelves. No, they will say furniture. Look at your game from the outside. Use how the players describe what is on screen. Look at how they describe their inventory. Look at how they describe the game, understand their mental model, match that, and you will find a strong correlation to what is taking up the players perception space.
When normalising your data, look at how your rows are aligned to some kind of container. If you have any form of grid, from 1D to 4D, it's worth looking at how you can utilise it. Don't ignore other tesselations, such as triangle grids, or hexagon grids. Hexagon grids, in particular, get a bad name, but they can be represented by a square grid with different traversal functions. Don't give up just because the literal grid is irregular either, in some grid-based games, the centres of the cells are perturbed to give a more natural look, but the game code can be strict grid-based, leading to better solution space, and more likely easier for the player to reason about what they can and can't do.
Richard Fabian 2018-10-08