Highline - question with multiple choices

Hi,

I've got an array of user logins and need to provide a way to select
one or more of them with auto-completion. Currently I've got code
straight from readline example:

users = ask("Select users: ", user_logins) do |q|
    q.readline = true
end

The problem is that it says "You must choose one of...." if I select
more than one login. How to allow to select multiple choices?

Hi,

Hello.

I've got an array of user logins and need to provide a way to select
one or more of them with auto-completion. Currently I've got code
straight from readline example:

users = ask("Select users: ", user_logins) do |q|
   q.readline = true
end

The problem is that it says "You must choose one of...." if I select
more than one login. How to allow to select multiple choices?

Is it okay to ask the user to enter one login per line with a blank line to end? If so, this code should work:

#!/usr/bin/env ruby -wKU

require "rubygems"
require "highline/import"

LOGINS = %w[bob joe dave alice hal]

selected = ask("Select Users:", LOGINS + [""]) do |q|
   q.readline = true
   q.gather = ""
end
p selected

__END__

Hope that helps.

James Edward Gray II

···

On Nov 14, 2008, at 4:23 AM, szimek wrote:

Thanks, I'll probably use this solution for now, but is it possible at
all with highline to make it in a single line?

Another question: I'd like user to be able to select a ticket number
from a list with auto-complete. But if user presses tab, I'd like to
display not only possible ticket numbers, but their descriptions as
well - one entry (i.e. "1234 - something doesn't work") per line, if
it's possible.

···

On 14 Lis, 14:52, James Gray <ja...@grayproductions.net> wrote:

On Nov 14, 2008, at 4:23 AM, szimek wrote:

> Hi,

Hello.

> I've got an array of user logins and need to provide a way to select
> one or more of them with auto-completion. Currently I've got code
> straight from readline example:

> users = ask("Select users: ", user_logins) do |q|
> q.readline = true
> end

> The problem is that it says "You must choose one of...." if I select
> more than one login. How to allow to select multiple choices?

Is it okay to ask the user to enter one login per line with a blank
line to end? If so, this code should work:

#!/usr/bin/env ruby -wKU

require "rubygems"
require "highline/import"

LOGINS = %w[bob joe dave alice hal]

selected = ask("Select Users:", LOGINS + [""]) do |q|
q.readline = true
q.gather = ""
end
p selected

__END__

Hope that helps.

James Edward Gray II

Hi,

Hello.

I've got an array of user logins and need to provide a way to select
one or more of them with auto-completion. Currently I've got code
straight from readline example:

users = ask("Select users: ", user_logins) do |q|
   q.readline = true
end

The problem is that it says "You must choose one of...." if I select
more than one login. How to allow to select multiple choices?

Is it okay to ask the user to enter one login per line with a blank
line to end? If so, this code should work:

#!/usr/bin/env ruby -wKU

require "rubygems"
require "highline/import"

LOGINS = %w[bob joe dave alice hal]

selected = ask("Select Users:", LOGINS + [""]) do |q|
   q.readline = true
   q.gather = ""
end
p selected

__END__

Hope that helps.

James Edward Gray II

Thanks, I'll probably use this solution for now, but is it possible at
all with highline to make it in a single line?

Not with autocompletion, no. HighLine doesn't allow you to manually set the autocompletion Proc used by Readline. Perhaps we should, but then if you do that you probably aren't gaining anything from HighLine and you should probably just use Readline manually.

Another question: I'd like user to be able to select a ticket number
from a list with auto-complete. But if user presses tab, I'd like to
display not only possible ticket numbers, but their descriptions as
well - one entry (i.e. "1234 - something doesn't work") per line, if
it's possible.

Sure, just set an Array of Strings with the number and description as you show above for the values. They will auto complete fine, and you can strip the description after you have their answer.

James Edward Gray II

···

On Nov 15, 2008, at 7:18 AM, szimek wrote:

On 14 Lis, 14:52, James Gray <ja...@grayproductions.net> wrote:

On Nov 14, 2008, at 4:23 AM, szimek wrote:

Hello all, I'm new here and i have a problem...
Can you tell me what I'm doing wrong?
Here is fragment of my code:
      choose do |menu|
        menu.prompt = "Please choose your test: "
            for j in 0..ip.length-1
              menu.choice(:"#{ip[j][0]}\t\t\t\t#{ip[j][1]} : #{port}",
"blahblah#{j}") do
                system "cls"
                ParsePING(ip[j][0], ip[j][1], port)
              end
            end#for
      end

All options prints great. But when I choose any option, always executes
only last one... It looks like every menu option have implemented
ParsePING function with last j parameter.
Can someone help?

Kraku

Happy new year for everyone!

···

--
Posted via http://www.ruby-forum.com/.

Hello all, I'm new here and i have a problem...

Welcome.

Can you tell me what I'm doing wrong?

I'll try to help.

Here is fragment of my code:
     choose do |menu|
       menu.prompt = "Please choose your test: "
           for j in 0..ip.length-1
             menu.choice(:"#{ip[j][0]}\t\t\t\t#{ip[j][1]} : #{port}",
"blahblah#{j}") do
               system "cls"
               ParsePING(ip[j][0], ip[j][1], port)
             end
           end#for
     end

All options prints great. But when I choose any option, always executes
only last one... It looks like every menu option have implemented
ParsePING function with last j parameter.
Can someone help?

I don't see an obvious problem with the code, so I suggest we start by validating ParsePING(). Without using HighLine at all, can you just manually call it with a few different parameters and make sure it is doing what you expect?

James Edward Gray II

···

On Dec 30, 2008, at 5:57 AM, Tomasz Krakowski wrote:

I don't see an obvious problem with the code, so I suggest we start by
validating ParsePING(). Without using HighLine at all, can you just
manually call it with a few different parameters and make sure it is
doing what you expect?

James Edward Gray II

Parseping is working well, here is it:

  def ParsePING(tvChann, tvIP, tvPort)
    puts"Checking: #{tvChann.upcase}, #{tvIP}:#{tvPort}"
    a = %x{mcfirst -t 10 -c 50 #{tvIP} #{tvPort}}
    a = a.split("\n")
    len= a.length
    for i in 0..len-1
      if a[i] != nil
        if a[i].match("Average") #search for line that matches text
          aa=a[i]
        else
          next
        end #if
      else
        next
      end #if
    end # for

    if aa ==nil
       puts "Something is wrong with: #{tvChann}, #{tvIP}:#{tvPort}"
       puts "I've not received any packets!"
       puts "================================================="
      else
       puts "#{aa}"
       puts
    end#if
end # def

I think there may be something with HighLine...:frowning:

Regards

···

--
Posted via http://www.ruby-forum.com/\.

I don't see an obvious problem with the code, so I suggest we start by
validating ParsePING(). Without using HighLine at all, can you just
manually call it with a few different parameters and make sure it is
doing what you expect?

James Edward Gray II

Parseping is working well, here is it:

OK, if you trust it, we will take it out of our consideration.

I think there may be something with HighLine...:frowning:

Let's try to rule that out then. Here is pretty much your original code, minus ParsePING() and your ip variable:

#!/usr/bin/env ruby -wKU

require "rubygems"
require "highline/import"

MENU = { :one => lambda { puts "You chose 'one.'" },
          :two => lambda { puts "You chose 'two.'" } }

choose do |menu|
   menu.prompt = "Please choose your test: "
   MENU.each do |name, code|
     menu.choice(name, "Help for #{name}") do
       code.call
     end
   end
end

__END__

That works as I expect it to. Is it the same for you?

That leaves the ip variable as our most likely candidate of problems. Did you perhaps accidentally load it with code similar to the following?

#!/usr/bin/env ruby -wKU

ip = Array.new(2, Array.new)
p ip
ip[0][0] = "Double"
p ip

__END__

Anyway, I recommend making sure that variable holds what you think it does.

James Edward Gray II

···

On Jan 5, 2009, at 1:17 AM, Tomasz Krakowski wrote:

Parseping is working well, here is it:

I also believe you can simplify this code quite a bit. I recommend this chunk of code:

   a = a.split("\n")
   len= a.length
   for i in 0..len-1
     if a[i] != nil
       if a[i].match("Average") #search for line that matches text
         aa=a[i]
       else
         next
       end #if
     else
       next
     end #if
   end # for

with:

   aa = a.find { |line| line.include? "Average" } # for Ruby 1.8

or:

   aa = a.lines.find { |line| line.include? "Average" } # for Ruby 1.9

I believe it's 100% equivalent to what you are doing above.

James Edward Gray II

···

On Jan 5, 2009, at 1:17 AM, Tomasz Krakowski wrote:

That works as I expect it to. Is it the same for you?

Yes it is ok but I'm in need to create that menu dynamically. I've done
already menu with 'static' menu items and that works. Now I have
problem,as you can see, with dynamic one.

Anyway, I recommend making sure that variable holds what you think it
does.

Yes I'm sure, by now it is included from other source file and looks
like that:
$ip = [
  ["tvp1", "238.269.2.1"],
  ["tvp2", "219.249.2.2"],
  ["tvp info", "219.269.2.3"],
  ["polsat", "219.269.2.4"], blahblah etc. one hundred more of them...In
the future it will be loaded from txt file in runtime, but now if
dynamic cration of menu items not work it makes no sense.

  aa = a.find { |line| line.include? "Average" } # for Ruby 1.8
or:
  aa = a.lines.find { |line| line.include? "Average" } # for Ruby 1.9

Very nice :), thank you. I'm only seasonal coder so I'm using syntax
which is familiar to me :slight_smile: I'm customer support who wants to make my own
life slighly easier.

···

--
Posted via http://www.ruby-forum.com/\.

That works as I expect it to. Is it the same for you?

Yes it is ok but I'm in need to create that menu dynamically.

Did you notice that the example I gave created a menu dynamically?

Anyway, I recommend making sure that variable holds what you think it
does.

Yes I'm sure, by now it is included from other source file and looks
like that:
$ip = [
["tvp1", "238.269.2.1"],
["tvp2", "219.249.2.2"],
["tvp info", "219.269.2.3"],
["polsat", "219.269.2.4"], blahblah etc. one hundred more of them...

Alright, I'm out of easy guesses. :slight_smile:

Here's what we can do. You can build a minimal script I can run to see how HighLine is broken. That should be pretty easy, since you can just drop in the variable definition above and your ParsePING() method definition.

Please try to reduce the code as much as possible though, to just show the problem. For example, you probably don't need to shell out. You could instead just print the command you would have executed.

Send me that script and the steps to see the problem. "I picked the third menu option by typing…," will be fine.

I promise to use that to fix any bugs it uncovers. Fair enough?

James Edward Gray II

···

On Jan 6, 2009, at 1:27 AM, Tomasz Krakowski wrote:

James Gray wrote:

I promise to use that to fix any bugs it uncovers. Fair enough?

Thank you James for your patience :slight_smile:

Here is sample script:

#!/usr/bin/env ruby -wKU

require "rubygems"
require "highline/import"

ip = [
  ["tvp1", "219.239.2.1"],
  ["tvp2", "219.239.2.2"],
  ["tvp info", "219.239.2.3"],
  ["polsat", "219.239.2.4"],
  ["tvn", "219.239.2.5"],
  ["tvp kultura", "219.239.2.6"],
  ["tvp polonia", "219.239.2.7"],
  ["tvp historia", "219.239.2.9"]]

  choose do |menu|
     menu.prompt = "Please choose your test: "
         for j in 0..ip.length-1
           menu.choice(:"#{ip[j][0]}\t\t\t#{ip[j][1]} ", "blabla#{j}")
do
             puts "#{ip[j][0]}\t\t\t#{ip[j][1]} - your choice"
           end
         end#for
    end

on my compilation there is always executed last option. Does not matter
which one you pick.

Regards

···

--
Posted via http://www.ruby-forum.com/\.

James Gray wrote:

I promise to use that to fix any bugs it uncovers. Fair enough?

Thank you James for your patience :slight_smile:

I'm glad we're getting it figured out.

Here is sample script:

OK, the short story is that there's no bugs here. You are just running into surprising "features" of Ruby.

First, let me show how to fix your code:

#!/usr/bin/env ruby -wKU

require "rubygems"
require "highline/import"

ip = [
["tvp1", "219.239.2.1"],
["tvp2", "219.239.2.2"],
["tvp info", "219.239.2.3"],
["polsat", "219.239.2.4"],
["tvn", "219.239.2.5"],
["tvp kultura", "219.239.2.6"],
["tvp polonia", "219.239.2.7"],
["tvp historia", "219.239.2.9"]]

choose do |menu|
    menu.prompt = "Please choose your test: "
        for j in 0..ip.length-1

ip.each_with_index do |row, i|

          menu.choice(:"#{ip[j][0]}\t\t\t#{ip[j][1]} ", "blabla#{j}") do

menu.choice("#{row.first}\t\t\t#{row.last} ", "blabla#{i}") do

            puts "#{ip[j][0]}\t\t\t#{ip[j][1]} - your choice"

puts "#{row.first}\t\t\t#{row.last} - your choice"

          end
        end#for
   end

Those simple changes should make your code run as expected.

on my compilation there is always executed last option. Does not matter
which one you pick.

For an explanation of why you were seeing this, please see this write up on my blog:

James Edward Gray II

···

On Jan 7, 2009, at 2:36 AM, Tomasz Krakowski wrote:

For an explanation of why you were seeing this, please see this write
up on my blog:

Gray Soft / Not Found

"The moral (my opinion, of course): for is evil because it's surprising
and hard to think through. Avoid it."

James Edward Gray II

Thank you!!
You are great! I didn't expected such... detailed explanation :slight_smile:
Now, all is working well.

Best regards
Kraku

···

--
Posted via http://www.ruby-forum.com/\.