Issue with my Ruby Assignment [closed] - ruby

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I am new to learn Ruby, I got an assignment from my teacher which I am trying to understand.
Here is the question. Consider the following code:
ary = Array.new(7, "--day")
ary[2] = "Tuesday"
ary[4] = "Thursday"
ary[7] = "Sunday"
ary[-1] = "Saturday"
puts ary[7]
puts ary[-4]
puts ary[-6, 2]
puts ary[2] = ary[7][-3,3]
puts ary.length
Why does this code produce 6 lines of output? Where did the extra line come from?
What is the value of ary[2] at the end?
Why is the length (or size) of the array different than when we constructed it?

I won't answer these questions directly, since it sounds like it's a homework assignment, but I will try to point you in the right direction.
Take a look at the documentation for Ruby's Array#[]. More specifically, take a look at which usages in your example code match the usages in the examples, and you might get a better idea of what's happening. Keep in mind that with Ruby, you can index from the end of your array by using negative index numbers.
Open up irb in the terminal and run the first 5 lines (all the ary[]= lines). Then run each of the puts lines individually and see what the output is. Keep in mind that lines with => something are the return values, not what is being printed.
Take a look at String#[], and try out the different parts of line 9 individually. For example, see what ary[7] does. Then see what ary[7][-3, 3] does. See what happens if you do "Any Random String"[a_number, another_number].
After you first create the array, check ary.length. Then run each of the following lines, checking ary.length after each subsequent assignment.
Don't get discouraged, and don't listen to people telling you to give up. This stuff can be confusing when you first start out, but getting familiar with where to find documentation, how to use the command line tools, and how to experiment will make it much easier to explore and discover what your code is doing, when, and why.
If you ever need to try and figure out what is going on in your code, just open up irb in your terminal and start playing around with it, and you should be able to answer most of your questions through experimentation.

Related

New to Ruby, looking for style tips on this function [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am brand new to both Ruby and Stackoverflow.
Below is some code for a function I wrote. The question isn't really specific to the function, just an example of something I wrote. The function takes in a string of any number of words, and reverses the order of the words. Also, for each word, it takes the vowels and moves it to the end of the word. It also downcases everything. Thus, "Hello World!" would become "wrld!o hlleo".
I am trying to use some Ruby features, hence why it is a one-liner so to speak. Basically I am just looking for style suggestions. Is it appropriate to do such a thing in this manner (one line?). I'm sure there are functions that could accomplish the task quicker, so I am open to those suggestions too, since my code is very long and convoluted. Also I should mention I wanted to write this with only base Ruby, no extra packages/gems.
def funky_words(s)
s.strip.gsub(/\s+/, " ").split(" ").reverse.instance_eval{map{|elt| elt.gsub(/([aeiou])/i,"")}}.
zip(s.strip.split(" ").reverse.map{|elt| elt.scan(/([aeiou])/i).flatten}.instance_eval{map{|elt| elt.join}}).
map(&:join).join(" ").downcase
#first "line" reverses word order removes vowels, second "line" captures vowels and moves them to the end,
#last "line" joins the new funky words.
end
If you want you code to follow best practices, as agreed upon by Ruby community, use Rubocop. It’s a tool that combines linter with style analyzer.
If you prefer to check your style manually, you can read the guidelines here.
This question is about style, so I am not commenting on the correctness of the code or other ways to write it.
Some developers would prefer this very long line to be broken up into 2-3 separate statements, more or less split up by logic or functionality. This would improve readability and make the code easier to maintain.
The first step in improving style is to use RuboCop, as suggested by Konrad. It will find style issues, and/or automatically reformat the code. RuboCop can be run on the command line for a single or multiple files, or for the entire project. You can also run RuboCop inside your editor.
See an example output of the RuboCop that was executed on your code below. Note that it does not create separate statements, which in this case could be more readable. It simply breaks the long lines into multiple lines (not ideal, but more readable than the original). It also reformats a few other items: make chained calls on multiple lines start with ., add space after comment (# ), fix spaces inside brackets and braces, etc.
def funky_words(s)
s.strip.gsub(/\s+/, ' ').split(' ').reverse.instance_eval { map { |elt| elt.gsub(/([aeiou])/i, '') } }
.zip(s.strip.split(' ').reverse.map { |elt| elt.scan(/([aeiou])/i).flatten }.instance_eval { map(&:join) })
.map(&:join).join(' ').downcase
# first "line" reverses word order removes vowels, second "line" captures vowels and moves them to the end,
# last "line" joins the new funky words.
end
Note that you can change the RuboCop settings from their default values and even disable some rules (called cops). For example, I am using longer max line length.
SEE ALSO:
RuboCop docs
Change RuboCop settings
Disable cops (rules) in your source code

ruby how to use #capitalize! and keep string numbers [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
so I'm doing prep work for a ruby dev bootcamp and need to create a program that will capitalize titles. My current code uses #capitalize! but when a number is included in the string it is omitted.
words = title.split(' ')
words.map! do |word|
if %w(a aboard about above absent across after against along alongside amid amidst among amongst an and around as aslant astride at
athwart atop barring before behind below beneath beside besides between beyond but by despite down during except for from in inside
into like mid minus near next nor notwithstanding of off on onto opposite or out outside over past per plus regarding round save
since so than the through throughout till times to toward towards under underneath unlike until up upon via vs. when with within
without worth yet ).include?(word) && word != words[0]
word
else
word.capitalize!
end
so when what I wish I knew when I was 20 is input I get What I Wish I Knew When I Was
any suggestions?
Use capitalize instead of capitalize!.
By the way, if your intention of word != words[0] is to leave any word in the list uncapitalized if it is not the first word, then you are wrong. It does not work like that. The reason is left to you as a homework.
just change word.capitalize! to word.capitalize! || word
"20".capitalize! #=> nil
"20".capitalize! || "20" #=> 20

Accidental NilClass in my instance variables [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am making a dating simulator. One of the first things I need is to keep track of the way characters feel about each other. In this sim, anyone can date anyone else, and there are two variables for relationship (one for love and one for friendship).
So I thought the easiest way to do this would be for each character to have a separate class that kept track of how they felt about everyone else. Below is one such sample class. I also thought that the easiest way to keep track of where points should be added was by giving each character a hash that pointed to their own variable, and then using a swap function to trade targets with the person they are speaking to.
However, I am getting an error message.
class HRelatStatus
def initialize
{#target=> #hrelat}
#krelat =[10, 10]
#arelat =[9, 4]
#srelat =[13, 11]
#jrelat =[12, 1]
#brelat =[5, 5]
#hrelat=[0, 0]
end
def dataaccess
attr_accessor :target, :krelat, :arelat, :srelat, :jrelat, :brelat, :hrelat
end
def makehappy
#target[0] = #target[0]+1
end
end
hfeels=HRelatStatus.new
puts #krelat.class
puts #krelat[1]
hfeels.makehappy
puts #target[0]
When I try to run this, #krelat comes back as a Nil class. And when I try to run the makehappy method (or any method, really) I get the error message undefined method '[]' for nil class.
How do I stop my instance variables from being nil classes? How can I sucessfully make methods that will add to one variable in the array for a specific character? And does anyone have a better idea for how I can specify who to target?
You are saying:
hfeels=HRelatStatus.new
puts #krelat.class
But there is no such thing as #krelat in this context. What you are after is the krelat instance variable inside your instance, i.e. hfeels.krelat.
(Of course, that won't work either because you've hidden your accessor generators inside an instance method.)
The first thing you actually need to do is learn how Ruby (or really, variable scope in any language) works.
#krelat outside of the class is totally unrelated to #krelat inside the class.
The makehappy method won't work because { #target => #hrelat } doesn't do anything in Ruby (well, it creates a hash with a nil key pointing to a nil value and then discards that hash. Ie. effectively nothing.
This code is a total mess, learn Ruby first. Buy "Programming Ruby" and read it.

Swap two strings 2 by 2 in ruby [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
I've go a string made in this way.
"AABBCCDD....." grouped by 4 with variable lenght.
I need a method that swap that 2 by two the chars in this string
def swap2_by_2( string )
???
end
If the input is AABBCCDD the output will be BBAADDCC
Thanks, i'm very noob in ruby.
Edit: my mistake, a more comprhensive example may be.. Input: ABCDEFGH -> CDABGHEF
It is not clear what the OP is trying to do, but if it is to flip the first and the second characters with the third and fourth characters for every four characters, then the example that the OP showed is highly misleading and inappropriate (It should have been "ABCD..." instead of "AABB..."). In that case, a solution would be:
string.gsub(/(..)(..)/, '\2\1')
Thinking about your question, an interpreting the "ABCDEF", I am sure, that you are looking for pack / unpack in Ruby: I found a good page here How to change bit order in Ruby
And here are two a non-regexp versions:
p 'AABBCCDD'.chars
.each_slice(2)
.each_slice(2)
.map(&:reverse)
.join
#=> "BBAADDCC"
# or
'AABBCCDD'.chars
.each_slice(4)
.map{|x| x.rotate(2)}
.join

refactoring ruby code inject issues [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hi can someone explain to me why my inject isn't working here?
Am I using inject correctly here? For some reason my code gets caught up in an endless loop once this scenario comes into play (the 5th move usually in my game)
def cpu_block_player
winning_combinations = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]
executed = 0
winning_combinations.each do |combination|
result_of_combination = ""
result_of_combination = combination.inject("") {|result, element| result + #board[element]}
if result_of_combination == "XXe" || result_of_combination == "eXX" || result_of_combination == "XeX"
executed += 1
puts executed
player_move(#current_turn, result_of_combination.index("e"))
end
break if executed >= 1
end
First of all, these kinds of questions are better suited for the Code Review Stack Exchange site.
However, here are my thoughts:
My first thought when looking at your code is that you're just having one large class. In order to see some real advantages with Object-Oriented Programming, I'd recommend extracting some of the code into separate classes. I can definitely see a Board class inside the Game class, just waiting to be extracted.
Some ideas for methods to add to a Board class:
to_s -- This would be what's in your print_board method at the moment, without the print.
finished? -- Check whether the game is "finished" (ie., someone has won). A winner method would also make sense.
taken? -- Whether someone has taken a position before.
A lot of the code in your Game class would benefit from naming. For instance, take this piece of code:
#current_turn == #player_x ? #current_turn = #player_o : #current_turn = #player_x
It's not super hard to figure out what this piece of code does, but exactly how you swap who is the current player is probably not important to know while reading the player_move method. All you want to know is that "at this point, we switch players".
Extracting methods and objects doesn't make you write less code, but in my opinion it makes for clearer code. If you can give every piece of line a name (ie., extract it to a method), then it is probably a lot easier to figure out what is going on.

Resources