Re: ePub/Mobi/AZW3/PDF of Phobos Runtime Library

2022-06-28 Thread forkit via Digitalmars-d-learn

On Tuesday, 28 June 2022 at 21:14:42 UTC, Marcone wrote:
Is there any way to do this automatically like Python? 
https://docs.python.org/3/download.html


Of course there is. But someone has to volunteer their time and 
effort to do it ;-)


Re: ePub/Mobi/AZW3/PDF of Phobos Runtime Library

2022-06-28 Thread forkit via Digitalmars-d-learn

On Tuesday, 28 June 2022 at 18:42:11 UTC, Marcone wrote:

Beloved,


I love programming in D. D is my favorite programming language. 
I'm not a professional programmer, but I love to program. I 
would like to learn D deeply. Most programming languages have a 
PDF/CHM/MOBI/ePub version of the standard library. But D still 
doesn't have such a portable version of the Phobos Runtime 
Library. I humbly ask you to make available a portable version 
of the Phobos library, to better disseminate the D programming 
language.



Thank you


So assuming i understand what you're asking for here, it already 
exists.


When you download D, you get a directory named 'html'.

In that directory is a file named 'index.html'.

Is that what you want? (see the Documentation menu at the top of 
the index.html)


The only problem with that, is that it downloads fonts, so you 
need access to the internet. It will still work fine without 
access, but it will default to a font that isn't particulary nice 
on the eyes.




Re: Can I create a package with friendly modules

2022-06-12 Thread forkit via Digitalmars-d-learn

On Sunday, 12 June 2022 at 05:46:17 UTC, Mike Parker wrote:




I don't get it.

How does this enable one module to access the private parts of 
another module?


Isn't 'private' *always* private to the module?

The idea I had, was to be able to spread a 'module' over more 
than one file - for the purpose of encapsulating this and that in 
different physical files, while *still* protecting the 'private 
is private to the module' concept.


e.g.

// main module
module myMainModule [extends: mod1, mod2, mod3];

when I compile this module myMainModule, the compiler brings the 
extensions of this module, and treats it as a single module.


similar to the concept of bringing in different modules into a 
package, only more fine-grained.


But if D has a one-to-one mapping between a module and a file, 
and if private is always private to the one module, then this 
could never work.




Re: Can I create a package with friendly modules

2022-06-11 Thread forkit via Digitalmars-d-learn

On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote:




e.g. If I could something like this:

// foo_1.d
module foo_1
private int a; // a is private to module foo_1

// foo_2.d
module foo_2
private int b; // b is private to module foo_2

// foo.d
module foo[dependencies:foo_1, foo_2];
import std;
writeln a; // can call foo_1.a directly even those its private to 
that module
writeln b; // can call foo_2.b directly even those its private to 
that module





Can I create a package with friendly modules

2022-06-11 Thread forkit via Digitalmars-d-learn
Is it possible to create a package.d, consisting of (for 
example), two modules, where each module can access private 
declarations within each other.


In essence, declaring 'a module level friendship', or a kind of 
'extended module' if you want.


I might still want to add another module to the package, that is 
NOT part of that friendship between those other two modules, but 
is otherwise related to the solution.




Re: C-like static array size inference - how?

2022-06-08 Thread forkit via Digitalmars-d-learn
On Wednesday, 8 June 2022 at 01:32:42 UTC, Steven Schveighoffer 
wrote:


I like `$`. It's got a well-defined meaning, and already is 
somewhat magic.


-Steve


I agree it's magic.

warray[5..$]  - this is one of the best uses of syntax magic in D!

I think it's what first attracted me to the language actually.

A little more 'magic', and this could be possible:

int[n] myArray = [1,2,3];

( I think I like the use of 'n' more than '..' or '$' actually).



Re: C-like static array size inference - how?

2022-06-07 Thread forkit via Digitalmars-d-learn

On Wednesday, 8 June 2022 at 01:11:45 UTC, Mike Parker wrote:


...The author withdrew the DIP 
..


That's a shame.

Seems like a useful language feature. I'd be using it already if 
it existed.


I'd have gone for:

int[..] arr = [1,2,3];


Re: Why are structs and classes so different?

2022-05-18 Thread forkit via Digitalmars-d-learn

On Sunday, 15 May 2022 at 21:33:24 UTC, Ali Çehreli wrote:


I still think my answer is the real one. My implied question 
remains: Why does C++ have struct and class disticnction? I 
know they have different default access specifications but does 
that warrant two kinds?




Here is a very interesting article that researches this subject.

https://belaycpp.com/2021/09/17/history-of-c-explanation-on-why-the-keyword-class-has-no-more-reason-to-exist/



Re: Question on shapes

2022-05-17 Thread forkit via Digitalmars-d-learn

On Tuesday, 17 May 2022 at 04:37:58 UTC, Ali Çehreli wrote:




In you OOP example, I am curious why you chose Shape to be an 
interface, rather than a base class.




Re: Why are structs and classes so different?

2022-05-15 Thread forkit via Digitalmars-d-learn

On Sunday, 15 May 2022 at 15:26:40 UTC, Kevin Bailey wrote:
I've done some scripting in D over the years but I never dug 
into D until recently. I'm going through Learning D and I was 
reminded that structs and classes are so different.


- struct methods are non-virtual while class methods are virtual
- Thus, structs can't inherit, because how would you find the 
child's destructor given a parent pointer?

- On the stack, structs by-value but classes are by-reference

I'm trying to understand why it is this way. I assume that 
there's some benefit for designing it this way. I'm hoping that 
it's not simply accidental, historical or easier for the 
compiler writer.


A virtual function call has to pass through a virtual function 
look-up, and thus there is (some) overhead involved.


Thus, by design, structs avoid this overhead (completely).

It's also (I think) another reason why D does not support 
multiple inheritance. Since you would need multiple virtual 
function tables.


Re: Why are structs and classes so different?

2022-05-15 Thread forkit via Digitalmars-d-learn

On Sunday, 15 May 2022 at 15:59:17 UTC, Alain De Vos wrote:

Can i summarize ,
structs are value-objects which live on the stack.
class instances are reference objects which live on the heap.


the real difference, is that structs, being value types, are 
passed by value, and classes, being reference types, are passed 
by reference.


this is the most important difference to be aware of.

where they live in memory should be less of the programmers 
concern, and more an implementation issue (although some 
programmers will of course consider this as well).


btw. where does a struct, inside a class live?



Re: Back to Basics at DConf?

2022-05-13 Thread forkit via Digitalmars-d-learn

On Friday, 13 May 2022 at 15:56:31 UTC, H. S. Teoh wrote:



My mental image of this is Ali presenting some simple common 
task, then at 3/4 of the presentation there's an amazing trick 
that lets you write it in D in 5 times less code than in other 
languages, and my mind is blown and I remember why I love D so 
much. :-P



T


perhaps someone should start a D version of this:

https://github.com/ruppysuppy/Daily-Coding-Problem-Solutions



Re: Back to Basics at DConf?

2022-05-13 Thread forkit via Digitalmars-d-learn

On Friday, 13 May 2022 at 03:31:53 UTC, Ali Çehreli wrote:

On 5/12/22 18:56, forkit wrote:

> So...you want to do a talk that challenges D's complexity, by
getting
> back to basics?

I wasn't thinking about challenging complexity but it gives me 
ideas.


I am looking for concrete topics like templates, classes, 
ranges, rvalues, etc. Are those interesting?


Ali


Perhaps those are a little too basic for your intended audience 
(which is?)


My first objective when searching for a path towards a solution 
for a problem, is setting out to find valid methods to solve that 
problem, and then chosing the best method (based on whatever 
criteria is appropriate at the time).


So, perhaps a talk that focuses on comparing different methods 
for solving common computational tasks (e.g. search and decision 
problems), might be more valuable to your audience.


Re: Back to Basics at DConf?

2022-05-12 Thread forkit via Digitalmars-d-learn

On Thursday, 12 May 2022 at 21:58:33 UTC, Ali Çehreli wrote:

I am considering proposing a presentation for DConf 2022.

Would a "Back to Basics" style presentation be interesting? If, 
so what exact topic would you like to see?


For ideas, here is what CppCon 2021 had on their track:

  https://cppcon2021.sched.com/?searchstring=Back+to+Basics

Ali


So...you want to do a talk that challenges D's complexity, by 
getting back to basics?


I'm afraid the ship has sailed :-(



Re: range result in Tuple! and how to convert into assocArray by sort?

2022-05-11 Thread forkit via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 03:22:04 UTC, MichaelBi wrote:

s is the string, and print result as following:

s.array.sort!("athen how to transfer into 
[['A',231],['C',247],['G',240],['T',209]]? tried map!, but can 
only sortout key or value... tried array(), but result is not 
sorted then...thanks in advance.


Adding tuples to an AA is easy.

Sorting the output of an AA is the tricky part.

// -

module test;
@safe:

import std;

void main()
{
uint[dchar] myAA;
Tuple!(dchar, uint) myTuple;

myTuple[0] = 'C'; myTuple[1] = 247;
myAA[ myTuple[0] ] = myTuple[1];

myTuple[0] = 'G'; myTuple[1] = 240;
myAA[ myTuple[0] ] = myTuple[1];

myTuple[0] = 'A'; myTuple[1] = 231;
myAA[ myTuple[0] ] = myTuple[1];

myTuple[0] = 'T'; myTuple[1] = 209;
myAA[ myTuple[0] ] = myTuple[1];

// NOTE: associative arrays do not preserve the order of the 
keys inserted into the array.

// See: https://dlang.org/spec/hash-map.html

// if we want the output of an AA to be sorted (by key)..
string[] orderedKeyPairSet;

foreach(ref key, ref value; myAA.byPair)
orderedKeyPairSet ~= key.to!string ~ ":" ~ 
value.to!string;


orderedKeyPairSet.sort;

foreach(ref str; orderedKeyPairSet)
writeln(str);

/+
A:231
C:247
G:240
T:209
   +/

}

// 



Re: Using regular expressions when reading a file

2022-05-06 Thread forkit via Digitalmars-d-learn

On Friday, 6 May 2022 at 07:51:01 UTC, Alexander Zhirov wrote:

On Friday, 6 May 2022 at 05:40:52 UTC, forkit wrote:

auto myTuple = line.split(" = ");


Well, only if as a strict form :)


well.. a settings file should be following a strict format.

..otherwise...anything goes... and good luck with that...

regex won't help you either in that case...

e.g:

user =som=eu=ser  (how you going to deal with this ?)



Re: Using regular expressions when reading a file

2022-05-05 Thread forkit via Digitalmars-d-learn

On Thursday, 5 May 2022 at 17:53:57 UTC, Alexander Zhirov wrote:
I want to use a configuration file with external settings. I'm 
trying to use regular expressions to read the `Property = 
Value` settings. I would like to do it all more beautifully. Is 
there any way to get rid of the line break character? How much 
does everything look "right"?


regex never looks right ;-)

try something else perhaps??

// 

module test;

import std;

void main()
{
auto file = File("d:\\settings.conf", "r");
string[string] aa;

// create an associate array of settings -> [key:value]
foreach (line; file.byLine().filter!(a => !a.empty))
{
auto myTuple = line.split(" = ");
aa[myTuple[0].to!string] = myTuple[1].to!string;
}

// write out all the settings.
foreach (key, value; aa.byPair)
writefln("%s:%s", key, value);

writeln;

// write just the host value
writeln(aa["host"]);

}


// 



Re: How to use destroy and free.

2022-05-04 Thread forkit via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 21:55:18 UTC, H. S. Teoh wrote:
On Wed, May 04, 2022 at 09:46:50PM +, forkit via 
Digitalmars-d-learn wrote: [...]
That languages with GC typically give the programmer some 
control over the GC, is evidence that programmers do care 
(otherwise such features would not be needed).


To deny a programmer the option to release the memory that was 
GC allocated within a particular scope, to be release 
immediately after that scope exits, seems kinda cruel.

[...]

scope ptr = GC.malloc(size);
scope(exit) GC.free(ptr);

... // use ptr however you like until end of scope


T


that's cruel!

I just want 'scope-based deallocation of GC allocated memory'.

I just want to write one word for this to happen -> 'inscope'


Re: How to use destroy and free.

2022-05-04 Thread forkit via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 15:04:13 UTC, cc wrote:
The MemUtils package offers a `ScopedPool` utility that seems 
interesting.  It isn't well documented however so I have no 
idea if it actually works like I expect.  I presume this would 
work something akin to a VM memory snapshot/rollback for the 
GC?  It would be pretty handy for some scenarios, say a 
serialization library.  You specify a snapshot point (add a 
pool to the stack?), incur all your GC allocations necessary 
for generating the structure of your serialized data (which go 
into the pool instead of the GC proper?), then you write it to 
disk and pop the stack, effectively rolling back to the 
original memory state of your program's GC.  As long as you 
make sure not to leak anything allocated within that phase, 
seems like a good deal.


https://code.dlang.org/packages/memutils


Interesting.

My idea was ... objects marked as 'inscope' would be GC allocated 
in a LIFO region of the heap, rather than the general GC pool.


Explicately deallocating such objects at end of scope then 
becomes a no brainer for the GC (since 'inscope' would ensure at 
compile time that no pointers/aliasing outside of that scope 
could exist).


The LIFO would also avoid the problem of fragmentation (i.e. if 
the objects were allocated in the general GC pool instead of a 
separate pool).


This would give the programmer 'scope-based deallocation of GC 
allocated memory'.





Re: How to use destroy and free.

2022-05-04 Thread forkit via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 12:57:26 UTC, Ali Çehreli wrote:

On 5/3/22 22:37, forkit wrote:

> In any case, I disagree that caring about when memory gets
deallocted
> means you shouldn't be using GC. (or did I get that one wrong
too??)

At least I don't agree with you there. :) Yes, one should not 
care about how memory gets freed if one did not care how that 
memory was allocated.




That languages with GC typically give the programmer some control 
over the GC, is evidence that programmers do care (otherwise such 
features would not be needed).


To deny a programmer the option to release the memory that was GC 
allocated within a particular scope, to be release immediately 
after that scope exits, seems kinda cruel.


To force a programmer to run a full GC in such a situation, is 
also kinda cruel.


To force a programmer back to using the ancient malloc/free 
well.. that's even crueler.





Re: How to use destroy and free.

2022-05-04 Thread forkit via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 08:23:33 UTC, Mike Parker wrote:

On Wednesday, 4 May 2022 at 05:37:49 UTC, forkit wrote:

That's not at all what I said. You don't have to care about 
*when* memory is deallocated, meaning you don't have to 
manage it yourself.


In any case, I disagree that caring about when memory gets 
deallocted means you shouldn't be using GC. (or did I get that 
one wrong too??)


You can have the best of both worlds, surely (and easily).

This (example from first post):

void main(){
int[] i = new int[1];

import object: destroy;
destroy(i);
import core.memory: GC;
GC.free(GC.addrOf(cast(void *)(i.ptr)));
}



All you're doing here is putting unnecessary pressure on the 
GC. Just use `malloc` and then `free` on `scope(exit)`. Or if 
you want to append to the array without managing the memory 
yourself, then use `std.container.array` instead. That's made 
for deterministic memory management with no GC involvement.



Reverting to C style 'malloc and free' is not the solution here, 
since the intent is not to revert to manually managing 
dynamically allocated memory.


Rather, the intent was to just have 'a simple form of control' 
over the lifetime of the dynamically allocated memory - the 
object being pointed to in GC memory pool.


I understand that my idea may put uncessary pressure on the 
existing GC, but a GC (in theory) could surely handle this 
scenario..


If D had such a feature, I'd already be using it.



Re: How to use destroy and free.

2022-05-03 Thread forkit via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 05:13:04 UTC, Mike Parker wrote:

On Wednesday, 4 May 2022 at 04:52:05 UTC, forkit wrote:



It is certainly *not* about you not having to care anymore 
(about memory management).




That's not at all what I said. You don't have to care about 
*when* memory is deallocated, meaning you don't have to manage 
it yourself.


In any case, I disagree that caring about when memory gets 
deallocted means you shouldn't be using GC. (or did I get that 
one wrong too??)


You can have the best of both worlds, surely (and easily).

This (example from first post):

void main(){
int[] i = new int[1];

import object: destroy;
destroy(i);
import core.memory: GC;
GC.free(GC.addrOf(cast(void *)(i.ptr)));
}

could (in theory) be replaced with this:

void main(){
inscope int[] i = new int[1];

// inscope means 2 things:
// (1) i cannot be referenced anywhere except within this 
scope.

// (2) i *will* be GC'd when this scope ends

}



Re: How to use destroy and free.

2022-05-03 Thread forkit via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 02:42:44 UTC, Mike Parker wrote:

On Tuesday, 3 May 2022 at 14:57:46 UTC, Alain De Vos wrote:
Note, It's not i'm against GC. But my preference is to use 
builtin types and libraries if possible,
But at the same time be able to be sure memory is given free 
when a variable is going out of scope.
It seems not easy to combine the two with a GC which does his 
best effort but as he likes or not.


What I described is an optional compiler optimization. The 
compiler is free to avoid the GC allocation for an array 
literal initializer if it is possible to do so. If you were to, 
e.g., return the array from the function, it would 100% for 
sure be allocated on the GC and not the stack. In practice, I 
don't know if any of the compilers actually do this.


Anyway, if you care when memory is deallocated, then the GC 
isn't the right tool for the job. The point of the GC is that 
you don't have to care.


GC is about reducing the complexity, cognitive load, and possible 
bugs - associated with manual memory management.


It is certainly *not* about you not having to care anymore (about 
memory management).


Why not have an option to mark an object, so that real-time 
garbage collection occurs on it as it exits scope?


Re: Where I download Digital Mars C Preprocessor sppn.exe?

2022-04-03 Thread forkit via Digitalmars-d-learn

On Saturday, 2 April 2022 at 23:40:39 UTC, Marcone wrote:
ImportC is deprecated as everything in D is deprecated and 
abandoned. No link works, every download link is broken as no 
one cares. All D code is always full of bugs and needs to be 
corrected by the user before trying to run it, in order to 
realize that it wasted time.


https://dlang.org/spec/importc.html


ImportC is an interesting, and possibly useful feature..to a 
select few, but ALL will have to carry it.


IMO...ImportC will be D's biggest mistake.



Re: How to remove all characters from a string, except the integers?

2022-03-04 Thread forkit via Digitalmars-d-learn

On Friday, 4 March 2022 at 02:10:11 UTC, Salih Dincer wrote:

On Thursday, 3 March 2022 at 20:23:14 UTC, forkit wrote:

On Thursday, 3 March 2022 at 19:28:36 UTC, matheus wrote:


I'm a simple man who uses D with the old C mentality:
[...]
```d
string s, str = "4A0B1de!2C9~6";
foreach(i;str){
if(i < '0' || i > '9'){ continue; }
s ~= i;
}
```
[...]


mmm..but we no longer live in simple times ;-)

(i.e. unicode)


If you look 
[here](https://github.com/dlang/phobos/blob/master/std/ascii.d#L315), you'll see that it's already the same logic. If it were me I would have even written like this:

```d
"4A0B1de!2C9~6".filter!(c =>
'0' <= c && c <= '9'
   ).writeln; // 401296
```


If you get this question at an interview, please remember to 
first ask whether it's ascii or unicode ;-)


" All of the functions in std.ascii accept Unicode characters but 
effectively ignore them if they're not ASCII." - 
https://github.com/dlang/phobos/blob/master/std/ascii.d




Re: How to use ImportC?

2022-03-03 Thread forkit via Digitalmars-d-learn

On Thursday, 3 March 2022 at 19:05:22 UTC, Leonardo wrote:
I saw the new feature called ImportC, it's cool to be able to 
use C code/libraries, but I'm not much experience in C and 
didn't understand this incomplete documentation: 
https://dlang.org/spec/importc.html

How to use ImportC?


I think you nailed it... with "incomplete".


Re: How to remove all characters from a string, except the integers?

2022-03-03 Thread forkit via Digitalmars-d-learn

On Thursday, 3 March 2022 at 19:28:36 UTC, matheus wrote:


I'm a simple man who uses D with the old C mentality:

import std.stdio;

void main(){
string s, str = "4A0B1de!2C9~6";
foreach(i;str){
if(i < '0' || i > '9'){ continue; }
s ~= i;
}
writeln("Result: ", s);
}

Result: 401296

Matheus.


mmm..but we no longer live in simple times ;-)

(i.e. unicode)


Re: initializing struct containing user defined type

2022-02-18 Thread forkit via Digitalmars-d-learn

On Friday, 18 February 2022 at 16:45:24 UTC, Ali Çehreli wrote:


...
I think that syntax will be obviated when D will have named 
arguments.


Ali


Huh? D doesn't have named arguments, already?

That's an important component for safe(r) programming.

Do you know if there is a DIP for this, and if so, it's current 
status.





Re: split Error - no overload matches

2022-02-14 Thread forkit via Digitalmars-d-learn

On Monday, 14 February 2022 at 11:37:38 UTC, ag0aep6g wrote:

On 14.02.22 12:14, forkit wrote:

However, if I uncomment the //import std.uni : isWhite;

then it will compile.

I don't understand. I thought 'import std;' would be 
sufficient here??


"isWhite" is ambiguous. There's std.uni.isWhite and 
std.ascii.isWhite. `import std;` can't know which one you want.


thanks.

a little more help from the compiler itself would also have been 
appreciated ;-)


e.g:

Error: The call to isWhite is ambiguous between the following 
methods: 'std.uni.isWhite' and 'std.ascii.isWhite'


split Error - no overload matches

2022-02-14 Thread forkit via Digitalmars-d-learn

This code will not compile.

Error: no overload matches for `split`

However, if I uncomment the //import std.uni : isWhite;

then it will compile.

I don't understand. I thought 'import std;' would be sufficient 
here??


//  

module test;
@safe:

import std;

void main()
{
//import std.uni : isWhite; // need to uncomment this for it 
to compile.

writeln("Learning D is fun".split!isWhite);
}

// ---


Re: Offline D documentation/tutorial

2022-02-13 Thread forkit via Digitalmars-d-learn

On Sunday, 13 February 2022 at 00:43:18 UTC, Mike Parker wrote:


If you’ve installed dmd via one of the supported installers (or 
the zip), you should already have the html files for the spec. 
On Windows, they’re in a subdirectory. I assume on other 
platforms they’re in the standard doc location for that 
platform.


Would be nice if you could use this html *completely* offline, 
too.


At the moment, if your're offline, you can't download the 
Roboto+Slab fonts that it tries to grab off the internet, from 
fonts.google.com, and so the pages end up with some default font 
that makes it look pretty awful.





Re: how to handle very large array?

2022-02-09 Thread forkit via Digitalmars-d-learn

On Thursday, 10 February 2022 at 01:43:54 UTC, H. S. Teoh wrote:
On Thu, Feb 10, 2022 at 01:32:00AM +, MichaelBi via 
Digitalmars-d-learn wrote:
On Wednesday, 9 February 2022 at 19:48:49 UTC, H. S. Teoh 
wrote:

> [...]

thanks, very helpful! i am using a assocArray now...


Are you sure that's what you need?


T


https://youtu.be/yJjpXJm7x0o?t=213


Re: How to verify DMD download with GPG?

2022-02-08 Thread forkit via Digitalmars-d-learn
On Tuesday, 8 February 2022 at 10:17:19 UTC, Ola Fosheim Grøstad 
wrote:
I don't use GPG often, so I probably did something wrong, and 
failed to get a trusted verification. I do like the idea that a 
hacker cannot change the signature file if gaining access to 
the web/file hosts, but how to verify it in secure way?

I also did not find the key listed here:

https://dlang.org/download.html


there are two parts to this gpg output:

(1)
"Good signature.." - ok. you can be sure the file is correctly 
signed.


(2)
"WARNING: This key is not certified with a trusted .." - ok. You 
have not fully trusted the key, that's fine, and makes sense, 
since you just downloaded the key, and the key itself might have 
been tampered with .. in which case you have a good signature 
from a fraudulent key.


On what basis would you trust the key? Think about it ;-)

btw. the key is listed there - not sure what you mean.



iteration over directories is unsafe

2022-02-05 Thread forkit via Digitalmars-d-learn
It is not possible to do a simple iteration over directories in 
@safe mode.


Really? I have to resort to unsafe??


//

module test;
@safe: // nope. no can do.

import std;

void main()
{
auto dFiles = dirEntries("", "*.{d,di}", SpanMode.depth);
foreach(d; dFiles)
writeln(d.name);
}

//



Re: ldc executable crashes with this code

2022-02-04 Thread forkit via Digitalmars-d-learn
On Friday, 4 February 2022 at 15:58:19 UTC, Stanislav Blinov 
wrote:


..
...
As others have already stated, casting immutability away is 
something that has to be supported, e.g. to interface with 
const-agnostic APIs. `@safe` requires such casts to be more 
verbose, with good reason.


I concede ;-)

That the compiler knows this is @safe:
cast(char[])iStr.dup;

and this is not @safe:
cast(char[])iStr;

is sufficent.


Re: ldc executable crashes with this code

2022-02-04 Thread forkit via Digitalmars-d-learn
On Friday, 4 February 2022 at 10:09:22 UTC, Patrick Schluter 
wrote:

On Thursday, 3 February 2022 at 02:01:34 UTC, forkit wrote:

On Thursday, 3 February 2022 at 01:57:12 UTC, H. S. Teoh wrote:




would be nice if the compiler told me something though :-(

i.e. "hey, dude, you really wanna to that?"


would be nice if programmers (C or D) learnt that a typecast 
means "shut up compiler I know what I do". You explicitly 
instructed the compiler to not complain.


Remove the typecast and the compiler will bring an error.

That's the reason why typecasts are to be avoided as much as 
possible.It is often a code smell.


If I had wrote the code below, then I should not expect anything, 
whatsoever, from the compiler.


() @trustMe_I_am_a_complete_idiot { char[] palindrome = 
cast(char[])"able was I ere I saw elba";  } ();




Re: ldc executable crashes with this code

2022-02-04 Thread forkit via Digitalmars-d-learn
On Friday, 4 February 2022 at 10:09:22 UTC, Patrick Schluter 
wrote:

On Thursday, 3 February 2022 at 02:01:34 UTC, forkit wrote:

On Thursday, 3 February 2022 at 01:57:12 UTC, H. S. Teoh wrote:




would be nice if the compiler told me something though :-(

i.e. "hey, dude, you really wanna to that?"


would be nice if programmers (C or D) learnt that a typecast 
means "shut up compiler I know what I do". You explicitly 
instructed the compiler to not complain.


Remove the typecast and the compiler will bring an error.

That's the reason why typecasts are to be avoided as much as 
possible.It is often a code smell.


In C, I would have no such expectation.

The cast will occur whether I typed it in or not. My problem was, 
that I forgot the .dup


For the compiler to allow me to cast from immutable to mutable 
(without the .dup), makes about as much sense as the compiler 
allowing this:


int i;
i = "Hello";



Re: ldc executable crashes with this code

2022-02-02 Thread forkit via Digitalmars-d-learn

On Thursday, 3 February 2022 at 03:25:39 UTC, H. S. Teoh wrote:
On Thu, Feb 03, 2022 at 02:01:34AM +, forkit via 
Digitalmars-d-learn wrote: [...]

would be nice if the compiler told me something though :-(

i.e. "hey, dude, you really wanna to that?"


Mark your function @safe, and the compiler will stop you from 
unsafe casts of this nature. That's part of the reason we have 
@safe. ;-)



T


so i mark all my modules as @safe, by default.

I commented it out though, so I could do the cast.

Then realised I didn't need the cast at all, just the .dup

now it's @safe again.

But @safe or not, nothing good can come from casting an immutable 
string to a mutable string, and the compiler really should know 
that ;-)




Re: ldc executable crashes with this code

2022-02-02 Thread forkit via Digitalmars-d-learn

On Thursday, 3 February 2022 at 01:57:12 UTC, H. S. Teoh wrote:




would be nice if the compiler told me something though :-(

i.e. "hey, dude, you really wanna to that?"



Re: ldc executable crashes with this code

2022-02-02 Thread forkit via Digitalmars-d-learn

On Thursday, 3 February 2022 at 01:39:33 UTC, forkit wrote:




oops!  forgot the .dup

char[] palindrome = cast(char[])"able was I ere I saw elba".dup;

;-)




Re: ldc executable crashes with this code

2022-02-02 Thread forkit via Digitalmars-d-learn

On Wednesday, 2 February 2022 at 23:30:50 UTC, H. S. Teoh wrote:
On Wed, Feb 02, 2022 at 11:21:52PM +, forkit via 
Digitalmars-d-learn wrote: [...]
char[] palindrome = cast(char[])"able was I ere I saw 
elba";


String literals are immutable by default. Casting immutable to 
mutable

is UB (Undefined Behaviour).


[...]

writeln(palindrome.reverse);


Especially because .reverse mutates its argument.  So you're 
attempting to overwrite immutable data here. That's probably 
what caused the crash: the literal is put in the read-only 
segment and the OS killed the program when it tried to write to 
data in that read-only segment.



T


that explains ldc perhaps (although i don't really get it. It's 
cast to mutable and being assigned to mutable.


in any case... ldc doesn't like it, but dmd is fine with this ??



ldc executable crashes with this code

2022-02-02 Thread forkit via Digitalmars-d-learn
Any reason why compiling this with ldc would cause the exe to 
crash?


Compiling with DMD (using either declaration of palindrome works 
just fine though)



// 

module test;

import std;

void main()
{
char[] palindrome = cast(char[])"able was I ere I saw elba";

   //char[] palindrome = 
['a','b','l','e','w','a','s','I','e','r','e','I','s','a','w','e','l','b','a'];


writeln(palindrome);

// note: The line below causes the exe to crash when compiled 
with ldc

// but only if using the first version of palindrome.

writeln(palindrome.reverse);
}

// ---


Re: gdc or ldc for faster programs?

2022-01-26 Thread forkit via Digitalmars-d-learn

On Wednesday, 26 January 2022 at 11:25:47 UTC, Iain Buclaw wrote:


Whenever I've watched talks/demos where benchmarks were the 
central topic, GDC has always blown LDC out the water when it 
comes to matters of math.

..


https://dlang.org/blog/2020/05/14/lomutos-comeback/



Re: gdc or ldc for faster programs?

2022-01-25 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 20:01:18 UTC, Johan wrote:


Tough to say. Of course DMD is not a serious contender, but I 
believe the difference between GDC and LDC is very small and 
really in the details, i.e. you'll have to look at assembly to 
find out the delta.

Have you tried `--enable-cross-module-inlining` with LDC?

-Johan


dmd is the best though, in terms of compilation speed without 
optimisation.


As I write/test A LOT of code, that time saved is very much 
appreciated ;-)


I hope it remains that way.


Re: passing a variadic parameter to randomSample

2022-01-25 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 22:35:29 UTC, forkit wrote:




I should point out (to anyone looking at that code I posted), 
that it's easier, and makes more sense, to just write:


writeln( ["typeA", "typeB", "typeC"].choice );

... but my main focus here, was learning about variadic template 
functions.




Re: passing a variadic parameter to randomSample

2022-01-25 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 22:07:43 UTC, Ali Çehreli wrote:




thanks. makes it even shorter and simpler :-)

// --

module test;
@safe:

import std;

auto RandomChoice(R...)(R r)
{
auto rnd = MinstdRand0(unpredictableSeed);
return only(r).choice(rnd);
}

void main()
{
writeln( RandomChoice("typeA", "typeB", "typeC") );
writeln( RandomChoice(5, 8, 2) );
writeln( RandomChoice(1.3, 5.09, 8, 2) );
writeln( RandomChoice(100.05, 110.8, 109.54) );

//writeln( RandomChoice("typeA", 5, 100.14) );
// nope. some issue with mixing strings with numeric types

writeln( RandomChoice("typeA", 5.to!string, 100.14.to!string) 
);

// NOTE: This registers with -profile=gc
}

// --




Re: passing a variadic parameter to randomSample

2022-01-25 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 11:50:08 UTC, vit wrote:




thanks. problem solved (providing all parameters are of the same 
type).


// ---

module test;
import std;

auto RandomChoice(R...)(R r)
{
auto rnd = MinstdRand0(unpredictableSeed);
return only(r).randomSample(1, rnd).front;
}

void main()
{
writeln( RandomChoice("typeA", "typeB", "typeC") );
writeln( RandomChoice(5, 8, 2) );
writeln( RandomChoice(100.05, 110.8, 109.54) );

//writeln( RandomChoice("typeA", 5, 100.14) ); // nope. they 
all need to be of the same type.
writeln( RandomChoice("typeA", 5.to!string, 100.14.to!string) 
);

}

//--


passing a variadic parameter to randomSample

2022-01-25 Thread forkit via Digitalmars-d-learn
so I'm trying to write (or rather learn how to write) a 'variadic 
template function', that returns just one of its variadic 
parameter, randomly chosen.


But can't get my head around the problem here :-(

.. Error: template `std.random.randomSample` cannot deduce 
function from argument types `


// --

module test;
import std;

string RandomChoice(R...)(R r)
{
auto rnd = MinstdRand0(42);
return r.randomSample(1, rnd).to!string;
}

void main()
{
writeln( RandomChoice("typeA", "typeB", "typeC") );
}

// --


Re: unordered output of an associated array of associated arrays

2022-01-24 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 02:12:50 UTC, H. S. Teoh wrote:


That's the *easy* way out??  Try this instead:

aaTable.keys.sort.each!((k) {
aaTable[k].keys.sort.each!((kk) {
writefln("%s:%s:%s", k, kk, aaTable[k][kk]);
});
});


T


surely, this is voodoo?  ;-)


Re: unordered output of an associated array of associated arrays

2022-01-24 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 00:43:07 UTC, forkit wrote:


oh. thanks :-)

I will get that integrated into my example code, and will post 
again, once it's working (so others can  learn too)


ok.. so I took the easy way out ;-)

output is now ordered:

typeA:10003:[1, 1, 1, 0, 0, 0, 0, 0]
typeA:10004:[1, 1, 1, 1, 0, 0, 0, 0]
typeA:10005:[1, 1, 1, 1, 1, 0, 0, 0]
typeB:10001:[1, 0, 0, 0, 0, 0, 0, 0]
typeB:10002:[1, 1, 0, 0, 0, 0, 0, 0]
typeC:10006:[1, 1, 1, 1, 1, 1, 0, 0]
typeC:10007:[1, 1, 1, 1, 1, 1, 0, 0]


// --
module test;

import std;

void main()
{
auto aaTable =
  ([
   "typeB" : [ 10002 : [1, 1, 0, 0, 0, 0, 0, 0],
   10001 : [1, 0, 0, 0, 0, 0, 0, 0]
 ],
   "typeC" : [ 10007 : [1, 1, 1, 1, 1, 1, 0, 0],
   10006 : [1, 1, 1, 1, 1, 1, 0, 0]
 ],
   "typeA" : [ 10005 : [1, 1, 1, 1, 1, 0, 0, 0],
   10003 : [1, 1, 1, 0, 0, 0, 0, 0],
   10004 : [1, 1, 1, 1, 0, 0, 0, 0]
 ]
  ]);

string[] orderedKeyPairSet;

foreach (key, pair; aaTable.byPair)
{
foreach(k, p; pair.byPair)
orderedKeyPairSet ~= key ~ ":" ~ k.to!string ~ ":" ~ 
p.to!string;

}

orderedKeyPairSet.sort;

foreach(s; orderedKeyPairSet)
writeln(s);

}

// ---


Re: unordered output of an associated array of associated arrays

2022-01-24 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 00:39:05 UTC, H. S. Teoh wrote:



AA's are unordered containers. Do not rely on entries to appear 
in any specific order when you traverse an AA; it is 
implementation-dependent and may differ from OS to OS / 
platform to platform / sequence of operations performed on the 
AA since its initialization / phase of the moon. Any specific 
order that may appear in an AA is pure coincidence and may not 
appear again next time, or may only appear again at 11:59:59 
Feb 29 under a blue moon.


If you need entries in your AA in a specific order, extract 
them (or their keys) into an array then sort them yourself. 
E.g.:


string[string] myAA;
auto keys = myAA.keys;
sort(keys);
foreach (k; keys) {
... // now keys will be in the expected order
}


T


oh. thanks :-)

I will get that integrated into my example code, and will post 
again, once it's working (so others can  learn too)





Re: unordered output of an associated array of associated arrays

2022-01-24 Thread forkit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 00:23:40 UTC, forkit wrote:



another example:

output is:
typeA:
10001:[0, 0, 1, 1, 1, 1, 1, 1]
10002:[0, 0, 0, 1, 1, 1, 1, 1]
typeB:
10005:[0, 0, 0, 0, 0, 0, 1, 1]
10003:[0, 0, 0, 0, 1, 1, 1, 1]
10004:[0, 0, 0, 0, 0, 1, 1, 1]


// --

module test;

import std;

void main()
{
auto aaTable2 =
  ([
   "typeA" : [ 10001 : [0, 0, 1, 1, 1, 1, 1, 1],
   10002 : [0, 0, 0, 1, 1, 1, 1, 1] ],
   "typeB" : [ 10003 : [0, 0, 0, 0, 1, 1, 1, 1],
   10004 : [0, 0, 0, 0, 0, 1, 1, 1],
   10005 : [0, 0, 0, 0, 0, 0, 1, 1] ]
 ]);

foreach (topLevelKey, topLevelValue; aaTable2.byPair)
{
writefln("%s:", topLevelKey);

foreach(key, value; topLevelValue)
{
writefln("\t%s:%s", key, value);
}
}

}

//--





unordered output of an associated array of associated arrays

2022-01-24 Thread forkit via Digitalmars-d-learn
so I'm trying to understand why the output of the code below, is 
in reverse order of the declaration (and how to fix it so that it 
outputs in an ordered way)


i.e. output is:
typeA:
A2:A2value
A1:A1value
typeB:
B3:B3value
B2:B2value
B1:B1value

// --

module test;

import std;

void main()
{
string[string][string] aaTable =
 ([ "typeA" : ["A1" : "A1value", "A2" : "A2value"],
"typeB" : ["B1" : "B1value", "B2" : "B2value", "B3" : 
"B3value"]

 ]);


foreach (topLevelKey, topLevelValue; aaTable.byPair)
{
writefln("%s:", topLevelKey);

foreach(key, value; topLevelValue)
{
writefln("\t%s:%s", key, value);
}
}

}

//--



Re: dynamic format specifier possible?

2022-01-23 Thread forkit via Digitalmars-d-learn

On Sunday, 23 January 2022 at 22:08:28 UTC, Ali Çehreli wrote:


You use an asterisk and provide the width as an argument. This 
one uses the length of the name of the program:


import std;

void main(string[] args)
{
  int val = 999000;
  writefln("[%*s]", args.front.length, val); // [   999000]
}

Ali


perfect! thanks.



dynamic format specifier possible?

2022-01-23 Thread forkit via Digitalmars-d-learn
I would like to calculate the width of the format specifier 
dynamically, at runtime.


e.g int WIDTH = something.length;

then my format specifier would be: %WIDTHs instead of %9s

// ---

module test;

import std;

void main()
{
int val = 999000;
writefln("[%9s]", val); // [   999000]
}

// ---


Re: map question

2022-01-22 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 19:55:43 UTC, Stanislav Blinov 
wrote:




thanks for the explanation. That really helped :-)

writeln( generate!(() => dice(0.6, 1.4)).take(howManyTimes) );
[1, 1, 1, 1, 0]

(or after reading Ali's response - getting rid of rnd, and using 
_ )


writeln( howManyTimes.iota.map!(_ => dice(0.6, 1.4)) );
[1, 0, 1, 1, 1]

They produce exactly the same thing, so I guess it comes down to 
personal choice now.




Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread forkit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 22:44:31 UTC, forkit wrote:




and here is how to get the ip (depending on the formatting of 
your output of course)


// ---
module test;

import std;

void main()
{
auto result = execute(["bash", "-c", "nmap -sn 
192.168.11.0/24 | ack -B2 \"Philips\""]);


string ip;

if(canFind(result.to!string, "Host is up"))
{
writeln("Host is up");

string str = result.to!string.chop;
ip = str[ (indexOf(str, "for Philips (") + 10)..$-4 ];
writeln(ip);
}
else
writeln("Host not found.");
}

// 



Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread forkit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 23:15:18 UTC, forkit wrote:




oh.. this is better i think...

ip = str[ ((lastIndexOf(str, "(")) + 1) .. lastIndexOf(str, ")") 
];






Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson 
wrote:




is this helpful:

// ---
module test;

import std;

void main()
{
auto result = execute(["bash", "-c", "nmap -sn 
192.168.11.0/24 | ack -B2 \"Phillips\""]);


if(canFind(result.to!string, "Host is up"))
writeln("Host is up");
else
writeln("Host not found.");
}

// ---




map question

2022-01-22 Thread forkit via Digitalmars-d-learn

trying to make sense of the below:


// ---
module test;

import std;

void main()
{
auto rnd = Random(unpredictableSeed);

int howManyTimes = 5;

// ok - using 'e =>' makes sense
writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");


// ok - though using 'howManyTimes =>' doesn't make much 
sense??
writeln(howManyTimes.iota.map!(howManyTimes => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");


// NOT ok - using '5 =>' - but isn't this effectively the 
same as above line?
//writeln(howManyTimes.iota.map!(5 => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");

}

// ---


Re: automate tuple creation

2022-01-22 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 01:33:16 UTC, Steven 
Schveighoffer wrote:



That second `valuesPerRecord` is not used in the lambda, and 
also it's not referring to the original element, it's the name 
of a parameter in the lambda.


Are you sure this is doing what you want?

-Steve


It just worked, so i didn't think about it too much.. but it 
seems to work either way.


And to be honest, the only part of it I understand, is the dice 
part ;-)


In any case I changed it:

from: valuesPerRecord =>
to:  i =>

// 

void CreateDataFile(const(int) recordsNeeded, const(int) 
valuesPerRecord, const(string) fname)

{
auto rnd = Random(unpredictableSeed);

auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(recordsNeeded);

const int iotaStartNum = 100_000_001;

foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)

{
bigString
~= id.to!string
~ ","
~ valuesPerRecord.iota.map!(i => rnd.dice(0.6, 
1.4)).format!"%(%s,%)"

~ "\n";
}

file.write(bigString[]);
}

// ---


Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 01:33:16 UTC, Steven 
Schveighoffer wrote:




so I why watching this video by Andrei:

https://www.youtube.com/watch?v=mCrVYYlFTrA

In it, he talked about writing the simplest design that could 
possibly work


Which got me thinking

// 

module test;
@safe:

import std.stdio : write, writef, writeln, writefln;
import std.range : iota, enumerate;
import std.array : array, byPair, Appender, appender;
import std.random : Random, unpredictableSeed, dice, randomCover;
import std.algorithm : map;
import std.conv : to;
import std.format;
import std.stdio : File;
import std.file : exists;
import std.exception : enforce;
import std.meta : Alias;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); }

void main(string[] args)
{
int recordsNeeded, valuesPerRecord;

string fname;

if(args.length < 4) // then set defaults
{
recordsNeeded = 10;
valuesPerRecord= 8;

version(Windows) { fname = "D:/rnd_records.txt"; }
version(linux) { fname = "./rnd_records.txt"; }
}
else
{
// assumes valid values being passed in ;-)
recordsNeeded = to!int(args[1]);
valuesPerRecord = to!int(args[2]);
fname = args[3];
}

debug
{ writefln("%s records (where a record is: id and %s 
values), will be written to file: %s", recordsNeeded, 
valuesPerRecord, fname); }

else
{
enforce(!exists(fname), "Oops! That file already 
exists!");
enforce(recordsNeeded <= 1_000_000_000, "C'mon! 
That's too many records!");

}

CreateDataFile(recordsNeeded, valuesPerRecord, fname);

writefln("All done. Check if records written to %s", fname);
}

void CreateDataFile(const(int) recordsNeeded, const(int) 
valuesPerRecord, const(string) fname)

{
auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(recordsNeeded);

const int iotaStartNum = 100_000_001;

foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)

{
bigString
~= id.to!string
~ ","
~ valuesPerRecord.iota.map!(valuesPerRecord => 
cast(int)rnd.dice(0.6, 1.4)).format!"%(%s,%)"

~ "\n";
}

file.write(bigString[]);
}

// 


Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 22:25:32 UTC, forkit wrote:




I really like how alias and mixin can simplify my code even 
further:


//---

int[][int][] CreateDataSet
(const(int) recordsNeeded, const(int) valuesPerRecord)
{
int[][int][] records;
records.reserve(recordsNeeded);

const int iotaStartNum = 100_000_001;
alias iotaValues = Alias!"iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate";
alias recordValues = 
Alias!"iota(valuesPerRecord).map!(valuesPerRecord => 
cast(int)rnd.dice(0.6, 1.4)).array";


foreach(i, id; mixin(iotaValues))
{
records ~= [ id: mixin(recordValues) ];
}

return records;
}

//---



Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 21:56:33 UTC, H. S. Teoh wrote:


What's the point of calling .dup here?  The only reference to 
records is going out of scope, so why can't you just return it? 
 The .dup is just creating extra work for nothing.



T


good pickup. thanks ;-)

// 

module test;
@safe:

import std.stdio : write, writef, writeln, writefln;
import std.range : iota, enumerate;
import std.array : array, byPair, Appender, appender;
import std.random : Random, unpredictableSeed, dice, randomCover;
import std.algorithm : map;
import std.conv : to;
import std.format;
import std.stdio : File;
import std.file : exists;
import std.exception : enforce;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); }

void main(string[] args)
{
int recordsNeeded, valuesPerRecord;
string fname;

if(args.length < 4)
{
recordsNeeded = 10; // default
valuesPerRecord= 8; // default

fname = "D:/rnd_records.txt"; // default
//fname = "./rnd_records.txt"; // default
}
else
{
// assumes valid values being passed in ;-)
recordsNeeded = to!int(args[1]);
valuesPerRecord = to!int(args[2]);
fname = args[3];
}

debug
{ writefln("%s records, %s values for record, will be 
written to file: %s", recordsNeeded, valuesPerRecord, fname); }

else
{
enforce(!exists(fname), "Oop! That file already 
exists!");
enforce(recordsNeeded <= 1_000_000_000, "C'mon! 
That's too many records!");

}

int[][int][] records = CreateDataSet(recordsNeeded, 
valuesPerRecord);


ProcessDataSet(records, fname);

writefln("All done. Check if records written to %s", fname);
}

int[][int][] CreateDataSet
(const(int) recordsNeeded, const(int) valuesPerRecord)
{
const int iotaStartNum = 100_000_001;

int[][int][] records;
records.reserve(recordsNeeded);
debug { writefln("records.capacity is %s", records.capacity); 
}


foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)

{
// NOTE: below does register with -profile=gc
records ~= [ id: 
iota(valuesPerRecord).map!(valuesPerRecord => 
cast(int)rnd.dice(0.6, 1.4)).array ];

}

debug { writefln("records.length = %s", records.length); }
return records;
}

// this creates a big string of 'formatted' records, and outputs 
that string to a file.

void ProcessDataSet
(in int[][int][] records, const(string) fname)
{
auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(records.length);
debug { writefln("bigString.capacity is %s", 
bigString.capacity); }


// NOTE: forward declaration required for this nested function
void processRecord(const(int) id, const(int)[] values)
{
bigString ~= id.to!string ~ "," ~ values.format!"%(%s,%)" 
~ "\n";

}

foreach(ref const record; records)
{
foreach (ref rp; record.byPair)
{
processRecord(rp.expand);
}
}

debug { writeln; writeln(bigString[].until("\n")); writeln; } 
// display just one record


file.write(bigString[]);
}
// 




Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 21:43:38 UTC, forkit wrote:




oops... should be:

// ---

int[][int][] CreateDataSet
(const(int) recordsNeeded, const(int)valuesPerRecord)
{
int[][int][] records;
records.reserve(recordsNeeded);

const int iotaStartNum = 100_000_001;

foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)

{
records ~= [ id: 
iota(valuesPerRecord).map!(valuesPerRecord => 
cast(int)rnd.dice(0.6, 1.4)).array ];

}

return records.dup;
}

// ---




Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 21:01:11 UTC, forkit wrote:




even better, I got rid of all those uncessary arrays ;-)

// ---

int[][int][] CreateDataSet
(const(int) recordsNeeded, const(int)valuesPerRecord)
{
int[][int][] records;
records.reserve(recordsNeeded);

foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)

{
records ~= [ id: 
iota(valuesPerRecord).map!(valuesPerRecord => 
cast(int)rnd.dice(0.6, 1.4)).array ];

}

return records.dup;
}

// ---



Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn
On Friday, 21 January 2022 at 18:50:46 UTC, Steven Schveighoffer 
wrote:


Yeah, iota is a random-access range, so you can just pass it 
directly, and not allocate anything.


Looking at the usage, it doesn't need to be an array at all. 
But modifying the code to properly accept the range might prove 
difficult for someone not used to it.


-Steve


thanks. that makes more sense actually ;-)

now i can get rid of the idArray completely, and just do:

foreach(i, id; enumerate(iota(iotaStartNum, iotaStartNum + 
recordsNeeded)))

{
records ~= [ id: valuesArray[i] ];
}



Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 18:36:42 UTC, H. S. Teoh wrote:


This is wasteful if you're not planning to use every ID in this 
million-entry long array.  Much better to just use an AA to 
keep track of which IDs have already been generated instead.  
Of course, if you plan to use most of the array, then the AA 
may wind up using more memory than the array. So it depends on 
your use case.



T


yes, I was thinking this over as I was waking up this morning, 
and thought... what the hell am I doing generating all those 
numbers that might never get used.


better to do:

const int iotaStartNum = 100_000_000;
int[] idArray = iota(startiotaStartNum, iotaStartNum + 
recordsNeeded).array;





Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 09:10:56 UTC, forkit wrote:




ok... in the interest of corecting the code I posted previously...

... here is a version that actually works in secs (for a million 
records), as opposed to hours!



// ---

/+
  
=
   This program create a sample dataset consisting of 'random' 
records,

   and then outputs that dataset to a file.

   Arguments can be passed on the command line,
   or otherwise default values are used instead.

   Example of that output can be seen at the end of this code.
   
=

+/

module test;
@safe:
import std.stdio : write, writef, writeln, writefln;
import std.range : iota, takeExactly;
import std.array : array, byPair, Appender, appender;
import std.random : Random, unpredictableSeed, dice, choice, 
uniform;

import std.algorithm : map, uniq, canFind, among;
import std.conv : to;
import std.format;
import std.stdio : File;
import std.file : exists;
import std.exception : enforce;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); } // thanks Ali

void main(string[] args)
{
int recordsNeeded, valuesPerRecord;
string fname;

if(args.length < 4)
{
//recordsNeeded = 1_000_000;
//recordsNeeded = 100_000;
recordsNeeded = 10;

valuesPerRecord= 8;

//fname = "D:/rnd_records.txt";
fname = "./rnd_records.txt";
}
else
{
// assumes valid values being passed in ;-)
recordsNeeded = to!int(args[1]);
valuesPerRecord = to!int(args[2]);
fname = args[3];
}

debug
{ writefln("%s records, %s values for record, will be 
written to file: %s", recordsNeeded, valuesPerRecord, fname); }

else
{ enforce(!exists(fname), "Oop! That file already 
exists!"); }


// id needs to be 9 digits, and needs to start with 999
int[] idArray = takeExactly(iota(999*10^^6, 10^^9), 
recordsNeeded).array;

debug { writefln("idArray.length = %s", idArray.length); }

int[][] valuesArray;
createValuesArray(valuesArray, recordsNeeded, 
valuesPerRecord);


int[][int][] records = CreateDataSet(idArray, valuesArray, 
recordsNeeded);


ProcessRecords(records, fname);

writefln("All done. Check if records written to %s", fname);
}

void createValuesArray
(ref int[][] valuesArray, const(int) recordsNeeded, const(int) 
valuesPerRecord)

{
valuesArray = iota(recordsNeeded)
.map!(i => iota(valuesPerRecord)
.map!(valuesPerRecord => cast(int)rnd.dice(0.6, 1.4))
.array).array;  // NOTE: does register with 
-profile=gc


debug { writefln("valuesArray.length = %s", 
valuesArray.length); }


}

int[][int][] CreateDataSet
(const(int)[] idArray, int[][] valuesArray, const(int) numRecords)
{
int[][int][] records;
records.reserve(numRecords);
debug { writefln("records.capacity is %s", records.capacity); 
}


foreach(i, const id; idArray)
{
// NOTE: below does register with -profile=gc
records ~= [ idArray[i] : valuesArray[i] ];
}

debug { writefln("records.length = %s", records.length); }

return records.dup;
}

void ProcessRecords
(in int[][int][] recArray, const(string) fname)
{
auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(recArray.length);
debug { writefln("bigString.capacity is %s", 
bigString.capacity); }


// NOTE: forward declaration required for this nested function
void processRecord(const(int) id, const(int)[] values)
{
// NOTE: below does register with -profile=gc
bigString ~= id.to!string ~ "," ~ values.format!"%(%s,%)" 
~ "\n";

}

foreach(ref const record; recArray)
{
foreach (ref rp; record.byPair)
{
processRecord(rp.expand);
}
}

file.write(bigString[]);
}

/+
sample file output:

9992511730,1,0,1,0,1,0,1
9995369731,1,1,1,1,1,1,1
9993136031,1,0,0,0,1,0,0
9998979051,1,1,1,1,0,1,1
9998438090,1,1,0,1,1,0,0
9995132750,0,0,1,0,1,1,1
9997123630,0,1,1,1,0,1,1
9998351590,1,0,0,1,1,1,1
9991454121,1,1,1,1,1,0,1
9997673520,1,1,1,1,1,1,1

+/

// ---



Re: automate tuple creation

2022-01-21 Thread forkit via Digitalmars-d-learn
On Friday, 21 January 2022 at 08:53:26 UTC, Stanislav Blinov 
wrote:




turns out the problem has nothing to do with appender...

It's actually this line:

if (!idArray.canFind(x)):

when i comment this out in the function below, the program does 
what I want in seconds.


only problem is, the ids are no longer unique (in the file)

// ---
void createUniqueIDArray
(ref int[] idArray, const(int) recordsNeeded)
{
idArray.reserve(recordsNeeded);
debug { writefln("idArray.capacity is %s", idArray.capacity); 
}


int i = 0;
int x;
while(i != recordsNeeded)
{
   // id needs to be 9 digits, and needs to start with 999
   x = uniform(999*10^^6, 10^^9); // thanks Stanislav

   // ensure every id added is unique.
   //if (!idArray.canFind(x))
   //{
   idArray ~= x; // NOTE: does NOT appear to register 
with -profile=gc

   i++;
   //}
}

debug { writefln("idArray.length = %s", idArray.length); }
}

// 


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 04:08:33 UTC, forkit wrote:


// --

void ProcessRecords
(in int[][int][] recArray, const(string) fname)
{
auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(recArray.length);
debug { writefln("bigString.capacity is %s", 
bigString.capacity); }


void processRecord(const(int) id, const(int)[] values)
{
bigString ~= id.to!string ~ values.format!"%(%s,%)" ~ 
"\n";

}

foreach(ref const record; recArray)
{
foreach (ref rp; record.byPair)
{
processRecord(rp.expand);
}
}

file.write(bigString[]);
}

// ---


actually something not right with Appender I think...

100_000 records took 20sec (ok)


1_000_000 records never finished - after 1hr/45min I cancelled 
the process.


??


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 03:57:01 UTC, H. S. Teoh wrote:


std.array.appender is your friend.

T


:-)

// --

void ProcessRecords
(in int[][int][] recArray, const(string) fname)
{
auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(recArray.length);
debug { writefln("bigString.capacity is %s", 
bigString.capacity); }


void processRecord(const(int) id, const(int)[] values)
{
bigString ~= id.to!string ~ values.format!"%(%s,%)" ~ 
"\n";

}

foreach(ref const record; recArray)
{
foreach (ref rp; record.byPair)
{
processRecord(rp.expand);
}
}

file.write(bigString[]);
}

// ---


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 03:45:08 UTC, forkit wrote:

On Friday, 21 January 2022 at 02:30:35 UTC, Ali Çehreli wrote:


The bigger question is, why did 'formattedRecords' exist at 
all? You could have written the output directly to the file.


Oh. this was intentional, as I wanted to write once, and only 
once, to the file.




oops. looking back at that code, it seems I didn't write what i 
intended :-(


I might have to use a kindof stringbuilder instead, then write a 
massive string once to the file.


similar to C#: File.WriteAllText(Path, finalString);


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 02:30:35 UTC, Ali Çehreli wrote:


The bigger question is, why did 'formattedRecords' exist at 
all? You could have written the output directly to the file.


Oh. this was intentional, as I wanted to write once, and only 
once, to the file.


The consequence of that decision of course, is the extra memory 
allocations...


But in my example code I only create 10 records. In reality, my 
dataset will have 100,000's of records, so I don't want to write 
100,000s of time to the same file.


But even *worse* and with apologies, ;) here is something crazy 
that achieves the same thing:


void ProcessRecords
(in int[][int][] recArray, const(string) fname)
{
import std.algorithm : joiner;
auto toWrite = recArray.map!(e => e.byPair);
File("rnd_records.txt", 
"w").writefln!"%(%(%(%s,%(%s,%)%)%)\n%)"(toWrite);

}

I've done lot's of trial and error for the required number of 
nested %( %) pairs. Phew...


Ali


Yes, that does look worse ;-)

But I'm looking into that code to see if I can salvage something 
from it ;-)





Re: -debug question

2022-01-20 Thread forkit via Digitalmars-d-learn
On Friday, 21 January 2022 at 02:10:34 UTC, Steven Schveighoffer 
wrote:




thanks Steven (and Ali too).



-debug question

2022-01-20 Thread forkit via Digitalmars-d-learn
I have a line of code, that I do NOT want executed when -debug is 
passed in.


enforce(!exists(fname), "Oop! That file already exists!");

Is this even possible? (with using -version ..)



Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Friday, 21 January 2022 at 01:35:40 UTC, forkit wrote:




oops. nasty mistake to make ;-)


module test;
@safe

should be:

module test;
@safe:




Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Thursday, 20 January 2022 at 23:49:59 UTC, Ali Çehreli wrote:




so here is final code, in idiomatic D, as far as I can tell ;-)

curious output when using -profile=gc

.. a line referring to: 
std.array.Appender!(immutable(char)[]).Appender.Data 
std.array.Appender!string.Appender.this 
C:\D\dmd2\windows\bin\..\..\src\phobos\std\array.d:3330


That's not real helpful, as I'm not sure what line of my code its 
referrring to.


// ---

/+
  
=
   This program create a sample dataset consisting of 'random' 
records,

   and then outputs that dataset to a file.

   Arguments can be passed on the command line,
   or otherwise default values are used instead.

   Example of that output can be seen at the end of this code.
   
=

+/

module test;
@safe

import std.stdio : write, writef, writeln, writefln;
import std.range : iota;
import std.array : array, byPair;
import std.random : Random, unpredictableSeed, dice, choice, 
uniform;

import std.algorithm : map, uniq, canFind;
import std.conv : to;
import std.stdio : File;
import std.format;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); } // thanks Ali

void main(string[] args)
{
int recordsNeeded, valuesPerRecord;
string fname;

if(args.length < 4)
{
recordsNeeded = 10;
valuesPerRecord= 8;
fname = "D:/rnd_records.txt";
}
else
{
// assumes valid values being passed in ;-)
recordsNeeded = to!int(args[1]);
valuesPerRecord = to!int(args[2]);
fname = args[3];
}

int[] idArray;
createUniqueIDArray(idArray, recordsNeeded);

int[][] valuesArray;
createValuesArray(valuesArray, recordsNeeded, 
valuesPerRecord);


int[][int][] records = CreateDataSet(idArray, valuesArray, 
recordsNeeded);

ProcessRecords(records, fname);

writefln("All done. Check if records written to %s", fname);
}

void createUniqueIDArray
(ref int[] idArray, const(int) recordsNeeded)
{
idArray.reserve(recordsNeeded);
debug { writefln("idArray.capacity is %s", idArray.capacity); 
}


int i = 0;
int x;
while(i != recordsNeeded)
{
   // id needs to be 9 digits, and needs to start with 999
   x = uniform(999*10^^6, 10^^9); // thanks Stanislav

   // ensure every id added is unique.
   if (!idArray.canFind(x))
   {
   idArray ~= x; // NOTE: does NOT appear to register 
with -profile=gc

   i++;
   }
}
}

void createValuesArray
(ref int[][] valuesArray, const(int) recordsNeeded, const(int) 
valuesPerRecord)

{
valuesArray = iota(recordsNeeded)
.map!(i => iota(valuesPerRecord)
.map!(valuesPerRecord => cast(int)rnd.dice(0.6, 1.4))
.array).array;  // NOTE: does register with 
-profile=gc

}

int[][int][] CreateDataSet
(const(int)[] idArray, int[][] valuesArray, const(int) numRecords)
{
int[][int][] records;
records.reserve(numRecords);
debug { writefln("records.capacity is %s", records.capacity); 
}


foreach(i, const id; idArray)
{
// NOTE: below does register with -profile=gc
records ~= [ idArray[i] : valuesArray[i] ];
}
return records.dup;
}

void ProcessRecords
(in int[][int][] recArray, const(string) fname)
{
auto file = File(fname, "w");
scope(exit) file.close;

string[] formattedRecords;
formattedRecords.reserve(recArray.length);
debug { writefln("formattedRecords.capacity is %s", 
formattedRecords.capacity); }


void processRecord(const(int) id, const(int)[] values)
{
// NOTE: below does register with -profile=gc
formattedRecords ~= id.to!string ~ 
values.format!"%(%s,%)";

}

foreach(ref const record; recArray)
{
foreach (ref rp; record.byPair)
{
processRecord(rp.expand);
}
}

foreach(ref rec; formattedRecords)
file.writeln(rec);
}

/+
sample file output:

9992511730,1,0,1,0,1,0,1
9995369731,1,1,1,1,1,1,1
9993136031,1,0,0,0,1,0,0
9998979051,1,1,1,1,0,1,1
9998438090,1,1,0,1,1,0,0
9995132750,0,0,1,0,1,1,1
9997123630,0,1,1,1,0,1,1
9998351590,1,0,0,1,1,1,1
9991454121,1,1,1,1,1,0,1
9997673520,1,1,1,1,1,1,1

+/

// ---






Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn
On Thursday, 20 January 2022 at 22:31:17 UTC, Steven 
Schveighoffer wrote:


Because it would allow altering const data.



I'm not sure I understand. At what point in this function is 
valuesArray modified, and thus preventing it being passed in with 
const?


// ---

int[][int][] CreateDataSet
ref const int[] idArray, ref int[][] valuesArray, const int 
numRecords)

{
int[][int][] records;
records.reserve(numRecords);

foreach(i, const id; idArray)
records ~= [ idArray[i] : valuesArray[i] ];

return records.dup;
}

// 


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Thursday, 20 January 2022 at 21:16:46 UTC, forkit wrote:




Cannot work out why I cannot pass valuesArray in as ref const??

get error: Error: cannot append type `const(int[])[const(int)]` 
to type `int[][int][]`



// --

int[][int][] CreateDataSet(ref const int[] idArray, ref 
const(int[][]) valuesArray, const int numRecords)

{
int[][int][] records;
records.reserve(numRecords);

foreach(i, id; idArray)
records ~= [ idArray[i] : valuesArray[i] ];

return records.dup;
}

// ---


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn
On Thursday, 20 January 2022 at 12:40:09 UTC, Stanislav Blinov 
wrote:


Allocating 4 megs to generate 10 numbers??? You can generate a 
random number between 99900 and 10.


...
// id needs to be 9 digits, and needs to start with 999
   x = uniform(999*10^^6, 10^^9);

   // ensure every id added is unique.
   if (!result[0 .. i].canFind(x))
   result[i++] = x;
}
import std.exception : assumeUnique;
return result.assumeUnique;
...


Nice. Thanks. I had to compromise a little though, as assumUnique 
is @system, and all my code is @safe (and trying to avoid the 
need for inline @system wrapper ;-)


//---

void createUniqueIDArray(ref int[] idArray, int recordsNeeded)
{
idArray.reserve(recordsNeeded);
debug { writefln("idArray.capacity is %s", idArray.capacity); 
}


int i = 0;
int x;
while(i != recordsNeeded)
{
   // generate a random 9 digit id that starts with 999
   x = uniform(999*10^^6, 10^^9); // thanks Stanislav!

   // ensure every id added is unique.
   if (!idArray.canFind(x))
   {
   idArray ~= x; // NOTE: does NOT register with 
-profile=gc

   i++;
   }
}
}

//---


Re: automate tuple creation

2022-01-20 Thread forkit via Digitalmars-d-learn

On Thursday, 20 January 2022 at 10:11:10 UTC, bauss wrote:



Don't make them random then, but use an incrementor.

If you can have ids that aren't integers then you could use 
uuids too.


https://dlang.org/phobos/std_uuid.html


The 'uniqueness' of id would actually be created in the database.

I just creating a dataset to simulate an export.

I'm pretty much done, just wish -profile=gc was working in 
createUniqueIDArray(..)


// ---

module test;
@safe:

import std.stdio : write, writef, writeln, writefln;
import std.range : iota, isForwardRange, hasSlicing, hasLength, 
isInfinite;

import std.array : array, byPair;
import std.random : Random, unpredictableSeed, dice, choice;
import std.algorithm : map, uniq, canFind;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); }

void main()
{
const int recordsNeeded = 10;
const int valuesPerRecord = 8;

int[] idArray;
createUniqueIDArray(idArray, recordsNeeded);

int[][] valuesArray;
createValuesArray(valuesArray, recordsNeeded, 
valuesPerRecord);


int[][int][] records = CreateDataSet(idArray, valuesArray, 
recordsNeeded);

ProcessRecords(records);
}

void ProcessRecords(ref const(int[][int][]) recArray)
{
void processRecord(ref int id, ref const(int)[] result)
{
writef("%s\t%s", id, result);
}

foreach(ref record; recArray)
{
foreach (ref rp; record.byPair)
{
processRecord(rp.expand);
}
writeln;
}
}

int[][int][] CreateDataSet(ref int[] idArray, ref int[][] 
valuesArray, int numRecords)

{
int[][int][] records;
records.reserve(numRecords);
debug { writefln("records.capacity is %s", records.capacity); 
}


foreach(i, id; idArray)
records ~= [ idArray[i] : valuesArray[i] ]; // NOTE: does 
register with -profile=gc


return records.dup;
}

void createValuesArray(ref int[][] m, size_t recordsNeeded, 
size_t valuesPerRecord)

{
m = iota(recordsNeeded)
.map!(i => iota(valuesPerRecord)
.map!(valuesPerRecord => cast(int)rnd.dice(0.6, 1.4))
.array).array;  // NOTE: does register with 
-profile=gc

}


void createUniqueIDArray(ref int[] idArray, int recordsNeeded)
{
idArray.reserve(recordsNeeded);
debug { writefln("idArray.capacity is %s", idArray.capacity); 
}


// id needs to be 9 digits, and needs to start with 999
// below will contain 1_000_000 records that we can choose 
from.
int[] ids = iota(999_000_000, 1_000_000_000).array; // NOTE: 
does NOT register with -profile=gc


int i = 0;
int x;
while(i != recordsNeeded)
{
   x = ids.choice(rnd);

   // ensure every id added is unique.
   if (!idArray.canFind(x))
   {
   idArray ~= x; // NOTE: does NOT register with 
-profile=gc

   i++;
   }
}
}

/+
sample output:

999623777   [0, 0, 1, 1, 1, 0, 0, 0]
999017078   [1, 0, 1, 1, 1, 1, 1, 1]
999269073   [1, 1, 0, 0, 1, 1, 0, 1]
999408504   [0, 1, 1, 1, 1, 1, 0, 0]
999752314   [1, 0, 0, 1, 1, 1, 1, 0]
999660730   [0, 1, 0, 0, 1, 1, 1, 1]
999709822   [1, 1, 1, 0, 1, 1, 0, 0]
999642248   [1, 1, 1, 0, 0, 1, 1, 0]
999533069   [1, 1, 1, 0, 0, 0, 0, 0]
999661591   [1, 1, 1, 1, 1, 0, 1, 1]

+/

// ---




Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Thursday, 20 January 2022 at 04:38:39 UTC, forkit wrote:




all done ;-)

// ---

module test;

import std.stdio : writeln;
import std.range : iota, isForwardRange, hasSlicing, hasLength, 
isInfinite;

import std.array : array, Appender;
import std.random : Random, unpredictableSeed, dice, choice;
import std.algorithm : map, uniq, canFind;

@safe:

Random rnd;

static this()
{
  rnd = Random(unpredictableSeed);
}

void main()
{
int recordsNeeded = 2;
int boolValuesNeeded = 3;

uint[] uniqueIDs;
makeUniqueIDs(uniqueIDs, recordsNeeded);

uint[][] tuples;
createBoolMatrix(tuples, recordsNeeded, boolValuesNeeded);

uint[][uint][] records = CreateTupleDictionary(uniqueIDs, 
tuples);

processRecords(records);

}

auto CreateTupleDictionary(ref uint[] ids, ref uint[][] tuples)
{
uint[][uint][] records;

foreach(i, id; ids)
records ~= [ ids[i] : tuples[i] ];

return records.dup;
}

void processRecords(T)(const ref T t) if (isForwardRange!T && 
hasSlicing!T && hasLength!T && !isInfinite!T)

{
t.writeln;

// output from above should look like this:
// [[999583661:[1, 1, 0]], [999273256:[1, 1, 1]]]

// hoping to explore parallel here too...
}

void createBoolMatrix(ref uint[][] m, size_t numberOfTuples, 
size_t numberOfBoolsInTuple)

{
m = iota(numberOfTuples)
.map!(i => iota(numberOfBoolsInTuple)
.map!(numberOfBoolsInTuple => cast(uint) 
rnd.dice(0.6, 1.4))

.array).array;
}


void makeUniqueIDs(ref uint[] arr, size_t sz)
{
arr.reserve(sz);

// id needs to be 9 digits, and needs to start with 999
int[] a = iota(999_000_000, 1_000_000_000).array;
// above will contain 1_000_000 records that we can choose 
from.


int i = 0;
uint x;
while(i != sz)
{
   x = cast(uint)a.choice(rnd);

   // ensure every id added is unique.
   if (!arr.canFind(x))
   {
   arr ~= x;
   i++;
   }
}
}

// ---



Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Thursday, 20 January 2022 at 04:00:59 UTC, forkit wrote:

void makeUniqueIDs(ref uint[] arr, size_t sz)
{
  ...
}


arrg!

what was i thinking! ;-)

// ---
void makeUniqueIDs(ref uint[] arr, size_t sz)
{
arr.reserve(sz);

// id needs to be 9 digits, and needs to start with 999
int[] a = iota(999_000_000, 1_000_000_000).array;
// above will contain 1_000_000 records that we can choose 
from.


int i = 0;
uint x;
while(i != sz)
{
   x = cast(uint)a.choice(rnd);

   // ensure every id added is unique.
   if (!arr.canFind(x))
   {
   arr ~= x;
   i++;
   }
   else
   i--;
}
}


//--




Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Thursday, 20 January 2022 at 00:30:44 UTC, H. S. Teoh wrote:


Do the id's have to be unique?


yep...

I'm almost there ;-)

// ---
module test;

import std.stdio : writeln;
import std.range : iota, isForwardRange, hasSlicing, hasLength, 
isInfinite;

import std.array : array, Appender;
import std.random : Random, unpredictableSeed, dice, choice;
import std.algorithm : map, uniq;

@safe:

Random rnd;

static this()
{
  rnd = Random(unpredictableSeed);
}

void main()
{
int recordsNeeded = 5;

uint[] uniqueIDs;
makeUniqueIDs(uniqueIDs, recordsNeeded);
writeln(uniqueIDs);

uint[][] mArrBool;

// e.g: create a matrix consisting of 5 tuples,
// with each tuple containing 3 random bools (0 or 1)
createBoolMatrix(mArrBool,recordsNeeded, 3);

// process just writeln's it's argument at the moment
process(mArrBool); // [[1, 1, 1], [0, 0, 1], [1, 1, 1], [1, 
1, 1], [1, 1, 0]]


// to do (integrate a single value taken from uniqueIDs so 
that each tuple looks like this: [999575454:[1, 1, 1]]

// e.g.
// processRecords(records);
// output from above should look like this below:
// [ [999575454:[1, 1, 1]], [999704246:[0, 0, 1]], 
[69331:[1, 1, 1]], [999678591:[1, 1, 1]], [999691754:[1, 1, 
0]] ]


}

void createBoolMatrix(ref uint[][] m, size_t numberOfTuples, 
size_t numberOfBoolsInTuple)

{
m = iota(numberOfTuples)
.map!(i => iota(numberOfBoolsInTuple)
.map!(numberOfBoolsInTuple => cast(uint) 
rnd.dice(0.6, 1.4))

.array).array;
}

void process(T)(const ref T t) if (isForwardRange!T && 
hasSlicing!T && hasLength!T && !isInfinite!T)

{
t.writeln;
}

void processRecords(T)(const ref T t) if (isForwardRange!T && 
hasSlicing!T && hasLength!T && !isInfinite!T)

{
t.writeln;
}


void makeUniqueIDs(ref uint[] arr, size_t sz)
{
// id needs to be 9 digits, and needs to start with 999
int[] a = iota(999_000_000, 1_000_000_000).array; // can 
produce a max of 1_000_000 records.


Appender!(uint[]) appndr;
// pre-allocate space to avoid costly reallocations
appndr.reserve(sz+1);

foreach(value; 1..(sz + 1))
appndr ~= cast(uint)a.choice(rnd);

// just interesting to see often this asserts.
//assert(appndr[].array == appndr[].uniq.array);

arr = appndr[].uniq.array;

// function should not return if this asserts (i.e. app will 
exit)

assert(arr[].array == arr[].uniq.array);
}
// ---



Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 21:59:15 UTC, forkit wrote:




so at the moment i can get a set number of tuples, with a set 
number of bool values contained within each tuple.


e.g.
createBoolMatrix(mArrBool,3, 2);
[[1, 0], [1, 1], [1, 0]]

my next challenge (more for myself, but happy for input)..

is to enhance this to an return an associative array:

e.g

createBoolAssociativeMatrix(mArrBool,3, 2);

[ [1000:[1, 0]], [1001:[1, 1]], [1001:[1, 0]]]


where 1000 is some random id...



Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 22:35:58 UTC, Ali Çehreli wrote:




so I combined ideas from all responses:

// --
module test;

import std.stdio : writeln;
import std.range : iota, isForwardRange, hasSlicing, hasLength, 
isInfinite, array;

import std.random : Random, unpredictableSeed, dice;
import std.algorithm : map;

@safe:

Random rnd;

static this()
{
  rnd = Random(unpredictableSeed);
}

void main()
{
uint[][] mArrBool;

// e.g: create a matrix consisting of 5 tuples, with each 
tuple containing 3 random bools (0 or 1)

createBoolMatrix(mArrBool,5, 2);

process(mArrBool);
}

void createBoolMatrix(ref uint[][] m, size_t numberOfTuples, 
size_t numberOfBoolsInTuple)

{
m = iota(numberOfTuples)
.map!(i => iota(numberOfBoolsInTuple)
.map!(numberOfBoolsInTuple => cast(uint) 
rnd.dice(0.6, 1.4))

.array).array;
}

void process(T)(const ref T t) if (isForwardRange!T && 
hasSlicing!T && hasLength!T && !isInfinite!T)

{
t.writeln;
}

//--



Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 23:22:17 UTC, forkit wrote:




oops

// e.g: create a matrix consisting of 5 tuples, with each tuple 
containing 3 random bools (0 or 1)

createBoolMatrix(mArrBool,5, 3);


Re: automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 21:59:15 UTC, forkit wrote:




oh. that randomShuffle was unnecessary ;-)



automate tuple creation

2022-01-19 Thread forkit via Digitalmars-d-learn

so I have this code below, that creates an array of tuples.

but instead of hardcoding 5 tuples (or hardcoding any amount of 
tuples),
what I really want to do is automate the creation of 
how-ever-many tuples I ask for:


i.e.

instead of calling this: createBoolMatrix(mArrBool);
I would call something like this: createBoolMatrix(mArrBool,5); 
// create an array of 5 typles.


Some ideas about direction would be welcome ;-)


// ---
module test;

import std.stdio;
import std.range;
import std.traits;
import std.random;

@safe:

void main()
{
uint[][] mArrBool;
createBoolMatrix(mArrBool);
process(mArrBool);
}

void process(T)(const ref T t) if (isForwardRange!T && 
!isInfinite!T)

{
t.writeln; // sample output -> [[0, 1], [1, 0], [1, 1], [1, 
1], [1, 1]]

}

void createBoolMatrix(ref uint[][] m)
{
auto rnd = Random(unpredictableSeed);

// btw. below does register with -profile=gc
m = [ [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 
1.6)].randomShuffle(rnd),
  [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 
1.6)].randomShuffle(rnd),
  [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 
1.6)].randomShuffle(rnd),
  [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 
1.6)].randomShuffle(rnd),
  [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 
1.6)].randomShuffle(rnd)

];
}
// --


Re: number ranges

2022-01-18 Thread forkit via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 03:00:49 UTC, Tejas wrote:

On Tuesday, 18 January 2022 at 20:43:08 UTC, forkit wrote:

On Tuesday, 18 January 2022 at 16:02:42 UTC, Tejas wrote:


Newer languages nowadays use `start..intent, think it's something we should follow?


I've decided to avoid using number ranges 'directly', and 
instead use a wrapper function...



auto range(T:T)(T a, T b)
{
import std.range : iota;
return iota(a, (b+1));
}


Aww, come on; it ain't that bad...


Well that depends on entirely on what the code is doing ;-)

The key is to *always* *remember* the stop index is not included.

I sure hope they 'remembered' this in the code running on that 
telescope floating out into open space...




Re: shared defaultlib with dmd

2022-01-18 Thread forkit via Digitalmars-d-learn

On Tuesday, 18 January 2022 at 22:35:08 UTC, H. S. Teoh wrote:
On Tue, Jan 18, 2022 at 10:04:15PM +, forkit via 
Digitalmars-d-learn wrote:

so I use this compile command (on Windows, using ldc)

-link-defaultlib-shared=true

Then (in simple example) the size of my compiled .exe:

From 806KB down to 18KB

Oh. That's so much nicer on my SSD ;-)

(yes, I understand the implictions here of dynamic sharing, 
but I test/compile/debug so much, that I'd like to limit the 
impact on my SSD drive.

[...]

Uhm... are you SURE this is actually nicer on your SSD?  For 
all you know, it could be writing the 806KB first and then 
optimizing that in-place to reduce it to 18KB...  Just because 
the final file size is small doesn't mean there aren't any 
large intermediate files.



T


no. there are no intermediary files. just this, and only this:

(bytes)
145 EZ_Compiler_tmpfile.d
15,360 EZ_Compiler_tmpfile.exe
18,384 EZ_Compiler_tmpfile.obj





Re: shared defaultlib with dmd

2022-01-18 Thread forkit via Digitalmars-d-learn

On Tuesday, 18 January 2022 at 22:09:18 UTC, Adam D Ruppe wrote:

On Tuesday, 18 January 2022 at 22:04:15 UTC, forkit wrote:

so I use this compile command (on Windows, using ldc)


On Linux dmd can do `-defaultlib=libphobos2.so` for the same 
thing.


On Windows, dmd cannot handle a shared druntime.


yes. but why?

 - is it technically too difficult? (ldc seems to have overcome 
that, if that's true)




Re: number ranges

2022-01-18 Thread forkit via Digitalmars-d-learn

On Tuesday, 18 January 2022 at 20:50:06 UTC, Ali Çehreli wrote:


Needs a little more work to be correct. The following produces 
and empty range. ;)


  range(uint.min, uint.max)

Also, is it important for the result to be the same as T? For 
example, even if T is ubyte, because b+1 is 'int', the range 
will produce ints.


Ali


a change of mind...

never use number ranges.. not ever!  ;-)

(except in combination with iota)



shared defaultlib with dmd

2022-01-18 Thread forkit via Digitalmars-d-learn

so I use this compile command (on Windows, using ldc)

-link-defaultlib-shared=true

Then (in simple example) the size of my compiled .exe:

From 806KB down to 18KB

Oh. That's so much nicer on my SSD ;-)

(yes, I understand the implictions here of dynamic sharing, but I 
test/compile/debug so much, that I'd like to limit the impact on 
my SSD drive.


But I can't do this with dmd ?? it has not such option ??



Re: number ranges

2022-01-18 Thread forkit via Digitalmars-d-learn

On Tuesday, 18 January 2022 at 16:02:42 UTC, Tejas wrote:


Newer languages nowadays use `start..intent, think it's something we should follow?


I've decided to avoid using number ranges 'directly', and instead 
use a wrapper function...



auto range(T:T)(T a, T b)
{
import std.range : iota;
return iota(a, (b+1));
}




Re: number ranges

2022-01-17 Thread forkit via Digitalmars-d-learn

On Monday, 17 January 2022 at 22:28:10 UTC, H. S. Teoh wrote:


If I ever needed to foreach over 1-based indices, I'd write it 
this way in order to avoid all confusion:


foreach (i; 1 .. 5 + 1)
{
}

This will immediately make whoever reads the code (i.e., myself 
after 2 months :D) wonder, "why +1?" And the answer will become 
clear and enlightenment ensues. ;-)



T


If I were able to write a compiler, my compiler would warn you:

"This is ill-advised and you should know better! Please rewrite 
this."




Re: number ranges

2022-01-17 Thread forkit via Digitalmars-d-learn

On Monday, 17 January 2022 at 22:06:47 UTC, H. S. Teoh wrote:


Basically,

foreach (i; a .. b)

is equivalent to:

for (auto i = a; i < b; i++)

Just think of that way and it will make sense.



I think it's fair to say, that I'm familiar with 0-based indexing 
;-)


my concern was with the 1..5 itself.

In terms of what makes sense, it actually makes more sense not to 
use it, at all ;-)




Re: number ranges

2022-01-17 Thread forkit via Digitalmars-d-learn

On Monday, 17 January 2022 at 11:58:18 UTC, Paul Backus wrote:


This kind of half-open interval, which includes the lower bound 
but excludes the upper bound, is used in programming because it 
lets you write


foreach (i; 0 .. array.length) writef("%s ", array[i]);

...without going past the end of the array.


Yes. But the intent here is clearly stated and cannot be 
misunderstood -> array.length


Whereas 1..5 is just an opportunity to shoot yourself in the foot.

"the heretic must be cast out not because of the probability that 
he is wrong but because of the possibility that he is right." - 
Edsger W. Dijkstra


number ranges

2022-01-17 Thread forkit via Digitalmars-d-learn

so I'm wondering why the code below prints:

1 2 3 4

and not

1 2 3 4 5

as I would expect.

foreach (value; 1..5) writef("%s ", value);

also, why is this not possible:

int[] arr = 1..5.array;




  1   2   >