digitalmars.D.learn - Error while generate DNA with uniform()
- Salih Dincer (39/39) Sep 03 2022 Hi All,
- Steven Schveighoffer (21/48) Sep 03 2022 I'm not sure why this doesn't work. First, I would change your enum to
- =?UTF-8?Q?Ali_=c3=87ehreli?= (9/12) Sep 03 2022 Yes, Generator is missing an Unqual:
- Salih Dincer (33/41) Sep 03 2022 But the bug may be in the templates, not in the structure. Maybe `
- Salih Dincer (27/29) Sep 03 2022 Clean-cut, thank you!
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/6) Sep 03 2022 Even cleaner:
- rassoc (5/7) Sep 03 2022 Nothing major, but instead of `uniform!"[]"(DNA.min, DNA.max)`, you can ...
Hi All, We discovered a bug yesterday and reported it: https://forum.dlang.org/thread/mailman.1386.1662137084.31357.digitalmars-d-bugs puremagic.com You know, there is `generate()` depend to `std.range`. It created the error when we use it with the value of an enum. Which get their values from an `enum DNA`, we have 4 members that we want to generate 32 pieces randomly like this: ```d import std; void main() { enum DNA { timin = 84, sitozin = 67, guanin = 71, adenin = 65 } char[] gene; enum n = 32; auto range = generate!(() => uniform(DNA.min, DNA.max)).take(n);/* auto preferred = generate!(() => uniform!"[]"(DNA.min, DNA.max)).take(n);//*/ foreach (_; 0..n) { gene ~= uniform!"[]"(DNA.min, DNA.max); } gene.writeln; // CGACGTGCTTCATCGATAGGAGCACGAGGAGC // If the ASCII table matches (capital group 64-95) there should be no problem... } ``` If there was no alternative solution, we would generate random numbers between 65 and 84 that have no equivalent in DNA. We want to use "[]" ( closed to the left and right) but preferred version doesn't compile. Can we solve this issue with our own `generate()` structure? SDB 79
Sep 03 2022
On 9/3/22 8:09 AM, Salih Dincer wrote:Hi All, We discovered a bug yesterday and reported it: https://forum.dlang.org/thread/mailman.1386.1662137084.31357.digitalmars- -bugs puremagic.com You know, there is `generate()` depend to `std.range`. It created the error when we use it with the value of an enum. Which get their values from an `enum DNA`, we have 4 members that we want to generate 32 pieces randomly like this: ```d import std; void main() { enum DNA { timin = 84, sitozin = 67, guanin = 71, adenin = 65 } char[] gene; enum n = 32; auto range = generate!(() => uniform(DNA.min, DNA.max)).take(n);/* auto preferred = generate!(() => uniform!"[]"(DNA.min, DNA.max)).take(n);//*/I'm not sure why this doesn't work. First, I would change your enum to this (for correctness and readability): ```d enum DNA : char { timin = 'T', sitozin = 'C', guanin = 'G', adenin = 'A' } ``` There is probably a bug in generate when the element type is an `enum` which somehow makes it const. But what you need anyway is a `char`, so just return a `char`. For that, you need to specify the return type, which requires a different kind of function literal: ```d auto preferred = generate!(function char() => uniform!"[]"(DNA.min, DNA.max)).take(n); ``` That works. -Steve
Sep 03 2022
On 9/3/22 07:25, Steven Schveighoffer wrote:There is probably a bug in generate when the element type is an `enum` which somehow makes it const.Yes, Generator is missing an Unqual: https://issues.dlang.org/show_bug.cgi?id=23319 Salih had asked:Yes, I did the following to determine that adding Unqual was a solution: - Copy generate() functions to your source file, - Copy the Generator struct to your source file, - Edit the definition of Generator's elem_ member as I hinted in the bug. AliCan we solve this issue with our own `generate()` structure?
Sep 03 2022
On Saturday, 3 September 2022 at 21:09:09 UTC, Ali Çehreli wrote:Salih had asked:But the bug may be in the templates, not in the structure. Maybe ` template functionTypeOf(alias func)` For example: ```d auto gen(alias fun)() { auto gen = Gen!fun(); gen.popFront(); return gen; } struct Gen(alias fn) { import std.traits: ReturnType!fn func; enum empty = false; auto front() { return func; } void popFront() { func = fn(); } } unittest { import std.random : uniform; import std.range : takeExactly; enum E { O = '0', P, Q, R, S, T, U, V, W, X, A = 'A', B, C, D, E, F } auto range = gen!(function char() => uniform!"[]"(E.min, E.max)) .takeExactly(15); assert(range.to!long(15) < long.max); } ``` SDB 79Yes, I did the following to determine that adding Unqual was a solution: - Copy generate() functions to your source file, - Copy the Generator struct to your source file, - Edit the definition of Generator's elem_ member as I hinted in the bug.Can we solve this issue with our own `generate()` structure?
Sep 03 2022
On Saturday, 3 September 2022 at 14:25:48 UTC, Steven Schveighoffer wrote:[...] what you need anyway is a `char`, so just return a `char`. [...]Clean-cut, thank you! It's very clear to me... ```d import std; void main() { alias fp = char function() system; enum DNA : char { timin = 'T', sitozin = 'C', guanin = 'G', adenin = 'A' } fp getDNA = () => uniform!"[]"(DNA.min, DNA.max); enum n = 30; auto genes = generate!getDNA.take(n).array; auto unique = genes.uniq.array; // AAAACATCATGGTAGGCCTTTCATGCGCTA assert(unique.length < n, "no repeat"); unique.writeln; // ACATCATGTAGCTCATGCGCTA } ``` SDB 79
Sep 03 2022
On 9/3/22 14:18, Salih Dincer wrote:uniform!"[]"(DNA.min, DNA.max);Even cleaner: uniform!DNA() :) Ali
Sep 03 2022
On 9/3/22 23:18, Salih Dincer via Digitalmars-d-learn wrote:Clean-cut, thank you! It's very clear to me...Nothing major, but instead of `uniform!"[]"(DNA.min, DNA.max)`, you can simply use `uniform!DNA`. `uniform` considers the whole enum: https://github.com/dlang/phobos/blob/v2.100.1/std/random.d#L2561 "Random variate drawn from the uniform distribution across all possible values of the [...] enum type T."
Sep 03 2022