Ruby using count to tally instances of a word instead of its component letters
I'm trying to tally up the number of wins a team has, but my code has it counting the instances of each individual letter in the team's name.
wins = 0
puts "Please enter a team name to check"
teamname = gets.chomp.to_s
tencentbeernight = IO.readlines("winners.txt").to_s
wins = tencentbeernight.count(teamname)
printf "The %2s have won %2i times" % [teamname, wins]
How do I get it to count the name of the team?
ruby
add a comment |
I'm trying to tally up the number of wins a team has, but my code has it counting the instances of each individual letter in the team's name.
wins = 0
puts "Please enter a team name to check"
teamname = gets.chomp.to_s
tencentbeernight = IO.readlines("winners.txt").to_s
wins = tencentbeernight.count(teamname)
printf "The %2s have won %2i times" % [teamname, wins]
How do I get it to count the name of the team?
ruby
Unrelated, but canonical Ruby code uses_
to separate words in variable names, e.g.,team_name
orten_cent_beer_night
. Please either use that (preferred) or something to avoid word smashes.
– Dave Newton
Nov 21 '18 at 19:01
gets
andchomp
returns strings, soto_s
is redundant.
– Cary Swoveland
Nov 21 '18 at 19:55
add a comment |
I'm trying to tally up the number of wins a team has, but my code has it counting the instances of each individual letter in the team's name.
wins = 0
puts "Please enter a team name to check"
teamname = gets.chomp.to_s
tencentbeernight = IO.readlines("winners.txt").to_s
wins = tencentbeernight.count(teamname)
printf "The %2s have won %2i times" % [teamname, wins]
How do I get it to count the name of the team?
ruby
I'm trying to tally up the number of wins a team has, but my code has it counting the instances of each individual letter in the team's name.
wins = 0
puts "Please enter a team name to check"
teamname = gets.chomp.to_s
tencentbeernight = IO.readlines("winners.txt").to_s
wins = tencentbeernight.count(teamname)
printf "The %2s have won %2i times" % [teamname, wins]
How do I get it to count the name of the team?
ruby
ruby
edited Nov 21 '18 at 19:00
Wayne Phipps
1,15342130
1,15342130
asked Nov 21 '18 at 18:23
ValleyantValleyant
154
154
Unrelated, but canonical Ruby code uses_
to separate words in variable names, e.g.,team_name
orten_cent_beer_night
. Please either use that (preferred) or something to avoid word smashes.
– Dave Newton
Nov 21 '18 at 19:01
gets
andchomp
returns strings, soto_s
is redundant.
– Cary Swoveland
Nov 21 '18 at 19:55
add a comment |
Unrelated, but canonical Ruby code uses_
to separate words in variable names, e.g.,team_name
orten_cent_beer_night
. Please either use that (preferred) or something to avoid word smashes.
– Dave Newton
Nov 21 '18 at 19:01
gets
andchomp
returns strings, soto_s
is redundant.
– Cary Swoveland
Nov 21 '18 at 19:55
Unrelated, but canonical Ruby code uses
_
to separate words in variable names, e.g., team_name
or ten_cent_beer_night
. Please either use that (preferred) or something to avoid word smashes.– Dave Newton
Nov 21 '18 at 19:01
Unrelated, but canonical Ruby code uses
_
to separate words in variable names, e.g., team_name
or ten_cent_beer_night
. Please either use that (preferred) or something to avoid word smashes.– Dave Newton
Nov 21 '18 at 19:01
gets
and chomp
returns strings, so to_s
is redundant.– Cary Swoveland
Nov 21 '18 at 19:55
gets
and chomp
returns strings, so to_s
is redundant.– Cary Swoveland
Nov 21 '18 at 19:55
add a comment |
2 Answers
2
active
oldest
votes
count
counts the number of individual characters, not the instances of the string.
Try:
wins = tencentbeernight.scan(teamname).length
This will use teamname
as a regular expression and count the number of times it appears.
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
1
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
1
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
add a comment |
Converting the array returned by IO::readlines to a string and then counting the number of times a string appears in that string can be made to work but it is not an approach that any experienced Rubiest would take.
First, let's create a file "winners.txt"
.
arr = ["Raiders", "Bears", "bearskin rug", "Chargers", "my bugbears", "bears"]
str = arr.join("n")
#=> "RaidersnBearsnbearskin rugnChargersnmy bugbearsnbears"
filename = "winners.txt"
File.write(filename, str)
#=> 53 (characters written)
and get the name of the team:
team = gets.chomp
#=> "bears"
See IO#write.1
The approach advocated in the question and provided in another answer is as follows:
array = IO.readlines(filename)
#> ["Raidersn", "Bearsn", "bearskin rugn", "Chargersn", "my bugbearsn", "bears"]
str = array.to_s
#=> "["Raiders\n", "Bears\n", "bearskin rug\n", "Chargers\n", "my bugbears\n", "bears"]"
a = str.scan(team)
#=> ["bears", "bears", "bears"]
a.size
#=> 3
which is incorrect. We could get around those problems, but the more conventional approach is the following:
team = gets.downcase.chomp
#=> "bears"
a = File.readlines(filename)
#=> ["raidersn", "bearsn", "bearskin rugn", "chargersn", "my bugbearsn", "bears"]
a.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
which gives the correct answer, as a[1]
and a[-1]
(and only those elements) are matched. The regular expression reads, "match a word break (b
) following by the value of team
followed by another word break".
We can improve on this however. There is no need to create the temporary array, a
. Instead we use IO::foreach, which reads the file line-by-line and, when used without a block, returns an enumerator:
enum = File.foreach(filename)
#=> #<Enumerator: File:foreach("winners.txt")>
We can see the values that will be generated by enum
by converting it to an array:
enum.to_a
#=> ["raidersn", "n", "bearsn", "n", "bearskin rugn", "n", "chargersn",
# "n", "my bugbearsn", "n", "bearsn"]
Continuing,
enum.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
One would normally chain the two methods:
File.foreach(filename).count { |s| s.downcase.match?(/b#{team}b/) }
#= 2
1 I've used File
as the receiver for some methods that are defined in the class IO
. That's commonly done and works because File.superclass #=> IO
.
add a comment |
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418354%2fruby-using-count-to-tally-instances-of-a-word-instead-of-its-component-letters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
count
counts the number of individual characters, not the instances of the string.
Try:
wins = tencentbeernight.scan(teamname).length
This will use teamname
as a regular expression and count the number of times it appears.
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
1
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
1
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
add a comment |
count
counts the number of individual characters, not the instances of the string.
Try:
wins = tencentbeernight.scan(teamname).length
This will use teamname
as a regular expression and count the number of times it appears.
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
1
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
1
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
add a comment |
count
counts the number of individual characters, not the instances of the string.
Try:
wins = tencentbeernight.scan(teamname).length
This will use teamname
as a regular expression and count the number of times it appears.
count
counts the number of individual characters, not the instances of the string.
Try:
wins = tencentbeernight.scan(teamname).length
This will use teamname
as a regular expression and count the number of times it appears.
edited Nov 21 '18 at 19:00
Dave Newton
141k19215258
141k19215258
answered Nov 21 '18 at 18:58
TrinculoTrinculo
7651519
7651519
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
1
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
1
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
add a comment |
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
1
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
1
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
IO.readLines returns an array so I believe count would return the number of elements?
– Wayne Phipps
Nov 21 '18 at 19:01
1
1
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
@WaynePhipps - He calls ".to_s" on it so it comes back as a string representation of the Array.
– Trinculo
Nov 21 '18 at 19:05
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
well spotted, my bad
– Wayne Phipps
Nov 21 '18 at 19:07
1
1
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
Thanks a ton, that did it.
– Valleyant
Nov 21 '18 at 19:37
add a comment |
Converting the array returned by IO::readlines to a string and then counting the number of times a string appears in that string can be made to work but it is not an approach that any experienced Rubiest would take.
First, let's create a file "winners.txt"
.
arr = ["Raiders", "Bears", "bearskin rug", "Chargers", "my bugbears", "bears"]
str = arr.join("n")
#=> "RaidersnBearsnbearskin rugnChargersnmy bugbearsnbears"
filename = "winners.txt"
File.write(filename, str)
#=> 53 (characters written)
and get the name of the team:
team = gets.chomp
#=> "bears"
See IO#write.1
The approach advocated in the question and provided in another answer is as follows:
array = IO.readlines(filename)
#> ["Raidersn", "Bearsn", "bearskin rugn", "Chargersn", "my bugbearsn", "bears"]
str = array.to_s
#=> "["Raiders\n", "Bears\n", "bearskin rug\n", "Chargers\n", "my bugbears\n", "bears"]"
a = str.scan(team)
#=> ["bears", "bears", "bears"]
a.size
#=> 3
which is incorrect. We could get around those problems, but the more conventional approach is the following:
team = gets.downcase.chomp
#=> "bears"
a = File.readlines(filename)
#=> ["raidersn", "bearsn", "bearskin rugn", "chargersn", "my bugbearsn", "bears"]
a.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
which gives the correct answer, as a[1]
and a[-1]
(and only those elements) are matched. The regular expression reads, "match a word break (b
) following by the value of team
followed by another word break".
We can improve on this however. There is no need to create the temporary array, a
. Instead we use IO::foreach, which reads the file line-by-line and, when used without a block, returns an enumerator:
enum = File.foreach(filename)
#=> #<Enumerator: File:foreach("winners.txt")>
We can see the values that will be generated by enum
by converting it to an array:
enum.to_a
#=> ["raidersn", "n", "bearsn", "n", "bearskin rugn", "n", "chargersn",
# "n", "my bugbearsn", "n", "bearsn"]
Continuing,
enum.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
One would normally chain the two methods:
File.foreach(filename).count { |s| s.downcase.match?(/b#{team}b/) }
#= 2
1 I've used File
as the receiver for some methods that are defined in the class IO
. That's commonly done and works because File.superclass #=> IO
.
add a comment |
Converting the array returned by IO::readlines to a string and then counting the number of times a string appears in that string can be made to work but it is not an approach that any experienced Rubiest would take.
First, let's create a file "winners.txt"
.
arr = ["Raiders", "Bears", "bearskin rug", "Chargers", "my bugbears", "bears"]
str = arr.join("n")
#=> "RaidersnBearsnbearskin rugnChargersnmy bugbearsnbears"
filename = "winners.txt"
File.write(filename, str)
#=> 53 (characters written)
and get the name of the team:
team = gets.chomp
#=> "bears"
See IO#write.1
The approach advocated in the question and provided in another answer is as follows:
array = IO.readlines(filename)
#> ["Raidersn", "Bearsn", "bearskin rugn", "Chargersn", "my bugbearsn", "bears"]
str = array.to_s
#=> "["Raiders\n", "Bears\n", "bearskin rug\n", "Chargers\n", "my bugbears\n", "bears"]"
a = str.scan(team)
#=> ["bears", "bears", "bears"]
a.size
#=> 3
which is incorrect. We could get around those problems, but the more conventional approach is the following:
team = gets.downcase.chomp
#=> "bears"
a = File.readlines(filename)
#=> ["raidersn", "bearsn", "bearskin rugn", "chargersn", "my bugbearsn", "bears"]
a.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
which gives the correct answer, as a[1]
and a[-1]
(and only those elements) are matched. The regular expression reads, "match a word break (b
) following by the value of team
followed by another word break".
We can improve on this however. There is no need to create the temporary array, a
. Instead we use IO::foreach, which reads the file line-by-line and, when used without a block, returns an enumerator:
enum = File.foreach(filename)
#=> #<Enumerator: File:foreach("winners.txt")>
We can see the values that will be generated by enum
by converting it to an array:
enum.to_a
#=> ["raidersn", "n", "bearsn", "n", "bearskin rugn", "n", "chargersn",
# "n", "my bugbearsn", "n", "bearsn"]
Continuing,
enum.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
One would normally chain the two methods:
File.foreach(filename).count { |s| s.downcase.match?(/b#{team}b/) }
#= 2
1 I've used File
as the receiver for some methods that are defined in the class IO
. That's commonly done and works because File.superclass #=> IO
.
add a comment |
Converting the array returned by IO::readlines to a string and then counting the number of times a string appears in that string can be made to work but it is not an approach that any experienced Rubiest would take.
First, let's create a file "winners.txt"
.
arr = ["Raiders", "Bears", "bearskin rug", "Chargers", "my bugbears", "bears"]
str = arr.join("n")
#=> "RaidersnBearsnbearskin rugnChargersnmy bugbearsnbears"
filename = "winners.txt"
File.write(filename, str)
#=> 53 (characters written)
and get the name of the team:
team = gets.chomp
#=> "bears"
See IO#write.1
The approach advocated in the question and provided in another answer is as follows:
array = IO.readlines(filename)
#> ["Raidersn", "Bearsn", "bearskin rugn", "Chargersn", "my bugbearsn", "bears"]
str = array.to_s
#=> "["Raiders\n", "Bears\n", "bearskin rug\n", "Chargers\n", "my bugbears\n", "bears"]"
a = str.scan(team)
#=> ["bears", "bears", "bears"]
a.size
#=> 3
which is incorrect. We could get around those problems, but the more conventional approach is the following:
team = gets.downcase.chomp
#=> "bears"
a = File.readlines(filename)
#=> ["raidersn", "bearsn", "bearskin rugn", "chargersn", "my bugbearsn", "bears"]
a.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
which gives the correct answer, as a[1]
and a[-1]
(and only those elements) are matched. The regular expression reads, "match a word break (b
) following by the value of team
followed by another word break".
We can improve on this however. There is no need to create the temporary array, a
. Instead we use IO::foreach, which reads the file line-by-line and, when used without a block, returns an enumerator:
enum = File.foreach(filename)
#=> #<Enumerator: File:foreach("winners.txt")>
We can see the values that will be generated by enum
by converting it to an array:
enum.to_a
#=> ["raidersn", "n", "bearsn", "n", "bearskin rugn", "n", "chargersn",
# "n", "my bugbearsn", "n", "bearsn"]
Continuing,
enum.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
One would normally chain the two methods:
File.foreach(filename).count { |s| s.downcase.match?(/b#{team}b/) }
#= 2
1 I've used File
as the receiver for some methods that are defined in the class IO
. That's commonly done and works because File.superclass #=> IO
.
Converting the array returned by IO::readlines to a string and then counting the number of times a string appears in that string can be made to work but it is not an approach that any experienced Rubiest would take.
First, let's create a file "winners.txt"
.
arr = ["Raiders", "Bears", "bearskin rug", "Chargers", "my bugbears", "bears"]
str = arr.join("n")
#=> "RaidersnBearsnbearskin rugnChargersnmy bugbearsnbears"
filename = "winners.txt"
File.write(filename, str)
#=> 53 (characters written)
and get the name of the team:
team = gets.chomp
#=> "bears"
See IO#write.1
The approach advocated in the question and provided in another answer is as follows:
array = IO.readlines(filename)
#> ["Raidersn", "Bearsn", "bearskin rugn", "Chargersn", "my bugbearsn", "bears"]
str = array.to_s
#=> "["Raiders\n", "Bears\n", "bearskin rug\n", "Chargers\n", "my bugbears\n", "bears"]"
a = str.scan(team)
#=> ["bears", "bears", "bears"]
a.size
#=> 3
which is incorrect. We could get around those problems, but the more conventional approach is the following:
team = gets.downcase.chomp
#=> "bears"
a = File.readlines(filename)
#=> ["raidersn", "bearsn", "bearskin rugn", "chargersn", "my bugbearsn", "bears"]
a.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
which gives the correct answer, as a[1]
and a[-1]
(and only those elements) are matched. The regular expression reads, "match a word break (b
) following by the value of team
followed by another word break".
We can improve on this however. There is no need to create the temporary array, a
. Instead we use IO::foreach, which reads the file line-by-line and, when used without a block, returns an enumerator:
enum = File.foreach(filename)
#=> #<Enumerator: File:foreach("winners.txt")>
We can see the values that will be generated by enum
by converting it to an array:
enum.to_a
#=> ["raidersn", "n", "bearsn", "n", "bearskin rugn", "n", "chargersn",
# "n", "my bugbearsn", "n", "bearsn"]
Continuing,
enum.count { |s| s.downcase.match?(/b#{team}b/) }
#=> 2
One would normally chain the two methods:
File.foreach(filename).count { |s| s.downcase.match?(/b#{team}b/) }
#= 2
1 I've used File
as the receiver for some methods that are defined in the class IO
. That's commonly done and works because File.superclass #=> IO
.
answered Nov 21 '18 at 22:01
Cary SwovelandCary Swoveland
70.9k54167
70.9k54167
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418354%2fruby-using-count-to-tally-instances-of-a-word-instead-of-its-component-letters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Unrelated, but canonical Ruby code uses
_
to separate words in variable names, e.g.,team_name
orten_cent_beer_night
. Please either use that (preferred) or something to avoid word smashes.– Dave Newton
Nov 21 '18 at 19:01
gets
andchomp
returns strings, soto_s
is redundant.– Cary Swoveland
Nov 21 '18 at 19:55