Re: how to count number of letters with std.algorithm.count / std.algorithm.reduce / std.algorithm.map ?
On Nov 16, 2012, at 7:49 AM, bioinfornatics wrote: > hi, > > I would like to count number of one ore more letter into a string or list of > string (string[]) without use a for loop but instead using std.algorithm to > compute efficiently. > > if you have: > string seq1 = "ACGATCGATCGATCGCGCTAGCTAGCTAG"; > string[] seq2 = ["ACGATCGATCGATCGCGCTAGCTAGCTAG", "ACGATGACGATCGATGCTAGCTAG"]; > > i try : > > reduce!( (seq) => seq.count("G"), seq.count("C"))(tuple(0LU,0LU),seq1) D has map and reduce but not MapReduce, so this approach feels a bit unnatural. Assuming ASCII characters and a reasonably sized sequence, here's the simplest approach: auto seq1 = cast(byte[])("ACGATCGATCGATCGCGCTAGCTAGCTAG".dup); foreach(e; group(sort(seq1))) { writefln("%s occurs %s times", cast(char) e[0], e[1]); } For real code, the correct approach really depends on the number of discrete values, how dense the set of values is, and the total number of elements to evaluate. For English letters the fastest result is likely an int[26]. For a more diverse set of input, a hash table. For a huge input size, something like MapReduce is appropriate.
Re: Converting a number to complex
On Friday, 23 November 2012 at 18:45:53 UTC, Artur Skawina wrote: template isComplex(T) { static if (is(T _ == Complex!CT, CT)) enum isComplex = true; else enum isComplex = false; } artur oh wow didnt know u could do that. much nicer.
Re: Can I call the default opAssign after overloading opAssign?
On Monday, 19 November 2012 at 12:10:32 UTC, Dan wrote: [...] provide it - you do not need an opAssign at all, as your postblit will be called. I think this is a step up over C++. The example below prints: -- Begin assign postblit A End assign -- import std.stdio; import std.traits; struct A { this(this) { c = c.dup; writeln("postblit A"); } char[] c; } struct B { A a; } struct C { B b; } struct D { C c; } void main() { D d1, d2; d1.c.b.a.c = ['a','b','c']; writeln("Begin assign"); d2 = d1; writeln("End assign"); } That's VERY interesting indeed and originally I had no idea it would do this without a custom opAssign at each level. This kind of behavior *really* needs to be documented in precise detail, it's rather critical to know. --rt
Re: Can I call the default opAssign after overloading opAssign?
On Monday, 19 November 2012 at 12:10:32 UTC, Dan wrote: Just following up to get confirmation. Hopefully Johnathan or similar expert can follow up. Here is a strong statement: If for any struct S you implement a postblit then there is no need to implement opAssign to get a working assignment operator from a type S because by design postblit is already called by default opAssign. This is the behavior I see, but I may be missing something since the language specification does not mention postblit, only blit. Thanks Dan On Monday, 19 November 2012 at 05:22:38 UTC, Jonathan M Davis wrote: On Monday, November 19, 2012 06:01:55 Rob T wrote: postblit constructors and opAssign aren't really related. The postblit constructor is used when a _new_ instance is being constructed (it plays the same role as a copy constructor in C++). opAssign overloads the assignment operator and is only used when the assignment operator is used, which does _not_ happen when contstructing a new instance but only when replacing the value of an instance with that of another. Is this correct? From a implementation point of view it looks like opAssign is related to postblit in that it does call postblit first. From the spec: Struct assignment t=s is defined to be semantically equivalent to: t = S.opAssign(s); where opAssign is a member function of S: S* opAssign(S s) { ... bitcopy *this into tmp ... ... bitcopy s into *this ... ... call destructor on tmp ... return this; } It does not say postblit as well, but it does call it. When assigning one object into another it will first blit, then custom postblit if you have written one. A benefit of this is, if you want deep copy semantics and postblit does the work to provide it - you do not need an opAssign at all, as your postblit will be called. I think this is a step up over C++. The example below prints: -- Begin assign postblit A End assign -- import std.stdio; import std.traits; struct A { this(this) { c = c.dup; writeln("postblit A"); } char[] c; } struct B { A a; } struct C { B b; } struct D { C c; } void main() { D d1, d2; d1.c.b.a.c = ['a','b','c']; writeln("Begin assign"); d2 = d1; writeln("End assign"); }
Re: sort associative array by key
On 11/23/2012 07:48 PM, dsmith wrote: On Friday, 23 November 2012 at 18:24:07 UTC, Timon Gehr wrote: On 11/23/2012 07:09 PM, dsmith wrote: What is the best way to have a function sort an associative array by key? The following yields a conversion error. double[string] aa_sort(double[string] aa) { return aa.keys.sort; } A hash table is unsorted by definition. What is it that you want to do exactly? The following will generate a newly allocated dynamic array of key-value pairs, sorted by key: import std.algorithm, std.typecons; Tuple!(string, double)[] aa_sort(double[string] aa){ typeof(return) r=[]; foreach(k,v;aa) r~=tuple(k,v); sort!q{a[0] Suppose the string is of the format 201207, 21208, ... So aa["201207"] == 123.45 How do you parse the tuple for the key and the value? tpl[0] is the key and tpl[1] is the value in this case.
Re: Can functions add properties?
On Friday, 23 November 2012 at 14:08:05 UTC, Jun wrote: I've never seen any documentation about this behaviour. I think it's a good feature, but I'm a bit confused. More info here http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394 UFCS is relatively new and has not been included in the language documentation yet. It was added to the language only a few months ago with the dmd 2.059 release. IMO it should be in the docs by now, and I think that's a problem area being worked (I hope). --rt
Re: sort associative array by key
On Friday, 23 November 2012 at 18:24:07 UTC, Timon Gehr wrote: On 11/23/2012 07:09 PM, dsmith wrote: What is the best way to have a function sort an associative array by key? The following yields a conversion error. double[string] aa_sort(double[string] aa) { return aa.keys.sort; } A hash table is unsorted by definition. What is it that you want to do exactly? The following will generate a newly allocated dynamic array of key-value pairs, sorted by key: import std.algorithm, std.typecons; Tuple!(string, double)[] aa_sort(double[string] aa){ typeof(return) r=[]; foreach(k,v;aa) r~=tuple(k,v); sort!q{a[0] Suppose the string is of the format 201207, 21208, ... So aa["201207"] == 123.45 How do you parse the tuple for the key and the value?
Re: Converting a number to complex
On 11/23/12 18:06, Joshua Niehus wrote: > meh, couldn't resist: > > import std.stdio, std.conv, std.traits, std.complex; > template isComplex(T) > { > static if (is(T == Complex!double)) > { > enum bool isComplex = true; > } > else static if (is(T == Complex!float)) > { > enum bool isComplex = true; > } > else static if (is(T == Complex!real)) > { > enum bool isComplex = true; > } > else { > enum bool isComplex = false; > } > } template isComplex(T) { static if (is(T _ == Complex!CT, CT)) enum isComplex = true; else enum isComplex = false; } artur
Re: sort associative array by key
On 11/23/2012 07:09 PM, dsmith wrote: What is the best way to have a function sort an associative array by key? The following yields a conversion error. double[string] aa_sort(double[string] aa) { return aa.keys.sort; } A hash table is unsorted by definition. What is it that you want to do exactly? The following will generate a newly allocated dynamic array of key-value pairs, sorted by key: import std.algorithm, std.typecons; Tuple!(string, double)[] aa_sort(double[string] aa){ typeof(return) r=[]; foreach(k,v;aa) r~=tuple(k,v); sort!q{a[0]
Re: sort associative array by key
On 11/23/12, dsmith wrote: > What is the best way to have a function sort an associative array > by key? The following yields a conversion error. > > double[string] aa_sort(double[string] aa) { >return aa.keys.sort; > } Hashes are unordered, you can't sort them by key because they don't preserve any order during insertion/removal. You can alternatively return a sorted array: string[] keys_sorted(double[string] aa) { string[] keys = aa.keys; sort(keys); // from std.algorithm; return keys; }
sort associative array by key
What is the best way to have a function sort an associative array by key? The following yields a conversion error. double[string] aa_sort(double[string] aa) { return aa.keys.sort; }
Re: Converting a number to complex
meh, couldn't resist: import std.stdio, std.conv, std.traits, std.complex; template isComplex(T) { static if (is(T == Complex!double)) { enum bool isComplex = true; } else static if (is(T == Complex!float)) { enum bool isComplex = true; } else static if (is(T == Complex!real)) { enum bool isComplex = true; } else { enum bool isComplex = false; } } template isComplexOrNumeric(T) { enum bool isComplexOrNumeric = (isComplex!T || isNumeric!T); } class Example(T) if (isComplexOrNumeric!T) { T k = to!T(1); }
Re: Converting a number to complex
On Friday, 23 November 2012 at 16:11:25 UTC, Joshua Niehus wrote: A bit messy, but im sure there is some room for cleanup somewhere... Errata... (what i get for copy/pasting) import std.stdio, std.conv, std.traits, std.complex; template isComplexNumeric(T) { static if(isNumeric!T) { enum bool isComplexNumeric = true; } else static if (is(T == Complex!double)) { enum bool isComplexNumeric = true; } else { enum bool isComplexNumeric = false; } } class Example(T) if (isComplexNumeric!T) { T k = to!T(1); } void main() { auto x = new Example!(Complex!double)(); writeln(x.k); auto y = new Example!double(); writeln(y.k); auto z = new Example!string(); writeln(z.k); } i did have to reference Philippe Sigaud's excellent book on Templates several times: https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf
Re: Converting a number to complex
On Friday, 23 November 2012 at 12:39:59 UTC, Frederik Vagner wrote: Now do it for complex number please ^^ touche! import std.stdio, std.conv, std.traits, std.complex; template isComplexNumeric(T) { static if(is(NumericTypeOf!T)) { enum bool isComplexNumeric = is(NumericTypeOf!T); } else static if (is(T == Complex!double)) { enum bool isComplexNumeric = is(Complex!double); } // fillin real and float here... (e.g. is(Complex!real); etc... } class Example(T) if (isComplexNumeric!T) { T k = to!T(1); } void main() { auto x = new Example!(Complex!double)(); writeln(x.k); auto y = new Example!double(); writeln(y.k); auto z = new Example!string(); // fail writeln(z.k); } A bit messy, but im sure there is some room for cleanup somewhere...
Re: Complex C typedef decl replacement
On Friday, 23 November 2012 at 15:07:05 UTC, Andrey wrote: Thank you much! If you're doing this to use OpenGL in D, rather than as a learning exercise, you can save yourself a lot of pain by using Derelict. https://github.com/aldacron/Derelict3/
Re: Complex C typedef decl replacement
Thank you much!
Re: Can functions add properties?
On Friday, 23 November 2012 at 14:08:05 UTC, Jun wrote: I found some codes write toStringz(myString) as mystring.toStringz So I tested this code myself and it worked. int pow2(int i) { return i*i; } int myint = 5; int otherint = myint.pow2; assert(otherint == 25); FYI, you could even do this: int otherint = 5.pow2; I've never seen any documentation about this behaviour. I think it's a good feature, but I'm a bit confused. It's called Universal Function Call Syntax (UFCS). The compiler essentially rewrites something.function to function(something), unless "something" is a struct or class with a method named "function", in which case it calls the method instead.
Re: Complex C typedef decl replacement
On Friday, 23 November 2012 at 14:22:11 UTC, Jacob Carlborg wrote: On 2012-11-23 14:26, Andrey wrote: Hello everyone! What a proper replacement is for C declarations like this? typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); I would guess that APIENTRYP and PFNGLGETCOMPRESSEDTEXIMAGEPROC are macros. You first have to look up what those evaluate to. This is probably a function pointer. typedef GLvoid (APIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); extern(System) alias void function(GLenum, GLint, GLvoid*) PFNGLGETCOMPRESSEDTEXIMAGEPROC; extern(System) alias void function(GLenum, const(GLint)*, const(GLsizei)*, GLsizei) PFNGLMULTIDRAWARRAYSPROC; So to make an alias to the above function pointer, it would look like this: extern (C) void function () _GLUfuncptr; Should likely be extern(System), as OpenGL & GLU are extern(Windows) on Windows and extern(C) everywhere else.
Re: Complex C typedef decl replacement
Thank you for the reply. I guess, I should have added this before. #if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) # if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ #define GLAPI __declspec(dllexport) # elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ #define GLAPI __declspec(dllimport) # else /* for use with static link lib build of Win32 edition only */ #define GLAPI extern # endif /* _STATIC_MESA support */ # if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ #define GLAPIENTRY # else #define GLAPIENTRY __stdcall # endif #elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ # define GLAPI extern # define GLAPIENTRY __stdcall #elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define GLAPI __attribute__((visibility("default"))) # define GLAPIENTRY #endif /* WIN32 && !CYGWIN */ #if (defined(__BEOS__) && defined(__POWERPC__)) || defined(__QUICKDRAW__) # define PRAGMA_EXPORT_SUPPORTED 1 #endif /* * WINDOWS: Include windows.h here to define APIENTRY. * It is also useful when applications include this file by * including only glut.h, since glut.h depends on windows.h. * Applications needing to include windows.h with parms other * than "WIN32_LEAN_AND_MEAN" may include windows.h before * glut.h or gl.h. */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif #include #endif #if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED #pragma import on #endif #ifndef GLAPI #define GLAPI extern #endif #ifndef GLAPIENTRY #define GLAPIENTRY #endif #ifndef APIENTRY #define APIENTRY GLAPIENTRY #endif /* "P" suffix to be used for a pointer to a function */ #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif Anyway, I don't understand C macro magic much and can't figure out, what exactly they do. Even if I process the macros, what should I expect from those typedefs? Simple functions?
Re: Complex C typedef decl replacement
On 2012-11-23 14:26, Andrey wrote: Hello everyone! What a proper replacement is for C declarations like this? typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); I would guess that APIENTRYP and PFNGLGETCOMPRESSEDTEXIMAGEPROC are macros. You first have to look up what those evaluate to. This is probably a function pointer. typedef GLvoid (APIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); Same as above. And this: void glAlphaFunc( GLenum func, GLclampf ref ); //ref is not acceptable as var name in D Just use a difference name, like ref_, the parameter names doesn't matter when creating bindings. alias void (* _GLUfuncptr)(); //how to make a proper aliasing of a function pointer? A function pointer in D looks like: void function () foo; So to make an alias to the above function pointer, it would look like this: extern (C) void function () _GLUfuncptr; Take a look at DStep, a tool for automatically converting C headers to D modules: https://github.com/jacob-carlborg/dstep -- /Jacob Carlborg
Can functions add properties?
I found some codes write toStringz(myString) as mystring.toStringz So I tested this code myself and it worked. int pow2(int i) { return i*i; } int myint = 5; int otherint = myint.pow2; assert(otherint == 25); I've never seen any documentation about this behaviour. I think it's a good feature, but I'm a bit confused.
Complex C typedef decl replacement
Hello everyone! What a proper replacement is for C declarations like this? typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); typedef GLvoid (APIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); And this: void glAlphaFunc( GLenum func, GLclampf ref ); //ref is not acceptable as var name in D alias void (* _GLUfuncptr)(); //how to make a proper aliasing of a function pointer?
Re: Converting a number to complex
On Thursday, 22 November 2012 at 16:09:46 UTC, Joshua Niehus wrote: On Thursday, 22 November 2012 at 15:47:11 UTC, Frederik Vagner wrote: I am trying to make a templated class to accept any numeric type: class example(Type) if (isNumeric(Type)) { Type k = to!Type(1); } however I always get a compiler erro stating I cannot make that conversion. How do I fix it? // phobos import std.stdio, std.conv, std.traits; class Example(T) if (isNumeric!T) { T k = to!T(1); } void main() { auto x = new Example!double(); writeln(x.k); } Now do it for complex number please ^^