How do you get directory listing sorted by date in Elixir?
File.ls/1 gives list sorted by filename only.
No other functions in File module seem relevant for this.
Maybe there's a built-in function I don't know about, but you can make your own by using File.stat!/2:
File.ls!("path/to/dir")
|> Enum.map(&{&1, File.stat!("path/to/dir" <> &1).ctime})
|> Enum.sort(fn {_, time1}, {_, time2} -> time1 <= time2 end)
Example output:
[
{"test", {{2019, 3, 9}, {23, 55, 48}}},
{"config", {{2019, 3, 9}, {23, 55, 48}}},
{"README.md", {{2019, 3, 9}, {23, 55, 48}}},
{"_build", {{2019, 3, 9}, {23, 59, 48}}},
{"test.xml", {{2019, 3, 23}, {22, 1, 28}}},
{"foo.ex", {{2019, 4, 20}, {4, 26, 5}}},
{"foo", {{2019, 4, 21}, {3, 59, 29}}},
{"mix.exs", {{2019, 7, 27}, {8, 45, 0}}},
{"mix.lock", {{2019, 7, 27}, {8, 45, 7}}},
{"deps", {{2019, 7, 27}, {8, 45, 7}}},
{"lib", {{2019, 7, 27}, {9, 5, 36}}}
]
Edit:
As pointed out in a comment, this assumes you're in the directory you want to see the output for. If this is not the case, you can specify it by adding the :cd option, like so:
System.cmd("ls", ["-lt"], cd: "path/to/dir")
You can also make use of System.cmd/3 to achieve this.
Particularly you want to use the "ls" command with the flag "-t" which will sort by modification date and maybe "-l" which will provide extra information.
Therefore you can use it like this:
# To simply get the filenames sorted by modification date
System.cmd("ls", ["-t"])
# Or with extra info
System.cmd("ls", ["-lt"])
This will return a tuple containing a String with the results and a number with the exit status.
So, if you just call it like that, it will produce something like:
iex> System.cmd("ls", ["-t"])
{"test_file2.txt\ntest_file1.txt\n", 0}
Having this, you can do lots of things, even pattern match over the exit code to process the output accordingly:
case System.cmd("ls", ["-t"]) do
{contents, 0} ->
# You can for instance retrieve a list with the filenames
String.split(contents, "\n")
{_contents, exit_code} ->
# Or provide an error message
{:error, "Directory contents could not be read. Exit code: #{exit_code}"
end
If you don't want to handle the exit code and just care about the contents you can simply run:
System.cmd("ls", ["-t"]) |> elem(0) |> String.split("\n")
Notice that this will however include an empty string at the end, because the output string ends with a newline "\n".
title: Lihaoyi PPrint Deep Tree
link: Lihaoyi PPrint Deep Tree
I have a "deep" tree of case classes that I want to pprint as "like Scala" source code.
... because I want to view, copy and paste them to make a UnitTest
I am using lihaoyi's pprint to perform the stringify of the values, BUT after a few levels, pprint stops printing.
I've checked in the tokenize thing and the instance is being emitted as-is; you can see that the strings aren't being excaped.
I can (manually) "tweak" my tests to test parts of the results and get my pretty source, but ... it feels wrong.
Original "Lack of deep" printout
Module(
Set(),
Set(
Material(
"testTextLayoutContainer",
List(
Attribute("Position", VecSingle(2)),
Attribute("UV", VecSingle(2)),
Attribute("Color", VecFixed(4))
),
List(
UniformInstance("ProjMtx", MatSingle(4, 4)),
UniformInstance("Texture", Texture(2, VecFixed(4)))
),
Set(
//
// this is the line that's not being pprinted
//
Program(ImGui,testTextLayoutContainer,Set(Attribute(Color,VecFixed(4)), Attribute(Position,VecSingle(2)), Attribute(UV,VecSingle(2))),Set(UniformInstance(Texture,Texture(2,VecFixed(4))), UniformInstance(ProjMtx,MatSingle(4,4))),Set(VaryingCopy(Attribute(Color,VecFixed(4))), VaryingCopy(Attribute(UV,VecSingle(2)))),List(Lookup(UniformInstance(ProjMtx,MatSingle(4,4))), Lookup(Attribute(Position,VecSingle(2))), Literal(0.0), Literal(1.0), Construct(VecSingle(4),List(Lookup(Attribute(Position,VecSingle(2))), Literal(0.0), Literal(1.0))), External(mat*vec,List(Lookup(UniformInstance(ProjMtx,MatSingle(4,4))), Construct(VecSingle(4),List(Lookup(Attribute(Position,VecSingle(2))), Literal(0.0), Literal(1.0)))),VecSingle(4)), Output(Vertex(ProductTransform(Lookup(UniformInstance(ProjMtx,MatSingle(4,4))),Construct(VecSingle(4),List(Lookup(Attribute(Position,VecSingle(2))), Literal(0.0), Literal(1.0))))),External(mat*vec,List(Lookup(UniformInstance(ProjMtx,MatSingle(4,4))), Construct(VecSingle(4),List(Lookup(Attribute(Position,VecSingle(2))), Literal(0.0), Literal(1.0)))),VecSingle(4))), Lookup(Attribute(Color,VecFixed(4))), Output(VaryingCopy(Attribute(Color,VecFixed(4))),Lookup(Attribute(Color,VecFixed(4)))), Lookup(Attribute(UV,VecSingle(2))), Output(VaryingCopy(Attribute(UV,VecSingle(2))),Lookup(Attribute(UV,VecSingle(2))))),List(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))), Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),x), Lookup(UniformInstance(Texture,Texture(2,VecFixed(4)))), Lookup(VaryingCopy(Attribute(UV,VecSingle(2)))), Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),x), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),x), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),x)),VecFixed(1)), Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),y), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),y), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),y), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),y)),VecFixed(1)), Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),z), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),z), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),z), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),z)),VecFixed(1)), Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),w), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),w), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),w), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),w)),VecFixed(1)), Construct(VecFixed(4),List(External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),x), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),x)),VecFixed(1)), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),y), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),y)),VecFixed(1)), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),z), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),z)),VecFixed(1)), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),w), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),w)),VecFixed(1)))), Output(Fragment(Construct(VecFixed(4),List(ProductAtomic(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),x),Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),x)), ProductAtomic(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),y),Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),y)), ProductAtomic(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),z),Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),z)), ProductAtomic(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),w),Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),w))))),Construct(VecFixed(4),List(External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),x), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),x)),VecFixed(1)), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),y), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),y)),VecFixed(1)), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),z), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),z)),VecFixed(1)), External(*,List(Access(Lookup(VaryingCopy(Attribute(Color,VecFixed(4)))),w), Access(Sample(UniformInstance(Texture,Texture(2,VecFixed(4))),Lookup(VaryingCopy(Attribute(UV,VecSingle(2))))),w)),VecFixed(1)))))))
)
)
)
)
You can provide a height and a width, so if you provide a big enough value it will show it all.
scala> pprint.pprintln(Seq(1, 2, 3), width = Int.MaxValue, height = Int.MaxValue)
so
# pprint.pprintln(1 to 10, 3, 10)
Range.Inclusive(
1,
2...
can be
# pprint.pprintln(1 to 10, Int.MaxValue, Int.MaxValue)
Range.Inclusive(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Edit:
as mentioned in the docs this is a feature to stop out of memory errors when printing really big data structures.
http://www.lihaoyi.com/upickle-pprint/pprint/#GettingStarted
I have to provide some C++ code consisting of const arrays initialised with well-known values.
More precisely, several arrays containing
Between 0 and 255 strings for a text-based user interface
Metadata, like lengths and positions of those strings
Data representing a hierarchical menu structure
Metadata connecting the menu structure with the strings and configuration data stored elsewhere
The menu items are accessed by their index in an array, and are related to other linked menu items, also accessed by index.
Here is the code I want to generate automatically from a better editable document:
/* gl_PsNMenuType holds one byte of metadata for each menu. This byte will describe
whether the menu only refers to a bunch of submenus or if it is a terminal item, where
the user actually can enter a setting to be saved */
const uint8_t gl_PsNMenuType[MAXMENUS] PROGMEM = { 0, 0, 0, 0, 0};
/* gl_PsNMenuParent holds the index of each menu's parent menu. i.e. tree one step up */
const uint8_t gl_PsNMenuParent[MAXMENUS] PROGMEM = { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3}; // referenz auf den übergeordneten MP
/* gl_PsNMenuFixTexts is a list of identifiers text snippets which build the layout of
the respective menu. The text snippets are stored in gl_PsFixTexts and the respective
index of a text snippet is saved here. MFTS is a list sentinel*/
const uint8_t gl_PsNMenuFixTexts[MAXMENUS][MAXFIXTEXTSPM] PROGMEM = {
{ 20, 2, MFTS}, // text snippets for menu 0
{2, 9, 1, MFTS}, // for menu 1
{2, 10, MFTS}, //2
{2, 11, MFTS}, //3
{2, 13, MFTS} //4
};
/* gl_PsNMenuParentListText holds the identifiers of the text snippets which shall be
displayed by the parent menu while selection before descending to the submenus. There's
one such snippet for each menu. */
const uint8_t gl_PsNMenuParentListText[MAXMENUS] PROGMEM = { 0, 9, 10, 11, 13};
/* gl_PsNMenuFtPos closely relates to gl_PsNMenuFixTexts. The positions on the display
for each text snippet of a menu are stored here. */
const uint8_t gl_PsNMenuFtPos[MAXMENUS][MAXFIXTEXTSPM] PROGMEM = { // Liste der Fixtextpositionen
{ 0, 5, MFTS, MFTS, MFTS}, // 0
{ 0, 5, MFTS, MFTS, MFTS}, // 1
{ 0, 5, MFTS, MFTS, MFTS}, // 2
{ 0, 5, MFTS, MFTS, MFTS}, // 3
{ 0, 5, MFTS, MFTS, MFTS}, // 4
};
/* gl_PsNMenuChildren stores the indices of all submenus reachable from a certain menu
this is essentially the structure of the menu tree MAXMENUS is used for array size and
also as sentinel*/
const uint8_t gl_PsNMenuChildren[MAXMENUS][MAXMENUCHILDREN] PROGMEM = {
{ 5, 1, 2, 3, 4, MAXMENUS}, // 0
{ 4, 7, 8, 9, MAXMENUS}, // 1
{1, MAXMENUS}, //2
{1, MAXMENUS}, // 3
{3, 5, 6, MAXMENUS} // 4
};
/* finally the text snippets */
const uint8_t gl_PsFixTexts[MAXFIXTEXTS][MAXFIXTEXTLEN] PROGMEM = {
{5, 0x54, 0x65, 0x73, 0x74, 0x31 }, // 0: Test1
{9, 0x62, 0x6c, 0x61, 0x62, 0x6c, 0x61, 0x62, 0x6c, 0x62 }, // 1: bla
{4, 0x4d, 0x65, 0x6e, 0x75}, // 2: Menu
{4, 0x4d, 0x61, 0x69, 0x6e}, // 20: Main
{4, 0x65, 0x78, 0x69, 0x74}, // 21: exit
{4, 0x62, 0x61, 0x63, 0x6b} // 22: back
};
This is shortened for brevity and dysfunctional in this state.
As the contents of those arrays are exclusively uint8_t characters it would be much simpler to write the data automatically, while ensuring that the referencing indices are all correct.
I want some other data describing the menu structure in a more elaborate but maintainable way.
I thought about making a spreadsheet where I could show the hierarchy across the columns and enter all the data. Then some tool would be needed to break down the hierarchy.
I hope someone can let me know of any tools that are suitable for this task. If there's nothing available then I have to write a Perl conversion program. Are there any useful CPAN libraries?
Edit: some further explanation of the use of the arrays
This data will be utilised by an user interface function, which is rather simplicistic. There will be an identifier pointing to the actual menu entry, which is edited or viewed by the user. This identifier will be used as index wherever MAXMENUS is defining the array size. these arrays describe the look and feel of every menu entry. The menu entries refer to different strings (gl_PsFixTexts) and positions (gl_PsNMenuFtPos) which declare, how and where to display strings when processing a certain menu entry.
The most important arrays are gl_PsNMenuParent and gl_PsNMenuChildren which point to the menu entries above and below in hierarchy. This is, how the code will let the user navigate through the menu structure.
There's also some information if this is an terminal entry in the menu tree, i.e. if there's some data to change, which again means modifying a setting for the software.
Here is my best answer, based on what you have told us.
Menu information like that is commonly stored as XML. An XML data file would allow you to relate menu items to their text labels and their children quite expressively.
In the end you could write a GUI front end that would present that XML in a graphical form and allow you as much facility and complexity as want to write.
In the end, it is the XML file that is the authority on the interface structure, and which can be converted very easily with Perl to any format that you desire.
Also, following on from what #MatsPetersson said in his comment, I would much rather see
{9, 'b', 'l', 'a', 'b', 'l', 'a', 'b', 'l', 'a'}, // 1: blablabla
which is certain to be acceptable to as a uint8_t [] initialiser.
If you want further help then you will have to expand your description with a line-by-line explanation of what your "desired output" means in English.