Re: Convert duration to years?
On 15/01/2017 4:43 PM, Nestor wrote: Hi, I would simply like to get someone's age, but I am a little lost with time and date functions. I can already get the duration, but after reading the documentation it's unclear to me how to convert that into years. See following code: import std.stdio; void getAge(int , int mm, int dd) { import std.datetime; SysTime t1 = SysTime(Date(, mm, dd)); SysTime t2 = Clock.currTime(); writeln(t2 - t1); } int main() { try getAge(1980, 1, 1); catch(Exception e) { writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); } } Notice getAge should return ubyte instead of void, only I haven't been able to find how to do it. Any suggestion would be welcome. Thanks in advance. So I had a go at this and found I struggled looking at "magic" functions and methods. Turns out there is a much simpler answer. int getAge(int , int mm, int dd) { import std.datetime; auto t1 = cast(DateTime)SysTime(Date(, mm, dd)); auto t2 = cast(DateTime)Clock.currTime(); int numYears; while(t2 > t1) { t1.add!"years"(1); numYears++; } return numYears; }
Re: Convert duration to years?
On Sunday, 15 January 2017 at 06:23:56 UTC, Dave Chapman wrote: Does this do what you want? import std.stdio; uint getAge(int , int mm, int dd) { import std.datetime; SysTime t1 = SysTime(Date(, mm, dd)); SysTime t2 = Clock.currTime(); return( (t2.year - t1.year)); } void main() { auto age = getAge(1980, 1, 1); writefln("age is %s", age); } It seems to work, but not very accurately, see variation: import std.stdio; uint getAge() { import std.datetime; SysTime t1 = SysTime(Date(2000, 12, 31)); SysTime t2 = SysTime(Date(2001, 1, 1)); return((t2.year - t1.year)); } void main() { auto age = getAge(); writefln("age is %s", age); } I eventually came up with this, but it seems an ugly hack: import std.stdio; uint getAge(int , ubyte mm, ubyte dd) { ubyte correction; import std.datetime; SysTime t = Clock.currTime(); if (t.month < mm) correction = 1; else if (t.month == mm) correction = (t.day < dd) ? 1 : 0; else correction = 0; return (t.year - - correction); } void main() { try writefln("Edad: %s años.", getAge(1958, 1, 21)); catch(Exception e) { writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); } } Isn't there a built-in function to do this?
Re: Convert duration to years?
On Sunday, 15 January 2017 at 03:43:32 UTC, Nestor wrote: Hi, I would simply like to get someone's age, but I am a little lost with time and date functions. I can already get the duration, but after reading the documentation it's unclear to me how to convert that into years. See following code: import std.stdio; void getAge(int , int mm, int dd) { import std.datetime; SysTime t1 = SysTime(Date(, mm, dd)); SysTime t2 = Clock.currTime(); writeln(t2 - t1); } int main() { try getAge(1980, 1, 1); catch(Exception e) { writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); } } Notice getAge should return ubyte instead of void, only I haven't been able to find how to do it. Any suggestion would be welcome. Thanks in advance. Does this do what you want? import std.stdio; uint getAge(int , int mm, int dd) { import std.datetime; SysTime t1 = SysTime(Date(, mm, dd)); SysTime t2 = Clock.currTime(); return( (t2.year - t1.year)); } void main() { auto age = getAge(1980, 1, 1); writefln("age is %s", age); }
Re: Gtkd how to add double value to liststore
On Sunday, 15 January 2017 at 01:36:44 UTC, Ali Çehreli wrote: It looks like ListStore is a collection of 'Value's. Does the following work? setValue(iterator, 1, new Value(price)); Yes it works. Ali bey teşekkürler! :)
Convert duration to years?
Hi, I would simply like to get someone's age, but I am a little lost with time and date functions. I can already get the duration, but after reading the documentation it's unclear to me how to convert that into years. See following code: import std.stdio; void getAge(int , int mm, int dd) { import std.datetime; SysTime t1 = SysTime(Date(, mm, dd)); SysTime t2 = Clock.currTime(); writeln(t2 - t1); } int main() { try getAge(1980, 1, 1); catch(Exception e) { writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); } } Notice getAge should return ubyte instead of void, only I haven't been able to find how to do it. Any suggestion would be welcome. Thanks in advance.
Re: Accessing a function within an object's superclass from the outside
On Saturday, 14 January 2017 at 23:31:53 UTC, Adam D. Ruppe wrote: On Saturday, 14 January 2017 at 21:55:27 UTC, David Zhang wrote: I seem to remember something about using aliases to fix this, but I can't find anything about it either way. So you can alias the names together to merge the overload sets, or at the call site, you can also specify which class's version you want with a dot: cb.ClassA.fun(a, b); // compiles, specifically calls the ClassA method Is this documented anywhere? I had no idea this was a feature.
Re: Gtkd how to add double value to liststore
On 01/14/2017 11:47 AM, Erdem wrote: > void addGoods(string name, double price) > { > TreeIter iterator = createIter(); > setValue(iterator, 0, name); > setValue(iterator, 1, price); > } > } > Error: none of the overloads of 'setValue' are callable using argument > types (TreeIter, int, double), candidates are: > > import/gtk/ListStore.d(273): > gtk.ListStore.ListStore.setValue(TreeIter iter, int column, string value) > import/gtk/ListStore.d(281): > gtk.ListStore.ListStore.setValue(TreeIter iter, int column, int value) > import/gtk/ListStore.d(569): > gtk.ListStore.ListStore.setValue(TreeIter iter, int column, Value value) It looks like ListStore is a collection of 'Value's. Does the following work? setValue(iterator, 1, new Value(price)); https://github.com/gtkd-developers/GtkD/blob/3e18afcc5f0b970db1ed042c3818cafebccb35bb/src/gobject/Value.d#L48 Ali
Re: Accessing a function within an object's superclass from the outside
On Saturday, 14 January 2017 at 21:55:27 UTC, David Zhang wrote: I seem to remember something about using aliases to fix this, but I can't find anything about it either way. So you can alias the names together to merge the overload sets, or at the call site, you can also specify which class's version you want with a dot: cb.ClassA.fun(a, b); // compiles, specifically calls the ClassA method
Re: Accessing a function within an object's superclass from the outside
Templates are not virtual. Depending the interface, a different function is called: import std.stdio; class ClassA { void fun(T)(T a) { writeln("ClassA"); } } class ClassB: ClassA { void fun(uint a) { writeln("ClassB"); } } void main() { auto cb = new ClassB(); ClassA ca = cb; uint a = 42; ca.fun(a);// calls ClassA.fun cb.fun(a);// calls ClassB.fun } Ali
Re: Accessing a function within an object's superclass from the outside
On Saturday, 14 January 2017 at 22:38:15 UTC, David Zhang wrote: On Saturday, 14 January 2017 at 22:17:23 UTC, ketmar wrote: class ClassB: ClassA { alias fun = super.fun; override void fun(uint a) {} } I tried that, but it seems to think I mean to override super.fun(uint) instead of super.fun(uint, float). ahem? `void fun(uint a)` == `void fun(uint a)` `void fun(uint a)` != `void fun(uint, float)` of course, you mean to override `void fun(uint a)` with this code.
Re: Accessing a function within an object's superclass from the outside
On Saturday, 14 January 2017 at 22:17:23 UTC, ketmar wrote: class ClassB: ClassA { alias fun = super.fun; override void fun(uint a) {} } I tried that, but it seems to think I mean to override super.fun(uint) instead of super.fun(uint, float). Looking at my code again, one of them is templated with a range interface. I think that might be the problem, though I can't figure out how to fix it. Wrapping the alias in a template block doesn't seem to do it.
Re: Accessing a function within an object's superclass from the outside
On Saturday, 14 January 2017 at 21:55:27 UTC, David Zhang wrote: Hello, Say I have a class, and it overrides a function from its superclass. However, the superclass has two overloaded versions of the same function. My intent is to override only one of the functions, but the second is rendered inaccessible from outside of the class. How can I make the overloaded function visible? ie: class ClassA { void fun(uint a) {} void fun(uint a, float b) {} } class ClassB: ClassA { void fun(uint a) {} } ca.fun(a); //ok ca.fun(a, b);//ok cb.fun(a); //ok cb.fun(a, b);//function fun not callable with uint and float I seem to remember something about using aliases to fix this, but I can't find anything about it either way. class ClassB: ClassA { alias fun = super.fun; override void fun(uint a) {} }
Accessing a function within an object's superclass from the outside
Hello, Say I have a class, and it overrides a function from its superclass. However, the superclass has two overloaded versions of the same function. My intent is to override only one of the functions, but the second is rendered inaccessible from outside of the class. How can I make the overloaded function visible? ie: class ClassA { void fun(uint a) {} void fun(uint a, float b) {} } class ClassB: ClassA { void fun(uint a) {} } ca.fun(a); //ok ca.fun(a, b);//ok cb.fun(a); //ok cb.fun(a, b);//function fun not callable with uint and float I seem to remember something about using aliases to fix this, but I can't find anything about it either way.
Re: switch to member
On Saturday, 14 January 2017 at 16:05:33 UTC, Ignacious wrote: Go join the Nazi Youth group, you OSS Sympathizer! What?
Re: Converting from DirIterator to string[] without a loop
On Saturday, 14 January 2017 at 01:02:38 UTC, Ali Çehreli wrote: On 01/13/2017 04:29 PM, Dave Chapman wrote: > When I use auto and print out the type of b it is something like > args.main.FilterResult!(__lambda2, DirIterator).FilterResult and for the > "if" version of > b and args.main.FilterResult!(__lambda3, DirIterator).FilterResult for > the "else" version > so they are really different types. The solution for that case is to use std.range.choose: auto b = choose(some_condition, all.filter!(f => baseName(f.name) == "file_name.txt"), all.filter!(f => (f.name.endsWith(".d") ))); but I get the following error with DMD64 D Compiler v2.072.1: Error: no property '__postblit' for type 'FilterResult!(__lambda2, DirIterator)', did you mean '__xpostblit'? So, I put .array after both expressions below. The idiomatic way for what you're looking for is std.array.array (which is also exposed through std.range): import std.stdio; import std.file; import std.algorithm; import std.range; import std.path; void main(string[] args) { bool some_condition = (args.length > 1) && (args[1] == "foo"); auto all = dirEntries("directory", SpanMode.shallow); auto b = choose(some_condition, all.filter!(f => baseName(f.name) == "file_name.txt").array, all.filter!(f => (f.name.endsWith(".d") )).array); writeln(b); } However, in most cases keeping 'b' as a lazy algorithm is sufficient. Unless you really need an array e.g. for sorting, you can use std.algorithm.each (or map, etc.). (Not applicable in this case because of the error I mentioned above.) Ali Thank you very much. I had a little trouble getting it working. It was acting as if both halves of the "choose" expression were always getting executed and the first half was making the contents of "all" empty and so the array b was always empty if I used the second half of the choose statement. I made a second copy of "all" and used it in the second half of the choose statement and then it worked. Like this: auto all = dirEntries("directory", SpanMode.shallow); auto all_2 = dirEntries("directory", SpanMode.shallow); auto b = choose(some_condition, all.filter!(f => (baseName(f.name) == requested_file)).array, all_2.filter!(f => (f.name.endsWith(".html") )).array); Note that I am really using requested_file instead of "file_name.txt" and ".html" instead of ".d" which is different than what I told you before just in case that matters. I am using Mac OS X 10.11.5 and dmd version 2.072.2 Thanks again for the help, Dave
Gtkd how to add double value to liststore
I would like to pass some double value to ListStore's constructor but it doesn't allows me to do. import gtk.Main; import gtk.MainWindow; import gtk.Box; import gtk.ListStore; import gtk.TreeView; import gtk.TreeViewColumn; import gtk.TreeIter; import gtk.CellRendererText; class MyWindow: MainWindow { Box mainBox; this() { super("Tree view exercise"); setBorderWidth(10); mainBox = new Box(Orientation.HORIZONTAL, 0); add(mainBox); showAll(); } } class InfoModel: ListStore /* model */ { this() { super([GType.STRING, GType.DOUBLE]); } void addGoods(string name, double price) { TreeIter iterator = createIter(); setValue(iterator, 0, name); setValue(iterator, 1, price); } } class DisplayModel: TreeView /* view */ { TreeViewColumn articleColumn; TreeViewColumn priceColumn; this (ListStore model) { articleColumn = new TreeViewColumn("Article", new CellRendererText(), "text", 0); } } void main(string[] args) { Main.init(args); new MyWindow(); Main.run(); } When I try to compile this program it gives this error message: Error: none of the overloads of 'setValue' are callable using argument types (TreeIter, int, double), candidates are: import/gtk/ListStore.d(273): gtk.ListStore.ListStore.setValue(TreeIter iter, int column, string value) import/gtk/ListStore.d(281): gtk.ListStore.ListStore.setValue(TreeIter iter, int column, int value) import/gtk/ListStore.d(569): gtk.ListStore.ListStore.setValue(TreeIter iter, int column, Value value) Also is it possible to round this double to 2 decimal places when presenting data with GtkTreeView.
Re: Android Status
On Wednesday, 11 January 2017 at 21:13:07 UTC, Ignacious wrote: On Wednesday, 11 January 2017 at 03:49:42 UTC, Joakim wrote: On Tuesday, 10 January 2017 at 18:48:17 UTC, Ignacious wrote: [...] It's probably not easier, and in any case, android-x86 won't be supported, largely because I don't have any working x86 devices. [...] Ok, well the x86 thing wasn't my idea! It seems I was using the wrong build command for trying to compile the examples. In any case, I'll just wait until things get working a bit better. I'd suggest you put, in the title of the page, a bit more information. I didn't realize I was looking at an old version(which looks too similar to the new one). I am currently preparing a repository on dockerhub which contains the newest ldc with android support and the Android NDK. While these two applications run in a container you only have to install the Android SDK on your host machine. The dockerfile is in an early state, I will create an anouncememt when it is finished. You can already have a look https://hub.docker.com/r/andre2007/ldc-android/ Kind regards Andre
Re: Referring to array element by descriptive name
On 01/14/2017 07:11 AM, albert-j wrote: > Is it possible to refer to an array element by a descriptive name, just > for code clarity, without performance overhead? E.g. > > void aFunction(double[] arr) { > double importantElement = arr[3]; > ... use importantElement ... > } > > But the above, I suppose, introduces an extra copy operation? > I've used nested functions before. Compiled with -O -inline -boundscheck=off even dmd produces exact code for the following three access methods: import std.stdio; void aFunction(double[] arr) { ref importantElement() { return arr[3]; } writeln("Indexed element : ", arr[3]); writeln("importantElement: ", importantElement); double originalIdea = arr[3]; writeln("Original idea : ", originalIdea); } void main() { } Here are the three calls; comments added by me. The only difference is RCX vs. RAX for one of the calls: .text._D6deneme9aFunctionFAdZv segment assume CS:.text._D6deneme9aFunctionFAdZv _D6deneme9aFunctionFAdZv: pushRBP mov RBP,RSP sub RSP,010h mov -010h[RBP],RDI mov -8[RBP],RSI ; arr[3] mov EDX,offset FLAT:_TMP0@32 mov EDI,012h mov RSI,RDX mov RAX,-8[RBP] movsd XMM0,018h[RAX] call _D3std5stdio18__T7writelnTAyaTdZ7writelnFNfAyadZv@PC32 ; importantElement: mov EDX,offset FLAT:_TMP0@32 mov EDI,012h mov RSI,RDX mov RCX,-8[RBP] movsd XMM0,018h[RCX] call _D3std5stdio18__T7writelnTAyaTdZ7writelnFNfAyadZv@PC32 ; originalIdea: mov EDX,offset FLAT:_TMP0@32 mov EDI,012h mov RSI,RDX mov RAX,-8[RBP] movsd XMM0,018h[RAX] call _D3std5stdio18__T7writelnTAyaTdZ7writelnFNfAyadZv@PC32 mov RSP,RBP pop RBP ret 0f1f add byte ptr [RAX],0 add [RAX],AL .text._D6deneme9aFunctionFAdZv ends Ali
Re: writeln and ~
On Saturday, 14 January 2017 at 17:42:05 UTC, Ignacious wrote: Why can't string concatenation automatically try to convert the arguments? Is there any reason this is bad behavior? Somehow I think that everything implicitly converting to a string seems like a bad idea. Although writefln and writeln using ,'s seems like better ideas than some minor JavaScript convenience.
Re: Referring to array element by descriptive name
On Saturday, 14 January 2017 at 15:11:40 UTC, albert-j wrote: Is it possible to refer to an array element by a descriptive name, just for code clarity, without performance overhead? E.g. void aFunction(double[] arr) { double importantElement = arr[3]; ... use importantElement ... } But the above, I suppose, introduces an extra copy operation? Is the array always a fixed size? Or what? I wonder since you might get away with a union, or a struct that simply redirects the information appropriately. However it's a lot of writing for very little benefit at all. But honestly for as little loss you'll get of copying the one element and then copying it back (maybe if you change it) I doubt it will mean much if you just ignore trying to do a 0-cost aliasing as you are trying to do. You'd have to be doing it millions of times for such a copy to be noticeable.
Re: writeln and ~
On Saturday, 14 January 2017 at 17:42:05 UTC, Ignacious wrote: writeln(x ~ " ok"); Just write writeln(x, " ok"); Any number of arguments, no unnecessary allocations. Do you really need ~?
Re: writeln and ~
On Saturday, 14 January 2017 at 17:42:05 UTC, Ignacious wrote: Why can't string concatenation automatically try to convert the arguments? Is there any reason this is bad behavior? You'd be liable to write buggy stuff like appending the wrong kind of array since the auto conversion was wrong. How bout then having writeln parse the arguments as a string(take an alias or something first) and then automatically convert them? writeln already knows how to convert. There's also a std.conv.text function that returns the string instead of printing it. http://dpldocs.info/experimental-docs/std.conv.text.html
writeln and ~
string concatenation is weird. We can do stuff like writeln(x); where x is, say a struct and it prints fine but when we do writeln(x ~ " ok"); it fails and requires us to convert x! Why can't string concatenation automatically try to convert the arguments? Is there any reason this is bad behavior? How bout then having writeln parse the arguments as a string(take an alias or something first) and then automatically convert them? Seems like there is no real excuse to add such obfuscation... Obviously I can roll my own but that is not an acceptable answer.
Re: switch to member
On Saturday, 14 January 2017 at 11:32:10 UTC, Marc Schütz wrote: You can utilize a little-known `switch` syntax trick in combination with `foreach`. Because a `foreach` over tuples is unrolled at compile time, it works even if your fields don't have exactly the same types: -- struct Foo { int x, y; long a, b, c; short i, j, k; } enum Which { x, y, a, b, c, i, j, k, } void assignValue(ref Foo q, Which member, short e) { import std.traits : EnumMembers; import std.conv : to; final switch(member) { // foreach over a tuple is unrolled at compile time foreach(w; EnumMembers!Which) { case w: // expands to: q.x, q.y, ... mixin("q." ~ w.to!string) = e; break; } } } void main() { import std.stdio : writeln; Foo q; writeln("before: ", q); assignValue(q, Which.a, 42); assignValue(q, Which.x, 1); writeln("after: ", q); } Cool, pretty straightforward and somewhat easy to use. I suppose it might be easier to mark the enum members with an attribute though and use that rather than having two enums? I didn't know about the foreach in the switch, cool idea! Thanks.
Re: switch to member
On Saturday, 14 January 2017 at 08:30:04 UTC, Meta wrote: On Saturday, 14 January 2017 at 05:29:49 UTC, Nicholas Wilson wrote: enum XX { X = Q.X.offsetof, Y = Q.Y.offsetof //ect. } and then *(cast(void*)(this) + x) = e; //if inside struct/class or *(cast(void*)(q) + x) = e; // if outside Unfortunately this loses you `@safe`ty, but as long as you trust the value of x then it should be safe to `@trusted` that code. If you are trying to avoid code duplication the enum declaration of X could also be done with a string mixin. IMO this is massive overkill to save some typing. To the OP, it's not really worth it to go to so much trouble. Just write some slightly duplicated code and move on. Go join the Nazi Youth group, you OSS Sympathizer!
Re: Referring to array element by descriptive name
On Saturday, 14 January 2017 at 15:11:40 UTC, albert-j wrote: Is it possible to refer to an array element by a descriptive name, just for code clarity, without performance overhead? E.g. void aFunction(double[] arr) { double importantElement = arr[3]; ... use importantElement ... } But the above, I suppose, introduces an extra copy operation? Unless the item type of that array is a complex like a big struct, copying basic types won't have much effect at all. You wouldn't notice it. You could point to that element with a pointer: double* importantElement = &arr[3]; But then you are going to define that pointer variable anyway. On top of that, for every access, instead of using the available data, CPU would look at the pointed memory address to get the value again and again (ignoring the cache).
Referring to array element by descriptive name
Is it possible to refer to an array element by a descriptive name, just for code clarity, without performance overhead? E.g. void aFunction(double[] arr) { double importantElement = arr[3]; ... use importantElement ... } But the above, I suppose, introduces an extra copy operation?
Re: switch to member
On Saturday, 14 January 2017 at 11:32:10 UTC, Marc Schütz wrote: You can utilize a little-known `switch` syntax trick in combination with `foreach`. Because a `foreach` over tuples is unrolled at compile time, it works even if your fields don't have exactly the same types: That looks concise. Perhaps enum Which can also be automatically filled by __traits (allMembers) or std.traits.Fields if needed.
Re: switch to member
On Saturday, 14 January 2017 at 03:20:24 UTC, Ignacious wrote: switch(x) { case X: q.X = e; break; case Y: q.Y = e; break etc... } Do you mean that verbatim? Or are the case values strings, like: switch(x) { case "foo": q.foo = e; break; case "bar": q.bar = e; break } I imagine one could write a string mixin that generates the cases and assignments but I'm hoping for a more elegant solution. In any case, I also can imagine a mixin answer, but not much better. Unless you want to actually look at the broader picture and maybe redesign the surrounding code to somehow cleverly get rid of the switch altogether. The question as it is however doesn't give the context to make it possible. Ivan Kazmenko.
Re: switch to member
You can utilize a little-known `switch` syntax trick in combination with `foreach`. Because a `foreach` over tuples is unrolled at compile time, it works even if your fields don't have exactly the same types: -- struct Foo { int x, y; long a, b, c; short i, j, k; } enum Which { x, y, a, b, c, i, j, k, } void assignValue(ref Foo q, Which member, short e) { import std.traits : EnumMembers; import std.conv : to; final switch(member) { // foreach over a tuple is unrolled at compile time foreach(w; EnumMembers!Which) { case w: // expands to: q.x, q.y, ... mixin("q." ~ w.to!string) = e; break; } } } void main() { import std.stdio : writeln; Foo q; writeln("before: ", q); assignValue(q, Which.a, 42); assignValue(q, Which.x, 1); writeln("after: ", q); }
Re: switch to member
On Saturday, 14 January 2017 at 05:29:49 UTC, Nicholas Wilson wrote: enum XX { X = Q.X.offsetof, Y = Q.Y.offsetof //ect. } and then *(cast(void*)(this) + x) = e; //if inside struct/class or *(cast(void*)(q) + x) = e; // if outside Unfortunately this loses you `@safe`ty, but as long as you trust the value of x then it should be safe to `@trusted` that code. If you are trying to avoid code duplication the enum declaration of X could also be done with a string mixin. IMO this is massive overkill to save some typing. To the OP, it's not really worth it to go to so much trouble. Just write some slightly duplicated code and move on.