Re: [go-nuts] Randomizing contents of a file

2016-09-20 Thread Bakul Shah
Not quite what you asked for but rather than use N goroutines, why not slurp in 
the whole file in a list  ([]string) of lines and then output them in random 
order? Something like

for _, i := range deal(len(lines)) {
  fmt.Println(lines[i])
}

Where you'd write deal(n) to return a list of n numbers in range 0..n-1 in a 
randomized order, without repeating a number.

> On Sep 20, 2016, at 3:43 AM, Unknown User  wrote:
> 
> Hi All,
> 
> I am trying to print the contents of  a file randomizing the lines.
> The following code works, but does not exit even after all the lines are read.
> What needs to be done to correct it?
> 
> package main
> 
> import(
> "fmt"
> "bufio"
> "os"
> "math/rand"
> "time"
> )
> 
> func main() {
> filename := os.Args[1]
> if filename == "" {
> panic("No filename")
> }
> fh,err := os.Open(filename)
> if err != nil { 
> panic(err)
> }
> scanner := bufio.NewScanner(fh)
> c := make(chan string)
> for scanner.Scan() {
> line := scanner.Text()
> err := scanner.Err()
> if err != nil { 
> close(c)
> }
> go func(l string){
> time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond)
> c <-  l
> }(line)
> }
> for  { 
> select { 
> case myline := <- c:
> fmt.Println(myline)
> default:
> break
> }
> }
> }
>  
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Randomizing contents of a file

2016-09-20 Thread Marvin Renich
* Unknown User  [160920 06:43]:
> Hi All,
> 
> I am trying to print the contents of  a file randomizing the lines.
> The following code works, but does not exit even after all the lines are 
> read.
> What needs to be done to correct it?

Try this 

package main

import(
"fmt"
"bufio"
"os"
"math/rand"
"sync"
"time"
)

func main() {
filename := os.Args[1]
if filename == "" {
panic("No filename")
}
fh,err := os.Open(filename)
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(fh)
c := make(chan string)
var wg sync.WaitGroup
for scanner.Scan() {
line := scanner.Text()
wg.Add(1)
go func(l string){
time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond)
c <-  l
wg.Done()
}(line)
}
go func() {
wg.Wait()
close(c)
}()
for  {
myline, ok := <-c
if !ok {
return
}
fmt.Println(myline)
}
}

You need a way to determine when all of the spawned goroutines have sent
their line to the channel so you know when to exit the bottom for loop.
A select doesn't help, because the goroutines are sending on the channel
at random intervals, so the default case will cause a busy loop between
sends, not just after all sends have completed.

The WaitGroup keeps track of how many worker goroutines have not yet
finished.  The final goroutine (started below the top for loop) waits
for all the workers to finish, then closes the channel.

The bottom for loop does not use a select statement; it merely reads
from the channel, which will block until the next worker sends its line.
When the final goroutine closes the channel, the channel read will
return "", false, and the bottom for loop will exit.

As a general rule of thumb, use a select only when you have more than
one channel send and/or receive that you want to wait for, and only use
a default case when you have other work that can be done if the channel
operations are all blocked (waiting).  Don't use default in an otherwise
empty for loop around a select.

hth...Marvin

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Randomizing contents of a file

2016-09-20 Thread Dave Cheney
Break breaks out of the select, not the for. Return would work here, or you 
could use a labled break. 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Randomizing contents of a file

2016-09-20 Thread Unknown User
Hi All,

I am trying to print the contents of  a file randomizing the lines.
The following code works, but does not exit even after all the lines are 
read.
What needs to be done to correct it?

package main

import(
"fmt"
"bufio"
"os"
"math/rand"
"time"
)

func main() {
filename := os.Args[1]
if filename == "" {
panic("No filename")
}
fh,err := os.Open(filename)
if err != nil { 
panic(err)
}
scanner := bufio.NewScanner(fh)
c := make(chan string)
for scanner.Scan() {
line := scanner.Text()
err := scanner.Err()
if err != nil { 
close(c)
}
go func(l string){
time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond)
c <-  l
}(line)
}
for  { 
select { 
case myline := <- c:
fmt.Println(myline)
default:
break
}
}
}
 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.