스스로 코딩/Codecademy

Ruby - Codecademy

Cyberworld 2020. 4. 26. 11:18

2018, 4, 1 일 ~ 2018, 8, 17 금 (10 hours) : 4개월간

코드카데미 Ctrl + Enter 실행함.

객체지향 스크립트 언어
RubyonRails 웹 프레임워크

코스 결과
이 과정에서는 변수, 루프, 제어 흐름, 그리고 가장 중요한 객체 지향 프로그래밍을 포함한 기본 프로그래밍 개념에 대해 Ruby에 친숙해 질 것이다. 현지에서 제작할 최종 프로젝트에 대한 이해도를 테스트할 수 있는 기회가 주어집니다. 

Ruby는 여전히 시장에서 큰 수요를 가진 범용 언어이며 Rails응용 분야에서 일반적으로 사용된다. 간결하고 읽기 쉽게, 집어 올리기 쉽지만 또한 강력하다. Twitter, Soundcloud, Goodreads및 Kickstarter와 같은 회사는 Ruby를 통해 그들의 제품을 시장에 내놓았다.

Ruby에선 순서가 중요하다.

=====
gets는 사용자로부터 입력을 받는 Ruby방법입니다. 입력을 받을 때마다 Ruby가 자동으로 입력 후 빈 줄(또는 새 라인)을 추가하고, chomp은 그 줄을 제거한다.

rev=false 비즈니스란 무엇입니까? 
이것이 루비에게 말하는 것은 사용자가 두개의 인수를 입력하지 않으면 기본적으로 false로 변하는 두번째 매개 변수인 rev(reverse)를 가지고 있다는 것이다. (2-3 참고)


루비에서의 느낌표 ! 는 "이 방법은 위험하거나 예기치 못한 일을 할 수 있다!"는 뜻을 상기하라. 이 경우에는 새로운 배열을 만드는 대신에 원래의 배열을 변형시킵니다.

루비에서는 인스턴스(instance)변수임을 나타내기 위해 변수 앞에@를 사용합니다. 이는 변수가 클래스의 인스턴스에 연결됨을 의미합니다.

메서드를 쓰고 꼭 end로 닫아주고 if문을 써도 end를 반드시 써서 닫아줘야 한다.

메서드 : 프로그램에서 특정 작업을 수행하기 위해 작성된 코드를 재사용할 수 있는 섹션입니다. def를 포함하여 사용한다.
인수 : 인수는 메서드를 호출할 때 메서드의 괄호 사이에 실제로 넣은 코드 조각
매개 변수 : 메서드의 괄호 사이에 정의할 때 입력하는 이름.
예) def A(n) # def를 사용한 A가 메서드가 된다.
        puts n + 1 # 여기선 n이 매개 변수다.
 
A(3)  # 여기선 3이 인수가 된다.
>> 4
=====

관례적으로 변수는 소문자로 시작한다. 문자열은 대문자로 쓸 수 있지만 변수는 모두 소문자로 쓰도록 한다.
ex) variable = "XkkkX"
단어는 counter와 masterful_method와 같이 밑줄로 구분되어야 한다.



'.length' : 문자열의 길이(문자, 숫자, 기호, 공간)를 반환해준다.
ex) puts "BA BK".length
      >> 5

.include? : 무엇을 포함하고 있는지 조건문 형태로 사용 된다.
ex) if variable.include? "AK"
        print "AK가 포함되어 있다."
        >> AK가 포함되어 있다.

.times : 특정 횟수만큼 작업을 수행하려는 경우, 같은걸 반복해서 출력할 때 사용. 
ex) 20.times {print "a"}
>> aaaaaaaaaaaaaaaaaaaa

우리가 포함시키고 싶은 숫자의 범위를 알고 있다면, .upto .downto를 사용할 수 있습니다.
.upto : 오름차순 
            95.upto(100) { |num| print num, " } 
            >> 95 96 97 98 99 100


.downto : 내림차순
                 95.downto(100) { |num| print num, " " } 
                 >> 100 99 98 97 96 95

.respond_to? : 객체가 해당 메서드를 수신할 수 있으면 기호를 사용하여 true를 반환하고 그렇지 않으면 false를 반환합니다.
                         방법을 참조하는데 symbol이 유용하여 사용한다. 한마디로 사용 여부 판단.
ex) [
1, 2, 3].respond_to?(:push)
어레이 개체를 누르면 호출할 수 있으므로(.push) true가 반환됩니다. 하지만
[1, 2, 3].respond_to?(:to_sym)
배열을 기호로 변환할 수 없으므로 거짓으로 반환합니다.


.select: 해시에서 특정 값을 가져오는 방법을 알고 있지만 특정 조건을 충족하는 값의 해시를 필터링 하려면 어떻게 해야 할까? 특정 조건의 값을 찾을 때 사용한다. ex) 3가지 방법. 조건 걸기, 특정 키 찾기, 조건 불러와서 사용하기

 

#조건 불러와서 사용하기
# 여기서 ages는 정수를 담은 숫자들이다. under_100은 100 미만의 정수를 찾아주는 조건이다.
# 사용 방법: 다른 값 집합체.select(&조건 있는 변수)
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44] 

under_100 = Proc.new { |x| x < 100 } 

puts ages.select(&under_100)

>> [23, 7, 11, 94, 70, 44]


.sort_by : 복사본 생성
.sort .sort! 차이 : .sort는 복사본을 정렬하나 .sort! 는 정렬한다. .sort는 원래 어레이는 그대로 두고 정렬된 어레이만 반환합니다. 두번째 방법인. sort!는 실제 어레이를 수정합니다.
.to_s : 값을 문자열로 변환시켜 준다.(.to_string)
.to_sym : 값을 기호로 변환시켜 준다.(.to_symbol)
.to_i : 값의 정수버전을 돌려준다.
.to_f : 실수버전 돌려준다.
.nil : nil은 사전적 의미 (전혀)없는, 존재하지 않는. 0을 의미한다. 참으로 절대적이게 같지 않으면 true. 같거나 다르면 false? false           와 nil은 다르다. 사실이 아니다와 아무것도 아닌 것과는 다른 말이다.
.next : .next은 해당 정수를 호출하는 즉시 다음 수의 정수를 반환합니다. 즉, 4.next 가 5를 반환합니다.
.collect : 수집이란 뜻. 원본 배열을 복사하여 다른 조건문을 사용하여 원본을 훼손하지 않고 사용 가능. (참고: 1-2. Collect 'Em All)
.map : .collect와 이름은 다르지만 정확히 똑같은 일을 한다. .collect == .map

.floor : 부동 소수 점 이하의 최대 정수를 반환합니다.
& : 변환 해주는 장치? ex) Symbol을 프로세스로 변환시켜줄 수도 있다. 어디에 사용하느냐에 따라 변환해주는 듯.
lambda 와 proc 차이? : 1-14. Lambdas vs. Procs 참고!!
.is_a? :
 이 방법은 개체가 이름이 지정된 개체 유형이면 true이고 그렇지 않으면 false이면 반환됩니다.( method, which returns true if an object is the type of object named and false otherwise:)  추가설명: 클래스가 obj의 클래스이면 true를 반환합니다. 또는 클래스가 obj또는 obj에 포함된 모듈의 superclass중 하나일 경우.
Integer : 정수를 의미한다. 아마 정수로 표현하거나 정수를 표현하려 할 때, 정수만을 불러오려 할 때? (.is_a? Integer 구문을 많이 사용하는 듯 하다.)


splat : splat 인수는 * 가 선행하는 인수로, 방법이 하나 이상의 인수를 수신할 수 있음을 프로그램에 알려 줍니다. 
메서드의 몇개의 인수를 받을지 정확히 모를 때 *을 인수에 붙여주어 사용한다. 입력한 만큼 출력된다.
ex) 1-6. Splat!
def what_up(greeting, *friends) 
  friends.each { |friend| puts "#{greeting}, #{friend}!" } 
end 

what_up("What up", "Ian", "Zoe", "Zenas", "Eleanor") 
>> What up, Ian! 
>> What up, Zoe! 
>> What up, Zenas! 
>> What up, Eleanor!



.push 와 concatenation 연산자 <<
.push 대신 << 연산자를 쓰는 것이 훨씬 편리하다.

ex.1) .push와 += 을 사용.
alphabet = ["a", "b", "c"]
alphabet.push("d") 

caption = "A giraffe surrounded by "
caption += "weezards!"     # .push를 사용하여 추가할 수 없다. 그릇이 배열 형태가 아니기 때문이다.


puts alphabet
puts caption

>> ["a", "b", "c", "d"]
>> 
A giraffe surrounded by weezards!

ex.2) << 연산자 사용.
alphabet = ["a", "b", "c"] 
alphabet << "d" 

caption = "A giraffe surrounded by " 
caption << "weezards!"  

puts alphabet 
puts caption

>> ["a", "b", "c", "d"] 
>> 
A giraffe surrounded by weezards!



문자열 보간 (참고: 1-14. String Interpolation)
+ 나 << 을 사용하여 문자열이나 정수를 변수에 추가할 수 있다. 
그러나 문자열이 아닌 정수 값을 합칠 때 정수를 .to_s로 문자열로 변환 시켜 주어야 한다.

하지만 문자열 보간을 사용하면 정수든 문자열이든 변수 이름을 문자열 안에 넣기만 하면 된다.

 

 

 

Ternary 연산자 (참고 : 1-4. One Good Trun Deserves a Ternary, 1-16. The Ternary Operator)
if / else 보다 간결한 조건적 표현이다.
문법 형식

ex.1)
if 1 > 5
  puts "true~~"
else
  puts "false~~~"
end
>> false~~~

if를 ternary 연산자를 사용하여 표현하였을 때,

puts 1 > 5 ? "true~~" : "false~~~"
>> false~~~


if 표현법
1. 한 줄에 표현하기: if가 뒤에 있어야 함. (참고: 1-2. A Simpler 'if')
puts "Hello!" if true
2. 여러 줄 표시:
if true 
   puts "Hello!" 
end

unless 한 줄 표현하기 if와 같음.




산술 연산자
> : 왼쪽이 더 커야 한다. 초과.
< : 오른쪽이 더 커야 한다. 미만.
>= : 왼쪽이 더 크거나 같아야 한다. 이상
<= : 오른쪽이 더 크거나 같아야 한다. 이하.

부울 연산자, 논리 연산자
&& : And 연산자. 둘다 참(true) 이어야 한다.
|| : Or 연산자. 둘 중 하나만 참(true)이면 된다.
! : Not 연산자. true, flase를 뒤집는다. !true면 false가 되고 !false면 true가 된다.

결합 비교 연산자 <=>
첫번째 피연산자(비교할 항목)가 두번째 피연산자와 같은 경우 0, 
첫번째 피연산자가 두번째 피연산자보다 큰 경우 1, 
첫번째 피연산자가 두번째 피연산자보다 작은 경우 -1

조건부 할당 연산자 ||= (참고. 1-6. Conditional Assignment )
연산자를 사용하여 변수에 값을 할당할 수 있습니다. 하지만 변수가 아직 할당되지 않은 경우에만 할당하려면 어떻게 해야 할까요?  
이를 위해 조건부 할당 연산자를 사용할 수 있습니다. 
||= 논리 연산자(||)와 일반 할당 연산자(=)로 구성되어 있습니다. 합쳐져 있다.

favorite_book = nil                        # favorite_book 변수가 nil로 설정되어 있다. 아무것도 아님을 뜻하는 것이기 때문에
puts favorite_book                           출력 결과가 없다.

favorite_book ||= "Cat's Cradle"   # 조건부 할당 연산자를 사용하여 조건을 걸어 Cat's Cradle 이라고 값을 주었다.
puts favorite_book                        # Cat's Cradle 이라고 출력된다.

favorite_book ||= "Why's (Poignant) Guide to Ruby"  # Why's (Poignant) Guide to Ruby 라는 새로운 값을 주었다. 
puts favorite_book                # 그러나 Cat's Cradle 이라는 값이 출력된다. 조건을 걸었기 때문이다.

favorite_book = "Why's (Poignant) Guide to Ruby"  # 이번엔 일반 할당 연산자를 사용하여 값을 주었다.
puts favorite_book   # 아무 이상 없이 변경 되었다. Why's (Poignant) Guide to Ruby 출력.
>> 아무것도 출력되지 않음.
>> Cat's Cradle 
>> Cat's Cradle 
>> Why's (Poignant) Guide to Ruby



변수 설명과 사용 기호
← 전역 변수(global variables) : 클래스를 처리할 때는 어디에서나 사용할 수 있는 변수 
지역 변수(local variables) : 특정 메서드 내에서만 사용할 수 있는 변수
@@ ← 클래스 변수(class variables) : 특정 클래스에서 사용할 수 있는 변수
@ ← 인스턴스 변수(instance variables) :  특정 인스턴스(인스턴스 변수)에만 사용할 수 있는 변수


변수를 사용하는데 있어서 기본적으로 글로벌 변수가 편하다. 그렇지만 프로그래밍을 하다 보면 많은 변수들을 만들어야 하기 때문에 변경될 우려가 많다. 그래서 일부 위치에서만 변경할 수 있는 범위가 제한된 변수를 생성하는 것이 나중에 관리하기가 훨씬 용이하다!


정렬 방법(.sort)으로 전달되는 블록은 1,0또는-1중 하나를 반환해야 합니다. 
첫번째 블록 매개 변수가 두번째 블록보다 먼저 와야 하는 경우-1, 
반대로 가중치가 같은 경우에는 1이 다른 값보다 앞에 있지 않음을 의미하는 경우 0을 반환해야 합니다.



반복문
for문에서 점이 두개일 때와 세개일 때 출력이 다르다. 세개일 경우에는 그 전까지의 숫자만 출력된다.
for "키" in "컨테이너" 
ex)1
for num in 1..15
  puts num
end
>> 1
>> 2
>> # 숫자가 계속 이어짐.
>> 14
>> 15
ex)2
for num in 1...15
  puts num
end
>> 1
>> 2
>> # 숫자가 계속 이어짐.
>> 13
>> 14

each, each do 사용법

집합의 모든 요소에 대해 작업을 반복하려는 경우

적용해보기.

둘의 차이점. 첫 번째 방법은 { |item| 요 안에다 코드를 다 써야 한다.
}
두 번째 방법은 item이라는 가상의 변수 이름을 할당 받아 자유롭게 불러와서 사용할 수 있다.

해쉬 사용법(값으로 문자가 오든, 정수가 오든, 불린 값이 오든 상관 없다. key는 달라야 하나  value는 같을 수 있다.)

 

ex)
my_hash = { "name" => "Eric",
  "age" => 26,
  "hungry?" => true
}
puts my_hash["name"]
puts my_hash["age"]
puts my_hash["hungry?"]
>> Eric
>> 26
>> true

Hash.new를 사용하면 빈 해시를 생성한다.
my_hash = Hash.new
print my_hash
>> {}

Hash.new는 다음과 같이 사용합니다.

기호(Symbol)
문자열, 기호 변환 방법
기호 ==> 문자열

문자열 ==> 기호

문자열 기호로 초기화 하는 방법 .intern 을 사용한다.
"hello".intern 
>> :hello

Symbol을 Key 로 사용하는 것이 좋은 이유.
기호를 사용하면 다음과 같은 몇가지 이유로 Hash Key 가 유용합니다.
1. 그것들은 불변한다. 즉, 그것들이 일단 만들어지면 그것들은 바뀔 수 없다는 것을 의미한다. 
2. 지정된 시간에 하나의 기호만 존재하므로 메모리를 절약합니다. 
3. 위의 두가지 이유 때문에 키를 돌리는 것이 키를 누르는 것보다 빠릅니다.

Ruby 1.8 버전
numbers = { 
    :one => 1, 
    :two => "two", 
    :three => 3, 
}

위 해시 구문(키와 값 사이에 => 기호가 있는 해시 구문)은 해시 로켓 스타일이라고도 합니다. 이것은 => 이 작은 로켓처럼 생겼기 때문이다. 

Ruby 1.9 버전 부터 구문 변경 되었음.

new_hash = { 
   one: 1, 
   two: 2, 
   three: 3
}
두가지 변경 사항은 다음과 같습니다. 
1. 기호의 처음이 아니라 끝에 콜론을 찍습니다. 
2. 너는 더 이상 해시 로켓(=>) 이 필요 없어.


case when 사용법
case language 
   when "JS" 
     puts "Websites!" 
   when "Python" 
     puts "Science!" 
   when "Ruby" 
     puts "Web apps!" 
   else 
     puts "I don't know!" 
end

그러나 다음과 같이 접을 수 있습니다.
case language 
  when "JS" then puts "Websites!" 
   when "Python" then puts "Science!" 
   when "Ruby" then puts "Web apps!" 
   else puts "I don't know!" 
end


문자열 포맷(?)을 보기 위해 #{변수} 구문 형식을 사용한다.

next if는 조건값이 참이면 next(다음)으로 넘어가는 기능을 한다.

Ruby의 next는 c, python의 continue랑 같다. 루프를 그 자리에서 한번 스킵한다. 실행을 바로 종료하고 다음 루프로 진행.


Block, Process, Lambda 요약
1. 블록은 단지 도 사이의 코드를 말한다. do..end or {}. 그것은 그 자체로는 물건이 아니지만, .each 또는 .select 같은 방법으로 전달될 수 있습니다. 
2. proc은 반복해서 사용할 수 있는 저장된 블록입니다. 
3. 람다는 프로세서와 같으며, 단지 인수되는 인수 개수에만 신경을 쓰고 즉시 반환하지 않고 호출 방법으로 돌아갑니다. 
블록, 프로세스 및 Lambda가 유사한 작업을 수행할 수 있는 경우는 많지만 프로그램의 정확한 상황은 사용할 항목을 결정하는 데 도움이 됩니다.


Proc 사용 방법(참고: 1-18. Creating a Proc)
이제 프로세스를 살펴보겠습니다. 첫번째 단계:새로 만들기!

Hint
my_proc = Proc.new { # block }
또는
my_proc = Proc.new do 
    # block 
end

1.Under_100이라는 프로세스를 생성하여 번호가 100미만인지 확인합니다. 아직 준비되지 않았습니다.)

# 첫 번째 방법
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44] 

under_100 = Proc.new { |x| x < 100 } 

puts ages.select(&under_100)

>> [23, 7, 11, 94, 70, 44]

# 두 번째 방법
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44] 

under_100 = Proc.new do |x| 
  x < 100 
end 

puts ages.select(&under_100)
>> [23, 7, 11, 94, 70, 44]


Lambda 구문
my_lambda = lambda { |k,v| # code }
또는
my_lambda = lambda do |k,v| 
   # code 
end


상속 구문(참고: 1-12. Inheritance Syntax (상속 구문))
class DerivedClass < BaseClass 
     # Some stuff! 
end
DerivedClass는 상속 받는 클래스이자 새로운 클래스이다. 하위 클래스라 함.(자식)
BaseClass는 상속 주는 클래스이자 기존에 있던 클래스이다. 상위 클래스라 함.(부모)
 "<" 기호로 상속 받을 수 있습니다.

예제 : 1-13. Override! 을 참고하면 알기 쉽게 상속에 대해 알 수 있다.



1. Introduction to Ruby

1. Introduction to Ruby

1-1. Overview & Sneak Peek
Ruby는 당신이 웹에서 사용할 수 있는 강력하고 유연한 프로그래밍 언어이며, 텍스트를 처리하고, 게임을 만들고, 인기 있는 RubyonRails의 웹 프레임워크의 일부이다. Ruby는 다음과 같다.
고급스러움, 루비 읽기, 쓰기는 정말 쉬워요. 보통 영어와 많이 닮았다고 합니다!
삽입됨. 루비를 쓰고 실행하는 데 컴파일러가 필요 없음을 의미한다. 여기 코더 카데미나 여러분 자신의 컴퓨터에서도 쓸 수 있어요.
객체 지향, 즉 사용자가 프로그램을 만들고 실행하기 위해 개체라는 데이터 구조를 조작할 수 있음을 의미합니다. 나중에 어떤 것에 대해 더 배우겠지만, 지금으로서는 루비의 모든 것이 물체라는 것만 알면 됩니다.
사용하기 쉽다. 루비는 1995년에 마쓰모토 유키히로에 의해 디자인되었다. 매츠는 사람들이 컴퓨터보다 더 많이 사용하는 언어를 디자인하기 시작했습니다. 그래서 루비는 쉽게 습득할 수 있죠.
이 과정에서는 Ruby에 대한 지식이 없거나 일반적으로 . 컴퓨터 공학에 대한 지식이 없다고 가정한다.


1-2. Data Types: Numbers, Strings, Booleans
Ruby에서, 당신의 정보(또는 데이터)는 다른 종류로 올 수 있다. 루비의 데이터는 숫자, boolean(참 또는 거짓일 수 있음), 스트링("Ruby!"와 같은 문자열)세가지가 있다.
데이터를 빠르게 분석하고 조작하기 위해 컴퓨터 프로그램이 존재한다. 따라서 프로그램에서 사용할 수 있는 다양한 데이터 유형을 이해하는 것이 중요합니다.
알림:Booleans에게 따옴표(또는")를 사용하지 마십시오. Ruby는 여러분이 참 또는 거짓 대문자로 될 수 있는 값 대신 문자열(단어 또는 구)에 대해 말한다고 생각합니다.

my_num = 25     
my_boolean = true     
my_string = "Ruby"     

puts my_num
puts my_boolean
puts my_string
>> 25
>> true
>> Ruby


1-3. Variables
컴퓨터 프로그래밍의 가장 기본적인 개념 중 하나는 변수이다. 변수를 단일 값을 파악하는 단어 또는 이름으로 생각할 수 있습니다. 예를 들어, 우리의 마지막 예에서 숫자 25가 필요했지만, 지금 당장은 사용하지 않을 거라고 합시다. my_volume과 같이 변수를 설정하여 25값을 파악하여 다음과 같이 나중에 사용할 수 있도록 유지할 수 있습니다.
Ruby에서 변수를 선언하는 것은 쉽습니다. my_num과 같은 이름을 쓰고,=를 사용해 값을 할당하면, 끝이다. 변수를 변경해야 할 경우에는 다음과 같이 하십시오. 변수를 다시 입력한 후 입력하면=를 눌러 새 값을 할당할 수 있습니다.
my_num = 100
puts my_num
>> 100


1-4. Math
Ruby는 나의_num=100과 같은 간단한 숙제 표현에 제한되지 않고, 당신이 학교에서 배운 모든 수학을 할 수 있다.
우리는 다음과 같은 6가지 산술 연산자에 초점을 맞출 것입니다.
Addition (+) 더하기
Subtraction (-) 빼기
Multiplication (*) 곱하기
Division (/) 나누기 몫의 값
Exponentiation (**) 제곱
Modulo (%) 나누기 나머지 값
당신에게 이상하게 보이는 유일한 것들은 아마도 외향적인 것과 이상한 것들일 것이다. exponentiation은 한 숫자(기준)를 다른 숫자(지수)의 제곱으로 올립니다. 예를 들어, 2**3은 "2*2*2"를 의미하기 때문에(2곱하기 3), 2*3은 8입니다. 3**2는 9(3*3)등입니다.
남은 분할 항목을 반환합니다. 예를 들어, 25%7은 4가 될 것이다. 왜냐하면 7은 4가 남아 있을 때 25에 세번 들어가기 때문이다.


1-5. 'puts' and  'print'
print 명령은 당신이 주는 것은 무엇이든지 가져가서 화면에 출력한다. "put string"는 약간 다릅니다. 즉, 인쇄할 항목 뒤에 새(공백)줄을 추가하는 것입니다. 다음과 같이 사용합니다.
puts "What's up?"
print "Oxnard Montalvo"
괄호나 세미 콜론은 필요 없음!
puts "Hello!"
print "Halo!"
puts "What's up?"
puts "the say"
puts "I'm Okay"

# print 뒤에 puts가 붙는다. 반면 puts 끼리는 붙지 않는다.

>> Hello!
>> Halo!What's up?
>> the say
>> I'm Okay


1-6. Everything in Ruby is an Object
루비의 모든 것은 객체(나중에 더 많은 것)이기 때문에 Ruby의 모든 것은 Method라는 특정한 기능을 내장하고 있다. 특정 개체가 가지고 있는 기술이라고 생각할 수 있습니다. 예를 들어 문자열(words or phrases)에는 문자열의 길이, 역 방향 등을 알려 주는 기본 제공 방법이 있습니다. 우리는 또한 당신에게 통역사에 대해 더 많은 것을 말해 주기로 약속했습니다. 
인터프리터는 당신이 쓰는 코드를 받아 실행하는 프로그램이다.


1-7. The '.length' Method
방법은 다음을 사용하여 호출한다. 만약 여러분이 "에스프레소의 길이를 좋아합니다"라는 문자열을 가지고 있다면, 루비는 그 문자열의 길이(즉, 문자 수, 숫자, 기호, 공간)를 반환할 것입니다. 확인해 보십시오.
"I love espresso".length
# ==> 15
(#로 시작하는 작은 줄은 쓸 내용의 일부가 아닙니다. Ruby가 제공하는 출력을 보여 줍니다. 더 자세한 내용은 다음 섹션을 참조하십시오!) 예를 들어, 신용 카드 결제가 가능한 웹 사이트를 만들려는 경우에는 입력한 길이를 확인하는 것이 유용할 수 있습니다. Ruby가 신용 카드 번호가 유효한지 확인할 수 있습니다.
1. 이름에. length method를 호출한다(이름 주위에 따옴표를 사용하는 것을 기억한다).
값을 보려면 콘솔에 응답을 입력합니다.

puts "Jamie".length
>> 5


1-8. The '.reverse' Method
.reverse 방법은 같은 방법입니다. 길이가 같습니다. 하지만 Ruby에게 문자열의 길이를 알려 달라고 부탁하는 대신, 그것은 문자열의 백 워드 버전을 뱉어 낸다.
"Eric".reverse
will result in
"cirE"
역 방향 입력은 가장 낮은 값에서 가장 낮은 값으로 값 목록을 정렬하려는 경우에 유용할 수 있다. (차후에 배울 내용을 정리하겠습니다.)
1. 이름에. 역 방향 방식을 호출합니다. 문자열로 만들기 위해 이름 주위에 따옴표가 있는 것을 잊지 마십시오!
값을 보려면 콘솔에 응답을 입력합니다.

puts "Good!".reverse
>> !dooG


1-9. '.upcase' & '.downcase'
한가지 방법을 더 시도해 봅시다(예:두가지 방법). 짐작했듯이. upcase및. down케이스 방법을 사용하면 문자열이 각각 모든 UPPERCASE또는 더 낮은 케이스로 변환됩니다.
1. 이름을 All CAPS로 만들고 다음과 같이 화면에 인쇄하기 위해 사용하기 위해 이름을 위로 불러 옵니다.
puts "eric".upcase # ==> ERIC
다음 줄에는, 이름을 소문자로 바꾸기 위해.downcase에 전화하세요. 인쇄물을 볼 수 있도록 반드시 화분을 사용하세요!

puts "ALL CAPS".upcase
puts "ALL CAPS".downcase
>> ALL CAPS
>> all caps


1-10. Single-Line Comments
여러분은 아마도 우리가 초기 운동에#표시를 몇번 사용하는 것을 보았을 것이다. #기호는 Ruby에서 설명을 합니다. 코멘트는 Ruby가 읽지 않고 단지 사람들이 읽을 수 있도록 하는 약간의 텍스트입니다. 좋은 논평을 쓰는 것은 그것을 읽을 수 있는 다른 사람들을 위해 여러분의 코드를 명확하게 할 뿐만 아니라 여러분이 코드 일을 쓸 때 무엇을 하고 있었는지를 상기시켜 준다.
#기호는 여러분의 의견 앞에 와야 하고, 여러분이 한줄로 서 있는 한, 그것 이후에 쓰는 모든 것에 영향을 주어야 합니다. (몇줄로 된 의견을 작성하는 방법을 곧 보여 드리겠습니다.)다음 예를 확인해 보십시오.
# I'm a full line comment!
"Eric".length # I'm a comment, too!
두번째 예시에서는 Ruby가 실행할 코드 다음에 설명이 있으므로 4개를 반환할 것이다.
1. 편집기에 설명을 씁니다. 네가 좋아하는 거라면 뭐든지 될 수 있어!
# The things I really want to be good at are math and coding and English. I'll do my best to be good at coding.


1-11. Multi-Line Comments
각 행을#로 시작하여 여러줄에 걸쳐 설명을 작성할 수 있지만 더 쉬운 방법이 있습니다. 시작과 끝을 각각=begin, =end로 시작하면 이 두 표현 사이의 모든 것이 코멘트가 됩니다. 다음 예를 살펴보겠습니다.
=begin
I'm a comment!
I don't need any # symbols.
=end
수화와 단어 사이에 공백을 두지 마라. 여러분은 수학으로 그렇게 할 수 있어요. 시작과 끝 모두 위에 표시된 것처럼 스스로 서 있어야 합니다.
1. 오른쪽의 에디터에서 다중 선 코멘트를 작성하세요. 시작과 끝이 같은지 확인하세요!
=begin
Comment
not bad
kkk
=end


1-12. Naming Conventions
이 과정을 진행하면서 여러분이 접하게 될 많은 다른 종류의 변수들이 있지만, 현재 우리는 단지 보통의 오래 된 지역적 변수에 관심이 있을 뿐입니다. 관례적으로 이러한 변수는 소문자로 시작해야 하고 단어는 카운터와 masterful_method와 같이 밑줄로 구분되어야 한다. 루비는 대문자,$s,@s등의 다른 기호로 로컬 변수를 시작하지 못하게 하지 않습니다. 하지만 관례에 따라 Ruby커뮤니티가 하는 것과 같은 다른 의미를 가집니다.
1. 편집기에서 변수 이름을 만들고 이를 문자열로 설정합니다(인용문 사이의 간격:"에릭"). 문자열은 대문자로 쓸 수 있지만 이름은 모두 소문자로 되어 있습니다!

name = "Eric"
puts name
>> Eric


1-13. Variables & Data Types
변수를 선언하고 설정하는 방법을 빨리 검토해 봅시다. 변수의 이름을 말하는 것만으로 변수를 선언하고 =로 설정할 수 있습니다. 도움이 더 필요하시면 아래 힌트를 확인하실 수 있습니다.
1.my_name이라는 변수를 생성하여 이름과 동일하게 문자열로 설정합니다. my_gee라는 두번째 변수를 만들어 사용자의 연령에 해당하는 숫자로 설정합니다(숫자 주위에 따옴표를 사용하지 않음).
변수 선언문은 다음과 같습니다.
variable_name
변수를 설정하는 방법은 다음과 같습니다.
name = "Eric"
age = 26
hungry = true

my_name = "my_name"
my_age = 20


1-14. Math
편집기에서 변수를 설정합니다.
13+377의 액수이다
923*15와 동등한 제품
13209/17과 같은 몫
결과를 보려면 Set(저장)을 사용하여 각 변수를 콘솔에 인쇄합니다.

sum = 13 + 379
product = 923 * 15
quotient = 13209 / 17

puts sum
puts product
puts quotient

>> 392
>> 13845
>> 777


1-15. Strings and String Methods
잘 했다! String 방법에 대해 조금 살펴봅시다. 을 사용하여 메서드를 호출합니다. 이런 식으로 작업자는 "string".methods.
1. 변수 이름을 지정하고 이름이 포함된 문자열과 동일하게 설정합니다. 모든 소문자를 소문자로 바꾸려면. 모두 거꾸로 돌려 이름을 뒤로 바꿉니다. 
Ruby에서는 다음 두가지 방법으로 할 수 있다. 각 메서드는 별도의 줄로 호출하거나, 다음과 같이 두 메서드를 함께 연결할 수 있다. 
name.method1.method2.method3 
결과를 보고 싶으면 메서드 호출을 지정합니다.
Hint 예를 들어 이름이 "스티브"라면
name = "Steve".downcase 
to convert your name to "steve".

name = "NAME"
puts name.downcase.reverse.upcase  #소문자로 바꾼 후 역순으로 만든 다음 다시 대문자로 만들었다.
>> EMAN


1-16. Comments
잘 했어요! 이 과의 마지막 복습 실습을 위해 단선 및 다중 행 의견을 살펴보겠습니다.
# I'm so sleepy.
=begin
I'll go to bed anyway.
Music is my life.
=end


2. Putting the Form in Formatter

2-1. What you'll Be Building
이 프로젝트는 사용자의 입력을 읽고 대문자를 수정하는 작은 프로그램을 만드는 것을 도와 줄 것이다. 사용자는 거의 무한한 범위의 입력을 제공할 수 있기 때문에 프로그래머로서 우리의 삶을 더 쉽게 만들어 줍니다.
에디터에 있는 코드를 확인해 봐요. 우리가 가르칠 새로운 것들을 추가했어요. 뭘 하는지 알겠어요? 자세한 내용을 보려면 실행을 클릭하십시오! 각 질문에 답하고 입력(키보드로 돌아감)을 누릅니다.
print "What's your first name? "
first_name = gets.chomp
first_name.capitalize!

print "What's your last name? "
last_name = gets.chomp
last_name.capitalize!

print "What city are you from? "
city = gets.chomp
city.capitalize!

print "What state or province are you from? "
state = gets.chomp
state.upcase!

puts "Your name is #{first_name} #{last_name} and you're from #{city}, #{state}!"
>> 입력 칸이 생기고 각 항목을 입력하면 출력된다.


2-2. Prompting the User
먼저, 우리가 이미 잘 알고 있는 코드를 입력해 봅시다. 사용자의 입력을 얻으려면, 먼저 화면에 메시지를 인쇄해야 할 것입니다.
1."이름이 무엇입니까?"라는 질문을 화면에 인쇄합니다. 구문 분석이 필요하면 자유롭게 첫번째 연습 문제를 다시 살펴보세요.
print "What's your first name?"
>> What's your first name?


2-3. Getting Input
좋아! 이제 새로운 것을 시도해 봅시다. 이 예에서 반복되는 이상한 코드 줄을 보시면 아실 수 있을 겁니다.
variable_name = gets.chomp
gets는 사용자로부터 입력을 받는 Ruby방법입니다. 입력을 받을 때마다 Ruby가 자동으로 입력 후 빈 줄(또는 새 라인)을 추가하고, chomp은 그 줄을 제거한다. (프로그램은 선택하지 않아도 잘 작동하지만, 빈 줄이 더 많이 생깁니다.)
1. 변수 lastnamefirst_name님을 설명하고 gets.chomp와 동등하게 설정하십시오.
이 체크 포인트는 영구적으로 실행되는 것처럼 보이지만, 오른쪽의 터미널은 gets.chomp때문에 실제로 입력을 기다리고 있습니다. 단자의 질문에 답하고"Enter"또는"Return"을 눌러 점검을 마칩니다.

print "What's your first name? "

first_name = gets.chomp


2-4. Repeat for More Input
좋아! 이제 성, 시, 주 마지막에 우리가 한 일을 반복해야 한다.
1. 사용자의 성, 도시 및 상태 .province에 대한 인쇄 프롬프트, 변수 및 gets를 추가합니다. last_namefirstname님을 사용자의 성, 시/군/도에 대한 구/군/시 변수로 사용하십시오. (힌트:사용자에게 주/도(예:"NY")라는 뉴욕의 약어를 입력하도록 요청합니다. 이것은 우리가 자연스럽게. upcase를 나중에 사용하도록 유도할 수 있습니다!)

print "What's your first name? "
first_name = gets.chomp
print "What's your last name? "
last_name = gets.chomp
print "What city are you from? "
city = gets.chomp 
print "What state or province are you from? "
state = gets.chomp


2-5. Printing the Output
여러분들도 아시다 시피 루비는 우리에게 아무런 피드백도 주지 않습니다. 우리는 우리의 문자열 포맷을 볼 수 있기를 바랍니다! 이렇게 하려면, 우리는 하나의 새로운 구문이 더 필요하다.
변수 원숭이를 "호기심 많은 조지"라는 문자열과 동일하게 정의하고"나는 동물원에#{원숭이}를 데려갔다"라는 문자열이 있다면 Ruby는 "문자열 보간"이라는 것이다. 우리도 여기서 같은 걸 할 수 있어! 예를 들어:
first_name = "Kevin"
puts "Your name is #{first_name}!"
"네 이름은 케빈이야!"라고 인쇄될 것이다.
1. 이 구문을 사용하여#{}구문을 사용하여 first_name, last_namefirst_state의 값을 인쇄하십시오.

print "What's your first name? "
first_name = gets.chomp
print "What's your last name? "
last_name = gets.chomp
print "What city are you from? "
city = gets.chomp 
print "What state or province are you from? "
state = gets.chomp

puts "#{first_name} #{last_name} #{city} #{state}"


2-6. Formatting with String Methods
좋았어! 이제 우리는 우리의 결과물을 얻었지만, 보시다시피, 우리는 아직 모든 것을 적절히 자본화하기 위해 끈 방식을 사용하지 않았습니다.
print "This is my question?"
answer = gets.chomp
answer2 = answer.capitalize
answer.capitalize!
먼저 우리는 대문자로 쓰는 새로운 방법을 소개한다. 그것은 끈의 첫번째 문자를 대문자로 바꾸기 때문에, 나머지 문자들은 소문자로 만든다. 우리는 그 결과를 answer2에 할당했다.
다음 줄은 조금 이상하게 보일 수도 있습니다. 우리는 변수에 대문자를 사용한 결과를 할당하지 않습니다. 대신에 당신은 그것을 알아챌지도 모른다! 대문자로 이 값은 가변 응답 자체에 포함된 값을 수정합니다. 다음에 이 가변 응답을 사용하면 answer.capitalize의 결과를 얻게 됩니다.
# !를 왜 붙이는 걸까? 이게 있어야 하긴 하는데..?
print "What's your first name? "
first_name = gets.chomp
first_name2 = first_name.capitalize!

print "What's your last name? "
last_name = gets.chomp
last_name2 = last_name.capitalize!

print "What city are you from? "
city = gets.chomp 
city2 = city.capitalize!

print "What state or province are you from? "
state = gets.chomp
state2 = state.upcase!

puts "#{first_name} #{last_name} #{city} #{state}"


2-7. Great Work!
완벽해! 몇개의 간단한 단계로, 당신은 당신만의 Ruby프로그램을 실제 어플리케이션으로 만들었다. 당신의 프로그램에 얼마든지 추가하거나 바꾸고 싶은 만큼 바꾸세요.


2. Control Flow in Ruby

1. Control Flow in Ruby

1-1. How It Works
여러분은 우리가 루비에서 지금까지 써 온 종류의 프로그램들이 그렇게 유연하지 않다는 것을 눈치 챘을지도 모릅니다. 물론, 사용자 입력을 받을 수는 있지만 항상 해당 입력에 기반한 동일한 결과를 생성하며 환경에 대한 대응으로 동작( 주어진 시간에 프로그램에 존재하는 모든 변수와 값의 집합)을 변경하지 않는다.
흐름을 조절하면 우리가 원하는 융통성을 얻을 수 있다. 우리는 사용자 유형, 연산의 결과, 프로그램의 다른 부분에 의해 반환되는 값에 따라 다른 결과를 선택할 수 있다.
1. 에디터에서 코드를 확인한다. 몇개의 새로운 구문이 있지만, 우리는 그것이 무엇을 하는지 짐작할 수 있을 것이라고 확신한다. 실행을 클릭하여 실행 중인 프로그램을 확인하세요! (계속해서 루비에 정수, 즉 소수가 없는 양수나 음수를 입력해 주세요.)

print "Integer please: "
user_num = Integer(gets.chomp)

if user_num < 0
  puts "You picked a negative integer!"
elsif user_num > 0
  puts "You picked a positive integer!"
else
  puts "You picked zero!"
end


1-2. if
Ruby의 말이 표현을 취한다면, 진실이나 거짓으로 평가되는 가치를 지닌 어떤 것을 일컫는 멋진 말이 될 것이다. 이 표현이 참이면 Ruby가 다음과 같은 코드 블록을 실행한다. 만일 그것이 사실이 아니라면(거짓)루비는 그 코드 블록을 실행하지 않습니다. 코드를 건너뛰고 다음 것으로 넘어가죠.
다음은 실제 작동 중인 경우의 예입니다.
if 1 < 2
print "I'm getting printed because one is less than two!"
end
루비는 화이트 스페이스(공백과 빈 선)에 대해서는 신경을 쓰지 않기 때문에 인쇄물에 새겨질 필요가 없습니다. 하지만, 그것은 루비 애호가들이 따르는 관습이기 때문에, 지금은 습관을 들이는 것이 좋습니다. 다음에 오는 코드 블록은 두 공간을 더 들여 써야 합니다. 만약의 경우가 끝나면, 루비 입력으로 알려 주셔야 합니다.
1. 편집기에 설명을 직접 작성합니다. 원하는 식을 입력할 수는 있지만(오직 true!)로 평가되어야 합니다. 그렇게 하면 사용자가 선택한 문자열을 콘솔에 인쇄하거나 넣어야 합니다.

if true
  print "Extension of You"
end
>> Extension of You

1-3. Else
만약 진술에 대한 동반자는 거짓 진술이다. Ruby에게 만약 이 표현이 사실이라면, 이 코드 블록을 실행하고, 그렇지 않으면, else문 뒤에 코드를 실행하라고 말하는 사람이 있다면, 여기에 한가지 예가 있다.
if 1 > 2
    print "I won't get printed because one is less than two."
else
   print "That means I'll get printed!"
end
1. 편집장님이 직접 해 보세요! 사용자가 원하는 표현을 사용하여 설명서를 작성하되, 두 분기 모두 원하는 문자열을 콘솔에 인쇄해야 합니다.

if false
  print "Extension of You"
else
  print "I'm real"
end
>> I'm real


1-4. Elsif
하지만 두개 이상의 옵션을 원하는 경우에는 어떻게 합니까? 구조를 요청한다! elsif성명은 만약 다음과 같은 경우에 어떤 대안도 추가할 수 있습니다:
if x < y # Assumes x and y are defined
puts "x is less than y!"
elsif x > y
puts "x is greater than y!"
else
puts "x equals y!"
end
1. 편집기에 설명이 있는 경우, elsif블록을 추가합니다. # 입력한 값을 받아 조건 비교해서 출력.
print "Enter number x >> "
x = gets.chomp
print "Enter number y >> "
y = gets.chomp

if x > y
  puts "Extension of You"
elsif x < y
  puts "I'm real"
else
  puts "Not bad"
end


1-5. Unless #if의 부정형. 거짓이여야 실행이 됨.
때로는 어떤 것이 거짓인지 확인하기 위해 제어 흐름을 이용하기도 합니다. 만일 그것이 사실이라면 Ruby가 더 잘 해 줄 것입니다.
배 고프지 않으면 먹고 싶지 않다고 합시다. 즉, 배 고프지 않을 때는 프로그램을 만듭니다. 하지만 배 고플 때는 먹습니다. 루비에서의 프로그램은 이렇게 써 놓으시겠지요.
unless hungry # Write some sweet programs
else # Have some noms
end
1. 편집장님께 시작했어요. 설명 코드가 없는 경우에는 "Ruby프로그램을 쓰고 있어요!"라고 인쇄하여 사용자의 프로그램을 올바르게 교체한다.

hungry = false

unless hungry #거짓의 조건이여야 실행.
  puts "I'm writing Ruby programs!"
else # 참의 조건이여야 실행.
  puts "Time to eat!"
end

>> I'm writing Ruby programs!


1-6. Equal or Not?
Ruby에서, 우리는 값을;에 할당 연산자를 사용하여 변수에 할당합니다. 하지만 우리가 이미 과제에 사용했다면 두가지 사항이 같은지 어떻게 확인해야 할까요? 음, 우리는==을 사용하는데, 이것은 대조군(관계 연산자라고도 함)입니다. ==는 " 같음"을 의미합니다.
x = 2
y = 2
if x == y
print "x and y are equal!"
end
즉,"x가 y와 같으면,'x와 y가 같다!"를 인쇄하십시오. 또한 != 비교기를 사용하여 두 값이 같지 않은지 여부를 확인할 수 있습니다.
1. 편집기에는 is_true및 is_fault이라는 두가지 변수가 있습니다. ___________________ 을(를)==또는!=로 바꾸어 is_true를 평가하고 false로 평가하게 합니다.

is_true = 2 != 3
is_false = 2 == 3


1-7. Less Than or Greater Than
또한 한 값이 다른 값보다 작거나, 작거나, 같거나, 크거나, 같은지 또는 같은지 확인할 수 있습니다. 이러한 운영자는 다음과 같습니다.
Less than: < 미만
Less than or equal to: <= 이하거나 같음.
Greater than: > 초과
Greater than or equal to: >= 이상이거나 같음
1. 편집기에 몇가지 변수를 설정했습니다. 우리는 그것들이 모두 참이기를 바란다.

test_1 = 17 > 16
test_2 = 21 <= 30
test_3 = 9 >= 9
test_4 = -11 < 4


1-8. Practice Makes Perfect
지금까지 잘 했어요! 연습이 완벽을 만든다는 말이 있잖아요. 몇가지 대조군을 더 시도해 보아요.
1. 이 라운드에서는 표현식이 반환될 것으로 예상되는 값에 따라 비교기를 표시하고 각 변수를 true또는 false로 설정합니다. 기억하세요:진실과 거짓 주위에 인용문이 없다는 것을!

# test_1 = 77 != 77
test_1 = false 

# test_2 = -4 <= -4
test_2 = true

# test_3 = -44 < -33
test_3 = true

# test_4 = 100 == 1000
test_4 = false


1-9. And(그리고 는 둘다 참 이어야 한다.)
루비에서는 비교할 만한 연산자가 많지 않습니다. 논리적 연산자 또는 부울 연산자를 사용할 수도 있습니다. Ruby는 3개가 있어요, 그리고. 불 리언 연산자는 True또는 False인 부울 값을 발생시킵니다.
불 리언 연산자와 이니스는 1980년대의 어느 한쪽의 두 표현이 모두 참일 때만 참이 될 수 있습니다.
true && true # => true
true && false # => false
false && true # => false
false && false # => false
1 < 2 && 2 < 3 is true. true && true이기 때문.
1. 좀 더 연습해 봅시다. 부울 표현식을 선택하여 표현식이 반환될 것으로 예상되는 값에 따라 각 변수를 true또는 false로 설정합니다.

# boolean_1 = 77 < 78 && 77 < 77
boolean_1 = false 

# boolean_2 = true && 100 >= 100
boolean_2 = true 

# boolean_3 = 2**3 == 8 && 3**2 == 9
boolean_3 = true 


1-10. Or(또는 둘 중 하나만 참이면 된다.)
Ruby는 또한 연산자를 가지고 있어요. Ruby의.....이 모든 것이 하나의 표현이 사실이거나 두개의 표현이 사실일 때, 진실을 평가하기 때문에, 이것을 확인해 보세요.
true || true # => true
true || false # => true
false || true # => true
false || false # => false
1. 표현식이 반환될 것으로 예상되는 값에 따라 각 변수를 true또는 false로 설정합니다.

# boolean_1 = 2**3 != 3**2 || true
boolean_1 = true 

# boolean_2 = false || -10 > -9
boolean_2 = false

# boolean_3 = false || false
boolean_3 = false


1-11. Not
마지막으로 Ruby는 Boolean 연산자가 없다.(!) ! 참 값을 거짓으로, 그 반대로 하여 값을 거짓으로 만듭니다.
!true # => false
!false # => true
1. 표현식이 반환될 것으로 예상되는 값에 따라 각 변수를 true또는 false로 설정합니다.
# boolean_1 = !true
boolean_1 = false

# boolean_2 = !true && !true     # and 연산자는 둘다 참 이어야 한다.
boolean_2 = false

# boolean_3 = !(700 / 10 == 70)
boolean_3 = false


1-12. Combining Boolean Operators
표현식에 부울 연산자를 결합할 수 있습니다. 같은 조합
(x && (y || w)) && z
법적 표현일 뿐만 아니라 프로그램에 매우 유용한 도구입니다.
이러한 표현에 익숙해지는 데는 약간의 시간이 걸릴 수 있지만 평가 순서를 제어하기 위해 항상 괄호를 사용할 수 있습니다. 괄호 안의 식은 항상 괄호 밖의 모든 것에 앞서 평가됩니다.
1. 마지막으로 표현식이 반환될 것으로 예상되는 값에 따라 각 변수를 true또는 false로 설정합니다.

# boolean_1 = (3 < 4 || false) && (false || true)
boolean_1 = true 

# boolean_2 = !true && (!true || 100 != 5**2)
boolean_2 = false

# boolean_3 = true || !(true || false)
boolean_3 = true


1-13. Nice Work!
잘 했어요! 지금까지 학습한 내용:  연산자
if, else, 또는 elsif인 경우 사용 방법
대조군/관계 연산자와 같은 대조군,!=, <, <, >, >=, <= 및 &&, ||, !,  
어떻게 불 리언/논리 연산자를 사용할 수 있을까?
지금까지 배운 내용을 잠깐 생각해 보세요. 준비가 되었으면 다음을 눌러 검토 연습을 시작하십시오.

> : 왼쪽이 더 커야 한다. 초과.
< : 오른쪽이 더 커야 한다. 미만.
>= : 왼쪽이 더 크거나 같아야 한다. 이상
<= : 오른쪽이 더 크거나 같아야 한다. 이하.
&& : And 연산자. 둘다 참(true) 이어야 한다.
|| : Or 연산자. 둘 중 하나만 참(true)이면 된다.
! : Not 연산자. true, flase를 뒤집는다. !true면 false가 되고 !false면 true가 된다.


1-14. If, Else, and Elsif
좋아! 외로워 하시는군요 (글쎄, 꼭 그렇지는 않아. 이 예는 여기에 남겨 두겠습니다.)
a = 10
b = 11
if a < b
print "a is less than b!"
elsif b < a
print "b is less than a!"
else
print "b is equal to a!"
end
1. 편집기에 설명서를 작성한다. 하나 이상의 elsif를 포함해야 합니다. 전표의 각 분기는 콘솔에 항목을 인쇄해야 합니다.
Hint
if/elsif/else 이면 구문은 다음과 같습니다.
if expression
# Do something
elsif expression
# Do something else
else # Do yet another thing
end
a = 2 * 4
b = 3 ** 2

if a > b
  print "over"
elsif a < b
  print "and over"
else
  print "Lemon"
end


1-15. Unless
좋아! 그럼 다음 문장을 검토해 보겠습니다.
problem = false
print "Good to go!" unless problem
기억하세요, 이것은 기본적으로 짧은 글입니다. 조건이 참이 아니라면 당신이 요구하는 것은 무엇이든지 할 것입니다. 우리의 예로는, 문제는 거짓이기 때문에 우리는 아무 문제가 없습니다. 인쇄할 준비 완료!
이 조건이 거짓으로 평가되는 경우 실행 됩니다.
unless condition
# Do something!
end
over = false

unless over
  print "~~~~"
end


1-16. Dare to Compare
이제 대조군/관계 연산자를 검토하겠습니다. 우리가 형세를 조금 역전시켰어요!
대조군은 진실 또는 거짓을 초래하기 위해 두 값을 서로 비교해야 한다는 점을 기억한다.
10 > 8 // true
8 > 10 // false
8 == 10 // false
8 != 10 // true
1. 우리는 우리가 각 변수에 어떤 값(참 또는 거짓)을 원하는지 알려 주고 있으며, 당신의 직업은 대조군을 사용하여 정확한 값으로 평가하는 표현을 추가하는 것이다.
비교 자료는 다음과 같습니다. ==, !=, >, >=, <, and <=.
# test_1 should be false
test_1 = 1 != 1 

# test_2 = should be false
test_2 = 22 <= 20

# test_3 = should be true
test_3 = 7 > 6


1-17. Billions of Booleans
( 1 == 1 ) && ( 2 == 2 ) # true
( 1 == 2 ) || ( 2 == 2 ) # true
!( false ) # true
1. && 는 둘다 참 이어야 한다. true true 아니면 다 false.
2. || 는 둘 중 하나만 참이면 true다. true false는 true.
3. !는 뒤집는다 보면 된다. true면 false. false면 true.
1. 편집기의 코드는 원하는 값(참 또는 거짓)을 나타내며, 사용자의 작업은 부울 연산자(x0,!x!),를 사용하여 올바른 값으로 평가하는 식을 추가하는 것입니다.

# test_1 should be true
test_1 = (2 ** 4 == ((3 ** 2) * 2 - 2)) && (16 == 16) 

# test_2 = should be true
test_2 = (4 != 2) || (2 != 2) 

# test_3 = should be false
test_3 = !(true)


2. Thith Meanth War!

제어 흐름을 사용하여 사용자의 입력을 수정하여 사용자에게 반환할 수 있습니다. 이 프로젝트에서는, 우리는 그들을 대피 덕으로 만들 것입니다!

2-1. What You'll Be Building
이제 우리는 만일/etc/문을 사용해서 프로그램의 방향을 정할 수 있으므로, 우리는 다른 사용자의 입력에 기초해 다른 결과를 생산할 수 있다.
이 프로젝트에서는 제어 흐름을 몇가지 새로운 Ruby스트링과 결합하고, 사용자의 스트링을 DaffyDuckify로 결합하고, 각"s"를 "th"로 교체할 것이다.
# gets.chomp로 입력을 받게 하고 대문자를 소문자로 바꿔준다. downcase! 또한 s가 들어간 것을 th로 교체해준다.

print "Thtring, pleathe!: "
user_input = gets.chomp
user_input.downcase!

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
else
  puts "Nothing to do here!"
end
  
puts "Your string is: #{user_input}"


2-2. Getting User Input
먼저 사용자에게 입력을 요구하는 문장을 인쇄한 다음 gets.chomp을 사용하여 해당 입력을 변수에 설정해야 한다.
1. 인쇄물을 사용하여 사용자에게 입력을 요청합니다.
User_input이라는 변수를 선언하고 gets.chomp를 사용하여 사용자의 입력에 동등하게 설정하십시오.
print "Input: " 
user_input = gets.chomp


2-3. Downcase!
우리는 우리가 사용자의 입력에 있는 "S"와 "s"모두를 캡처했는지 확인하고 싶다. 만일 이것을 처리하기 위해 if / else 다른 진술들을 따로 쓸 수도 있지만, 우리는 또한. downcase!를 사용할 수도 있습니다. 사용자 입력을 모든 소문자로 변환합니다. 그런 식으로, 우리는 "s"를 검색하기만 하면 된다.
1. 다운 케이스를 불러 오세요! user_input방법 꼭 포함시켜 주세요! 사용자 문자열이 인 플레이스 방식으로 수정되도록 하기 위해 Ruby가 user_input의 복사본을 생성하고, 대신 수정할 수 있도록 한다.

print "Pleathe enter a thtring: " 
user_input = gets.chomp
user_input.downcase!


2-4. Setting Up the 'If' Branch, Part 1
좋아! 제어 흐름을 약간 추가할 시간입니다.
분기의 절반에 해당하는 경우 사용자의 입력에 "s"가 포함되어 있는지 확인하려고 합니다.
if string_to_check.include? "substring"
루비를 사용해서 할 수 있어요. .include? 방법을 사용하여 원하는 것을 찾았는지 여부를 확인하고, 그렇지 않으면 거짓인지 평가합니다.(true or false)
(루비 방법은 일반적으로 어떻게 끝이 납니까? 값이 참인지 거짓인지 평가하십시오.)
1.user_input에 하위 문자열"s"가 있는지 확인하고자 합니다.
만일의 경우에는 편집자에게 성명서를 쓰시오. user_input에 "s"가 포함되어 있는지 확인해야 한다. 
현재로서는 선택한 문자열로 "s"를 발견하면 콘솔에 출력한다.

print "Pleathe enter a thtring: " 
user_input = gets.chomp
user_input.downcase!

if user_input.include? "s"
  print "s"
else
  print "Does not include s."
end 


2-5. Setting Up the 'if' Branch, Part 2
좋아! 이제 우리의 진술을 완성합시다.
우리가 "s"를 발견했을 때, 루비가 발견한 모든"s"인스턴스를 "th"로 대체했으면 합니다. 우리는 이것을 .gsub!로 할 수 있어 이 방법은 전 지구적 대체를 나타낸다. global substitution.
구문은 다음과 같습니다.
string_to_change.gsub!(/s/, "th")
나중에 배울 내용을 배울 때는 왜 /s/가 따옴표 대신 slash사이에 있어야 하는지 설명해 드리겠어요. 참고:gsub 사이에 공백을 둘 수 없습니다! 그리고 괄호 안의 비트.
기억해, 너는 그 것을 원한다는 것을! 메서드 이름의 끝에서 Ruby가 문자열 인 플레이스를 변경하도록 합니다.
1. 설명문에 추가한 인쇄 문구를 제거하고 .gsub!에 대한 호출로 대체합니다. user_input에. /s/를 "th"로 교체하도록 합니다.
# .gsub(/목표 단어/, "목표 단어 바꿀 것")
print "Pleathe enter a thtring: " 
user_input = gets.chomp
user_input.downcase!

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
end

print user_input
>> Pleathe enter a thtring: asb # Input
>> athb # Ouput


2-6. Setting Up the 'Else' Branch
어려운 부분은 끝났어! 이제 사용자에게 문자의 인스턴스를 찾을 수 없으면 알려 주기만 하면 됩니다.
1. 사용자에게 문자열이 있는지 여부를 알려 주는 추가 설명을 추가합니다.

print "Pleathe enter a thtring: " 
user_input = gets.chomp
user_input.downcase!

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
else
  print "Does not include s."
end


2-7. Returning the Final String—Er, "Thtring"
HomeStretch—이제 DaffyDuckified문자열이 사용자에게 표시됩니다. 앞서 배운 문자열 보간을 사용하여 다음을 수행할 수 있습니다.
my_string = "muchachos"
print "Adios, #{my_string}!"
# ==> "Adios, muchachos!"

1. 문자열 보간을 사용하여 사용자에게 변환된 문자열이 표시되도록 하는 퍼팅 문을 추가합니다.
print "Pleathe enter a thtring: " 
user_input = gets.chomp
user_input.downcase!

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
  puts "Ahai~, #{user_input}!"
else
  print "Does not include s."
end


2-8. Congratulationth!
잘 했어요!
이 프로젝트를 어떻게 개선할 것인가? 다음과 같은 이점이 있습니다.
아무것도 입력하지 않은 경우 사용자의 입력을 다시 처리하기 위한 설명을 추가합니다.
문자"c"가 "s"와 같이 들리는 단어를 설명하는 방법에 대해 생각해 보세요.
사용자의 원래 대문자를 보존하는 방법에 대해 생각해 보십시오.
1. 일단 심사 숙고해 보세요. 준비가 되었으면 실행을 클릭하여 이 프로젝트를 완료하십시오.

print "Pleathe enter a thtring: " 
user_input = gets.chomp

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
  puts "Ahai~, #{user_input}!"
elsif user_input.include? "S"
  user_input.gsub!(/S/, "th")
  puts "Ahai~, #{user_input}!"
elsif user_input == ""
  print "Pleathe enter a thtring: "
  user_input = gets.chomp
else
  print "Does not include s."
end


3. Looping with Ruby

1. Loops & Iterators

루프 및 일정을 사용하여 Ruby가 쉽고 빠르게 반복 작업을 자동화할 수 있습니다.

1-1. The 'While' Loop
어떤 상황이 참일 때 Ruby에서 어떤 동작을 몇번이나 반복하고 싶을 때, 당신은 얼마나 많이 그 동작을 반복해야 할지 모른다. 한가지 좋은 예는 사용자에게 특정 유형의 입력을 요구하는 것입니다. 즉, 사용자가 잘못된 정보를 제공해야 하는 경우에는 찾으려는 입력 정보를 얻기 전에 여러번 다시 입력해야 할 수 있습니다.
이를 위해 우리는 '일시 루프'라고 하는 것을 사용합니다. 이 기능은 특정 조건이 참인지 여부를 확인하고, 그렇게 하는 동안 루프가 계속 실행되는지 확인합니다. 이 상태가 참이 되지 않으면 루프가 멈춥니다!
편집자의 코드를 확인해 보세요. 그것이 무엇을 할 것인지 알아맞힐 수 있나요? 알고 있다고 생각되면 Run을 눌러 결과를 확인하십시오.

counter = 1
while counter < 11
  puts counter
  counter = counter + 1
end
>> 1 ~ 10 까지 연속적으로 출력.


1-2. Danger: Infinite Loops!
너 방금 그거 봤니? 루프는 1에서 10까지 숫자를 출력한 다음 멈췄다. 이것은 카운터가 11미만일 때 루프의 상태가 계속되도록 지시되었기 때문입니다;카운터가 루프를 통해 1씩 증가하기 때문에, 카운터가 11을 칠 때 루프가 멈추었습니다.
카운터를 늘리는 걸 까먹었으면 어떻게 하죠? 루프가 1에 유지되고, 루프가 11보다 작은지, 그리고 1이 항상 11보다 작은지 계속 점검했을 것이며, 루프가 결코 끝나지 않았을 것입니다. 이를 무한 루프라고 하며 프로그램 충돌을 유발합니다. 어떤 일이 있어도 그것들을 피하세요!
1. 편집기의 루프는 현재 무한 루프입니다. 끝이 나도록 고쳐 주세요! (주의하십시오. 바로 실행을 클릭하면 무한 루프가 시작되고 페이지를 새로 고쳐야 합니다.)

i = 0
while i < 5
  puts i
  i = i + 1
end


1-3. The 'Until' Loop
시간 루프에 대한 보완은~ 까지 루프입니다. 그건 일종의 퇴보인 셈이죠
i = 0
until i == 6
i = i + 1
end
puts i 
1. 위의 예에서는 변수 i를 생성하여 0으로 설정합니다. 
2. 그러면 내가 6살이 될 때까지 우리는 코드 블록을 실행한다. 그 코드 블록은 i를 증가시킨다.
3. 내가 6과 같을 때, 그 블록은 끝난다.
4. 마지막으로, 콘솔에 i의 값인 6개를 인쇄합니다.

2번 라인에서, 카운터가 10보다 클 경우 루프가 끊어지도록 공백을 채우십시오.
5호선에서는 위의 예와 같이 카운터를 늘립니다.
루프 모양이 다음과 같아야 합니다.

1.On라인 2는 카운터가 10보다 클 경우 루프가 끊어지도록 __________________ 공백을 채웁니다.
5호선에서는 위의 예와 같이 카운터를 늘립니다.

until # Counter is greater than 10
puts counter
#Increment counter
end

counter = 1
until counter > 10
  puts counter
  counter = counter + 1
end
>> 10 까지 출력

until counter == 10
>> 9 까지 출력.


1-4. More Assignment Operators
counter = counter + 1 과 같은 구문을 사용해 왔지만 루비에서의 사용이 늘어나면서 항상 다른 방법이 있습니다.
바로 가기는 할당 연산자를 사용하는 것입니다. 하나의 할당 연산자, 즉 변수를 설정하는=를 이미 알고 있습니다. 그러나+=, -=, *=및/=를 포함하는 추가 할당 연산자를 사용하여 변수를 업데이트할 수 있습니다. 예를 들어, 입력할 때 
counter += 1
Ruby에게 이렇게 말합니다."1을 추가하고, 다시 카운터에 새로운 값을 할당하세요."이것은 우리의 프로그램에서 변수 값을 업데이트하는 간결한 방법을 제공합니다.
일부 언어에는 증가 연산자 ++ 가 있으며 --(값에서 1을 추가 또는 차감하기도 함), Ruby에는 없다. 당신은 +로 해야 할 것이다.
1. 첫번째 연습의 루프가 편집기에 있습니다. 적절한 할당 연산자를 사용하여 다시 쓰십시오.

counter = 1
while counter < 11
  puts counter
  counter += 1
end


1-5. The 'For' Loop
하지만, 때때로 여러분은 여러분이 얼마나 많이 루프를 반복하는지 알게 됩니다.
편집기에서 루프의 예를 살펴보십시오. 여러분은 이것이 무엇을 하는지 추측할 수 있나요? 실행을 클릭하여 작업을 확인하십시오.
for num in 1...10
  puts num
end
>> 1
>> 2
>> ...
>> 9         #1~9 까지 연속적으로 출력.


1-6. Inclusive and Exclusive Ranges
이전 연습에서 1...10의 num에 대한 약간의 새로운 구문을 보았습니다. Ruby가 말하는 것은 다음과 같습니다."1~10범위의 변수 num은 다음과 같습니다. puts"#{num}"은(는)1부터 10까지의 값을 입력하는 콘솔입니다.
이 프로그램이 10이 아닌 9까지 계산된 이유는 우리가 범위 안에 점 세개를 사용했기 때문이다. 루비는 1.10에 숫자를 마지막으로 넣지 않았다고 한다.
1. 편집기의 루프를 두가지 방법으로 업데이트합니다.
15를 포함해 1에서 15까지 인쇄하게 하세요.
사용하려면 변경하십시오. 대신에...
for num in 1..15
  puts num
end
>> 1 ~ 15 까지 출력.

for num in 1...15
  puts num
end
>> 1 ~ 14 까지 출력.


1-7. Building Your Own
잘 했어요! 여러분은 자신만의 루프를 만들 준비가 되어 있습니다.
20을 포함하여 숫자 1을 20에 이르게 하는 루프는 다음 중 하나를 사용하여 쓰기 바랍니다. 또는....구문을 새로 고쳐야 할 경우 힌트를 확인하십시오.
루프는 다음과 같아야 합니다.
for variable in range #.. or ...
puts variable
end
for num in 1..20
  puts num
end
>> 1 ~ 20 까지 출력.

for num in 1...21
  puts num
end
>> 1 ~ 20 까지 출력.


1-8. The Loop Method
지금까지 루비에서의 동작을 반복하는 한가지 방법에 대해 배웠는데, 바로 루프입니다. 루비의 경우가 흔히 그렇듯, 주어진 임무를 완수하는 데는 여러가지 방법이 있다. 이 경우에, 이터레이터를 사용하여 동작을 반복할 수도 있습니다.
이터레이터는 Ruby방식으로 몇번이고 코드 블록을 불러 온다. 코드 블록은 반복될 지시 사항을 포함하고 있는 비트에 불과하고, 그러한 지시는 여러분이 좋아하는 어떤 것이든지 될 수 있어요!
가장 간단한 온도 조절기는 루프 방법입니다. 단순히 입력하여( 하지만 무한대!)기본 루프를 만들 수 있습니다.
loop { print "Hello, world!" }
Ruby에서는, flook브레이스({})가 일반적으로 키워드 do(블록을 열기 위해)및 end(닫기 위해)과 호환됩니다. 이것을 알면 위에 있는 것보다 더 똑똑한 루프를 만들 수 있습니다.
i = 0
loop do
i += 1
print "#{i}"
break if i > 5
end
1. 편집기의 ____파일을 적절한 키워드로 바꿉니다. 도움이 필요하시면 힌트를 확인하세요!
누락된 키워드는 루프, 실행 및 분할입니다. 예제를 통해 올바른 순서로 정렬되었는지 확인하십시오.

i = 20
loop do
  i -= 1
  print "#{i}"
  break if i <= 0
end
>> 191817161514131211109876543210


1-9. Next!
다음 키워드를 사용하여 루프의 특정 단계를 건너뛸 수 있습니다. 예를 들어 짝수를 인쇄하지 않으려면 다음을 수행할 수 있습니다.
for i in 1..5
next if i % 2 == 0   #짝수인 참의 값이 스킵된다.
print i
end
1. 위의 예에서는 1~5의 범위를 순환하여 각 숫자를 i에 차례로 할당합니다.
2. i/2의 나머지가 0이면 루프의 다음 반복으로 이동합니다.
3. 그런 다음 i값을 인쇄합니다. 이전 줄로 인해 이 줄은 1,3,5개의 라인만 인쇄됩니다.

1. 인쇄 문구 전에 루프에 줄을 추가하십시오. 숫자 i가 홀수인 경우 다음 반복으로 건너뛸 수 있도록 다음 키워드를 사용하십시오.
위의 예는 도움이 필요한 경우에도 사용할 수 있지만, 위의 예에서는 짝수를 건너뜁니다.

i = 20
loop do
  i -= 1
  next if i % 2 != 0
  puts "#{i}"
  break if i <= 0
end
>> 181614121086420


1-10. Saving Multiple Values
변수에 일련의 숫자를 저장한다고 합시다. 어떻게 하면 될까요? 변수는 하나의 값만 가질 수 있습니다, 그렇죠?
Ruby에서는, 우리는 여러 값들을 하나의 배열을 사용해 하나의 변수로 묶을 수 있다. 배열은 대괄호 사이에 있는 항목의 목록일 뿐입니다:[1,2,3,4]. 이러한 항목은 주문할 필요가 없습니다.[10,31,19,400]만큼 쉽게 주문할 수 있습니다.
1.my_array라는 변수를 만들어 1부터 5까지 순차적으로 설정합니다.

my_array = [1, 2, 3, 4, 5]


1-11. The .each Iterator
잘 했어요! 당신은 정말 이것의 요령을 터득하고 있어요.
루프 이터레이터는 가장 간단하지만 가장 강력하지 않은 것 중 하나이기도 합니다. 더 유용한 것은. 각 방법이며, 이것은 한번에 하나씩 개체의 각 요소에 표현을 적용할 수 있다. 구문은 다음과 같습니다.
object.each { |item|
# Do something
}
{}대신 다음과 같은 작업 키워드를 사용할 수도 있습니다. do
object.each do |item|
# Do something
end
여러분이 좋아하는 것은 무엇이든지 다양한 이름이 될 수 있어요:그것은 여러분이 사용하고 있는 물체의 각 요소에 대한 자리 표시자에 불과합니다.

array = [1,2,3,4,5]

array.each do |x|
  x += 10
  puts "#{x}"  # 이 형식 중요. "#{}" 그래야 제대로 출력 됨.
end
>> 11 12 13 14 15


1-12. Try It Out!
멋지지 않아? 이제 당신이 각 방법을 시험 주행에 사용할 차례입니다.
numbers = [1, 2, 3, 4, 5]

# one way to loop
numbers.each { |item| puts item }

# another way to loop
numbers.each do |item|
puts item
end
1. 위의 예에서는 숫자라는 배열을 생성합니다. 
2. 그런 다음 각 항목을 콘솔에 숫자로 인쇄하는 두가지 방법을 보여 줍니다.

1. 배당률 어레이의. 각 방법을 사용해 어레이의 각 항목 값의 두배를 인쇄한다. 다시 말해, 각 항목에 2를 곱합니다. 그러면 출력이 한줄에 나타납니다.
막히면 힌트를 확인하세요!

odds = [1,3,5,7,9]

odds.each do |placeholder|
  placeholder *= 2
  puts placeholder
end


1-13. The .times Iterator
.times메서드는 슈퍼 콤팩트 루프와 같습니다. 이것은 지정된 횟수만큼 개체의 각 항목에 대해 작업을 수행할 수 있습니다.
예를 들어, 우리가 " 두툼한 베이컨"을 인쇄하고 싶었다면,
10.times { print "Chunky bacon!" }
우리가 왜 그것을 타이핑해야 하는지 모르겠지만, 우리는 할 수 있었어요!
1. 원하는 횟수만큼 원하는 문자열을 인쇄하는 데. time연산자를 사용하십시오. 도움이 필요하면 위 텍스트에 있는 코드를 가이드로 사용하십시오.

10.times { print "Black " }
>> Black Black Black Black Black Black Black Black Black Black


1-14. Looping with 'While'
자, 바퀴를 떼어 내세요. 네 물건을 좀 보자!
i = 3
while i > 0 do
print i
i -= 1
end
위의 예에서는 i라는 변수를 생성하여 3으로 설정합니다.
그럼 우리가 긍정적으로 생각하는 한 루프를 실행하기 때문에 3,2,1번을 출력합니다.
1. 1번부터 50번까지의 숫자를 인쇄하기 위해 약간의 루프를 사용한다. 위의 예는 계산하기 힘들지만, 여러분은 숫자를 세고 싶을 거예요.

i = 1
while i <= 50 do
  puts i
  i += 1
end
>> 1 ~ 50 까지 출력.


1-15. Looping with 'Until'
i = 3
while i > 0 do
    print i
    i -= 1

end
j = 3
until j == 0 do
    print j
    j -= 1
end
위의 예에서, 우리는~ 까지 사용하는 동안 같은 루프를 썼습니다.
1. 루프를 사용하여 을(를)다시 쓰지 마십시오. 여전히 1번부터 50번까지의 숫자를 출력해야 합니다.

i = 1
until i == 51 
  puts i
  i += 1
end
>> 1 ~ 50까지 출력.


1-16. Looping with 'For'
루비가 어떤 일을 하든 상관 없이 수백만가지의 방법으로 한다는 주제를 잘 이해하지 못하시는 분들을 위해, 우리 루프를 다시 한번 변환해 봅시다.
for k in 1..3
 print k
end
위의 예에서는 루프를 통해 1에서 3까지 123을 인쇄합니다.
1. 이제 until 가 아닌 for 를 사용하여 1~50범위의 숫자를 출력하십시오.

i = 1 
for i in 1..50  
  print i 
  i += 1 
end
>> 1 ~ 50 까지 출력.


1-17. Loop the Loop with Loop
잘 했어요! 우리가 숫자 맞추기 게임에서 잠시 빠져 볼게요.
m = 0
loop do
   m += 1
   print m
   break if m == 10
end
위의 예에서는 루프를 10번 수행한 후 12345678910이 인쇄되어 있습니다.

1. loop iterator를 사용하여"Ruby!"라는 문자열을 30회 출력합니다.
문자열이 그림과 같이 정확히 입력되도록 하십시오!
loop는 다음과 같아야 합니다.
counter = 0
loop do
counter += 1
print "Ruby"
break if counter > # The value to stop at
end

counter = 0
loop do
  counter += 1
  print "Ruby!"
  break if counter == 30
end


1-18. Iterating with .times
마지막으로, 우리 루프를. timestoerator로 교체합시다.
1."Ruby!"를 콘솔에 30번 인쇄할 때는. times를 사용하세요. 코드를 확인하러 뛰어가서 이 수업을 마치세요!

30.times { print "Ruby!" }


2. Redacted!

이 프로젝트에서는 여러분의 이름을 찾기 위해 한줄의 텍스트를 찾아서"수정된 "이라는 단어로 바꾸는 프로그램을 만들 거예요.

2-1. What You'll Be building
정보를 숨기는 것은 암호를 보호하고, 보안 연결을 설정하고, 모든 정보에 대한 액세스 제어에 의존하는 무단 변경으로부터 프로그램을 보호하는 프로그램의 주요 부분입니다.
이후의 과정에서 해시를 다룰 때까지 실제로 정보를 검색할 수는 없지만, 지금까지 사용한 툴, 즉 배열과 일정을 사용하여 사용자의 입력을 변경하는 간단한 프로그램을 작성할 수 있습니다.

puts "Text to search through: "
text = gets.chomp
puts "Word to redact: "
redact = gets.chomp

words = text.split(" ")

words.each do |word|
  if word != redact
    print word + " "
  else
    print "REDACTED "
  end
end


2-2. Getting the User's Input
제일 먼저 해야 할 일은 사용자의 입력 정보를 얻는 것입니다.
1. 사용자에게 두번 입력하라는 메시지를 표시합니다. 첫번째 puts의 경우 텍스트라 불리는 변수를 선언하고 gets.chomp을 통해 사용자의 입력과 동등하게 설정합니다. 
두번째로, redact라고 하는 변수를 선언하고 gets.chomp를 사용하여 사용자의 입력과 동등하게 설정합니다.

puts "Please enter it twice."
text = gets.chomp
puts "Please enter it twice."
redact = gets.chomp


2-3. The .split Method
그 다음에는 사용자의 입력을 개별 단어로 나누어 보겠습니다.
Ruby는. split이라는 내장 방법을 사용하며, 문자열로 배열을 반환한다. 괄호 안에 있는 약간의 텍스트를 전달하면,. split는 구분 기호라고 불리는 해당 텍스트를 보는 곳마다 문자열을 나눕니다. 예를들면
text.split(",")
Ruby에게 쉼표를 볼때마다 문자열을 나누라고 합니다.
1. 단어라 불리는 변수를 표시하고 텍스트에 .split메서드를 호출한 결과와 동일하게 설정합니다. 구분 기호로 사용할 공백(")을 분할하여 텍스트에서 단어 배열을 만들 수 있도록 합니다.

puts "Please enter it twice." 
text = gets.chomp 
puts "Please enter it twice." 
redact = gets.chomp

words = text.split(" ")


2-4. Redacted!
좋아! 사용자의 텍스트를 검토할 일정을 작성할 시간입니다.
letters = ['a', 'b', 'c', 'd']
letters.each do |letter|
print letter
end
위의 예는 문자 배열에 각각. 의 사용을 상기시켜 주는 역할을 할 뿐이다.

Remember, the syntax for .each is
array.each { |placeholder| #action }
or
array.each do |placeholder|
# action
# another action
# yet another action!

end
1. 간단하게 시작해 봅시다:단어를 반복해서 쓰고 발견한 단어를 하나씩 출력해 보세요.

puts "Enter some text: "
text = gets.chomp

puts "Enter words to redact: "
redact = gets.chomp

words = text.split(" ")
words.each { |word| print word }


2-5. Control Flow Know-How
좋아! 하지만 우리의 결과에는 두가지 문제가 있었습니다. 우리의 말 사이에 간격이 없었고, 우리의 프로그램은 우리가 수정하고자 하는 단어를 "업데이트 됨"으로 바꾸지 못 했습니다.
if var == 10
print "Variable is 10"
else
print "Variable is something else"
end
마법이라도 부리면 그걸 고칠 수 있어! if/else 블록이 어떻게 작동하는지 상기시켜 주는 위의 예시
1. 각자의. 안에 성명을 추가한다. 
현재 단어와 다시 선택할 단어가 같으면 추가 공백과 함께"REDATECTED"를 인쇄합니다.
그렇지 않으면( 다른),+""를 인쇄합니다.
두 경우에 모두 공백이 있으면 단어가 함께 실행되지 않습니다.

puts "Enter some text: "
text = gets.chomp

puts "Enter words to redact: "
redact = gets.chomp

words = text.split(" ")
words.each { |word| 
  if word == redact
    print "REDACTED "
  else
  print word + " "
  end 
  }


2-6. Great Work!
완벽해! 당신이 어떤 결과를 얻을 수 있는지 보려면 당신의 Redactor와 어울리지 말아라. 다음에 대해 생각해 보십시오.
당신의 리덕터가 대문자와 소문자를 구분하지 않고 단어를 다시 설명하도록 하기 위해 당신은 무엇을 할 수 있는가?
어떻게 하면 당신의 프로그램이 여러개의 단어를 별도로 RedaCT로 가져가게 만들 수 있는가?
새 수정된 문자열을 생성하여 콘솔에 인쇄하는 것이 아니라 변수로 저장하는 방법은 무엇입니까?
이것들이 질문입니다. 그동안 실행을 클릭하여 이 업데이트됨을 완료합니다.


4. Arrays and Hashes

1. Data structures

이미 어레이에 대해 조금 알고 있습니다. 이 과정에서는 어레이, 해시라는 새로운 데이터 구조, 더 나은 프로그램을 구축하기 위해 두가지 모두에서 Ruby가 어떻게 반복할 수 있는지에 대해 더 많은 것을 배울 것이다.

1-1. Creating Arrays
앞에서 단일 변수의 값 목록을 저장하는 데 어레이를 사용할 수 있음을 보았습니다. 여러분은 그 안에 있는 어떤 숫자든지 입력할 수 있고, 여러분은 숫자를 반복할 수 있고, 그것들은 숫자 순서대로 있을 필요가 없어요!
1. 편집기에서 변수 my_array를 선언하고 선택한 배열과 같게 설정합니다. 구문 세척이 필요한 경우 Hint(힌트)를 확인합니다.
my_array = [70, 24, 1]


1-2. Access by Index
어레이에 대해 흥미로운 점이 있습니다. 어레이의 각 요소에 인덱스라는 것이 있습니다. 첫번째 요소는 인덱스 0이고, 다음 요소는 인덱스 1이며, 다음 요소는 인덱스 2입니다. 다음과 같은 대괄호를 사용하여 어레이의 요소에 직접 액세스 할 수 있습니다.
array = [5, 7, 9, 2, 0]
array[2]
# returns "9", since "9" # is at index 2
아래 다이어그램은 이러한 지수가 당사의 샘플 어레이인[5,7,9,2,0]에 대해 어떻게 작동하는지를 보여 줍니다. 첫번째 요소는 인덱스 0이고, 다음 요소는 1, 다음 요소는 2등입니다.
       +---+---+---+---+---+
array | 5 | 7 | 9 | 2 | 0 |
       +---+---+---+---+---+
index  0   1   2   3   4
(이것은 다소 지나친 단순화이지만, 현재로서는 이해가 됩니다.)
다음과 같이 인덱스를 대괄호로 묶어서 어레이라고 하는 어레이의 항목 요소에 액세스 할 수 있습니다:array[i]. 어레이[0]는 첫번째 요소를 얻고 어레이[1]는 두번째 요소를 얻는 식입니다. 이것을 색인별 액세스라고 합니다.
1. 사각 괄호 표기법을 사용하여 demo_array의 세번째 값을 콘솔에 인쇄합니다.
세번째 값은 인덱스 3이 아니라 인덱스 2입니다. 우리는 제로부터 지수를 계산하기 시작한다.

demo_array = [100, 200, 300, 400, 500]
print demo_array[2]
>> 300


1-3. Arrays of Non-Numbers
여기 여러분이 알지 못 했을 수도 있는 것들이 있습니다. 루비 객체들의 모음을 만들 수 있습니다. 여러분은 보울린을 다발로 만들 수 있어요! 줄이 늘어서 있어요! 가능성은 무궁무진하다
1.string_array라는 새 어레이를 생성합니다. strings(문자열)으로 묶어 놔!
string_array = ["These", "are", "some", "strings"]


1-4. Arrays of Arrays
여러분은 이렇게 자문할 수도 있어요."만약 내가 어떤 것을 배열할 수 있다면, 배열할 수 있을까?"정답은:네!
우리가 편집기에 가지고 있는 배열을 확인해 보세요. 어레이를 더 추가하는 작업을 수행하면 어레이를 스프링 같은 형태로 확장하여 다차원 어레이라고 합니다. 예를 들어 편집기의 배열은 2차원 배열입니다.
우리가 프린트하면 이 2차원 배열이 어떤 모습일지 아시겠어요? 보려면 실행을 클릭하십시오.

multi_d_array = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]

multi_d_array.each { |x| puts "#{x}\n" }

>> [0, 0, 0, 0]
>>
>> [0, 0, 0, 0]
>>
>> [0, 0, 0, 0]
>>
>> [0, 0, 0, 0]


1-5. Create Your Own
한줄에 요소 수와 전체 행이 동일한 2차원 배열이 어떻게 정사각형인지 확인하시겠습니까? 배열( 선 같은)은 1차원이며 배열(정사각형 같은)은 2차원입니다.

1. 편집기에서 my_2D_array라고 하는 자신만의 2차원 배열을 만듭니다. 내부 배열의 요소는 숫자, 문자열, 불 리언 등과 같이 원하는 대로 지정할 수 있습니다. 도움이 필요하면 힌트를 확인하세요.
Hint 단순한 2D어레이는 다음과 같습니다.
array = [[thing, thing], [thing, thing]]

my_2d_array = [[1, 2, 3, 4], [5, 6, 7, 8]]

print my_2d_array
>> [[1, 2, 3, 4], [5, 6, 7, 8]] 


1-6. Introduction to Hashes
우리는 어레이가 0으로 시작하여 어레이 길이에서 1을 뺀 숫자로 인덱싱 되어 있다는 것을 알고 있습니다. (생각해 보세요. 네개의 요소가 있는 배열에 0,1,2,3이라는 지수가 있습니다.)
하지만 0부터 배열 끝까지 순서대로 배열되지 않는 숫자 색인을 사용하려는 경우에는 어떻게 할까요? 만일 우리가 숫자를 전혀 지수로 사용하지 않길 원한다면? 해시라는 새 배열 구조가 필요해
해시는 JavaScript개체나 Python사전과 비슷합니다. 이러한 언어를 공부하지 않았다면 해시는 키-값 쌍 모음이라는 것만 알면 됩니다. 해시 구문은 다음과 같습니다.
hash = {
key1 => value1,
key2 => value2,
key3 => value3
 }
값은 => 를 사용하여 키에 할당됩니다. 모든 Ruby개체를 키 또는 값으로 사용할 수 있다.
오른쪽 편집기에 해시를 만들었습니다. 키와 값으로 어떻게 구성되어 있는지 보시겠습니까? 밑에 있는 코드를 확인해 보세요. 어딘가 익숙하게 보일 겁니다. 어떻게 되는지를 보려면 Run(실행)을 클릭하십시오!

my_hash = { "name" => "Eric",
  "age" => 26,
  "hungry?" => true
}

puts my_hash["name"]
puts my_hash["age"]
puts my_hash["hungry?"]
>> Eric
>> 26
>> true


1-7. Using Hash.new
방금 보여 드린 건 해시 문자 표기법이에요 우리는 이것을 글자 그대로 해시에 원하는 것을 묘사하기 때문에 그렇게 부릅니다:이름을 붙이고 그것을 곱슬한 버팀대 안에 있는 하나 이상의 key => value 쌍과 동등하게 설정합니다.
해시. new를 사용하여 다음과 같이 해시를 생성할 수도 있습니다.
my_hash = Hash.new
변수를 hash.new와 동일하게 설정하면 새로운 빈 해시가 생성됩니다. 이는 변수를 비어있는 {} 에 동일하게 설정하는 것과 같습니다.
1. Hash.new를 사용하여 애완 동물이라고 하는 새로운 해시를 생성합니다. 해시는 대문자로 쓰지 않으면 Ruby한테 무슨 말을 하는지 못 들을 거야!
pets = Hash.new

print pets
>> {}


1-8. Adding to a Hash
우리는 두가지 방법으로 해시에 추가할 수 있습니다. 만약 우리가 문자 표기법을 사용하여 해시를 만든다면, 우리는 새로운 키-값 쌍을 곱슬 머리 치열 교정기 사이에 바로 추가합니다. 해시. new를 사용할 경우 괄호 표기법을 사용하여 해시에 추가할 수 있습니다.
pets = Hash.new
pets["Stevie"] = "cat"
# Adds the key "Stevie" with the
# value "cat" to the hash
1. 애완 동물 해시에 애완 동물을 추가합니다. 여러분이 좋아하는 어떤 키 값 쌍도 될 수 있습니다!

pets = Hash.new
pets["blackhole"] = "cat"


1-9. Accessing Hash Values
어레이와 마찬가지로 해시의 값에 액세스 할 수 있습니다.
pets = { "Stevie" => "cat",
"Bowser" => "hamster",
"Kevin Sorbo" => "fish"
}

puts pets["Stevie"]
# will print "cat"

1. 위의 예에서는 pets 이라는 해시를 만듭니다.
2. 그리고 나서 우리는 pets 해시에 있는 Key "Stevie"에 접속하여 cat를 인쇄한다.

1. 위 예의 2단계와 같이 애완 동물에 추가한 키 값 쌍에 액세스 합니다.
이 값을 콘솔에 인쇄하려면 삽입을 사용합니다.

pets = Hash.new
pets["blackhole"] = "cat"

puts pets["blackhole"]
>> cat


1-10. (Re)Introduction to Iteration
우리가 루프와 여행기를 다룰 때 기억 나요? 우리는 프로그램을 반복하기 위해 아주 다양한 방법을 사용할 수 있습니다. 우리가 어레이나 해시를 반복할 때, 우리는 그것을 반복한다고 말합니다.
이 섹션에서는. 각 항목을 사용하여 어레이 및 해시를 반복합니다. 편집기에서 코드를 확인하여 이 문제를 어떻게 해결할지 한가지 예를 들어 보십시오.

friends = ["Milhouse", "Ralph", "Nelson", "Otto"]

family = { "Homer" => "dad",
  "Marge" => "mom",
  "Lisa" => "sister",
  "Maggie" => "sister",
  "Abe" => "grandpa",
  "Santa's Little Helper" => "dog"
}

friends.each { |x| puts "#{x}" }
family.each { |x, y| puts "#{x}: #{y}" }


1-11. Iterating Over Arrays
어레이를 통해 스트리밍 하는 것은 보기보다 쉽습니다.
numbers = [1, 2, 3, 4, 5]
numbers.each { |element| puts element }
위의 예제에서는 5개의 요소가 있는 숫자라는 배열을 생성합니다.
그리고 나서 우리는 "이 배열을 가지고 각 요소에 대해 콘솔에 프린트하세요."라고 말합니다. 평소처럼, 2|문자 사이의 어떤 자리 표시자 이름도 사용할 수 있습니다.
1. 언어 배열의 각 요소를 표시하려면. iterator를 사용합니다.
각 요소가 고유한 선에 있도록 인쇄하는 대신 반드시 배치를 사용하십시오.

languages = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]

languages.each { |element| print element + " "}
>> HTML CSS JavaScript Python Ruby


1-12. Iterating Over Multidimensional Arrays
이제 다차원 배열을 반복하는 방법을 살펴보겠습니다.
2-D어레이를 만들었습니다("sandwiches"). 우리는 각 요소를 배열로 출력하지 않고["ham","swiss"]와 같은 방식으로 반복하고 싶지만, 각 하위 범주에 속하는 각 요소는 목록에 포함됩니다.
"swiss"에 액세스 하려면
s[0][1]
즉,"첫번째 요소의 두번째 요소를 가져다 주세요.""스위스"라는 뜻입니다.
array.each { |element| action }
그렇다면 스토리지 어레이를 어떻게 반복해야 할까요?

Hint 중첩된 항목 .each는 다음과 같아야 합니다.
s.each do | sub_array |
     sub_array.each do | y |
          puts y
     end
end

1. 하위 영역 내부의 모든 요소를 지정합니다.
배열의 각 요소를 반복합니다. 요소 sub_array를 호출합니다.
그런 다음 각각 sub_array를 반복하여 항목을 출력합니다.
s = [["ham", "swiss"], ["turkey", "cheddar"], ["roast beef", "gruyere"]]

s.each do | sub_array |
  sub_array.each do | y |
    puts y
  end
end

>> ham
>> swiss
>> turkey
>> cheddar
>> roast beef
>> gruyere

# .each do 반복문을 한번만 사용할 때는 그대로 출력이 되는데 한번 더 엮어서 사용하니 개개인이 출력된다.


1-13. Iterating Over Hashes
해시를 반복할 때 각 키/값 쌍을 나타내는 자리 표시자 변수가 두개 필요합니다.
restaurant_menu = {
"noodles" => 4,
"soup" => 3,
"salad" => 2
}
restaurant_menu.each do |item, price|
puts "#{item}: #{price}"
end
위의 예에서는 restaurant_menu 이라는 새 해시를 생성합니다.
그런 다음 restaurant_menu 해시를 순환하여 항목에 대한 키와 각 반복 가격에 값을 할당합니다.
마지막으로, 다음과 같은 기능을 제공합니다.
noodles: 4
soup: 3
salad: 2

1. 각각 secret_identies해시를 반복합니다.
위의 예제와 같이 콘솔에 키-값 쌍을 콜론과 공백(:)으로 구분하여 각각 인쇄할 때 사용합니다.

secret_identities = {
  "The Batman" => "Bruce Wayne",
  "Superman" => "Clark Kent",
  "Wonder Woman" => "Diana Prince",
  "Freakazoid" => "Dexter Douglas"
}

secret_identities.each do |sec, name|
  puts "#{sec}: #{name}"
end
>> The Batman: Bruce Wayne
>> Superman: Clark Kent
>> Wonder Woman: Diana Prince
>> Freakazoid: Dexter Douglas


1-14. Multidimentional Arrays
잘했어! 이번 수업을 통해 많은 것을 배웠습니다. 여러분이 정말 여러분의 물건을 알고 있는지 확인하기 위해 약간의 검토를 해 봅시다.
1. 편집기에서 my_array라는 다차원 배열을 만듭니다. 가장 안쪽에 있는 배열의 요소는 숫자, 문자열, 경계 등 원하는 모든 것일 수 있습니다. 도움이 필요하면 힌트를 얻으세요.

my_array = [[1, 2, 3, 4, 5], ["Another", "multidimensional", "array!"], [false, true]]

puts my_array[0]
puts my_array[1]
puts my_array[2]
puts my_array[0, 0]
puts my_array[0, 1]
puts my_array[0, 2]
puts my_array[0, 3]
puts "================="
puts my_array[1, 0]
puts my_array[1, 1]
puts my_array[1, 2]

>> [1, 2, 3, 4, 5]
>> ["Another", "multidimensional", "array!"]
>> [false, true]
>> []
>> [[1, 2, 3, 4, 5]]
>> [[1, 2, 3, 4, 5], ["Another", "multidimensional", "array!"]]
>> [[1, 2, 3, 4, 5], ["Another", "multidimensional", "array!"], [false, true]]
>> =================
>> []
>> [["Another", "multidimensional", "array!"]]
>> [["Another", "multidimensional", "array!"], [false, true]]


1-15. Hashes
해시 표기법 2가지.
좋아! 이제 해시를 생성하겠습니다. 해시 리터럴 표기법 또는 Hash.new를 사용하십시오.
prices = {
"apple" => 0.52,
"banana" => 0.23,
"kiwi" => 1.42
}
sounds = Hash.new
sounds["dog"] = "woof"
sounds["cat"] = "meow"
Hint 해시 리터럴 표기법은 다음과 같습니다.
hash_name = {
key1 => value1,
key2 => value2,
key3 => value3
}
Hash.new는 다음과 같이 사용합니다.
hash_name = Hash.new
# 새 키-값 쌍을 지정할 때 괄호 표기법을 사용합니다.
hash_name[key1] = value1

1. 편집기에서 my_hash라는 해시를 만듭니다.
키-값 쌍을 하나 이상 지정하십시오.

my_hash = {
  "sleepy" => 450,
  "eat" => 300,
  "game" => 200,
  "health" => 270
  }


1-16. Iterating Over a Hash
어레이에 대해 상당히 많은 반복 작업을 수행했으므로, 마지막으로 해시를 반복하는 방법을 검토해 보겠습니다.
numbers = [1, 2, 3, 4, 5]
numbers.each { |element| puts element }
1. 각각의 키/값 쌍을 lunch_Order에 입력합니다.
각 쌍의 값을 표시하십시오(키가 아닌 값만 표시).

lunch_order = {
  "Ryan" => "wonton soup",
  "Eric" => "hamburger",
  "Jimmy" => "sandwich",
  "Sasha" => "salad",
  "Cole" => "taco"
}

lunch_order.each { |name, food| puts food }
>> wonton soup
>> hamburger
>> sandwich
>> salad
>> taco


2. Create Histogram

이 프로젝트에서는 텍스트 블록을 읽고 각 단어가 몇번 나타나는지 알려 주는 프로그램을 작성할 것입니다.

2-1. What You'll Be Building
이 프로젝트에서는 사용자의 입력을 받은 다음 해당 입력에서 해시를 작성하는 프로그램을 작성합니다. 해시의 각 키는 사용자의 단어가 됩니다. 각 값은 해당 단어가 발생하는 횟수입니다. 예를 들어, 만약 우리의 프로그램이 "the rain in Spain falls mainly on the plain,"라는 문자열을 얻는다면, 그것은 돌아올 것이다.
the 2 
falls 1 
on 1 
mainly 1 
in 1 
rain 1 
plain 1 
Spain 1
이와 같은 데이터의 시각적 표현을 히스토그램이라고 합니다.
실행해 보세요!

puts "Text please: "
text = gets.chomp

words = text.split(" ")
frequencies = Hash.new(0)
words.each { |word| frequencies[word] += 1 }
frequencies = frequencies.sort_by {|a, b| b }
frequencies.reverse!
frequencies.each { |word, frequency| puts word + " " + frequency.to_s }
# why not 이라고 입력 했을 시
>> not? 1
>> why 1


2-2. You Know the Drill
지금까지 우리는 어떻게 시작할지 알고 있습니다. 우리는 사용자로부터 입력을 받아야 합니다.
1. 사용자에게 입력할 것을 요구하는 문장을 사용합니다. gets.chomp을 사용하여 텍스트라는 변수에 이 입력을 저장합니다.

puts "Write: "
text = gets.chomp


2-3. Building the Words Array (단어 배열(Array) 만들기)
다음으로, 우리는 사용자의 문자열을 우리가 반복할 수 있는 것으로 바꾸고 싶을 것이다. 모든 요소들로 이루어진 데이터 구조가 한줄에 있다고 말할 수 있나요? 그건 마치 배열처럼 들리네요!
텍스트에 있는 .split 메서드를 호출하여 배열로 변환할 수 있습니다.
1. words 라고 하는 변수를 구분하여 text 에 .split 을 호출한 결과와 동일하게 설정합니다.

puts "Write: "
text = gets.chomp

puts "Write: "
text2 = gets.chomp

words = text.split(",")


2-4. Creating the Frequencies Hash (빈도 해시(Hash) 만들기)
좋아! 이제 해시를 사용하여 단어 수를 세어 보겠습니다.
해시에 기본 값이 있는지 확인합니다.
h = Hash.new("nothing here")

puts h
# {}

puts h["kitty"]
# nothing here

1. 위의 예에서는 기본 값이 " 없음"인 빈 해시 h를 새로 생성합니다.
2. 그런 다음 h 값인 {} 을(를)인쇄하여 h이(가) 비어 있음을 보여 줍니다.
3. 그런 다음 "키티"가 저장한 값에 액세스 하려고 할 때 여기에 아무것도 인쇄하지 않습니다.

1. 편집기에서 주파수라는 해시를 만듭니다. 기본 값 0을 지정합니다.

puts "Write: "
text = gets.chomp

puts "Write: "
text2 = gets.chomp

words = text.split(",")

frequencies = Hash.new(0)


2-5. Iterating Over the Array (배열 (Arrays)반복시키기)
완벽해! 다음으로, 우리는 한번에 하나씩 각 단어를 frequencies 해시에 추가하기 위해 단어를 반복하고자 합니다.
colors = { "red" => 2, "blue" => 3 }
colors["blue"] += 1
puts colors["blue"]

1. 위의 예에서는 먼저 해시 매핑 문자열을 정수로 생성합니다.
2. 그런 다음" blue"으로 저장된 값을 1씩 증가시킵니다.
3. 마지막으로 " blue"으로 저장된 값인 4개를 인쇄합니다.

1. 단어 배열을 반복하려면 each. 를 사용합니다.
우리가 찾은 각 단어에 대해, 단어 자체가 빈도의 핵심이며 그 값을 1씩 증가시킨다고 가정하자.
이것이 우리의 기본 값이 0인 이유입니다. 처음으로 단어를 찾으면 1씩 증가시킬 수 있는 0x0의 기본 값이 있습니다.
도움이 필요하시면 힌트를 보세요.

우리가 원하는 작업은 해시를 단어와 동일한 키로 업데이트한 다음 값을 1씩 증가시키는 것입니다. 각 키는 빈도가 있으며+=1을 사용하여 증가할 수 있습니다.

puts "Enter a phrase you'd like to analyze: "
text = gets.chomp

words = text.split

frequencies = Hash.new(0)

words.each { |word| frequencies[word] += 1 }


2-6. Sorting the Hash (해시 정렬하기)
좋았어! 워드/주파수 키-값 쌍이 가득 찬 해시가 있습니다. 이제 우리는 정보를 원하는 순서대로 얻을 수 있는 방법을 찾아야 합니다.
colors = {
"blue" => 3,
"green" => 1,
"red" => 2
}
colors = colors.sort_by do |color, count|
  count
end
colors.reverse!
1. 위의 예제에서는 색상 문자열을 숫자에 매핑 하는 색상이라는 해시를 먼저 만듭니다.
2. 그리고 나서, 우리는 색을 숫자별로 가장 작은 것부터 가장 큰 것까지 초록색, 빨간 색, 파란 색으로 분류합니다. 알다시피,. sort_by함수는 배열을 반환하지만, 우리의 목적에는 괜찮습니다.
3. 마지막으로 배열 순서를 반대로 적용하여 계수가 가장 큰 색상을 먼저 선택합니다.
주파수 해시에도 동일한 작업을 수행할 수 있습니까?

1. 위의 2단계와 같이, .sort_by을 사용하여 워드 카운트별로 주파수 해시를 정렬합니다. 결과를 주파수로 다시 저장합니다.
사용하세요. 후진! 정렬된 주파수 배열을 반전시킵니다.
자세한 내용은 힌트를 확인하십시오!

첫번째 단계는 frequencies를 정렬된 버전에 재할당하는 것입니다(. sort_by해시 인 플레이스 정렬 안 함—정렬된 복사본 생성).
frequencies = frequencies.sort_by { |k, v| v }
그러면 실제로 값 배열이 반환되며, 이 값을 역 방향으로 되돌릴 수 있습니다!
frequencies.reverse!

puts "Enter a phrase you'd like to analyze: "
text = gets.chomp

words = text.split

frequencies = Hash.new(0)

words.each { |word| frequencies[word] += 1 }

frequencies = frequencies.sort_by do |word, count|
  count
end

frequencies.reverse!
print frequencies


2-7. Iterating Over the Hash (해시 반복 시키기)
거의 다 왔어! 마지막으로, 콘솔에 각 키-값 쌍을 인쇄하려면 어레이를 반복해야 합니다.
fruit = {
"apple" => 2,
"banana" => 3,
"cherry" => 5
}
fruit.each do |name, count|
puts name + " " + count.to_s
end

1. 위의 예에서, 우리는 과일의 이름을 우리가 가지고 있는 양에 매핑 하는 과일이라고 불리는 해시를 만듭니다.
2. 그런 다음 각 키/값 쌍에 키를 이름으로 저장하고 값을 카운트로 저장합니다.
3. 마지막으로, 키와 가치를 공간으로 구분하여 인쇄합니다. 값을 연결하려면 먼저 .to_s를 사용하여 값을 숫자에서 문자열로 변환해야 합니다.

1. 반복합니다. 각 키/값 쌍은 주파수 해시에 있습니다.
그런 다음 위의 예제와 같이 각 단어, 공백 및 빈도를 콘솔에 넣습니다.

puts "Enter a phrase you'd like to analyze: "
text = gets.chomp

words = text.split

frequencies = Hash.new(0)

words.each { |word| frequencies[word] += 1 }

frequencies = frequencies.sort_by do |word, count|
  count
end

frequencies.reverse!

frequencies.each do |word, count|
  puts word + " " + count.to_s
end

# count를 그냥 출력하면 출력되지 않기에 .to_s를 사용하여 문자열로 변환시켜 준다.


2-8. You Did It!
잘 만들었다! 프로그램이 완료되었습니다. 몇번 실행하여 문자열에 있는 각 단어의 발생 개수를 계산하는 방법을 확인합니다.
실행을 클릭하면 끝납니다! 다음 프로그램 모험을 시작하기 전에 잠시 시간을 내어 승리의 빛을 만끽하십시오.


5. Blocks and Sorting

1. Methods, Blocks, &Sorting

이 과에서는 루비에서 자신만의 방법을 정의하는 방법과 블록을 사용하여 강력한 정렬 알고리즘을 개발하는 방법에 대해 알아보겠습니다.

1-1. Why Methods?
메서드는 프로그램에서 특정 작업을 수행하기 위해 작성된 코드를 재사용할 수 있는 섹션입니다. 여러분은 왜 모든 것을 하나의 큰 덩어리로 작성하는 것이 아니라 여러분의 코드를 방법으로 분리해야 하는지 궁금해 할지도 모릅니다. 프로그램을 방법으로 나누는 몇가지 좋은 이유가 있습니다.
1. 코드에 문제가 있으면 프로그램을 잘 구성한 경우 버그를 찾아 수정하는 것이 훨씬 쉽습니다. 특정 작업을 별도의 방법에 할당하는 것이 이 조직에 도움이 됩니다.
2. 특정 작업을 별도의 방법(컴퓨터 과학자가 우려 사항 분리라고 함)에 할당하면 프로그램이 중복되지 않고 코드를 재사용할 수 있습니다.
3. 객체에 대해 자세히 알게 되면 루비의 메소드를 사용하여 많은 흥미로운 것들을 배울 수 있습니다.

편집자가 작성한 방법을 확인하십시오. 여러분은 그것이 무엇을 할 것인지 추측할 수 있나요? 알고 있다고 생각되면 Run(실행)을 클릭합니다!

def prime(n)
  puts "That's not an integer." unless n.is_a? Integer
  is_prime = true
  for i in 2..n-1
    if n % i == 0
      is_prime = false
    end
  end
  if is_prime
    puts "#{n} is prime!"
  else
    puts "#{n} is not prime."
  end
end

prime(2)
prime(9)
prime(11)
prime(51)
prime(97)

>> 2 is prime!
>> 9 is not prime.
>> 11 is prime!
>> 51 is not prime.
>> 97 is prime!


1-2. Method Syntax
메소드는 키워드 def를 사용하여 정의됩니다("define"의 약자). 방법에는 세 부분이 있습니다.
1. def키워드, 메서드 이름 및 메서드에 사용되는 인수가 포함된 헤더입니다. (다음 섹션에서 논의하겠습니다.)
2. 본문-방법이 수행하는 절차를 설명하는 코드 블록입니다. 본문은 규칙에 따라 두개의 공간을 들여 놓습니다(예:for, if, elseif, else및 다른 문).
3. 메소드는 end 키워드로 끝납니다.
다음은 "루비에 오신 것을 환영합니다!"라고 콘솔에 인쇄하는 간단한 기능의 구문 예입니다.
def welcome
   puts "Welcome to Ruby!"
end

1. 편집기에서 오른쪽에 있는 방법을 시작했는데, 완전하지가 않아요. ___를 올바른 키워드로 교체하여 이 방법이 제대로 작동하도록 하십시오!

def puts_1_to_10
  (1..10).each { |i| puts i }
end

puts_1_to_10 # 지금은 이것을 무시하세요. 곧 설명해 드릴게요!


1-3. Create Your Own
이제는 독자 분이 독자적인 방법을 찾아야 할 때입니다. 구문은 다음과 같습니다.
def method_name
  # Do something!
end
1. 편집기에서 메서드, 인사말을 작성합니다. 콘솔에 인사말을 인쇄할 때는 puts을 사용해야 합니다.

def greeting
  puts "Hello~"
end

greeting # 지금은 이것을 무시하세요. 곧 설명해 드릴게요!


1-4. Call It!
방법을 정의하는 것은 좋지만, 방법을 호출하거나 프로그램에서 실행하도록 지시하지 않는 한 그다지 유용하지 않습니다. 예를 들어 cartoon_fox라는 메서드를 호출하면 프로그램이 해당 이름의 메서드를 찾기 시작하고 해당 메서드 내에서 코드를 실행하려고 시도합니다. 
cartoon_fox라는 메서드를 찾지 못하면 NameError가 반환됩니다. 우리는 또 다른 수업 시간에 오류를 다룰 것이다.
이름만 입력하여 메서드를 호출합니다. 지난 두번의 연습에서 puts_1_to_10을 입력하거나 메서드 정의를 마친 후에 인사말을 입력한 것을 기억하십니까? 그건 우리가 우리의 방법을 부른 거야!
1. 편집기 오른쪽에 array_of_10 함수를 설정했습니다. 5번으로 전화하세요!

def array_of_10
  puts (1..10).to_a
end

print array_of_10

>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> 40


1-5. Parameters And Arguments
만약 어떤 방법이 논쟁을 한다면, 우리는 그것이 그러한 주장을 받아들이거나 기대한다고 말한다. 
다음과 같은 함수를 정의할 수 있습니다.
def square(n)
   puts n ** 2
end
그리고 다음과 같이 부르세요:
square(12)
# ==> prints "144"
인수는 메서드를 호출할 때 메서드의 괄호 사이에 실제로 넣은 코드 조각이며 매개 변수는 메서드의 괄호 사이에 정의할 때 입력하는 이름입니다. 예를 들어, 위의 제곱을 정의할 때는 n매개 변수("number")를 지정하고 12라는 인수를 전달했습니다.
매개 변수를 자리 표시자로 생각할 수 있습니다. 메서드 정의는 인수가 어떤 인수를 얻을지 정확히 미리 알지 못하기 때문입니다.
루비에서는 괄호를 선택할 수 있지만 읽기 쉽도록 괄호 안에 변수와 인수를 넣어 두는 것이 좋습니다.

1. 편집자에게 Cubertino 메서드를 호출하고 8의 인수를 전달합니다.

def cubertino(n)
  puts n ** 3
end

cubertino(8)
>> 512


1-6. Splat!
무엇을 기대해야 할 지 모른다는 말입니다. 여러분의 방법은 그들이 어떤 주장을 미리 해야 할지 뿐만 아니라 때로는 얼마나 많은 논쟁이 있을지도 모릅니다.
예를 들어 사용자로부터 받은 인수를 사용하는 방법이 있다고 가정해 봅시다. 다음과 같이 보일 수 있습니다.
def friend(name):
puts "My friend is " + name + "."
end
이것은 한명의 친구에게만 좋은 일이지만, 사용자가 몇명의 친구 이름을 미리 입력할지 모른 채 모든 사용자의 친구를 인쇄하고 싶다면 어떻게 해야 할까요?
해결책은 분할 원칙입니다. splat 인수는 * 가 선행하는 인수로, 방법이 하나 이상의 인수를 수신할 수 있음을 프로그램에 알려 줍니다.
코드를 실행합니다. 자유롭게 놀고 싶은 만큼 친구를 불러 주세요!

def what_up(greeting, *friends)
  friends.each { |friend| puts "#{greeting}, #{friend}!" }
end

what_up("What up", "Ian", "Zoe", "Zenas", "Eleanor")
>> What up, Ian!
>> What up, Zoe!
>> What up, Zenas!
>> What up, Eleanor!

메서드의 인수 friend에 붙어 있는 *을 때보면
wrong number of arguments (given 5, expected 2) 라고 뜬다. 잘못된 인수. 주어진건 5인데 예상되는건 2란다.


1-7. Let's Learn Return
콘솔에 어떤 것을 인쇄하는 방법을 원하지 않을 때도 있지만 실제로는 그 방법을 사용하여 가치를 다시 전달하고 싶습니다. 그것을 위해 우리는 반품을 사용한다.
def double(n)
    return n * 2
end

output = double(6)
output += 2
puts output
1. 위의 예에서, 우리는 n이라고 불리는 하나의 인수를 수용하는 더블이라는 새로운 방법을 정의한다.
2. 그 방법 안에서 우리는 두번 돌아온다.
3. 그 후에, 우리는 6의 인수를 가진 우리의 새로운 이중 방법을 부르고 12의 결과를 결과에 저장한다.
4. 그런 다음 출력을 14개로 늘리고 콘솔에 출력합니다.

1. 두 숫자를 인수로 사용하는 추가라는 새 메서드를 정의합니다.
메소드 내에 해당 숫자의 합계를 반환합니다.

def add(a, b)
  return c = a + b
end

print add(3, 5)
>> 8


1-8. Practice Makes Perfect
방법을 엉망으로 만들기 전까지는 당신은 마스터 메서드 메이커가 되지 않을 것이다. (그것을 3배 빨리 말하세요.)
def by_five?(n)
return n % 5 == 0
end
위의 예는 방법을 정의하는 방법을 상기시키는 것입니다.
1. 단일 문자열 매개 변수를 사용하여 이름을 지정하고 해당 문자열을 반환하는 녹색 문자열 방법을 정의합니다. 
반드시 return 을 사용하고 인쇄물이나 인쇄물을 사용하지 마십시오.
2. a를 by_3으로 정의하시겠습니까? 단일 정수 매개 변수, 숫자를 사용하고 이 숫자가 3으로 균등하게 구분되면 true를 반환하고 그렇지 않으면 false를 반환하는 방법입니다.

def greeter(name)
  return "Hello, #{name}!"          #.to_s 사용도 괜찮지 않나?
end

def by_three?(number)
  if number % 3 == 0
    return true
  else 
    return false
  end
end


1-9. Blocks Are Like Nameless Methods (블록은 이름 없는 방법(메서드)과 같다.)
사용자가 작업한 대부분의 방법은 사용자 또는 다른 사용자가 지정한 이름을 정의합니다(예:[array].sort(), "string".downcase(),등). 블록을 이름이 없는 메서드를 만드는 방법으로 생각할 수 있습니다. (이는 JavaScript의 익명 기능이나 Python의 Lambdas와 유사합니다.)
블록은 키워드를 사용하여 정의할 수 있습니다.
편집자의 예를 보세요. 낯이 익으세요? 코드를 실행하여 블록이 해당 코드를 실행하는지 확인합니다.
# 반복문 do와 .each에서 본 구문 모양 같다.

1.times do
  puts "I'm a code block!"
end

1.times { puts "As am I!" }
>> I'm a code block!
>> As am I!


1-10. How Blocks Differ from Methods (블록과 메서드 차이)
그러나 블록과 방법에는 약간의 차이가 있다.
편집기에서 코드를 확인합니다. 대문자로 쓰는 방법은 단어를 대문자로 바꾸고, 우리는 계속해서 이름으로 대문자로 쓰는 방법을 사용할 수 있다. 우리는 우리가 좋아하는 어떤 문자열을 우리의 마음의 내용에 이용할 수 있습니다.
하지만, 우리가 정의하는(각각을 따르는)블록은 우리가 반복하는 배열의 맥락에서 단 한번만 불릴 것입니다. 그것은 각각의 일을 할 만큼 충분히 길어 보이고, 그리고 나서 밤이 되면 사라진다.
이해했어? 방법과 블록의 마법적인 결합을 보려면 코드를 실행하십시오.

# 단어를 대문자로 쓰는 방법
def capitalize(string) 
  puts "#{string[0].upcase}#{string[1..-1]}"
end

capitalize("ryan") # prints "Ryan"
capitalize("jane") # prints "Jane"

# 배열의 각 문자열을 대문자로 표시하는 블록
["ryan", "jane"].each {|string| puts "#{string[0].upcase}#{string[1..-1]}"} # prints "Ryan", then "Jane"

>> Ryan
>> Jane
>> Ryan
>> Jane


1-11. Using Code Blocks
메소드가 블록을 매개 변수로 사용할 수 있습니다. 그것이 바로 그 점입니다. 각각은 지금까지 계속 해왔습니다. 매개 변수로서 블록을 가져다가 그것으로 무언가를 하는 것입니다. 우리가 선택적 괄호를 사용하지 않았기 때문에 너는 알아차리지 못 했다. 우리는 교활하다.
메소드에 블록을 전달하는 것은 메서드에서 특정 작업을 추상화하고 메서드를 호출할 때 해당 작업을 정의하는 좋은 방법입니다. 추상화는 컴퓨터 공학에서 중요한 아이디어입니다. 여러분은 이것을 "단순한 무언가를 만드는 것"이라고 생각할 수 있습니다. 만약 여러분이 사냥을 하고 싶다면, "하우스"라고 말하는 것처럼 블록을 사용하여 원하는 작업(예:각각)을 정의하면 구성 요소 목록 작성이 간소화됩니다.

현재, 두번째입니다. 각각 다섯번씩 인쇄됩니다(어레이의 각 항목에 대해 5번 인쇄되고 5개 항목이 있기 때문에). 블록을 수정하여 배열의 각 항목을 5배로 인쇄합니다.
  # 사람이 어렵게 생각하면 안된다. 눈 앞에 쉽게 풀라고 답을 적어 놨는데 어렵게 생각하면 돌아간다. 덧셈을 고등 방식으로 풀려하       는건 어리석을 짓!
[1, 2, 3, 4, 5].each { |i| puts i }
[1, 2, 3, 4, 5].each { |i| puts 5*i }
>> 1
>> 2
>> 3
>> 4
>> 5
>> 5
>> 10
>> 15
>> 20
>> 25


1-12. Introduction to Sorting
배열을 정렬하는 것은 컴퓨터 과학에서 매우 흔한 문제이며, 그러한 이유로 잘 연구되고 있다. 단계별로 잘 정의된 여러 알고리즘이 있으며, 이를 통해 각 알고리즘의 장단점도 확인할 수 있습니다.
알고리즘을 정렬하는 것은 이론적인 훈련으로써 컴퓨터 과학에 대한 좋은 소개가 될 수 있지만, 지금은 루비의 내장된 분류 라이브러리를 사용하는 방법에 초점을 맞출 것입니다.

1. .sort! 정렬을 사용하세요! my_array의 값을 정렬하는 방법입니다. 마법이죠?
콘솔에 my_array를 표시합니다.
.sort는 my_array의 복사본을 정렬하는 반면 .sort!는 정렬합니다 는 my_array (즉, 원래 어레이를 삭제하고 정렬된 버전으로 대체)을 정렬합니다.

my_array = [3, 4, 8, 7, 1, 6, 5, 9, 2]

print my_array.sort!
>> [1, 2, 3, 4, 5, 6, 7, 8, 9]


1-13.  Foundations
책 다섯권을 나눠 드리고 제목별로 정렬해 달라고 한다면 어떻게 하시겠어요?
대부분의 분류 알고리즘은 우리가 배열에 있는 두개의 항목을 비교하고 어떤 것이 먼저 와야 하는지 결정하는 것을 포함하는 항목들의 배열을 분류한다고 가정한다.
예를 들어, 만약 우리가 알파벳에서 제목이 가장 먼저 나오는 책을 항상 고른다면, 우리는 분류 전략을 고안할 수 있을 것이다. 이러한 "전략"은 앞의 예제에서 언급한 정렬 알고리즘입니다. 우리가 할 일은 목록에 있는 두개의 항목을 비교하고 루비가 어떤 전략을 사용할지 결정하는 것입니다.

1. 책 목록을 알파벳 순으로 정렬하기 위해 어떤 루비 방법으로 책을 찾을 수 있을까요? 편집자가 해 보세요.
books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]

print books.sort!
>> ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]


1-14. The Combined Comparison Operator
우리는 또한 두 루비 객체를 비교하기 위해 결합 비교 연산자라는 새로운 연산자를 사용할 수 있습니다. 조합된 비교 연산자는 다음과 같습니다. <=> 첫번째 피연산자(비교할 항목)가 두번째 피연산자와 같은 경우 0, 첫번째 피연산자가 두번째 피연산자보다 큰 경우 1, 첫번째 피연산자가 두번째 피연산자보다 작은 경우 -1

정렬 방법으로 전달되는 블록은 1,0또는-1중 하나를 반환해야 합니다. 첫번째 블록 매개 변수가 두번째 블록보다 먼저 와야 하는 경우-1, 반대로 가중치가 같은 경우에는 1이 다른 값보다 앞에 있지 않음을 의미하는 경우 0을 반환해야 합니다.

1. 조합된 비교 연산자를 사용하여 book_1과 bok_2를 비교합니다(순서대로). 코드를 실행하기 전에 결과에 대해 생각해 보십시오.

book_1 = "A Wrinkle in Time"

book_2 = "A Brief History of Time"

print book_1 <=> book_2
>> 1


1-15. Getting Technical
책을 제목별로 정렬하고 Z-A또는 내림차순으로 정렬하려면 어떻게 해야 합니까? 루비의 분류 법은 A–Z또는 오름차순으로만 사용할 수 있는 것으로 보입니다. 
정렬 방법은 기본적으로 오름차순으로 정렬하는 것으로 가정하지만 두 항목을 비교하는 방법을 지정하는 프로그래머(프로그래머)의 선택적 인수로 블록을 사용합니다.

1. 8번 줄에서 책을 내림차순으로 정렬하십시오. 4행의 오름차순 정렬 예를 참고하십시오.
콘솔에 결과를 표시합니다.

조합된 비교 연산자를 사용할 필요는 없습니다. 이 코드는 다음과 같은 경우에도 작동합니다.
books.sort do |first, second|
  if first < second # first book before second alphabetically
    -1
  elsif first > second # first after second
      1
else # first and second are the same
      0
   end
end

books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
# 오름차순
books.sort! { |firstBook, secondBook| firstBook <=> secondBook }
puts books
# 내림차순
books.sort! { |firstBook, secondBook| secondBook <=> firstBook }
puts books
>> ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"] ["War and Peace", "Utopia", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "A Brief History of Time"]

# 간단하게 생각해서 {} 안에서 첫번째 두번째가 있는데 첫번째는 변수 선언 그대로 가니 오름차순이고 두번째는 결합 비교 연산자에 서로 바꿔서 했으니 오름차순이 바껴서 내림차순이 된 것 같다.


1-16. Basic Methods
기본 루비를 만드는 방법에 대해 간단히 복습해 보겠습니다.
def double(n)
  return n * 2
end
위의 예는 구문 주의 사항에 불과합니다.
1."루비에 오신 것을 환영합니다!"라고 적힌 방법을 만들고 난 후에 전화 주세요.

def welcome
  puts "Welcome to Ruby!"
end

welcome
>> Welcome to Ruby!


1-17. Methods With Arguments
좋아! 이제 우리의 방법을 좀 더 복잡하게 만들어 봅시다.
1. 환영 방법 정의를 변경합니다. 이름이라는 단일 문자열을 추가합니다.
puts문을 제거하고"Hello,#{name}"(으)로 바꿉니다.

def welcome(name)
  return "Hello, #{name}"
end

print welcome("happy")
>> Hello, happy


1-18. Blocks
블록에 대해 배웠던 것을 다시 살펴봅시다.
numbers = [5, 2, 8]
sum = 0
numbers.each do |n|
  sum += n
end
puts sum
위의 예는 구문에 대한 주의 사항입니다. 우리는 숫자 목록의 합계를 계산한다.
1. 각 항목을 자체적으로 제곱 하고 결과를 콘솔에 저장하는 다음 블록을 추가합니다.

my_array = [1, 2, 3, 4, 5]

my_array.each do |num|
  puts num * num
end
>> 1
>> 4
>> 9
>> 16
>> 25


1-19. Sorting
마지막으로, 우리가 분류에 대해 배웠던 것을 복습해 봅시다.
books.sort! do |firstBook, secondBook|
      firstBook <=> secondBook
end
위의 예는 우리가 알파벳 순으로 정렬한 방법을 기억하라.
1. 사용하세요. 정렬하세요! 과일 배열을 내림차순(즉, 역순)으로 정렬합니다. 결합된 비교 연산자(위 예와 같음)또는 가능한 경우 if, elsif, else 문을 사용할 수 있습니다.

fruits = ["orange", "apple", "banana", "pear", "grapes"]

fruits.sort! { |first, second| second <=> first }

print fruits
>> ["pear", "orange", "grapes", "banana", "apple"]


2. Ordering Your Library

이 프로젝트에서는 많은 양의 데이터를 오름차순 또는 내림차순으로 정렬할 수 있는 단일 루비 방식을 설계합니다.

2-1. What You'll Be Building (무엇이 될 것인가)
우리는 지난 수업에서 그것을 알아챘다. 알파벳 역순으로 정렬을 처리하는 기본 제공 방법이 없습니다. 이제 루비 기술을 직접 쓸 수 있게 되었으니 고칠 수 있겠네요!
1. 편집자의 코드는 가족처럼 보여야 합니다. 새로운 아이디어가 하나밖에 없습니다. 준비가 되었으면 실행을 클릭하여 코드를 실행하고 고유한 방법을 작성합니다.

def alphabetize(arr, rev=false)
  if rev
    arr.sort { |item1, item2| item2 <=> item1 }
  else
    arr.sort { |item1, item2| item1 <=> item2 }
  end
end

books = ["Heart of Darkness", "Code Complete", "The Lorax", "The Prophet", "Absalom, Absalom!"]

puts "A-Z: #{alphabetize(books)}"
puts "Z-A: #{alphabetize(books, true)}"

>> A-Z: ["Absalom, Absalom!", "Code Complete", "Heart of Darkness", "The Lorax", "The Prophet"]
>>Z-A: ["The Prophet", "The Lorax", "Heart of Darkness", "Code Complete", "Absalom, Absalom!"]


2-2. Defining Our Method (방법을 정의)
우선, 우리는 우리의 알파벳 표기법을 정의해야 할 것이다.
1. 편집자의 오른쪽에 정의 알파벳이 있습니다. 그것은 아직 어떤 논쟁도 필요로 하지 않으며, 방법의 구성에 어떤 것도 필요하지 않다.
Hint 잊지 마세요:
def method_name(optional parameters)
      # Do something
end

def alphabetize()
  
end


2-3. Default Parameters (기본 매개 변수)
연습 1에서 보았던 새로운 코드를 살펴보겠습니다.
def alphabetize(arr, rev=false)
첫번째 부분은 의미를 부여한다. 우리는 방법을 정의하고, 알파벳을 표기하고 있다. 첫번째 매개 변수는 어레이라고 추측할 수 있지만, rev=false 비즈니스란 무엇입니까?
이것이 루비에게 말하는 것은 사용자가 두개의 인수를 입력하지 않으면 기본적으로 false로 변하는 두번째 매개 변수인 rev(reverse)를 가지고 있다는 것이다. 당신은 연습 1에서 우리가 처음으로 알파벳을 부른 것이
alphabetize(books)
루비는 rev를 보지 못 해서 기본 값인 false를 주었습니다.
1. 전달할 배열을 나타내는 Arr매개 변수와 기본적으로 false로 설정된 부울 매개 변수를 사용하여 영숫자 지정 방법을 업데이트합니다.

def alphabetize(arr, rev=false)
  
end


2-4. Sorting
좋았어! 이제 우리의 방법에 약간의 논리를 추가해 봅시다.
numbers = [5, 1, 3, 8]
numbers.sort!
puts numbers
1. 위의 예에서는 숫자라는 새 어레이를 생성합니다.
2. 그리고 나서, 우리는 배열을 분류합니다.
3. 마지막으로, 정렬된 배열을 1,3,5,8개 인쇄합니다.
루비에는 두가지의 분류 방법이 있어요. 첫번째 방법인 .sort는 원래 어레이는 그대로 두고 정렬된 어레이만 반환합니다. 두번째 방법인. sort!는 실제 어레이를 수정합니다.

1. 방법에 따라, 호출할 줄을 추가합니다. 정렬! 수목에 이 행이 메서드의 마지막 행이므로 정렬된 배열이 반환됩니다.
이제 시험해 보세요! 방법을 마친 후 위 예제와 같은 몇개의 숫자가 포함된 숫자라는 새 배열을 만듭니다.
숫자 배열과 함께 알파벳 순으로 된 방법을 매개 변수로 불러서 콘솔에 넣으세요.

def alphabetize(arr, rev=false)
  arr.sort!
  
end

numbers = [9, 20, 6, 1, 7]

puts alphabetize(numbers)
>> [1, 6, 7, 9, 20]


2-5. Sorting With Control Flow (제어 흐름으로 정렬)
좋았어! 이제 우리는 우리의 방법에 올바른 논리를 추가할 필요가 있다.
numbers = [1, 2, 3, 4, 5]
numbers.reverse!
puts numbers
1. 위의 예제에서는 숫자라고 하는 배열을 생성합니다.
2. 그리고 나서, 우리는 배열을 뒤집었습니다. 예를 들면... 
느낌표는 실제 배열을 수정하는 것을 의미합니다.
3. 마지막으로 5,4,3,2,1을 인쇄합니다.

1. 당신의 .sort! 부르고, 필요한 경우를 추가합니다. rev가 true이면 reverse를 호출합니다! arr에, 그렇지 않으면(else)  arr를 반환합니다.
당신의 작업이 실제로 이루어지는 것을 볼 수 있도록 당신의 숫자 체계와 인용문을 유지하세요!

def alphabetize(arr, rev=false)
  arr.sort!
  if rev == true
    arr.reverse!
  else
    return arr
  end
end

numbers = [9, 20, 6, 1, 7]

puts alphabetize(numbers)
>> [1, 6, 7, 9, 20]


2-7. You Did It! (For Real This Time)
잘 했다! 이제 루비가 가지고 있지도 않은 기능을 추가하는 독자적인 방법이 생겼습니다.
고유한 방법을 만드는 것은 프로그램을 다시 입력하지 않고도 코드를 반복해서 사용할 수 있으며 프로그램을 추상화하거나 단순화하는 데도 유용합니다. 일단 알파벳 순(alphabetize)으로 쓰면 그것이 어떻게 작동하는지 생각할 필요가 없다. 필요할 때 부르기만 하면 된다.
Run을 클릭하여 이 프로젝트를 마치고 RubyMethodMastery로 이동합니다.


6. Hashes and Symbols

1. Hashes and Symbols

보시다시피 해시는 루비의 중요한 데이터 구조입니다. 여기서는 베이컨에서 해시 달걀:기호에 대해 알아보겠습니다!
1-1. The Story So Far (지금까지 이야기)
해시는 키-값 쌍의 수집이며, 고유 키가 일부 값과 연관되어 있음을 기억하십시오. 예:
breakfast = {
"bacon" => "tasty",
"eggs" => "tasty",
"oatmeal" => "healthy",
"OJ" => "juicy"
}
키는 고유해야 하지만 값이 반복될 수 있습니다. 따라서" 맛있는 "이라는 값을 둘 이상의 키로 공유할 수 있습니다.)
해시를 생성할 수 있는 방법은 여러가지가 있지만
1. 해시 리터럴 표기법
new_hash = { "one" => 1 }
2. 해시 생성자 표기법
new_hash = Hash.new

1. 원하는 방법으로 my_hash라는 해시를 만듭니다.
my_hash = Hash.new


1-2. Iterating Over Hashes
또한 각 방법을 사용하여 해시를 반복할 수도 있습니다. 예를 들어, 우리는 할 수 있다
my_hash.each do |key, value|
      puts my_hash[ ]
end
이렇게 하면 각각 고유한 my_hash의 키와 값 목록이 인쇄됩니다.

1. matz 해시를 검토하고 각 값을 배치를 사용하여 콘솔에 인쇄합니다.

matz = { "First name" => "Yukihiro",
  "Last name" => "Matsumoto",
  "Age" => 47,
  "Nationality" => "Japanese",
  "Nickname" => "Matz"
}

matz.each do |key, value|
  puts "#{value}"     
  
end
>> Yukihiro
>> Matsumoto
>> 47
>> Japanese
>> Matz


1-3. Nil: a Formal Introduction (공식 소개)
하지만 존재하지 않는 키에 액세스 하려고 하면 어떻게 됩니까?
많은 언어로, 당신은 어떤 종류의 오류를 얻을 것이다. 루비에서는 그렇지 않아요. 대신에 특별한 가치는 0이 될 겁니다.
거짓과 함께, 루비에서는 0이 두개의 실제가 아닌 값 중 하나이다. ( 다른 모든 오브젝트는 "truthy"로 간주되며, if 2를 입력하거나"if bacon"를 입력할 경우 문을 실행할 때 코드가 표시됩니다.)
거짓(false)과 아무것도 같지 않다는 것을 깨닫는 것이 중요합니다. 거짓(false)은 "사실이 아니다"라는 뜻이고, 루비는 "아무것도 아니다"라고 말하는 법이 없습니다.

1. 존재하지 않는 생명체의 열쇠에 접근해 보세요.
creatures = { "weasels" => 0,
  "puppies" => 6,
  "platypuses" => 3,
  "canaries" => 1,
  "Heffalumps" => 7,
  "Tiggers" => 1
}

puts creatures["cat"]
>> 출력 결과 없음. 실행은 되고 오류는 없음.



1-4. Setting Your Own Default (기본 값 설정)
하지만 기본 값으로 0에 만족할 필요는 없습니다. Hash.new구문을 사용하여 해시를 생성하는 경우 다음과 같이 기본 값을 지정할 수 있습니다.
my_hash = Hash.new("Trady Blix")
이제 my_hash에 존재하지 않는 키에 액세스 하려고 하면"TradyBlix"가 표시됩니다.
당신은 공식 루비 문서에서 항상 더 많은 친절함을 읽을 수 있습니다.

1. 그 사이에 no_nil_hash라는 해시를 만들고 0이외의 기본 값을 지정합니다.

no_nil_hash = Hash.new("kimchi")   # kimchi 는 key 이다.

puts no_nil_hash["what the"]
>> kimchi


1-5. A Key of a Different Color (다른 색의 키)
우리는 확실히 루비 해시 키로 문자열을 사용할 수 있습니다. 루비에서는 항상 한가지 이상의 방법이 있습니다. 그러나, Rubyist의 접근법은 상징(symbols)을 사용하는 것이 될 것이다.

편집기에서 코드를 확인합니다. 콜론으로 시작하는 웃기게 생긴 변수들은 상징이다. 기호 런 다운을 보려면 다음 섹션에서 다음을 클릭합니다.

menagerie = { :foxes => 2,
  :giraffe => 1,
  :weezards => 17,
  :elves => 1,
  :canaries => 4,
  :ham => 1
}


1-6. What's a Symbol? (기호가 뭐죠?)
루비 기호는 일종의 이름이라고 생각하시면 됩니다. 기호는 문자열이 아닙니다.
"string" == :string # false
다른 구문의 위와 뒤에는 기호를 문자열과 다르게 만드는 주요 동작이 있습니다. 모든 문자열에 동일한 값이 있을 수 있지만 지정된 시간에 특정 기호의 복사본은 하나만 있습니다.

.object_id 메서드는 객체의 ID를 얻습니다. 이를 통해 두 객체가 동일한 객체인지 알 수 있습니다. 편집기에서 코드를 실행하여 두"문자열"이 실제로 다른 개체인지 확인하고,:기호는 두번 나열된 동일한 개체입니다.

# 문자열 값은 계속 변하지만 기호(symbol)의 값은 변하지 않는다.
puts "string".object_id
puts "string".object_id

puts :symbol.object_id
puts :symbol.object_id
>> 21736580
>> 21734660
>> 802268
>> 802268


1-7. Symbol Syntax (기호 구문)
기호는 항상 콜론(:)으로 시작합니다. 유효한 루비 변수 이름이어야 하므로 콜론 뒤의 첫번째 문자는 문자 또는 밑줄(_)이어야 합니다. 그 다음에는 문자, 숫자 및 밑줄을 조합할 수 있습니다.
기호 이름에 공백을 두지 마십시오. 공백을 입력하면 루비가 혼동됩니다.
:my symbol # Don't do this!
:my_symbol # Do this instead.

1. 모두 맞아요! 첫번째 기호를 만들 시간입니다. my_first_symbol이라는 일반적인 오래 된 변수를 만들고 원하는 올바른 기호와 동일하도록 설정하십시오!

my_first_symbol = :starjinx

Hint 이렇게 하면 됩니다.
my_first_symbol = :starmonkey


1-8. What are Symbols Used For? (기호는 무엇에 사용됩니까?)
루비에서는 기호가 여러곳에서 나타나지만, 주로 해시 키나 메서드 이름을 참조할 때 사용됩니다. (이후 단원에서 기호가 어떻게 방법을 참조할 수 있는지 알아보겠습니다.)
sounds = {
  :cat => "meow",
  :dog => "woof",
  :computer => 10010110,
}
기호를 사용하면 다음과 같은 몇가지 이유로 해시 키가 유용합니다.
1. 그것들은 불변한다. 즉, 그것들이 일단 만들어지면 그것들은 바뀔 수 없다는 것을 의미한다.
2. 지정된 시간에 하나의 기호만 존재하므로 메모리를 절약합니다.
3. 위의 두가지 이유 때문에 키를 돌리는 것이 키를 누르는 것보다 빠릅니다.

1. symbol_hash 해시에 _____ 빈 자리를 바꾸는 키를 두개 이상 추가합니다.
키는 모두 기호여야 합니다. 키와 연결된 값은 원하는 것이면 무엇이든 될 수 있습니다.

symbol_hash = {
  :one => 1,
  :two => 2,    
  :three => 3,
}


1-9. Converting Between Symbols and Strings (기호와 문자열 변환)
문자열과 기호를 변환하는 것은 식은 죽 먹기입니다.
:sasquatch.to_s
# ==> "sasquatch"

"sasquatch".to_sym
# ==> :sasquatch
.to_s및. to_sym메서드를 찾고 있습니다!
1. 나중에 해시 키로 사용할 문자열이 여러개 있지만 기호로 사용하는 것이 좋습니다.
  1. 새 변수, 기호를 생성하고 빈 배열을 저장합니다.
  2. 문자열 배열을 반복하려면 .each를 사용합니다.
  3. 문자열의 각 s에 대해.to_sym을 사용하여 s를 기호로 변환하고를 사용합니다.를 눌러 새 기호를 기호에 추가합니다.
  4. 기호 배열을 인쇄합니다.
각 및...푸시에 대한 주의 사항을 확인하십시오.

Hint
각각.each를 사용하여 배열을 순환할 수 있습니다. .push 방법을 사용하면 배열 끝에 요소를 추가할 수 있습니다!
numbers = [1, 2, 3, 4, 5, 6]
evens = []
numbers.each do |number|
if number % 2 == 0
   evens.push(number)
   end
end
print evens # prints '[2, 4, 6]'

strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []

strings.each do |s| 
 symbols.push(s.to_sym)
end 
print symbols
>> [:HTML, :CSS, :JavaScript, :Python, :Ruby]
# symbols 라는 빈 배열을 만들고 strings를 .each를 사용하여 symbols에 기호로 변환시켜 넣으라는 얘기.


1-10. Many Paths to the Same Summit (많은 경로로 가는 정상)
루비에서 무언가를 성취하는 데는 항상 많은 방법이 있다는 것을 기억하세요. 문자열을 기호로 변환하는 것도 다르지 않습니다!
.to_sym 사용 외에도. intern 을 사용하실 수 있습니다. 이렇게 하면 문자열이 기호로 초기화되고. to_sym처럼 작동합니다.
"hello".intern
# ==> :hello
다른 사용자의 코드를 볼 때 문자열을 기호로 변환할 때. to_sym또는. intern(또는 둘 다!)가 표시될 수 있습니다.
1... 마지막 연습에서 .to_sym 대신 .intern를 사용하도록 코드를 업데이트합니다.
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []

strings.each do |s| 
 symbols.push(s.intern)
end 
print symbols
>> [:HTML, :CSS, :JavaScript, :Python, :Ruby]


1-11. All Aboard the Hash Rocket! (모두들 해시 로켓!)
지금까지 보신 해시 구문(키와 값 사이에 => 기호가 있는 해시 구문)은 해시 로켓 스타일이라고도 합니다.
numbers = {
    :one => 1,
    :two => "two",
    :three => 3,
}
이것은 => 이 작은 로켓처럼 생겼기 때문이다.
기호를 키로 사용하여 처음부터 해시를 작성해 보겠습니다.

1. 기호가 있는 동영상이라는 해시를 키로, 문자열을 값으로 만듭니다.
해시 안에 키 2값 쌍 2개를 추가합니다.
열쇠는 영화의 이름이어야 한다.
값은 빠른 설명 또는 검토이어야 합니다.
시작할 수 있는 예를 들어 보려면 힌트를 확인하십시오!

movies = {
  :jinx => "hahaxxx",
  :Darkin => "kill",
}


1-12. The Hash Rocket Has Landed (해시 로켓이 장착됨)
그러나 루비 1.9에서는 해시 구문이 변경되었습니다. 네가 편안해 지고 있을 때!
다행히도 변경된 구문은 이전 해시 로켓 구문보다 입력하기가 더 쉽고 JavaScript개체 또는 Python사전에 익숙한 경우 매우 익숙하게 보일 것입니다.
new_hash = {
   one: 1,
   two: 2,
   three: 3
}
두가지 변경 사항은 다음과 같습니다.
1. 기호의 처음이 아니라 끝에 콜론을 찍습니다.
2. 너는 더 이상 해시 로켓(=>) 이 필요 없어.

비록 이 열쇠들이 처음이 아닌 끝에 콜론을 가지고 있지만, 그것들은 여전히 상징입니다!

puts new_hash # => { :one => 1, :two => 2, :three => 3 }
지금부터 예제를 제공하거나 기본 코드를 제공할 때 1.9해시 구문을 사용하겠습니다. 여러분은 다른 사람들의 코드를 읽을 때 해시 로켓 스타일에 친숙해 지고 싶을 거예요.

1. 이전 해시 로켓 구문 대신 새로운 1.9해시 구문을 사용하도록 이전 연습에서 해시를 업데이트합니다.

movies = { 
  jinx: "hahaxxx", 
  Darkin: "kill" 
}

puts movies
>> {:jinx=>"hahaxxx", :Darkin=>"kill"}  # 출력은 이전 구문 형식으로 출력 된다. 보기 좋아 보여서?


1-13. Dare to Compare (타 제품과 비교가 안됨)
해시 조회는 문자열 키보다 기호 키를 사용할 때 더 빠릅니다. 자, 우리가 증명해 보자!
편집기의 코드는 새로운 구문을 사용하므로 아직은 모든 것을 이해하는 것에 대해 걱정하지 마세요. 문자열과 알파벳 문자의 위치 ( "a" with 1, "b" with 2...)를 쌍으로 하는 문자와 기호(:a with 1, :b with 2...)를 사용하는 문자 해시를 구성합니다. 어떤 프로세스가 더 빨리 실행되는지 알아보기 위해 문자"r"을 100,000번 검색할 것입니다!
여러분이 보실 수 있는 숫자들은 단지 몇분의 일밖에 안된다는 것을 기억하는 것이 좋습니다. 그리고 우리는 해시 룩을 각각 100,000번씩 했습니다. 이 경우에 상징을 사용하는 것이 성능 향상에 큰 도움이 되지는 않지만, 분명 있습니다!
숫자는 거짓말이 아니다. 직접 확인하려면 실행을 클릭하십시오!

require 'benchmark'

string_AZ = Hash[("a".."z").to_a.zip((1..26).to_a)]
symbol_AZ = Hash[(:a..:z).to_a.zip((1..26).to_a)]

string_time = Benchmark.realtime do
  100_000.times { string_AZ["r"] }
end

symbol_time = Benchmark.realtime do
  100_000.times { symbol_AZ[:r] }
end

puts "String time: #{string_time} seconds."
puts "Symbol time: #{symbol_time} seconds."
# 2번 출력한 결과 미세한 차이더라도 확실히 차이가 있다. 시스템의 효율성을 위해.
>> String time: 0.014318784698843956 seconds.
>> Symbol time: 0.008909519761800766 seconds.

>> String time: 0.01439235545694828 seconds.
>> Symbol time: 0.009139424189925194 seconds.


1-14. Becoming More Selective (더욱 선택적이 되기)
연결된 키를 지정하여 해시에서 특정 값을 가져오는 방법을 알고 있지만 특정 조건을 충족하는 값의 해시를 필터링 하려면 어떻게 해야 합니까? 이를 위해 사용할 수 있습니다.

grades = { alice: 100,
bob: 92,
chris: 95,
dave: 97
}
grades.select { |name, grade| grade < 97 }   # 조건 걸기
# ==> { :bob => 92, :chris => 95 }  
grades.select { |k, v| k == :alice }     # 특정 키 찾기.
# ==> { :alice => 100 }

1. 위의 예제에서는 기호를 정수로 매핑 하는 등급 해시를 먼저 생성합니다. 
2. 그런 다음. Select메서드를 호출하고 코드 블록을 전달합니다. 이 블록에는 일치 키/값 쌍을 선택하기 위한 표현식이 포함되어 있습니다. 이것은 밥과 체리를 포함한 해시를 반환합니다. 
3. 마지막으로. Select메서드를 다시 호출합니다. 우리 블록은 열쇠만 찾아요:앨리스. 키/값 쌍을 가져오는 데는 비효율적인 방법이지만 이를 보여 줍니다.를 선택하면 해시가 수정되지 않습니다.

(여기서는 "name"또는"k"를 사용하여 키를 나타내고,"grade"또는"v"를 사용하여 값을 나타내지만, 블록에서는 원하는 대로 변수를 호출할 수 있습니다.)

1. 새로운 변수인 good_movies를 만들고 호출 결과와 동일하게 설정합니다. movie_ratings를 선택하고 등급이 3보다 큰 동영상만 선택합니다.

movie_ratings = {
  memento: 3,
  primer: 3.5,
  the_matrix: 5,
  truman_show: 4,
  red_dawn: 1.5,
  skyfall: 4,
  alex_cross: 2,
  uhf: 1,
  lion_king: 3.5
}

good_movies = movie_ratings.select {|movie, rating| rating > 3}  #선언과 동시에 선택적 조건을 달았다.

puts good_movies
>> {:primer=>3.5, :the_matrix=>5, :truman_show=>4, :skyfall=>4, :lion_king=>3.5}


1-15. More Methods, Mor Solutions (더 많은 방법, 더 많은 해결책) 
잘했어!
키/값 쌍과 관련된 키 또는 값만 원하는 경우가 많은데, 블록에 둘 다 입력하고 하나만 사용하는 것은 다소 고통스러운 일입니다. 키만 사용하거나 값만 반복할 수 있습니까?
루비입니다. 물론 우린 할수 있어요.
루비에는 두가지 해시 방법인 .each_key와 .each_value가 포함되어 있으며, 이는 예상하는 바와 같습니다.
my_hash = { one: 1, two: 2, three: 3 }
my_hash.each_key { |k| print k, " " }
# ==> one two three
my_hash.each_value { |v| print v, " " }
# ==> 1 2 3
루비 해시와 기호에 대한 연구는 이 방법들을 시험해 보면서 마치도록 하겠습니다.
1. 계속해서 저희 영화 제목만 출력하세요.

movie_ratings = {
  memento: 3,
  primer: 3.5,
  the_matrix: 3,
  truman_show: 4,
  red_dawn: 1.5,
  skyfall: 4,
  alex_cross: 2,
  uhf: 1,
  lion_king: 3.5
}

movie_ratings.each_key {|k| puts k}
>> memento
>> primer
>> the_matrix
>> truman_show
>> red_dawn
>> skyfall
>> alex_cross
>> uhf
>> lion_king


2. A Night at the Movies

이 프로젝트에서는 루비 해시 및 기호에 대한 지식을 활용하여 동영상 등급을 표시, 추가, 업데이트 및 제거하는 프로그램을 구성할 것입니다!

2-1. What You'll Be Building (무엇이 될 것인가)
디지털 라이프의 모든 부분을 기록하는 것은 고통스러운 일이다. 하지만 루비를 쓸 줄 알게 되었으니 이제 여러분 스스로 일을 쉽게 할 수 있겠군요! 먼저 영화 등급을 추적할 프로그램을 만드는 것으로 시작하겠습니다.

해시에 새 동영상 추가, 기존 동영상의 등급 업데이트, 해시에 이미 있는 동영상 및 등급 표시 또는 해시에서 동영상 삭제 등 네가지 작업 중 하나를 수행합니다. 이러한 네가지 명령 중 하나가 수신되지 않으면 프로그램에서 일부 오류 메시지를 출력합니다.

이 프로젝트는 여러분에게 창의성을 위한 많은 공간을 제공할 것입니다. 하지만 우리는 때때로 엄격한 지시를 따르지 않는 것이 약간 혼란스러울 수 있다는 것을 알고 있습니다. 만약 여러분이 상실감을 느낀다면, 주저하지 말고 여러분을 도와 주기 위해 이 연습에서 예시 코드를 확인하세요!

movies = {
  Memento: 3,
  Primer: 4,
  Ishtar: 1
}

puts "What would you like to do?"
puts "-- Type 'add' to add a movie."
puts "-- Type 'update' to update a movie."
puts "-- Type 'display' to display all movies."
puts "-- Type 'delete' to delete a movie."

choice = gets.chomp.downcase
case choice
when 'add'
  puts "What movie do you want to add?"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "What's the rating? (Type a number 0 to 4.)"
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
    puts "#{title} has been added with a rating of #{rating}."
  else
    puts "That movie already exists! Its rating is #{movies[title.to_sym]}."
  end
when 'update'
  puts "What movie do you want to update?"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "Movie not found!"
  else
    puts "What's the new rating? (Type a number 0 to 4.)"
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
    puts "#{title} has been updated with new rating of #{rating}."
  end
when 'display'
  movies.each do |movie, rating|
    puts "#{movie}: #{rating}"
  end
when 'delete'
  puts "What movie do you want to delete?"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "Movie not found!"
  else
    movies.delete(title.to_sym)
    puts "#{title} has been removed."
  end
else
  puts "Sorry, I didn't understand you."
end

#코드가 길다고 어렵게 생각할 필요 없다. 자세히 조금조금 읽어 보면 이해가 된다. 전부 이해가 안가더라도 이렇게 이렇게 작동하는구나 정도만 알아도 나중에 쌓이면 도움이 된다.


2-2. Setting Up (설정)
먼저 영화와 등급을 저장할 해시를 만들고 사용자에게 입력 메시지를 표시하여 동영상 및 등급 쌍을 해시에 저장하겠습니다.

favorite_foods = {
'vegetable' => 'broccoli'
}
puts "Do you like coding in Ruby?"
answer = gets.chomp

1. 해시는 숫자로만 정렬할 수 있는 배열이 아니라 지정 가능한 키로 데이터를 저장하는 방법입니다. 위의{}과( 와)같이 생성됩니다.
2. puts 에서는 명령줄에 질문이 있습니다. 루비 코딩을 좋아하는지 물어 보겠습니다.
3. 사용자 입력을 얻기 위해서는 gets.chomp를 사용해야 한다.

시작합시다.
1. 해시를 만들고 변수가 있는 동영상에 할당합니다. 가장 좋아하는 영화를 가치에 대한 등급을 매기는 열쇠로 넣으세요.
2. 사용자에게 입력을 입력하도록 프롬프트하고 선택이라는 변수에 입력을 저장합니다.

movies = {
  warcraft: 8, 
  avengers: 7.2,
  ironman: 4.0
  }

puts "What would you like to do? "
puts "-- Type 'add' to add a movie."
puts "-- Type 'update' to update a movie."
puts "-- Type 'display' to display all movies."
puts "-- Type 'delete' to delete a movie."

choice = gets.chomp


2-3. The Case Statement (사례 설명)
잘 했어요! 이제 사용자가 입력하는 내용에 따라 수행할 조치를 결정하는 사례 설명이라는 프로그램의 주요 부분을 생성하겠습니다.
만약 다른 것들이 강력하다면, 우리는 우리가 점검해야 할 많은 조건들이 있다면, 가정과 추측들 속에 수렁에 빠질 수 있다. 감사하게도 루비는 우리에게 사례 진술이라는 간단한 대안을 제시해 주었습니다. 구문은 다음과 같습니다.
case language
   when "JS"
     puts "Websites!"
   when "Python"
     puts "Science!"
   when "Ruby"
     puts "Web apps!"
   else
     puts "I don't know!"
end
또 다른 방법은 사례에 대한 문장(이 경우 언어의 가치)과 일치하는 문장이 하나도 없는 경우에 적용됩니다.
1. 기존 코드를 확인하여 조건이 다음과 같은 경우 선택 변수에 대한 사례 문을 만듭니다.
 1."추가"시"추가됨!"을 입력하십시오. 
 2. "업데이트"시"업데이트!"를 입력하십시오.
 3. "표시"시에는 "동영상!"을 넣으십시오.
 4. "삭제"시"삭제됨!"을 입력하십시오.
 5. 그렇지 않으면(예:),"오류!"라고 써 주세요.

movies = {
  warcraft: 8, 
  avengers: 7.2,
  ironman: 4.0
  }

puts "What would you like to do? "
puts "-- Type 'add' to add a movie."
puts "-- Type 'update' to update a movie."
puts "-- Type 'display' to display all movies."
puts "-- Type 'delete' to delete a movie."

choice = gets.chomp

case choice
  when "add"
   puts "Added!"
  when "update"
   puts "Updated!"
  when "display"
   puts "Movies!"
  when "delete"
   puts "Deleted!"
else
  puts "Error!"
end

# 문자를 입력했을 시 case when 문에 의해 입력 조건을 비교하여 출력한다.
>> add 입력시
>> Added!
>> what 입력시
>> Error!


2-4. Prompting: Redux!
좋았어! 사건의 각 부분을 한번에 한 단계씩 작성해 봅시다. "add"분기부터 시작하겠습니다.
1."add"블록을 열때"Added!"문을 제거합니다.
대신 사용자에게 동영상 제목을 입력하도록 요청합니다. 결과를 제목이라는 새 변수에 저장합니다. (코드에 이미 이 작업을 수행하는 방법의 예가 나와 있습니다!)
그런 다음 사용자에게 동영상 등급을 묻습니다. 등급이라는 새 변수에 저장합니다.
movies 해시에 movie/rating쌍을 추가하고 쌍이 추가되었음을 나타내는 메시지를 추가합니다. (아직to_sym또는to_i를 사용할 필요가 없습니다!)
도움이 필요하면 힌트를 확인하세요!
입력창 만드는 법.
puts "Enter a number"
number = gets.chomp

 키/값 쌍 해시에 추가하는 방법.
numbers = {}
numbers["one"] = 1
puts 3 + numbers["one"]
# prints out "4"

movies = {
  warcraft: 8,  
  avengers: 7.2, 
  ironman: 4.0 
  }

puts "What would you like to do? " 
puts "-- Type 'add' to add a movie." 
puts "-- Type 'update' to update a movie." 
puts "-- Type 'display' to display all movies." 
puts "-- Type 'delete' to delete a movie." 

choice = gets.chomp

case choice
when "add"
  puts "movies name"
  title = gets.chomp
  puts "movies rating?"
  rating = gets.chomp
  movies[title] = rating
when "update"
  puts "Updated!"
when "display"
  puts "Movies!"
when "delete"
  puts "Deleted!"
else
  puts "Error!"
end


2-5. Not My Type (내 취향은 아니다)
완벽해! 우리 프로그램은 정말 잘 되어 가고 있어요.
여러분은 어떻게 하면 영화를 기호로, 등급을 정수로 만들고 싶은 해시에 사용자로부터 영화와 등급을 가져올지 궁금해 하셨을 것입니다. 루비 마법사 내장!
루비의 .to_sym방법은 문자열을 기호로 변환할 수 있으며,. i에서 문자열을 정수로 변환합니다.

1. 영화 제목이 해시에 기호로 저장되고 관련 등급이 정수로 저장되도록 제목의 .to_sym과 등급의 .to_i를 입력합니다.

원하신다면 .to_sym 대신 .intern을 사용하실 수도 있습니다.

movies = {
  warcraft: 8,  
  avengers: 7.2, 
  ironman: 4.0 
  }

puts "What would you like to do? " 
puts "-- Type 'add' to add a movie." 
puts "-- Type 'update' to update a movie." 
puts "-- Type 'display' to display all movies." 
puts "-- Type 'delete' to delete a movie." 

choice = gets.chomp

case choice
when "add"
  puts "movies name"
  title = gets.chomp
  puts "movies rating?"
  rating = gets.chomp
  movies[title.to_sym] = rating.to_i   #여기다 .to_sym .to_i 만 추가해 줌.
when "update"
  puts "Updated!"
when "display"
  puts "Movies!"
when "delete"
  puts "Deleted!"
else
  puts "Error!"
end


2-6. Error! Error!
좋아! 우리는 우리 사건의 "추가"부분을 거의 끝냈다. 추가할 동영상이 이미 해시에 있는지 확인하기 위해 마지막으로 수행할 작업입니다.
이렇게 하기 위해 가능한 if/else 경우 문을 추가합니다.
1. if/else 문을 사례의 추가 분기에 추가합니다. 동영상이 아직 해시에 있지 않은 경우(즉,movies[title.to_sym]이 nil 이면
동영상/등급 쌍을 추가해야 합니다. 그렇지 않으면 동영상이 이미 존재하며 해시에 아무것도 추가하지 않아야 합니다.) 꼭 시험해 보세요!
Hint
아무것도? 호출된 객체가 0이면 메서드가 true를 반환하고 그렇지 않으면 false를 반환합니다.
nil_variable = nil
age = 26

nil_variable.nil? # true
age.nil? # false

movies = {                                                            # movies 에는 symbol로 동영상 등급인 값과 묶었다.
  warcraft: 8,   
  avengers: 7.2,  
  ironman: 4.0  
  } 

puts "What would you like to do? "  
puts "-- Type 'add' to add a movie."  
puts "-- Type 'update' to update a movie."  
puts "-- Type 'display' to display all movies."  
puts "-- Type 'delete' to delete a movie."  

choice = gets.chomp                                  # 어떻게 추가할 건지 선택권을 주고 입력한 것을 choice 라는 새 변수에 담는다.       

case choice                                                  # 입력한 값을 저장한 choice를 case when문으로 열어 알맞게 비교하여 넣는다.
when "add" 
  puts "movies name" 
  title = gets.chomp                                    # add 에 영화 제목을 받을 수 있게 title이라는 변수에 담는다.
  if movies[title.to_sym].nil?                      # if 문으로 movies를 내가 입력한 값(title)과 비교하기 위해 .to_sym으로 변환시킨다. 
    puts "movies rating?"                            .nil? 로 참이면 절대적이게 같지 않기 때문에 추가할 수 있게 영화 등급까지 rating 변수
    rating = gets.chomp                              에 받게 하고 movies에 title을 symbol 값으로 저장받아 rating.to_i 로 값을 넣어둔다.
    movies[title.to_sym] = rating.to_i         (.to_i는 값을 정수버전으로 바꿔준다.)
  else
    puts "video already exists. #{movies[title.to_sym]}"  #nil이 거짓이기 때문에 절대적이게 같다는 거다. 이 경우 영화가 이미       end                                                                                   존재하기에 #{} 으로 movies에 값을 불러와 준다.
when "update" 
  puts "Updated!" 
when "display" 
  puts "Movies!" 
when "delete" 
  puts "Deleted!" 
else 
  puts "Error!" 
end


2-7. Update (갱신하다)
완벽해! 해시의 기존 동영상 업데이트를 처리하는 사례 설명의 다음 분기로 이동하겠습니다. ("추가"지점에서 수행한 작업과 매우 유사할 것입니다!)이 작업은 세가지 단계로 수행합니다.

1."업데이트"블록을 열때"업데이트됨!"설명문을 제거합니다.
사용자에게 동영상 제목을 입력하도록 요청합니다. 제목으로 저장하세요.
if the movies[title] is nil, 그러면 그 영화는 문제가 되지 않는다. 사용자에게 오류를 알리는 문자열을 입력하십시오.
그렇지 않으면 동영상 해시를 업데이트해야 합니다. 사용자에게 새 등급을 지정하도록 요청합니다. 동영상 등급을 새 값으로 설정합니다.
꼭 테스트해 보세요!

movies = { 
  warcraft: 8,   
  avengers: 7.2,  
  ironman: 4.0  
  }

puts "What would you like to do? "  
puts "-- Type 'add' to add a movie."  
puts "-- Type 'update' to update a movie."  
puts "-- Type 'display' to display all movies."  
puts "-- Type 'delete' to delete a movie."  

choice = gets.chomp 

case choice
when "add"
  puts "What movie would you like to add? "
  title = gets.chomp
  if movies[title.to_sym].nil? 
    puts "What rating does the movie have? "
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
  else
    puts "That movie already exists! Its rating is #{movies[title.to_sym]}."
  end
 when "update"         #choice에서 update를 입력하면 when 조건으로 들어온다.
  puts "movies name"  
  title = gets.chomp  # 제목을 입력하게 하고 title 변수에 담는다.
  if movies[title.to_sym].nil?  # 내가 입력한 값과 movies 가 참이면 절대적이게 같지 않기 때문에 입력 값이 다르다는 거다.
    puts "error"                            에러 메시지 호출.
  else
    puts "Please specify a new video rating."  # nil 조건이 거짓이면 절대적이게 같기 때문에 새로운 등급을 쓰도록 한다.
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i  #rating movies 변수에 알맞은 제목을 찾게 하여 새로 입력한 rating 값을 갱신한다.
    puts "It was successfully changed => #{movies[title.to_sym]}"
  end
when "display"
  puts "Movies!"
when "delete"
  puts "Deleted!"
else
  puts "Error!"
end


2-8. Display (표시하다)
대단해! 이제 동영상 해시의 내용을 표시하는 작업을 처리하겠습니다. 이는 "추가"및"업데이트"분기와 약간 다를 것입니다.
1. 첫째, 사용자가 "표시"를 입력할 때"동영상!"을 제거한다.
다음으로, 해시를 사용하여 .each를 사용하고 각 movie/rating쌍을 배치합니다. 형식은 "#{Movie}:#{rating}. 테스트해야 합니다!
Hint
간격을 잘 두세요! 출력 형식은 다음과 같아야 합니다. #{Movie}:#{rating}, 이 경우 아래와 같은 결과가 발생합니다.
Memento: 3
Primer: 4
Ishtar: 1



movies = { 
  warcraft: 8,   
  avengers: 7.2,  
  ironman: 4.0  
  }

puts "What would you like to do? "  
puts "-- Type 'add' to add a movie."  
puts "-- Type 'update' to update a movie."  
puts "-- Type 'display' to display all movies."  
puts "-- Type 'delete' to delete a movie."  

choice = gets.chomp 

case choice
when "add"
  puts "What movie would you like to add? "
  title = gets.chomp
  if movies[title.to_sym].nil? 
    puts "What rating does the movie have? "
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
  else
    puts "That movie already exists! Its rating is #{movies[title.to_sym]}."
  end
 when "update" 
  puts "movies name"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "error"
  else
    puts "Please specify a new video rating."
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
    puts "It was successfully changed => #{movies[title.to_sym]}"
  end
when "display"
  movies.each {|movie, rating| puts "#{movie}: #{rating}"}
when "delete"
  puts "Deleted!"
else
  puts "Error!"
end
 
display 입력시
>> warcraft: 8
>> avengers: 7.2
>> ironman: 4.0

# puts를 앞에 써도 출력이 된다. 여기선 정답은 아니지만.
puts movies.each {|movie, rating| "#{movie}: #{rating}"}
{:warcraft=>8, :avengers=>7.2, :ironman=>4.0}


2-9. Delete
거의 다 왔어! 사용자가 해시에서 지정한 키를 모두 제거하는 "삭제"부분을 처리해 보겠습니다. (이는 "추가"및"업데이트"와 매우 유사합니다.)
루비를 사용하면 해시에서 movie/rating 쌍을 쉽게 제거할 수 있습니다. 우리는 그냥 movies.delete(제목)만 쓰면 됩니다!

1."삭제"를 입력하면"삭제됨!"을 제거합니다.
사용자로부터 제목을 가져옵니다.
동영상이 해시에 없는 경우 오류가 발생하는 경우를 포함합니다. 동영상이 있으면을 사용하여 삭제하여 위에 표시된 대로 제거하십시오. 테스트해 보십시오!
Hint
각 분기에서 title.to_sym을 변환하는 것을 잊지 마십시오. 항상 문자열이 아닌 해시에 기호를 저장, 검사 및 업데이트하려고 합니다.

movies = { 
  warcraft: 8,   
  avengers: 7.2,  
  ironman: 4.0  
  }

puts "What would you like to do? "  
puts "-- Type 'add' to add a movie."  
puts "-- Type 'update' to update a movie."  
puts "-- Type 'display' to display all movies."  
puts "-- Type 'delete' to delete a movie."  

choice = gets.chomp 

case choice
when "add"
  puts "What movie would you like to add? "
  title = gets.chomp
  if movies[title.to_sym].nil? 
    puts "What rating does the movie have? "
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
  else
    puts "That movie already exists! Its rating is #{movies[title.to_sym]}."
  end
 when "update" 
  puts "movies name"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "error"
  else
    puts "Please specify a new video rating."
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
    puts "It was successfully changed => #{movies[title.to_sym]}"
  end
when "display"
  movies.each {|movie, rating| puts "#{movie}: #{rating}"}
when "delete"
  puts "enter movie title"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "error"
 else
   puts movies.delete(title)
 end


2-10. Nice Work!
훌륭하다! 당신은 단지 수십줄의 코드를 가진 작은 앱을 만들었다. 감명 깊지?
프로그램에서 알고 있는 4개의 동사(추가, 표시, 업데이트 및 삭제)는 보편적입니다. 이 약어는(각각 생성, 읽기, 업데이트 및 삭제를 위해 사용되는 create, read, update, delete CRUD)로 더 잘 알려져 있습니다. 데이터베이스에서 항목을 업데이트하거나, 웹 사이트에 정보를 요청하거나, 블로그 게시물을 작성할 때 수행하는 작업입니다. API호출부터 RubyonRails와 같은 웹 프레임워크에 이르기까지 이 설정에 익숙해지는 것은 좋습니다.

마음에 드는 대로 프로그램을 실행할 수 있을 때까지 얼마든지 프로그램을 사용하십시오. ("오류!"보다 더 구체적인 메시지를 추가할 수 있습니까?)
준비가 되었으면 실행을 클릭하여 이 프로젝트를 완료하십시오!

movies = {  
  warcraft: 8,    
  avengers: 7.2,                                                    # movies라는 변수에 기호(symbol)로 정수 값과 묶었다.                      
  ironman: 4.0   
  } 

puts "What would you like to do? "                   # 입력할 수 있는 조건들을 표시해 두었다.
puts "-- Type 'add' to add a movie."     
puts "-- Type 'update' to update a movie."   
puts "-- Type 'display' to display all movies."   
puts "-- Type 'delete' to delete a movie."   

choice = gets.chomp                                          # 사용자로부터 입력 받은 것을 choice 변수에 담는다.

case choice                                                          # case when문으로 choice 값을 비교한다. when에 맞춰서 값을 찾아간다.
when "add" 
  puts "What movie would you like to add? "   # 사용자로부터 추가하라는 입력을 받게 한다.
  title = gets.chomp 
  if movies[title.to_sym].nil?                             # if문으로 영화와 내가 입력한 값을 .nil로 검사한다. 절대적이게 같지 않아야 한다.
    puts "What rating does the movie have? " 
    rating = gets.chomp 
    movies[title.to_sym] = rating.to_i 
  else                                                                  # else로 온 경우 사용자가 입력한게 movies에 담긴 영화가 있다는 거다.
    puts "That movie already exists! Its rating is #{movies[title.to_sym]}." 
  end 
 when "update"  
  puts "movies name" 
  title = gets.chomp 
  if movies[title.to_sym].nil?       # 절대적이게 같지 않아야 한다. 여기선 영화 제목이 같지 않으면 업데이트 할 수 없기 때문에
    puts "error"                             # error 메시지를 보내준다.
  else 
    puts "Please specify a new video rating."  # 같다면 rating을 업데이트 하라 한다.
    rating = gets.chomp 
    movies[title.to_sym] = rating.to_i   # movies 변수에 내가 입력한 title 값을 sym볼로 바꾸어 rating과 추가한다.
    puts "It was successfully changed => #{movies[title.to_sym]}" 
  end 
when "display"        # .each를 사용하여 표시한다.
  movies.each {|movie, rating| puts "#{movie}: #{rating}"} 
when "delete" 
  puts "enter movie title" 
  title = gets.chomp 
  if movies[title.to_sym].nil?   # 절대적이게 같지 않기 때문에 입력한 값과 movies에 담긴게 다르니 에러 메시지.
    puts "error" 
  else                                        # 입력한 값과 같다면 삭제를 진행한다. .delete(입력한 값)
    puts movies.delete(title) 
    puts "clear"
  end
else   # add, update, display, delete를 안골랐다면 이 메시지 호출.
  puts "bye bye~"
end


7. Refactoring

1. The Zen of Ruby

이 과정에서는 루비를 독특하게 만드는 모범 사례와 규약에 대해 알아보겠습니다.

1-1. Ruby is a Delight
루비는 언어로 프로그램 최적화보다는 프로그래머 생산성을 우선시합니다. 이는 루비가 항상 프로그램을 가장 빠르게 실행하는 것은 아니지만 프로그래머들이 쉽고 재미 있게 사용할 수 있는 언어가 되기 위해 노력하고 있다는 것을 의미합니다. 언어의 구문이 직관적일수록 사용자의 생산성이 높아집니다. 네가 조종할 수 있는 거야, 기계가 아니라!
편집기에서 코드를 확인합니다. 그것은 거의 영어처럼 보이지 않나요?
출력 결과를 알고 있다고 생각되면 Run을 클릭합니다.

ruby_is_eloquent = true
ruby_is_ugly = false

puts "Ruby is eloquent!" if ruby_is_eloquent
puts "Ruby's not ugly!" unless ruby_is_ugly       #unless if의 부정형. 거짓이어야 실행 됨.

>> Ruby is eloquent!
>> Ruby's not ugly!


1-2. A Simpler 'if'
다음과 같은 경우 루비를 보셨을 겁니다.
if
condition
  # Do something!
end
그러나"do something"이 짧고 간단한 표현이라면 한줄로 이동할 수 있습니다(마지막 연습에서 보신 것처럼). 구문은 다음과 같습니다.
expression if boolean
루비는 부울이 뒤에 오면 다음에 표현이 올 겁니다. 순서는 중요하다. 다음 작업을 수행할 수 있습니다.
puts "It's true!" if true

그러나 이것은 아니다.
if true puts "It's true!"
if 당신이 한줄에 모든 것을 적을 때 당신의 말을 끝낼 필요가 없다는 것(end) 또한 중요하다.

Hint
한 줄에 표현하기:
puts "Hello!" if true
다음과 같습니다:
if true 
   puts "Hello!" 
end

1. 한번 해 보세요! 오른쪽에 있는 편집기에 문장을 입력합니다. 그것은 당신이 좋아하는 무엇이든지 될 수 있다.

puts "one-line expression" if true
>> one-line expression


1-3. The One-Line Unless
진술이 없으면 똑같은 일을 할 수 있다. 루비가 할 수 있는 것, 키워드가 없는 것, 그리고 진실과 거짓을 평가하는 표현 등의 순서는 전과 동일합니다.
단 한줄로 쓸 때도, 쓰지 않을 때도 end가 필요 없다는 것을 기억하라!

Hint
다음과 같은 간단한 원 라인을 사용해 볼 수 있습니다:
puts "Hello!" unless false
이는 다음과 같습니다:
unless false
    puts "Hello!"
end
1. 편집기 오른쪽에 있는 unless를 사용하여 한줄만 입력합니다. 그것은 당신이 좋아하는 무엇이든지 될 수 있다.

puts "The use of negative statements" unless false    # unless 가 거짓이여야 실행됨. 그래서 false
>> The use of negative statements


1-4. One Good Trun Deserves a Ternary (눈물을 자아내는 한번의 좋은 반전?)
루비 모험을 하는 동안, 여러분은 어떤 하나의 목표를 달성하는데 있어서 많은 선택권이 있다는 것을 보았습니다. 예외가 아닌 경우!  if/else 이면 더욱 더 간결한 형태가 ternary조건적 표현이다. 이를 "ternary"라고 하는 이유는 세가지 인수가 필요하기 때문입니다. 부울, 부울이 참인지 여부를 평가하는 식이, 부울이 거짓인지를 평가하는 식입니다.
구문은 다음과 같습니다:
boolean ? Do this if true: Do this if false
예를 들어
puts 3 < 4 ? "3 은 4보다 작다 4!" : "3 은 4보다 작지 않다 4."
기억하세요: 논쟁의 순서는 중요하고 end는 필요하지 않다. 이 버전의 경우 if/else
Hint
다음과 같은 간단한 요약 설명을 사용해 볼 수 있습니다.
puts true ? "True!" : "False!"
이는 다음과 같습니다.
if true
    puts "True!"
else
    puts "False!"
end

1. 편집기에서 순간적인 표현을 지웁니다. 도움이 필요하면 언제든지 힌트를 보세요!

puts true ? "True!" : "False!"
>> True!

puts false ? "True!" : "False!"
>> False!

puts 3 < 4 ? "3 is less than 4!" : "3 is not less than 4."
>> 3 is less than 4!

puts 3 > 4 ? "3 is less than 4!" : "3 is not less than 4."
>> 3 is not less than 4.


1-5. When and Then: The Case Statement(시기 및 시기: 사례 설명)
if/else 가 강력한 것 같지만, 만약 우리가 점검해야 할 조건이 많다면 우리는 if/elseif 에 빠져 버릴 수도 있다.
감사하게도 루비는 우리에게 case문 이라는 간단한 대안을 제시해 주었습니다. 구문은 다음과 같습니다.
case language
   when "JS"
     puts "Websites!"
   when "Python"
     puts "Science!"
   when "Ruby"
    puts "Web apps!"
  else
    puts "I don't know!"
end
그러나 다음과 같이 접을 수 있습니다.
case language
  when "JS" then puts "Websites!"
  when "Python" then puts "Science!"
  when "Ruby" then puts "Web apps!"
  else puts "I don't know!"
end

1. 사용자의 입력을 유도하기 위해 몇가지 코드를 추가했습니다.
case greeting(어느 스타일이든!)을 편집자에게 추가합니다. 다음 작업을 수행해야 합니다.
사용자가 "영어"를 입력할 때, 프로그램은 "Hello!"를 입력해야 합니다.
사용자가 "프랑스어"를 입력할 때, 프로그램은 "봉주르!"를 넣어야 한다.
사용자가 "독일어"를 입력할 때 프로그램은 "Guten태그!"를 표시해야 합니다.
사용자가 "핀란드어"를 입력할 때 프로그램은 "Haloo!"를 입력해야 한다.
그렇지 않으면, 프로그램은 "나는 그 언어를 몰라!"라고 써야 해.

puts "Hello there!"
print "Choice >> English, French, German, Finnish: "
greeting = gets.chomp

case greeting
  when "English" then puts "Hello!"
  when "French" then puts "Bonjour!"
  when "German" then puts "Guten Tag!"
  when "Finnish" then puts "Haloo!"
else puts "I don't know that language!"  
end

>> Hello there!
>> Choice >> English, French, German, Finnish: # Finnish 입력. 
>> Haloo!

>> Hello there! 
>> Choice >> English, French, German, Finnish: # now 입력. 
>> I don't know that language!


1-6. Conditional Assignment (조건부 할당)
연산자를 사용하여 변수에 값을 할당할 수 있습니다. 하지만 변수가 아직 할당되지 않은 경우에만 할당하려면 어떻게 해야 할까요? 
이를 위해 조건부 할당 연산자를 사용할 수 있습니다. ||= (||) 논리 연산자와 일반 = 할당 연산자로 구성되어 있습니다.

편집기에서 코드를 실행합니다. 다음과 같은 상황이 발생했습니다.
1. 변수 favorite_book는 아무것도 아님을 뜻하는 nil로 설정되어 있습니다. 이 상태에서 해당 변수를 출력하면 말 그대로 화면에 아무것도 표시되지 않을 겁니다.
2. 이제 해당 변수는 조건적으로 "Cat's Cradle"라고 지정됩니다. 이전엔 변수가 비어있었기 때문에(nil), 해당 변수에 "Cat's Cradle"이 할당되는 것이고, 따라서 해당 변수를 출력하면 "Cat's Cradle"이 출력될 겁니다.
3. 이제 다시 조건부 할당을 시도합니다. 이번에는 "Why's (Poignant) Guide to Ruby"를 변수에 할당하려 합니다. 하지만 잠깐! 해당 변수는 이미 "Cat's Cradle"라는 값을 가지고 있으므로, 새로운 값을 할당하지 않고 기존의 값을 계속 변수에 유지합니다. 따라서 변수를 출력해도 "Cat's Cradle"이 출력될 겁니다.
4. 마지막으로, 일반적인 할당 연산자를 사용해서 변수 favorite_book의 값으로 "Why's (Poignant) Guide to Ruby"를 할당할 겁니다. 따라서 변수를 출력하면 변경된 값이 출력됩니다.

favorite_book = nil
puts favorite_book

favorite_book ||= "Cat's Cradle"
puts favorite_book

favorite_book ||= "Why's (Poignant) Guide to Ruby"
puts favorite_book

favorite_book = "Why's (Poignant) Guide to Ruby"
puts favorite_book

>> Cat's Cradle
>> Cat's Cradle
>> Why's (Poignant) Guide to Ruby


1-7. Now You Try!
이제 네 차례야!
1. 변수, favorite_language를 만들고 그리고 조건부로 당신이 가장 좋아하는 프로그래밍 언어에 맞추세요.

favorite_language = nil

favorite_language ||= "Ruby"

puts favorite_language


1-8. Implicit Return  (암시적 반환)
루비에서의 방법이 값을 반환할 수 있다는 것을 알고 있으며, 프로그램의 다른 부분에서 값을 사용하고자 할 때 값을 반환하는 방법을 요청(return) 합니다. 하지만, 만약 우리가 우리의 방법 정의에 반환문을 붙이지 않는다면 어떻게 될까요?
예를 들어, JavaScript기능에 반환할 내용(return)을 정확하게 알려 주지 않으면 정의되지 않은 상태(undefined)로 반환됩니다. Python의 경우 기본 반환 값은 없음(None)입니다. 루비의 경우는 좀 다릅니다. 루비의 방법은 마지막으로 평가한 표현의 결과를 보여 줍니다.

# 한 마디로 return 대신 ruby는 end 사용한다는거 아닐까? return도 사용이야 하겠지만.

이는 다음과 같은 루비 방식을 사용하고 있을 경우:
def add(a,b)
    return a + b
end
다음과 같이 간단하게 쓸 수 있습니다.
def add(a,b)
    a + b
end
어느 쪽이든 add(1,1)를 누르면 2가 나옵니다.

1. 암시적 반환을 사용하도록 편집기의 코드를 수정합니다.
Hint 한 단어만 빼면 돼!

def multiple_of_three(n)
   n % 3 == 0 ? "True" : "False"
end

puts multiple_of_three(7)
puts multiple_of_three(396)

>> False
>> True


1-9. Short-Circuit Evaluation (단락 회로 평가)
루비에는 부울 연산자 and(&&) 그리고 or(||)로 구성된 연산자가 있다는 것을 상기하십시오. && 연산자는 연산자의 양쪽에 있는 식을 모두 참일 때만 true를 반환합니다. || 관련된 식 중 하나 또는 둘 다가 참이면 true를 반환합니다.

루비는 이것을 단락 평가를 통해 한다. 루비가 두 표현을 다 보지 않는 한 둘 다 보지 않는다는 뜻입니다.
false && true
&&은 무엇이든 거짓임(false)을 알기 때문에 &&이 읽는 것을 보자마자 멈춘다.

루비가 마지막으로 평가한 표현식의 결과를 어떻게 반환하는지 기억하세요? 우리는 그것을 사용하여 실제 단락 평가를 보여 줄 수 있다.

편집기에서 코드를 확인한 다음 실행을 클릭합니다. 루비에서는 false와 nil이 모두 거짓 값이기 때문에 두 문자열이 모두 true으로 간주된다. 루비는 뭐든지 사실(true ||)이라는 걸 알고 있어요. 그래서 a || b는 a만 평가해요. 하지만 b의 a && b부분에서 거짓(false)이 발견될 수도 있기 때문에 b를 평가해야 해요.

ex.1)  a == true, b == true
def a
  puts "A was evaluated!"
  return true
end

def b
  puts "B was also evaluated!"
  return true
end

puts a || b       #  or 연산자 이기 때문에 둘 중 하나만 보면 된다. a가 바로 true이기 때문에 a만 출력한다.
puts "------"
puts a && b   # and 연산자 이기 때문에 둘 다 참 이어야 한다. 

>> A was evaluated!
>> true                        # 여기까지 || 연산자.
>> ------
>> A was evaluated!        # && 연산자 이기에 둘다 출력. a
>> B was also evaluated! # 당연 b도 검사.
>> true                              # 결론은 둘다 참이기에 true


ex.2)  a == true, b == false
def a
  puts "A was evaluated!"
  return true
end

def b
  puts "B was also evaluated!"
  return false
end

puts a || b
puts "------"
puts a && b

>> A was evaluated!
>> true                               # or 연산자 부분이다. 둘 중 하나만 참이면 된다. a가 참이니 바로 사실을 확인하고 종료한다.
>> ------
>> A was evaluated!         # and 연산자 부분이다. 둘 다 참 이어야 한다. a 가 참이니 넘어간다.
>> B was also evaluated!  # b puts 부분까지는 출력한다.
>> false                              # b가 false 이기에 false를 반환하고 종료한다.


ex.3) a == false, b == true
def a
  puts "A was evaluated!"
  return false
end

def b
  puts "B was also evaluated!"
  return true
end

puts a || b      # or 연산자. a가 false 이다. 
puts "------"
puts a && b

>> A was evaluated!         # a의 puts은 출력된다.
>> B was also evaluated!  # b의 puts도 출력된다.
>> true                               # or 연산자는 둘 중 하나만 참이면 되기 때문에 b로 인해 true가 반환.
>> ------
>> A was evaluated! # and 연산자 부분이다. 둘 다 참이어야 한다. a의 puts은 출력된다. 
>> false                      # a가 false 이기 때문에 볼 것도 없이 중단시킨다. false가 나오면 중단된다.


1-10. The Right Tool for the Job (업무에 적합한 도구)
조만간, 여러분은 프로그램에서 반복적인 작업을 해야 할 것입니다. 많은 프로그래밍 언어는 루프에 대한 for를 사용하여 이 작업을 수행할 수 있도록 해 주며, 루비에는 루프에 대한 기능이 포함되어 있지만, 더 나은 도구가 있습니다.

특정 횟수만큼 작업을 수행하려는 경우 .times방법을 다음과 같이 사용할 수 있습니다.
5.times { puts "Odelay!" }
# Prints 5 "Odelay!"s on separate lines
집합의 모든 요소에 대해 작업을 반복하려는 경우 다음을 각각 사용할 수 있습니다.
[1, 2, 3].each { |x| puts x * 10 }
# Prints 10, 20, 30 on separate lines

1. 좀 창의적으로 해 봅시다. my_array의 짝수 값만 넣는 루프를 작성합니다.. (한줄만 사용할 경우 보너스 포인트!)

ex.1)
my_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
my_array.each do |x|
  if x % 2 == 0
    puts x
  end
end

ex.2)
my_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
my_array.each { |x| puts x if x % 2 == 0 }

ex.3)
my_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
my_array.each { |num| puts num unless num % 2 !=0 }
# num % 2 != 0 설명. my_array의 값들을 각각 2로 나누었을때 나머지가 0과 다르다면 홀수란 의미. unless를 사용하여 거짓일 때 실행되게 한다. 거짓일 때는 조건이 0과 같을 때다. 고로 짝수 값을 찾게 해준다.

>> 2
>> 4
>> 6
>> 8
>> 10


1-11. Up the Down Staircase (위쪽 계단)
우리가 포함시키고 싶은 숫자의 범위를 알고 있다면, .upto .downto를 사용할 수 있습니다. 이것은 카운터 변수가 특정 값에 도달할 때 중지되는 루프(for)에 사용하는 것보다 훨씬 더 Rubyist솔루션입니다.

.upto를 사용하여 특정 범위의 값을 인쇄할 수 있습니다.
95.upto(100) { |num| print num, " " }
# Prints 95 96 97 98 99 100
그리고. downto를 사용하여 내림차순으로 동일한 작업을 수행할 수 있습니다.

당신은 .upto 그리고 .downto를 알파벳으로 사용하는 것에 대해 생각합니까? 알아 낼 수 있는 유일한 방법!

Hint
전체 알파벳을 사용하려면 다음을 수행합니다.
"A".upto("Z") { |letter| puts letter }

1. 대문자"L"을 "P"로 표시할 때까지 사용합니다.
(puts은 사용하고 print는 하지 마십시오. 따라서 각 문자는 독자적으로 사용할 수 있습니다!)

"L".upto("P") { |letter| puts letter}

>> L
>> M
>> N
>> O
>> P


1-12. Call and Response (통화 및 응답)
방법 이름을 참조하는 데 기호(Symbol)가 유용하다고 언급한 것을 기억하십니까? 음, .respond_to? 객체가 해당 메서드를 수신할 수 있으면 기호를 사용하여 true를 반환하고 그렇지 않으면 false를 반환합니다. 예를들면
[1, 2, 3].respond_to?(:push)
어레이 개체를 누르면 호출할 수 있으므로(.push) true가 반환됩니다. 하지만
[1, 2, 3].respond_to?(:to_sym)
배열을 기호로 변환할 수 없으므로 거짓으로 반환합니다.

1. age 변수가 정수인지 확인하는 것보다 확인하는 것이 좋습니다. .respond_to? 다음의 방법 (.next은 해당 정수를 호출하는 즉시 정수를 반환합니다. 즉, 4.next가 5를 반환합니다.)

age = 26

puts age.respond_to?(:next)
>> true


1-13. Being Pushy
어레이로 푸시 하는 것에 대해 말하자면, 루비는 일반적인 방법을 사용하기 위한 몇가지 좋은 지름길을 가지고 있습니다. 운 좋게도, 하나는…  .push!

.Push메서드 이름을 입력하는 대신 concatenation 연산자인 << 를 사용하여 배열 끝에 요소를 추가할 수 있습니다.
[1, 2, 3] << 4
# ==> [1, 2, 3, 4]
좋은 소식:그것은 또한 문자열에도 작용합니다! 다음 작업을 수행할 수 있습니다.
"Yukihiro " << "Matsumoto"
# ==> "Yukihiro Matsumoto"

1. .push와 + 대신 concatenation 연산자를 사용하도록 편집기의 코드를 업데이트합니다. (puts the caption)

alphabet = ["a", "b", "c"]
alphabet << "d"

caption = "A giraffe surrounded by "
caption << "weezards!" 

puts alphabet
puts caption

>> ["a", "b", "c", "d"]
>> A giraffe surrounded by weezards!


1-14. String Interpolation
항상 이전 + 또는 << 를 사용하여 문자열에 변수 값을 추가할 수 있습니다.
drink = "espresso"
"I love " + drink
# ==> I love espresso
"I love " << drink
# ==> I love espresso

그러나 문자열이 아닌 값을 사용하려면. to_s를 사용하여 문자열로 만들어야 합니다.
age = 26
"I am " + age.to_s + " years old."
# ==> "I am 26 years old."
"I am " << age.to_s << " years old."
# ==> "I am 26 years old."

이것은 복잡하고, 복잡한 것은 루비 방식이 아닙니다. 더 나은 방법은 문자열 보간입니다. 구문은 다음과 같습니다.
"I love #{drink}."
# ==> I love espresso.
"I am #{age} years old."
# ==> I am 26 years old.
변수 이름을 문자열 안에 넣기만 하면 됩니다!

1. concatenation 연산자를 제거하고 #{thing}을사용하도록 코드를 다시 작성하십시오. 6번 선에 하나의 완전한 문자열을 넣어야 합니다.

favorite_things = ["Ruby", "espresso", "candy"]

puts "A few of my favorite things:"

favorite_things.each do |thing|
  puts "I love #{thing}!"
end

>> A few of my favorite things:
>> I love Ruby!
>> I love espresso!
>> I love candy!


1-15. One-Liners
좋아! 기존 코드를 수정하여 새로운 지식을 적용할 시간입니다. 개조는 우리가 실제로 하는 것을 바꾸지 않고 우리의 코드의 구조나 외관을 개선하고 있다고 말하는 화려한 방법일 뿐이다.
이전 연습의 모든 구문을 다루지는 않겠지만, 요점을 짚어 보겠습니다. 준비됐나요

Hint action if boolean
1. 편집기의 내용을 코드 행 한줄로 수정합니다.

puts "One is less than two!" if true
>> One is less than two!


1-16. The Ternary Operator
three = 3
puts three == 3 ? "Of course." : "What?"
# ==> puts "Of course."
좋아! Ternary 연산자를 이용해서 우리의 암호를 좀 더 능률적으로 만들자.
위의 예는 구문 주의 사항에 불과합니다.

Hint
다음은 실제 사용 중인 원격 조작자의 다른 예입니다.
name = "Matz"
puts name == "Matz" ? "Hi Dad!" : "Who are you?"
>> Hi Dad!

1. 편집기의 문장을 수정하여 ternary연산자를 사용하여 올바른 문장을 작성합니다.

# 주어진 문장
if 1 < 2
  puts "One is less than two!"
else
  puts "One is not less than two."
end
>> One is less than two!

# 수정하여 만든 문장
puts 1 < 2 ? "One is less than two!" : "One is not less than two."
>> One is less than two!


1-17. In Case of Many Options (다양한 옵션의 경우)
훌륭합니다. 만약에 우리가 수정할 수 있는 것이 일반적인 것이 아니라, 
if/elsif/else 이면, 그 진술은 정말 좋게 깨끗할 수 있다!

1.편집기에서 가능하면 if/elsif/else 문을 수정하여 명확한 대 소문자를 구분합니다.

Hint
사례 설명을 구성하는 한가지 방법은 다음과 같습니다.
case variable
when value1 then #Do something!
when value2 then #Do something else!
...
when value9 then #Do another thing!
else
# Do the default thing!
end

#바꾸기 전
puts "What's your favorite language?"
language = gets.chomp

if language == "Ruby"
  puts "Ruby is great for web apps!"
elsif language == "Python"
  puts "Python is great for science."
elsif language == "JavaScript"
  puts "JavaScript makes websites awesome."
elsif language == "HTML"
  puts "HTML is what websites are made of!"
elsif language == "CSS"
  puts "CSS makes websites pretty."
else
  puts "I don't know that language!"
end

================================
#바꾼 후
puts "What's your favorite language?"
language = gets.chomp

case language
when "Ruby" then puts "Ruby is great for web apps!"
when "Python" then puts "Python is great for science."
when "JavaScript" then puts "JavaScript makes websites awesome."
when "HTML" then puts "HTML is what websites are made of!"
when "CSS" then puts "CSS makes websites pretty."
else
puts "I don't know that language!"
end


1-18. Conditional Assignment (조건부 할당)
완벽해! 그럼 이번에는 조건부 과제를 검토해 보겠습니다. 엄격한 편집 모드에서 잠시 벗어나 필기를 좀 더 할 수 있도록 하겠습니다.
1.favorite_animal이라는 변수를 만들고 조건에 따라 좋아하는 동물의 이름이 포함된 문자열을 할당합니다.

favorite_animal ||= "cat"


1-19. Implicit Return (암시적 반환)
다음으로, 우리의 코드에서 불필요한 반품을 제거함으로써 우리의 미친 방법을 단순화하자.

Hint
Ruby메서드는 자동으로 마지막으로 평가한 표현식의 값을 반환하므로 square 에 올바른 표현식을 넣으면 됩니다. 반환할 필요가 없습니다!
다음 중 하나를 입력하여 n의 제곱을 계산할 수 있습니다.
n * n
또는
n ** 2

1. 메서드 사용, 변수로 숫자를 사용하고 해당 숫자의 제곱을 암시적으로 반환하는 제곱 법을 작성합니다.
def square(num)
  num ** 2
end


1-20. 'For' Shame! (애석한 for)
좋아! 마지막으로, 편집자의 루프에 대해 확실히 알 수 없는 것을 해 봅시다.
10.times do
    puts "Knock knock." puts "Who's there?"
end


1. 마지막으로 for문을 대체하여 .times를 사용하여 루프를 사용하도록 합니다.

#바꾸기 전
for i in (1..3)
  puts "I'm a refactoring master!"
end


#바꾼 후
3.times do
  puts "I'm a refactoring master!"
end

둘다 출력 결과는 같음.
>> I'm a refactoring master!
>> I'm a refactoring master!
>> I'm a refactoring master!


2. The Refactor Factory

이 프로젝트에서는 프로그램의 가독성과 구조를 크게 개선하기 위해 단계별 리폼을 사용할 것이다.

2-1. What You'll Be Fixing (수정할 사항)
기존의 몇몇 코드를 수정하여 루비 베스트 프랙티스에 대한 지식을 강화하겠습니다. 위에서 언급한 바와 같이 리팩토링은 코드의 전반적인 동작을 수정하지 않고 코드의 구조, 모양 및/또는 성능을 개선하는 프로세스입니다.

편집기의 코드는 루비 메서드(first_n_primes)로, 번호 n을 입력하고 처음 n개의 주요 번호 목록을 생성합니다. 불행하게도, 우리의 가난한 작가는 루비에서 사용 가능한 모든 도구를 아직 다 익히지 못 했습니다. 하지만 우리는 그것을 고칠 수 있어요!

일을 시작하고 프로그램의 이 괴물을 다시 만들어 봅시다!

$VERBOSE = nil    #수업이 끝나면 이것을 설명하겠습니다. 
require 'prime'   #모듈입니다. 곧 처리할게요!

def first_n_primes(n)

  unless n.is_a? Integer
    return "n must be an integer."
  end

  if n <= 0
    return "n must be greater than 0."
  end
  
  prime_array = [] if prime_array.nil?
  
  prime = Prime.new
  for num in (1..n)
    prime_array.push(prime.next)
  end
  return prime_array
end

first_n_primes(10)


2-2. Omit  Needless Words (말 없이 생략)
글쓰기에 있어서 가장 일반적인 제안 중 하나는 불필요한 단어를 생략하는 것이고 루비가 쓰는 이야기에도 똑같이 적용됩니다.

여기에서는 두가지 제어 구조를 변경할 수 있습니다.
1. The unless on line 6
2. The if on line 10

Hint
진술의 형식이 다음과 같아야 합니다.
action if boolean
action unless boolean 
기억하세요, end는 필요 없다. 싱글 라인에 if 또는 unless를 사용하라.

1.편집기에서 코드를 수정하여 단일 행 가정 및 unless를 사용합니다.


바꾸기 전
require 'prime'   # This is a module. We'll cover these soon!

def first_n_primes(n)

  unless n.is_a? Integer
    return "n must be an integer."
  end

  if n <= 0
    return "n must be greater than 0."
  end

  return Prime.first n
end

first_n_primes(10)

바꾸기 후
require 'prime'   # This is a module. We'll cover these soon!

def first_n_primes(n)
    return "n must be an integer." unless n.is_a? Integer
    return "n must be greater than 0." if n <= 0
  
    return Prime.first n
end

puts first_n_primes(10)
>> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]


2-3. Less is More (적을수록 낮다)
잘했어! 이 코드가 이미 더 나아 보이네요.
하지만 우리는 훨씬 더 제거할 수 있다. 이 코드에는 명시적인 것에서 암시적인 것으로 변경할 수 있는 하나의 반환 문구가 있습니다!
루비는 마지막으로 평가한 표현식의 값을 자동으로 반환합니다.

힌트:마지막입니다!
처음 두개의 return 신고서가 필요합니다. 입력 값이 양의 숫자가 아니면 빨리 반환해야 할 수도 있습니다. 조기에 돌아오는 유일한 방법은 명시적인 회신 문구를 사용하는 것이다.

1.불필요한 return 키워드를 찾아 제거합니다.

require 'prime'   # This is a module. We'll cover these soon!

def first_n_primes(n)
  return "n must be an integer." unless n.is_a? Integer
  return "n must be greater than 0." unless n > 0
  Prime.first n
end

first_n_primes(10)


2-4. Nice Work!
훌륭하다! 당신은 정말로 그 코드를 향상시켰고, 그 모든 것이 루비 같은 노하우였습니다.
원하는 만큼 코드를 가지고 자유롭게 이동한 다음 실행을 클릭하여 이 프로젝트를 완료하십시오!
# 소수를 구하는 프로그램!
require 'prime'   # This is a module. We'll cover these soon! 

def first_n_primes(n) 
  return "n must be an integer." unless n.is_a? Integer 
  return "n must be greater than 0." unless n > 0 
  Prime.first n 
end 

first_n_primes(10)


8. Blocks, Procs, and Lambdas

1. Blocks, Procs, and Lambdas

이 과정에서는 루비 프로그래밍 언어의 가장 강력한 세가지 측면, 즉 블록, 프로커스, 람다에 대해 살펴보겠습니다.

1-1. You Know This!
우리는 Loops&Iterator 그리고 Method, Block&Sorting에서 블록에 대해 조금 배웠다. 우리는 앞서 한 블록이 이름 없는 방법과 같다고 말했지만, 그것은 사실이 아니다. (이 과의 후반부에서는 이름 없는 실제 방법인 람다 라고 하는 방법에 대해 알아보겠습니다.)
루비 블록은 실행할 수 있는 코드입니다. 블록 구문은 다음 중 하나를 사용합니다. do..end 또는 ( {} )
예)
[1, 2, 3].each do |num|
    puts num
end
# ==> Prints 1, 2, 3 on separate lines

[1, 2, 3].each { |num| puts num }
# ==> Prints 1, 2, 3 on separate lines
블록을 각각. .each 그리고 .times 결합하여 집합의 각 요소에 대한 명령을 실행할 수 있습니다(예:해시 또는 배열).

1.복습을 좀 합시다! "나는 블록이다!"라는 문자열을 다섯번 사용한다.

5.times {puts "I'm a block!"}
>> I'm a block!
>> I'm a block!
>> I'm a block!
>> I'm a block!
>> I'm a block!


1-2. Collect 'Em All
좋아! 블록을 떼어 내는 정말 유용한 루비 방법들이 많이 있습니다. 우리가 아직 다루지 않은 것은 수집이다.

수집(collect) 방법은 블록을 사용하고 블록의 표현식을 배열의 모든 요소에 적용합니다. 확인해 보십시오.
my_nums = [1, 2, 3]
my_nums.collect { |num| num ** 2 }
# ==> [1, 4, 9]
그러나 my_nums의 가치를 살펴보면 변하지 않았다는 것을 알 수 있습니다.
my_nums
# ==> [1, 2, 3]
collect를 사용하면 my_nums 복사본이 반환되지만 원래 my_nums 배열은 변경되지 않기 때문입니다. 

원본을 바꾸려면 느낌표와 함께 .collect! 를 사용할 수 있습니다.
my_nums.collect! { |num| num ** 2 }
# ==> [1, 4, 9]
my_nums
# ==> [1, 4, 9]
루비에서의 ! 는 "이 방법은 위험하거나 예기치 못한 일을 할 수 있다!"는 뜻을 상기하라. 이 경우에는 새로운 배열을 만드는 대신에 원래의 배열을 변형시킵니다.

1.우리는 배열과 거짓말을 만들었고 처음 10개의 피보나치 숫자를 거기에 넣었다.
새 변수인 duubled_fibs를 생성한 다음 file.collect 호출 결과와 동일하게 설정합니다. 당신이. 수집한 블록은 위의 예와 같이 각 피보 나찌의 수를 두배로 늘려야 한다.
배열의 최종 내용을 보려면 duubled_fibs를 넣습니다.

fibs = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

doubled_fibs = fibs.collect { |num| num * 2}

puts doubled_fibs
>> [2, 2, 4, 6, 10, 16, 26, 42, 68, 110]

# 번외
fibs.each { |key|  
  key = key * 2
  puts key
  }


1-3. Learning to Yield (양보 학습)
일부 방법은 블록을 허용하지만 다른 방법은 허용하지 않는 이유는 무엇입니까? 블록을 수용하는 방법은 통화 방법에서 블록으로 제어권을 다시 전송하고 다시 되돌리는 방법을 가지고 있기 때문입니다. 우리는 이것을 우리가 정의하는 방법으로 만들 수 있다.

편집기에서 코드를 확인합니다. 우리가 block_test방법에 있을 때와 블록에 있을 때 그것을 전달할 수 있도록 일련의 puts문을 설정했습니다. 실행을 클릭하여 결과를 확인하십시오!

def block_test
  puts "We're in the method!"
  puts "Yielding to the block..."
  yield
  puts "We're back in the method!"
end

block_test { puts ">>> We're in the block!" }

# 출력 결과 yield문에 들어간 출력문은 맨 마지막에 출력되는 모습을 보여주고 있다.
We're in the method!
Yielding to the block...
>>> We're in the block!
We're back in the method!


1-4. Yielding With Parameters
또한 매개 변수를 수율로 전달할 수도 있습니다! 편집자에게 예를 들어 보세요. 

1. yield_name 방법은 매개 변수, name 하나로 정의됩니다.
2. 9행에서, 우리는 yield_name 법을 호출하고 name 매개 변수에 대한 인수"Eric"을 제공한다. yield_name에 출력 문이 있으므로 블록도 제공해야 합니다.
3. 그 방법 안에, 2행에, 우리는 먼저 머리말을 출력합니다. 
4. 그리고 나서 우리는 그 블록에 yield 하고"Kim"을 패스한다. 
5. 이 블록에서, n은 이제"Kim"과 같고, 출력 결과로  "My name is Kim"을 내놓는다.
6. 다시 그 방법으로 출력한다. yield 사이에 
7. 그리고 나서 우리는 다시 한번 그 블록에 굴복한다. 이번에는 이름 매개 변수에 저장된 "Eric"을 전달합니다.
8. 이 블록에서, n은 이제"Eric"과 같아요. 그리고 우리는 "My name is Eric."
9. 마지막으로, 우리는 statement를 닫습니다.

Hint
당신의 코드는 9번 선의 코드와 동일하게 보여야 하며, 당신의 이름만 괄호 사이에 있어야 한다.

1.사용자의 이름을 매개 변수로 yield_name을(를)호출합니다. "내 이름은#{여기에 당신의 이름}!"이라는 블록을 꼭 통과해야 합니다.

def yield_name(name)
  puts "In the method! Let's yield."
  yield("Kim")
  puts "In between the yields!"
  yield(name)
  puts "Block complete! Back in the method."
end

yield_name("Eric") { |n| puts "My name is #{n}." }
puts "============================================"
yield_name("hahaXX") { |x| puts "My name is #{x}"} 

>> In the method! Let's yield.
>> My name is Kim.
>> In between the yields!
>> My name is Eric.
>> Block complete! Back in the method.
>> ============================================
>> In the method! Let's yield.
>> My name is Kim
>> In between the yields!
>> My name is hahaXX
>> Block complete! Back in the method.


1-5. Try It Yourself!
그렇죠?비록 이 블록 버스터 사업이 우리가 생각했던 것보다 더 큰 문제를 안고 있지만, 여전히 꽤 간단합니다.

방법이 수율 키워드를 사용하여 블록을 수용하는 방법을 알았으니 이제 자체 방법을 정의하고 블록을 전달해 봅시다!

Hint
코드는 다음과 같아야 합니다. (Your code should look something like this:)
def method_name(parameter)
    yield parameter
end

method_name(argument) { block }

1. 단일 파라미터를 허용하고 블록에 수율을 산출하는 방법을 정의합니다. 그런 다음 숫자 파라미터를 2로 곱하는 블록으로 호출합니다. 원하는 숫자를 두배로 늘릴 수 있어요!
여러분의 생산량이 활동하는 것을 보기 위해 결과를 보여 주세요!

def double(number)
  yield(number)
end

double(7) { |x| puts x *= 2}
>> 14


1-6. Keeping Your Code DRY (코드를 반복해서 사용하지 마세요)
루비의 물건이라고 했을 때 기억 나? 음, 우린 좀 속은 것 같아. 블록은 객체가 아니며 루비의 "모든 것은 객체"규칙에서 몇가지 예외 중 하나입니다.
이것 때문에 블록은 변수에 저장될 수 없고 실제 객체의 모든 힘과 능력을 가지고 있지 않습니다. 그러기 위해선... 프로스!
프로세스를 "저장된 "블록이라고 생각할 수 있습니다. 코드 이름을 지정하고 메서드로 변환하는 것처럼 블록 이름을 지정하여 proc으로 변환할 수 있습니다. 프로세스는 코드를 건조하게 유지하는 데 매우 유용합니다. 블록을 사용하면 필요할 때마다 코드를 작성해야 합니다. proc을 사용하면 코드를 한번 작성하여 여러번 사용할 수 있습니다.
Don't Repeat Yourself DRY
편집기에서 코드를 확인해 보세요. 프로스에요! 여러분은 그것이 무엇을 하는지 추측할 수 있나요? 알고 있다고 생각되면 실행을 클릭합니다.

multiples_of_3 = Proc.new do |n|
  n % 3 == 0
end

print (1..100).to_a.select(&multiples_of_3)
>> [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]


1-7. Proc Syntax
프로세스는 정의하기 쉽습니다! 프로세스. new에 전화해서 저장할 블록을 전달하면 된다. 다음은 숫자를 제곱하는 큐브라고 하는 프로세서를 만드는 방법입니다(세번째 전원으로 올림).
cube = Proc.new { |x| x ** 3 }
그러면 우리는 proc을 블록을 다른 블록을 사용할 수 있는 메서드로 전달할 수 있으며, 블록을 반복해서 다시 작성할 필요가 없습니다.
[1, 2, 3].collect!(&cube)
# ==> [1, 8, 27]
[4, 5, 6].map!(&cube)
# ==> [64, 125, 216]
(. collect! 와.map!은 정확히 같은 일을 한다.)
맵은 큐브 프로세서를 블록으로 변환하는 데 사용됩니다(.collect!그리고. map!보통 블록을 가져간다.).
&는 변환하는데 사용 됩니다. 여기선 cube를 블록으로 만든다. 우리는  proc을 블럭이 예상되는 방식으로 변환할 때마다 이 작업을 수행합니다.

1. 바닥 방법은 부동 소수 점 이하 숫자를 가장 가까운 정수로 반올림합니다. round_down이라는 프로세스를 작성하여 반올림합니다(floats.collect에 전달하기 위해 코드를 추가했습니다).

floats = [1.2, 3.45, 0.91, 7.727, 11.42, 482.911]

round_down = Proc.new { |x| x.floor }

ints = floats.collect(&round_down)
print ints
>> [1, 3, 0, 7, 11, 482]

# 설명 floats 라는 변수에 소수 값이 들어 있다.
round_down이라는 변수에 새로운 프로세서를 만들고 블록을 담는 곳을 만든다.
ints 라는 변수에 floats 변수를 컬렉트로 만들어 새로운 곳에다 round_down을 끌어다 쓴다.
그럼 실수 값을 .floor로 인해 부동 소수점 이하의 최대 정수 값을 반환하게 된다.


1-8. Why Procs?
왜 굳이 블록을 프로세스로 저장하려고 합니까? 다음과 같은 두가지 주요 이점이 있습니다.
1. 프로세스는 완전한 개체이므로 모든 개체의 기능과 능력을 가지고 있습니다. (블럭은 그렇지 않습니다.)
2. 블록과 달리 프로세스는 다시 작성하지 않고도 계속 호출될 수 있습니다. 따라서 특정 코드 비트를 실행해야 할 때마다 블록의 내용을 다시 입력할 필요가 없습니다.

1. 편집기에서 코드를 확인합니다. 이런, 우리는 그 블록을 여러번 다시 써야 했어! 블록을 제거하고 블록의 코드를 한번만 기록할 수 있도록 over_4_feet이라는 프로세서로 교체합니다.

# 여기 놀이 공원에서, 너는 키가 4피트가 되어야 한다.
# 롤러 코스터를 타기 위해#혹은 더 키가 크다. 사용합시다.
# 각 그룹은 키가 4피트 이상인 그룹만 가질 수 있다.

group_1 = [4.1, 5.5, 3.2, 3.3, 6.1, 3.9, 4.7]
group_2 = [7.0, 3.8, 6.2, 6.1, 4.4, 4.9, 3.0]
group_3 = [5.5, 5.1, 3.9, 4.3, 4.9, 3.2, 3.2]

over_4_feet = Proc.new {|height| height >= 4}

can_ride_1 = group_1.select(&over_4_feet)
can_ride_2 = group_2.select(&over_4_feet)
can_ride_3 = group_3.select(&over_4_feet)

puts can_ride_1
puts can_ride_2
puts can_ride_3

>> [4.1, 5.5, 6.1, 4.7]
>> [7.0, 6.2, 6.1, 4.4, 4.9]
>> [5.5, 5.1, 4.3, 4.9]


1-9. Create Your Own!
좋아!연습용 바퀴를 뗄 시간이야.
cube = Proc.new { |x| x ** 3 }
[1, 2, 3].map(&cube)
# [1, 8, 27]

여러분만의 프로세스를 만들 수 있습니다. 우리는 이것을 두 단계로 나눌 것이다. 위의 예제를 구문 미리 알림으로 사용하십시오.

Hint
yield 방법은 다음과 같아야 합니다.
def method_name
    yield
end
프로세스는 다음과 같아야 합니다.
proc_name = Proc.new do
      puts "Text"
end

1. 인수를 사용하지 않고 블록에 산출되는 메서드, Greeter를 만듭니다.
"Hello!"를 표시하는 Proc, 구문을 작성합니다. 이것을 블록 대신 그린 터에 넘겨라. (문구 대신에 문구를 쓰는 것을 잊지 마세요!)

def greeter
  yield
end

phrase = Proc.new { puts "Hello there!"}

greeter(&phrase)

>> Hello there!


1-10. Call Me Maybe
잘 만들었다! proc을 method로 호출하는 것은 그리 까다롭지 않다. 하지만, 훨씬 더 쉬운 방법이 있습니다.
블록과 달리 루비의 통화 방식으로 직접 프로스를 호출할 수 있습니다. 한번 보세요!

test = Proc.new { # does something }
test.call # does that something!

루비에는 항상 여러가지 방법이 있습니다.


1. 계속해서 hell이라고 불리는 proc을 만들어"Hello!"를 입력한 다음, 호출하십시오!

hi = Proc.new { puts "Hello!" } 

hi.call

> Hello!


1-11. Symbols,  Meet Procs (기호 프로세스 충족)
루비 언어의 좀 더 복잡한 부분들을 배우고 있으니, 그것들을 결합하여 정말 신비로운 마법을 부릴 수 있습니다. 예를 들어, 루비 메서드 이름을 기호와 함께 전달할 수 있다고 했을 때 기억 나세요? 음, 당신은 또한 그 편리한 작은 것을 이용하여 상징을 프로세스로 변환할 수 있습니다.

strings = ["1", "2", "3"]
nums = strings.map(&:to_i)
# ==> [1, 2, 3]

모든 문자열 요소에 대해 매핑 &:to_i 를 통해 우리는 각 문자열을 정수로 변환했습니다.

Hint
당신의 코드는 예시와 똑같이 보여야 하며, 단지 그것이 단지 &:to_s 대신에 &:to_i를 호출해야 한다.

1. 지침서의 예제를 가이드로 사용하여 수집 또는 매핑을 사용하여 number_array에서 strings_array를 만듭니다. strings_array의 각 요소는 number_array의 해당 요소의 문자열 버전이어야 합니다(즉,["1","2","3"..."). "10"]).

numbers_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

strings_array = numbers_array.map(&:to_s)

puts strings_array

>> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]


1-12. The Ruby Lambda
procs와 마찬가지로 lambda는 객체이다. 유사점들은 거기서 끝나지 않습니다. 약간의 구문과 몇가지 행동적인 실마리를 제외하면, Lambda는 Proc와 같습니다.

편집기에서 코드를 확인해 보세요. 람다 비트가 보입니까? 타이핑을 치는 건 너무 쉬워요.
lambda { puts "Hello!" }
거의 같다
Proc.new { puts "Hello!" }
오른쪽 예에서 람다를 lambda_demo로 전달하면 람다가 호출되고 람다 코드가 실행됩니다.

이제 블록과 프로세스가 어떻게 작동하는지 알았으니 람다가 콘솔에 어떤 영향을 미칠지 추측할 수 있습니다. 의심스러운 내용을 확인하려면[실행]을 클릭하십시오.

def lambda_demo(a_lambda)
  puts "I'm the method!"
  a_lambda.call
end

lambda_demo(lambda { puts "I'm the lambda!" })
>>  I'm the method!
>> I'm the lambda!


1-13. Lambda Syntax
Lambdas는 다음 구문을 사용하여 정의됩니다.
lambda { |param| block }
lambda는 proc를 사용하는 것과 같은 상황에서 유용하다. 다음 연습에서는 Lambda와 procs의 차이를 다룰 것이다. 그 동안 람다 구문을 사용하여 약간의 연습을 해 보자.

Hint
.to_sys또는. 인턴을 사용하여 문자열을 기호로 변환할 수 있습니다.
코드는 다음과 같아야 합니다.
symbolize = lambda { |x| x.magic! }
여기서 x.magic!는 배열의 각 요소를 기호로 변환하는 곳입니다.

1. 편집자에게 줄 수 있는 문자열이 있는데, 상징이 여러개 필요합니다.
4라인 에서 상징이라고 불리는 새로운 변수를 만들어 내세요. 기호에서 매개 변수 하나를 사용하여 해당 매개 변수에. to_sym을 호출하는 람다를 저장합니다.
그리고 나서 우리는. collect방법으로 문자열에 있는 항목을 기호로 변환하기 위해 심볼을 사용한다!

strings = ["leonardo", "donatello", "raphael", "michaelangelo"]

symbolize = lambda {|x| x.to_sym}

symbols = strings.collect(&symbolize)
print symbols

>> [:leonardo, :donatello, :raphael, :michaelangelo]


1-14. Lambdas vs. Procs
만약 여러분이 프로스와 람브다가 매우 비슷하게 생겼다고 생각한다면, 그것은 그들이 그렇기 때문이다! 오직 두가지의 주요 차이점이 있다.
먼저 람다는 람다에 전달되는 인수 수를 확인하는 반면 프로세서는 확인하지 않습니다. 즉, 람다가 잘못된 인수를 통과하면 오류가 발생하는 반면, proc은 예기치 않은 인수를 무시하고 누락된 인수에 0을 할당합니다.
둘째, 람다가 반환되면 제어를 호출 방법으로 전달하고, proc이 반환되면 호출 방법으로 돌아가지 않고 즉시 제어를 수행합니다.
어떻게 작동하는지 보려면 편집기의 코드를 살펴보십시오. 우리의 첫번째 방법은 proc, 두번째 방법은 람다라고 합니다.

실행을 클릭하여 반환 값을 확인하십시오. proc이 배트맨이 이길 것이라고 말하는 것을 봤나요? 이것은 batman_ironman_proc메서드로 돌아가지 않고 즉시 반환되기 때문입니다.
그러나 람다는 호출된 후에 메서드로 돌아가므로 이 방법은 마지막으로 평가한 코드를 반환합니다."아이언 맨이 이길 것입니다.

def batman_ironman_proc
  victor = Proc.new { return "Batman will win!" }
  victor.call
  "Iron Man will win!1"
end

puts batman_ironman_proc

def batman_ironman_lambda
  victor = lambda { return "Batman will win!" }
  victor.call
  "Iron Man will win!2"
end

puts batman_ironman_lambda
>> Batman will win!
>> Iron Man will win!2


1-15. Now You Try!
잘했어! 너는 너 자신의 람다를 적었고 어떻게 그것을 방법으로 전달하는지 보았다. 이제 람다를 작성하여 방법으로 전달해야 합니다!
만약 당신이 이것이 당신이 이미 프로스를 가지고 했던 것과 많이 비슷할 것이라고 생각한다면, 당신이 정확하게 옳다. procs과 마찬가지로, 메서드로 전달할 때 람다 이름의 시작 부분에 & 를 넣어야 합니다. 왜냐하면 람다가 람다를 메서드에서 예상하는 블록으로 변환하기 때문입니다.
람다의 상징은 꽤 시원했다. 어레이의 각 요소가 기호인지 확인하는 람다로 이 값을 조정합니다. .is_a?메서드를 사용하여 이 확인을 수행할 수 있습니다. 이 방법은 개체가 이름이 지정된 개체 유형이면 true이고 그렇지 않으면 false이면 반환됩니다.
:hello.is_a? Symbol
# ==> true
.is_a?확인하려면 기호가 대문자로 표시되어야 합니다!

1. 람다(symbol_filter)를 생성하여 매개 변수 하나를 사용하고 해당 매개 변수가 .is_a?기호인지 확인합니다.
기호라는 새 변수를 생성하고 my_array를 호출한 결과를 저장합니다.람다 값을 선택하여 전달합니다.
파일 끝에 기호를 넣어 배열의 최종 내용을 확인합니다.

my_array = ["raindrops", :kettles, "whiskers", :mittens, :packages]


symbol_filter = lambda {|x| x.is_a? Symbol}

symbols = my_array.select(&symbol_filter)

puts symbols
>> [:kettles, :mittens, :packages]


1-16. Quick Review
이 모든 블록, 프로스 그리고 람바다에 대한 이야기들은 당신의 머리를 회전시킬지도 모른다. 잠시 시간을 내어 각각에 대해 정확히 설명해 보겠습니다.
1. 블록은 단지 도 사이의 코드를 말한다. do..end or {}. 그것은 그 자체로는 물건이 아니지만, .each 또는 .select 같은 방법으로 전달될 수 있습니다.
2. proc은 반복해서 사용할 수 있는 저장된 블록입니다.
3. 람다는 프로세서와 같으며, 단지 인수되는 인수 개수에만 신경을 쓰고 즉시 반환하지 않고 호출 방법으로 돌아갑니다.
블록, 프로세스 및 Lambda가 유사한 작업을 수행할 수 있는 경우는 많지만 프로그램의 정확한 상황은 사용할 항목을 결정하는 데 도움이 됩니다.

이해했어? 좋습니다!준비가 되었으면 다음을 클릭하여 최종 검토 섹션을 시작하십시오.


1-17. Been Around the Block a Few Times
이 시점에서 당신은 루비 블록 마스터입니다. 이것은 꽤 쉬워야 해요!

Hint
ints = odds_n_ends.select { block }

1. 대기 열은 모든 종류의 개체로 가득 차 있지만 정수(10진수 비트가 없는 숫자)만 원합니다.
새 변수 ints를 만들고 요소가 is._a?정수인지 확인하는 블록을 사용하여 idds_n_ends.selected메서드를 호출한 결과를 저장합니다.
파일 끝에 점을 배치하여 배열의 최종 내용을 확인합니다.

odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]

ints = odds_n_ends.select { |x| x.is_a? Integer}

puts ints
>> [42, 3, 19]


1-18. Creating a Proc
이제 프로세스를 살펴보겠습니다. 첫번째 단계:새로 만들기!

Hint
my_proc = Proc.new { # block }
또는
my_proc = Proc.new do
    # block
end

1.Under_100이라는 프로세스를 생성하여 번호가 100미만인지 확인합니다. 아직 준비되지 않았습니다.)

# 첫 번째 방법
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]

under_100 = Proc.new { |x| x < 100 }

puts ages.select(&under_100)

>> [23, 7, 11, 94, 70, 44]

# 두 번째 방법
ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]

under_100 = Proc.new do |x|
  x < 100
end

puts ages.select(&under_100)
>> [23, 7, 11, 94, 70, 44]


1-19. Passing Your Proc to a Method (메서드로 프로세스 전달)
완벽해! 이제 우리의 프로세스를 하나의 방법으로 전달해 봅시다.

Hint
구문은 다음과 같아야 합니다.
youngsters = ages.select(&your_proc)

1. 이제 연령층을 사용하게 됩니다. young이라고 하는 변수를 생성하여 호출과 동일하게 설정합니다. age를 선택하고 under_100proc을 전달하여 100미만의 시간을 필터링 합니다. 프로세서를 블록으로 변환하려면_100을(를)패스해야 합니다!
마지막 내용을 보기 위해 젊은이들을 파일의 끝에 둔다.

ages = [23, 101, 7, 104, 11, 94, 100, 121, 101, 70, 44]

under_100 = Proc.new { |x| x < 100 }

youngsters = ages.select(&under_100)

puts youngsters
>> [23, 7, 11, 94, 70, 44]


1-20. Creating a Lambda
2절:1절과 같음! 어서 람다를 만들자.

Hint 구문은 다음과 같아야 합니다.
my_lambda = lambda { |k,v| # code }
또는
my_lambda = lambda do |k,v|
   # code 
end
여기서#코드는 해시 값이<"M"인지 확인하는 비트입니다.

1. 해시 값이 "M"보다 작은지(초기 알파벳에서)확인하는 첫번째_절반 람다를 만듭니다. 대문자 M은 꼭 사용해야 합니다. 그것은 해시를 체크하는 것이기 때문에, 당신의 람다는 단지 가치|대신|키, 가치|를 포함해야 합니다.

crew = {
  captain: "Picard",
  first_officer: "Riker",
  lt_cdr: "Data",
  lt: "Worf",
  ensign: "Ro",
  counselor: "Troi",
  chief_engineer: "LaForge",
  doctor: "Crusher"
}

first_half = lambda { |h,v| v < "M" }


1-21. Passing Your Lambda to a Method (메소드에 람다 전달)
스트레칭! 이제 람다도 방법으로 전달해 보자.

1. 마지막으로, a_to_m라는 변수를 생성하고 호출과 동일하게 설정한 다음, first_half람다를 입력하여"M"이전 이름을 필터링 합니다.내기. 람다를 블록으로 전환하려면 먼저 통과해야 한다는 것을 기억하세요!
어레이의 최종 내용을 보려면 a_to_m를 파일 끝에 배치합니다.

crew = {
  captain: "Picard",
  first_officer: "Riker",
  lt_cdr: "Data",
  lt: "Worf",
  ensign: "Ro",
  counselor: "Troi",
  chief_engineer: "LaForge",
  doctor: "Crusher"
}

first_half = lambda { |h,v| v < "M" }

a_to_m = crew.select(&first_half)

puts a_to_m
>> {:lt_cdr=>"Data", :chief_engineer=>"LaForge", :doctor=>"Crusher"}


9. Object-Oriented Programming. Part l

1. Object-Oriented Programming l

루비는 객체 지향 언어입니다. 이 과정에서는 객체, 클래스 및 프로그램에서 정보와 동작을 구성하는 데 사용되는 방법에 대해 설명합니다.

1-1. Why Classes? 
루비는 객체 지향 프로그래밍 언어로, 객체라 불리는 프로그래밍 구조를 조정한다는 뜻입니다. 루비의 모든 것은 물건이야! 당신은 그것들을 줄곧 사용해 왔기 때문에 그것들은 매우 친숙할 것이다. 개체에는 이전에 보았던 방법과 속성이 있습니다.
"Matz".length # ==> 4
예를 들어"Matz"개체는 길이가. length method이고 길이 속성이 4인 문자열이다. 다음 몇가지 실습에서는 고유한 방법과 내부 변수를 사용하여 개체를 만드는 방법에 대해 알아보겠습니다.
하지만"마츠"가 줄을 이루는 것은 정확히 무엇일까요? 문자열 클래스의 한 인스턴스라는 사실입니다. 클래스는 유사한 특성과 방법을 가진 객체를 구성하고 생산하는 방법일 뿐입니다.

오른쪽에 있는 편집기에서 코드를 확인하세요. 우리는 우리의 클래스, 언어를 정의하고 루비, 파이썬 및 자바 스크립트 인스턴스를 생성했습니다. 어떻게 작동하는지 보려면 코드를 실행하십시오!
이제 여러분만의 클래스와 객체를 만들기 시작할 준비가 되었으면 다음 단계로 넘어가십시오.

class Language
  def initialize(name, creator)
    @name = name
    @creator = creator
  end

  def description
    puts "I'm #{@name} and I was created by #{@creator}!"
  end
end

ruby = Language.new("Ruby", "Yukihiro Matsumoto")
python = Language.new("Python", "Guido van Rossum")
javascript = Language.new("JavaScript", "Brendan Eich")

ruby.description
python.description
javascript.description
>> I'm Ruby and I was created by Yukihiro Matsumoto!
>> I'm Python and I was created by Guido van Rossum!
>> I'm JavaScript and I was created by Brendan Eich!


1-2. Class Syntax
기본 클래스는 클래스 키워드와 클래스 이름으로만 구성됩니다. 확인해 보십시오.
class NewClass
    # Class magic here
end
NewClass는 새로운 루비 객체 클래스를 만들 수 있습니다. 규칙에 따라 클래스 이름은 대문자로 시작하고 relying_on_underscores대신 CamelCase를 사용합니다.

1. 편집기에서[사용자]라는 클래스를 만듭니다. 아직은 class와 end만 만들어라.

class Person
  
end


1-3. Classing It Up
우리는 우리의 수업이... 음, 아무것도 없어요. 그래서 우리 반의 사람과 끝 사이에 암호를 추가해야 해요.

여러분은 우리의 첫번째 연습에서 우리가 초기화라고 불리는 방법으로 클래스 정의를 시작했다는 것을 알 수 있습니다. 초기화는 클래스에서 생성하는 각 객체를 "부팅" 하는 기능으로 간주할 수 있습니다.

Hint
Person 클래스에는 초기화 방법이 포함되어야 합니다.
def initialize end

1. 계속해서 사용자 클래스에 대한 초기화 방법을 정의하십시오. 아직까지 방법론자들에게 아무것도 넣을 필요가 없다.

class Person
  def initialize
    
  end
end


1-4. What's in a @name?
좋아! 사용자 클래스에서 사용자를 만들기 전에 한 단계만 더 진행하십시오. 각 사용자가@이름을 가지고 있는지 확인해야 합니다.

루비에서는 인스턴스(instance)변수임을 나타내기 위해 변수 앞에@를 사용합니다. 이는 변수가 클래스의 인스턴스에 연결됨을 의미합니다.

class Car
    def initialize(make, model)
      @make = make
      @model = model
      end
end
kitt = Car.new("Pontiac", "Trans Am")

위의 예에서 코드는 클래스 Car의 kitt인스턴스를 생성합니다. kitt는 자체@제조사("Pontiac")와@모델("Trans암")을 가지고 있습니다. 이러한 변수는 kitt인스턴스(instance)에 속하며, 이를 인스턴스(instance)변수라고 합니다.

다음 몇가지 연습에서는 다른 종류의 변수(예:전체 클래스에 첨부된 변수)를 다룰 것입니다.

Hint
매개 변수와 인스턴스 변수를 정확하게 유지하는 것은 까다로운 일일 수 있습니다. 그래서 여기 프리 빈 이 있습니다. 초기화 방법은 다음과 같아야 합니다.

def initialize(name)
    @name = name
end

1. 초기화 방법에 단일 매개 변수 이름을 지정합니다. 메서드의 본문에서@name=name을 설정합니다.


이것은 루비가 사람을 만들 때마다 이름을 가지고 있어야 한다는 것을 알려 줍니다. 그러면 각각의 사람들은 자신의@이름을 가지게 될 것입니다.

class Person
  def initialize(name)
    @name = name
  end
end


1-5. Instantiating Your First Object (첫번째 개체 인스턴스화)
완벽해! 이제 객체를 생성할 준비가 되었습니다.

클래스 이름에 .new를 호출하여 클래스의 인스턴스를 만들 수 있습니다.
me = Person.new("Eric")

1. 변수 Matz를 생성하고 이를 호출과 동일하게 설정하십시오. 새로운 사용자 클래스. 새로운 이름인 유키히로를 유일한 인수로 붙인다.

class Person
  def initialize(name)
    @name = name
  end
end

matz = Person.new("Yukihiro")


1-6. Scope it Out (범위 설정)
루비 강의 또 다른 중요한 측면은 스코프입니다. 변수의 범위는 프로그램에 표시되는 컨텍스트입니다.

루비 프로그램의 모든 부분에서 모든 변수에 액세스 할 수 있는 것은 아니라는 사실을 알면 놀라실 겁니다. 클래스를 처리할 때는 전역(전역 변수), 특정 메서드 내에서만 사용할 수 있는 변수(로컬 변수)및 의 멤버인 변수를 사용할 수 있습니다. 특정 클래스(클래스 변수)및 클래스의 특정 인스턴스(인스턴스 변수)에만 사용할 수 있는 변수입니다.

방법에서도 마찬가지입니다. 일부는 어디에서나 사용할 수 있고 일부는 특정 클래스의 멤버만 사용할 수 있으며 일부는 특정 인스턴스 개체에만 사용할 수 있습니다.

$ ← 전역 변수(global variables) : 클래스를 처리할 때는 어디에서나 사용할 수 있는 변수 
지역 변수(local variables) : 특정 메서드 내에서만 사용할 수 있는 변수
@@ ← 클래스 변수(class variables) : 특정 클래스에서 사용할 수 있는 변수
@ ← 인스턴스 변수(instance variables) :  특정 인스턴스(인스턴스 변수)에만 사용할 수 있는 변수

편집기에서 코드를 확인해 보세요. 일부 변수는$,@또는@start @ @로 시작합니다. 이렇게 하면 전역, 인스턴스(instance)및 클래스 변수(각각)로 표시됩니다. 다음 섹션에서 설명하겠습니다. 이러한 다양한 변수의 작동 방식을 확인하려면 코드를 실행하십시오!

class Computer
  $manufacturer = "Mango Computer, Inc."
  @@files = {hello: "Hello, world!"}
  
  def initialize(username, password)
    @username = username
    @password = password
  end
  
  def current_user
    @username
  end
  
  def self.display_files
    @@files
  end
end

#새 컴퓨터 인스턴스 만들기
hal = Computer.new("Dave", 12345)

puts "Current user: #{hal.current_user}"
#@사용자 이름은 hal인스턴스에 속합니다.

puts "Manufacturer: #{$manufacturer}"
#$제조 업체는 세계적인 기업입니다! 우리는 그것을 직접 얻을 수 있다.

puts "Files: #{Computer.display_files}"
#@ . 파일은 컴퓨터 클래스에 속합니다.


1-7. Naming Your Variables (변수 이름 지정)
인스턴스 변수는@로 시작합니다. 이건 그냥 루비(Ruby)의 개념이 아니에요. 이건 구문의 일부예요! 항상@를 사용하여 인스턴스 변수를 시작하십시오.

클래스 변수는 인스턴스 변수와 같지만 클래스의 인스턴스에 속하는 대신 클래스 자체에 속합니다. 클래스 변수는 항상 @@로 시작합니다.

글로벌 변수는 두가지 방법으로 선언할 수 있습니다. 첫번째는 이미 익숙한 것입니다. 어떤 방법이나 클래스에 상관 없이 변수를 정의하면 됩니다. 글로벌 합니다. 메소드나 클래스 안에서 변수를 글로벌 하게 만들려면 $ 같은 것으로 시작하면 됩니다.

잠시 후 인스턴스(instance)와 클래스 변수를 더 자세히 살펴보겠습니다. 먼저, 지역 및 글로벌 범위에 대해 간단히 검토해 보겠습니다.

Hint
다음 두가지 중 하나를 수행할 수 있습니다.
1. my_variable을 클래스에서 글로벌 범위로 이동하거나
2. my_variable맨 앞에$를 붙여 놓으면 글로벌화됩니다. 두 변수를 모두 업데이트해야 합니다.

1. 오른쪽에 있는 코드를 보세요. my_variable변수가 클래스 안에 있으므로 해당 변수 외부의 puts메서드로 연결할 수 없습니다. 하지만 당신은 이것을 고칠 수 있어요! 위에서 언급한 두가지 글로벌 변수 방법 중 하나를 사용합니다.

도움이 더 필요하면 힌트를 확인하세요.

원형
class MyClass
  my_variable = "Hello!"
end

puts my_variable

방법 1) 아예 모든 곳에서 사용할 수 있게 변수를 빼둠.
my_variable = "Hello!"
class MyClass
  
end

puts my_variable

방법 2) 전역 변수로 만듬.
class MyClass
  $my_variable = "Hello!"
end

puts $my_variable


1-8. For Instance... (인스턴스의 경우)
좋아요! 하지만 주의 사항 하나는 프로그램의 어느 곳에서든 글로벌 변수가 변경될 수 있다는 것이고, 일반적으로 좋은 생각은 아닙니다. 일부 위치에서만 변경할 수 있는 범위가 제한된 변수를 생성하는 것이 훨씬 좋습니다!

예를 들어 인스턴스 변수는 특정 개체(또는"인스턴스")에 속합니다. 인스턴스(instance)변수에 대해 연습해 봅시다! 전부터 편집자에게 개인 수업을 추가했습니다.

Hint
이름(매개 변수)과@n을 사용한 것처럼, 초기화 본문에 나이와 직업을 초기화하고 동일하게 설정하기 위한 매개 변수로 연령과 직업을 포함해야 한다.ame(인스턴스 변수).

1. 초기화 방법에 연령 및 직업 매개 변수를 추가한 다음 이 변수를 방법 본문에 인스턴스(instance)변수와 동일하게 설정합니다. name@name(이름)예제를 참조하십시오.

class Person
  def initialize(name, age, profession)  
    @name = name
    @age = age
    @profession = profession
  end
end


1-9. Twice the @,Twice as Classy (@의 2배, Classy의 2배)
두개의@기호로 변수 이름을 시작하여 클래스 변수를 만들 수 있습니다. 클래스 변수는 클래스의 인스턴스가 아니라 전체 클래스에 연결됩니다.
class MyClass
    @@class_variable
end
클래스의 모든 인스턴스가 공유하는 클래스 변수의 복사본이 하나만 있기 때문에 멋진 루비 기술을 실행하는 데 사용할 수 있습니다. 예를 들어 클래스 변수를 사용하여 생성한 클래스의 인스턴스 수를 추적할 수 있습니다. 지금 하자!

Hint
첫번째 단계를 위해, @ . people_count변수를 선언하고 이를 0으로 설정하기만 하면 됩니다.

두번째 단계에서는 이 단계에 하나를 추가하여 @@people_count만 증가 하면 됩니다. 우리는
@@people_count += 1
마지막 단계에서는 @@people_account를 반환하기만 하면 됩니다. 루비는 암시적으로 반환할 수 있으니 원한다면 간단히 @@people_count을 입력하세요!

1. 세가지를 해 봅시다.

3번 라인에서 @@people_count를 0으로 설정
8번 라인에 @@people_count  추가
13번 라인에서 @@people_count 반환

class Person
  
  @@people_count = 0
  
  def initialize(name)  # 2. matz와 dhh가 여기에 값이 입력된다.
    @name = name
    @@people_count += 1  # 3. 입력이 되면 people_count 변수가 하나씩 증가한다.
  end
  
  def self.number_of_instances
    return @@people_count  # 4. 카운터 값을 리턴하여 반환한다.
  end
end

matz = Person.new("Yukihiro")   # 1. 얘네를 Person이라는 클래스에 값을 준다.
dhh = Person.new("David")

puts "Number of Person instances: #{Person.number_of_instances}"  # 출력 값 나옴.
>> Number of Person instances: 2


1-10. Classes Are Serious Business (수업은 진지한 비즈니스 입니다)
언어와 사람과 같은 클래스는 클래스와 인스턴스의 개념을 배우기 시작할 때 좋습니다.

그러나 클래스와 객체는 종종 실제 객체를 모형화하는 데 사용됩니다. 편집기의 코드는 상용 소프트웨어에서 찾을 수 있는 클래스와 객체의 종류를 좀 더 사실적으로 보여 줍니다. 여기 Rails소스 코드 조각이 있습니다. 기록/무효 클래스의 인스턴스를 만드는 방법을 보시겠습니까?

구문의 대부분은 친숙해 보일 것입니다. 사용자가 잘못된 레코드를 만들거나 저장하려고 하면 상승 비트(향후 학습에서 다룰 예정)에서 새로운 레코드/ 잘못된 레코드가 생성됩니다.

계속하려면 실행을 클릭하십시오!

def create_record(attributes, raise_error = false)
  record = build_record(attributes)
  yield(record) if block_given?
  saved = record.save
  set_new_record(record)
  raise RecordInvalid.new(record) if !saved && raise_error
  record
end


1-11. Watch Your Step (발걸음 조심 하십시오)
상속은 까다로운 개념이므로 단계적으로 살펴보겠습니다.

상속은 한 클래스가 다른 클래스의 특성과 방법을 취하는 프로세스이며, is-a관계를 표현하는 데 사용됩니다. 예를 들어, 만화 속 여우는 만화 속 포유류이다. 그래서 CartoonPox클래스는 CartoonMammal클래스로부터 물려받을 수 있다.

하지만 마법사는 엘프가 아니므로, 엘프급에서 상속 받아서는 안 된다. 대신에, 마법사와 엘프는 결국 동일한 MagicalBeing 클래스에서 상속 받을 수 있다.

편집기에서 코드를 확인해 보세요. ApplicationError라는 클래스와 ApplicationError에서 상속되는 SuperBadError 클래스를 정의했습니다. SuperBadError본문에 display_error메서드를 정의하지는 않지만 상속을 통해 해당 메서드에 액세스 할 수 있습니다. 직접 확인하려면 Run(실행)을 클릭하십시오.

class ApplicationError
  def display_error
    puts "Error! Error!"
  end
end

class SuperBadError < ApplicationError
end

err = SuperBadError.new
err.display_error


1-12. Inheritance Syntax (상속 구문)
루비에서는 상속이 다음과 같이 작동합니다.
class DerivedClass < BaseClass
     # Some stuff!
end
파생 클래스는 사용자가 만드는 새 클래스이고 기본 클래스는 새 클래스가 상속하는 클래스입니다. "<" 으로 이어받을 수 있습니다.

Hint
기억하세요, 빈 클래스 구문은
class ClassName
end

1. 오른쪽 편집기에 애플리케이션 클래스를 생성했습니다. 응용 프로그램에서 상속되는 고유 클래스 MyApp을 만듭니다. 아직은 수업 내용에 아무것도 넣을 필요가 없어요!

class Application
  def initialize(name)
    @name = name
  end
end


class MyApp < Application
end


1-13. Override!
경우에 따라 상속되는 클래스 중 하나가 상위 클래스의 메서드 및 속성을 상속할 뿐만 아니라 하나 이상의 클래스를 재정의할 수도 있습니다.

예를 들어 메시지에서 상속되는 이메일 클래스가 있을 수 있습니다. 두 클래스 모두 전송하는 보내기 방법이 있을 수 있지만, 전자 메일 버전은 유효한 전자 메일 주소를 식별하고 메시지에 대해 알 수 없는 여러 전자 메일 프로토콜을 사용해야 합니다. 파생 클래스에 send_mail메서드를 추가하고 절대 사용하지 않을 전송 방법을 상속하는 대신 이메일 클래스에 전송 방법을 명시적으로 생성하여 모든 email를 수행할 수 있습니다.

이 새 버전의 보내기는 전자 메일 인스턴스인 모든 개체의 상속된 버전을 재정의합니다(즉, 대체).

Hint
puts를 입력하지 말고 return 하라.

1. 좀 더 재미 있는 예를 들어 보자 Creature로부터 상속 받은 새로운 클래스 Dragon을 만듭니다. 여러분의 파생된 학생들에게 창조를 무시하는 싸움 방법을 주세요;"펀치를 휘두르는 것!"대신에, 그것은 "불을 다스리는 것!"을 되돌려야 합니다.

class Creature
  def initialize(name)
    @name = name
  end
  
  def fight
    return "Punch to the chops!"
  end
end


class Dragon < Creature
  def fight
    return "Breathes fire!"    # 재정의 하여 사용.
  end
end


1-14. When Good isn't Good Enough (좋은 것이 충분하지 않을 때)
반면 파생 클래스(또는 하위 클래스)를 사용하여 작업할 때 해당 클래스의 기본 클래스(상위 또는 하위 클래스라고도 함)에 정의된 메서드 또는 속성을 덮어쓴 경우가 있습니다.정말 필요한 거야 아무 걱정 마십시오! 루비의 내장 수퍼 키워드를 사용하여 슈퍼 클래스의 속성이나 메서드에 직접 액세스 할 수 있습니다.

구문은 다음과 같습니다.
class DerivedClass < Base
    def some_method
      super(optional args)
          # Some stuff
      end
    end
end
메소드 안에서 수퍼에 전화하면 루비가 현재 클래스의 슈퍼 클래스를 보고수퍼 클래스라고 불리는 것과 같은 이름의 메소드를 찾습니다. 발견되면 루비가 슈퍼 클래스 버전을 사용하게 됩니다.

Hint 코드는 다음과 같아야 합니다.
def fight
    puts "Instead of breathing fire..."
    super
end

1. 우리는 결국 속임수를 쓰기로 결정했습니다! 두가지를 해 봅시다.

불을 숨쉬는 것 대신에 " 넣는 것...용의 싸움 방법의 첫번째 줄로.
드래곤의 싸움의 정의 안에 있는 복귀 문장을 슈퍼 단어로 바꾸어라. (창조론의 싸움 방법은 필요 없기 때문에 슈퍼에게 어떤 논쟁도 넘길 필요가 없다.)

class Creature
  def initialize(name)
    @name = name
  end
  
  def fight
    return "Punch to the chops!"
  end
end


class Dragon < Creature
  def fight
    puts "Instead of breathing fire..."
    super
  end
end


1-15. There Can Be Only One!
주어진 루비 클래스는 모두 슈퍼 클래스를 하나만 가질 수 있습니다. 일부 언어는 클래스에 다중 상속이라는 모델인 둘 이상의 부모를 가질 수 있도록 허용합니다. 이것은 정말로 추하게 될 수 있습니다. 그래서 루비는 그것을 허락하지 않습니다.
그러나 여러 클래스의 데이터나 동작을 단일 클래스로 통합하려는 경우가 있으며, Ruby는 Mixin을 사용하도록 허용합니다. 우리는 다음 수업에서 mixins에 대해 배울 거예요! 지금은 루비에서 다중 상속을 시도하면 어떻게 되는지 보여 드리겠습니다.
지금 보여 드릴 데모 코드에는 멋진 트릭이 포함되어 있습니다. 새로운 줄을 사용하지 않고 루비 문을 닫으려면 세미 콜론을 입력하면 됩니다. 이것은 당신이 다음과 같은 것을 쓸 수 있다는 것을 의미한다.
class Monkey
end
단 한줄로. class Monkey; end 이것은 빈 클래스 또는 메서드 정의와 같이 매우 짧은 항목을 쓸 때 시간을 절약하는 기능입니다.

편집기에서 코드를 확인해 보세요. 우리가 드래곤을 Creature와 Person으로부터 물려받으려고 하는 거 보여? 드래곤 클래스 오류에 대한 슈퍼 클래스 불일치가 발생합니다. 직접 확인하려면 코드를 실행하십시오!

class Creature
  def initialize(name)
    @name = name
  end
end

class Person
  def initialize(name)
    @name = name
  end
end

class Dragon < Creature; end        # 루비의 모든 클래스는 슈퍼 클래스 하나만 가질 수 있다.(상속받을 수 있다. only 1)
class Dragon < Person; end           # 오류명 : 드래곤의 슈퍼 클래스 불일치


1-16. Class Basics
좋아! 복습 좀 합시다.

Hint 너의 코드는 이렇게 되어야 합니다.
class ClassName
    def initialize(param1, param2)
        @param1 = param1
        @param2 = param2
    end
end

1. Message라는 클래스를 만들고 초기화 방법을 지정합니다. 초기화 방법은 두개의 매개 변수(각각 시작 및 끝)를 사용하여 인스턴스(instance)변수@및@~()로 설정해야 합니다. 아직 너의 학급의 인스턴스를 만드는 것에 대해 걱정하지 마라.

class Message
  def initialize(from, to)
    @from = from
    @to = to
  end
end


1-17. Getting classier
완벽해! 이제 클래스 변수에 대해 좀 더 자세히 살펴보겠습니다.

Hint
초기화 방법을 정의하기 전에 메시지 클래스 내에서 @@messages_sent변수를 선언해야 합니다.
다음과 같이 @@messages_sent변수를 증가시킬 수 있습니다.

def initialize(from, to)
    @from = from
    @to = to
    @@messages_sent += 1
end


1. 메시지 클래스에 class @@message_sent class변수를 지정하고 이를 0으로 설정합니다. 초기화 방법 본문에서 이 값을 1씩 증가시켜 새 메시지 개체가 생성될 때마다 @@message_sent가 1씩 증가합니다. 아직 클래스의 인스턴스를 만들지 마십시오.

class Message
  @@messages_sent = 0
  def initialize(from, to)
    @from = from
    @to = to
    @@messages_sent += 1
  end
end


1-18. Forge an Object in the Fires of Mount Ruby (루비 화산 화재 사건에 객체를 하나 만들어라)
완벽해! 이제 메시지 클래스의 인스턴스를 생성하겠습니다.

Hint
다음과 같은 클래스에서 개체의 인스턴스를 생성할 수 있습니다.
obj = ClassName.new(parameters)

1. 수업이 끝난 후 my_message라는 변수를 생성합니다.
메시지를 사용하여 메시지 클래스의 인스턴스를 만듭니다.당신이 원하는 논쟁들을 가진 새로운 것! 결과를 my_message로 저장하십시오.

class Message
  @@messages_sent = 0
  
  def initialize(from, to)
    @from = from
    @to = to
    @@messages_sent += 1
   
  end
  
end

my_message = Message.new("fuck", "you")


1-19. Inheriting a Fortune (행운의 상속)
완벽해! 이제 상속에 대해 연습을 좀 해 봅시다.

Hint
이것은 당신이 이미 작성한 코드와 매우 유사할 것입니다. 패턴들, 패턴들은 어디에나!
루비에서의 상속은 다음과 같습니다.
DerivedClass < BaseClass
    # Some class stuff
end

전자 메일에 대한 초기화 방법은 다음과 같아야 합니다.
def initialize(subject)
    @subject = subject
end

1. 메시지에서 상속되는 두번째 클래스인 Email을 만듭니다. 하나의 매개 변수, 제목만 사용하고 제목과 동일하게 설정된 인스턴스 변수@제목을 가진 고유한 초기화 방법을 제공합니다.

class Message 
  @@messages_sent = 0
  def initialize(from, to)
    @from = from 
    @to = to 
    @@messages_sent +=1 
  end
end

my_message = Message.new("fuck", "you")

class Email < Message
  def initialize(subject)
    @subject = subject
  end
end


1-20. Up, Up, and Away!
당신은 챔피언이에요! 마지막 주제는 루비의 수퍼 키워드입니다. (결국 메시지 초기화 방법이 마음에 들기로 결정했습니다.)

Hint
이메일 클래스에는 초기화라는 단일 방법이 포함되어 있어야 하며, 이 방법을 사용하려면 시작과 종료라는 두 변수가 필요합니다. 초기화 본문에 있는 유일한 코드 행은 단어:수퍼!

1. 이 과정을 마치려면 계속해서 전자 메일에서 제목 매개 변수와@subject인스턴스 변수를 제거하십시오.
전자 메일의 초기화 방법은 처음부터 끝까지 메시지에 전달된 것과 동일한 두가지 매개 변수를 전달하고 전자 메일의 초기화 방법 본문에 수퍼 키워드를 유일한 코드 행으로 추가합니다.

class Message  
  @@messages_sent = 0 
  def initialize(from, to) 
    @from = from  
    @to = to  
    @@messages_sent +=1  
  end 
end 

class Email < Message 
  def initialize(from, to)
   super
  end
end

my_message = Message.new("Jinx", "Vi")  


2. Virtual Computer

종종 프로그래머는 가상 시스템을 사용하여 실제 컴퓨터를 시뮬레이션합니다. 실제 VM을 구축하지는 않겠지만, 이 프로젝트에서는 루비 클래스를 사용하여 데이터를 저장하는 가상 컴퓨터를 만들 예정입니다.

2-1. What You'll Be Building (무엇을 만들 것인가)
루비의 클래스와 객체에 대한 모든 것을 배웠으니, 심장에 필요한 루비 객체를 만들 수 있습니다. 이 프로젝트에서는 새로운 지식을 활용하여 머신 클래스를 만들고 가상 파일을 조작할 수 있는 해당 클래스의 인스턴스를 생성합니다.
준비됐어?시작하려면 코드를 실행해!

class Machine
  @@users = {}
  
  def initialize(username, password)
    @username = username
    @password = password
    @@users[username] = password
    @files = {}
  end
  
  def create(filename)
    time = Time.now
    @files[filename] = time
    puts "#{filename} was created by #{@username} at #{time}."
  end
  
  def Machine.get_users
    @@users
  end
end

my_machine = Machine.new("eric", 01234)
your_machine = Machine.new("you", 56789)

my_machine.create("groceries.txt")
your_machine.create("todo.txt")

puts "Users: #{Machine.get_users}"


2-2. Create Your Class
좋아! 어서 수업을 시작하자.

Hint
이 시점에서 당신의 클래스와 메서드는 꽤 비어 있을 것입니다. 초기화는 다음과 같아야 합니다.
def initialize
end
클래스 시스템에는 초기화 방법 외에는 아무것도 포함되지 않아야 합니다.

1. 시스템이라는 클래스를 생성하고 매개 변수를 사용하지 않는 초기화 방법을 지정하십시오. 초기화 본문은 비어 있어야 합니다.

class Computer
  def initialize
    
  end
end


2-3. Fancify Your Initialize Method (초기화 방법 조정)
잘 했다! 이제 초기화 방법에 일부 매개 변수를 전달하고 일부 인스턴스 변수를 설정하여 재미를 더해 보겠습니다.

Hint
다음과 같이 인스턴스(instance)변수를 전달된 매개 변수의 값으로 설정할 수 있습니다.
def initialize(my_var) @my_var = my_var end
모든 인스턴스(instance)변수를 매개 변수로 설정할 필요는 없습니다! @파일은@파일={}이어야 합니다.

1. 업데이트 초기화를 수행하여 사용자 이름과 암호의 두가지 매개 변수를 사용합니다. 초기화 본문에서 인스턴스 변수@사용자 이름과@password(각각)를 이러한 매개 변수로 설정합니다.

초기화 방법에서는@파일 인스턴스 변수를 생성하여 이를 빈 해시로 설정할 수도 있습니다. 이것은 우리가 나중에 파일들을 추적할 수 있도록 하기 위함이다!

class Computer
  def initialize(username, password)
    @username = username
    @password = password
    @files = {}
  end
end


2-4. Have a Little Class
어서 가서 학급 변수를 던져 보자. 변수 We @ . 사용자를 사용하여 컴퓨터의 모든 사용자를 추적합니다.

Hint
도움이 필요하다면 자유롭게 첫번째 연습을 돌아보세요!
변수를{}(으)로 동등하게 설정하기만 하면 변수를 빈 해시로 설정할 수 있습니다.

1. 컴퓨터 클래스에 @ . @ 사용자라는 클래스 변수를 추가합니다. 빈 해시에 동일하게 설정합니다.

초기화 방법에서 사용자 해시가 각 사용자 이름의 암호가 연결된 값으로 사용자 이름을 키로 유지하도록 @@users[username]=password를 설정합니다.

class Computer
  @@users = {}
  def initialize(username, password)
    @username = username
    @password = password
    @@users[username] = password
    @files = {}
  end
end


2-5. Getting More Creative (더욱 창의적으로 만들기)
잘 했어요 우리 반은 하나가 되어 가는데, 조금 지루해요. 다른 방법을 추가하고 만들어 봅시다. 여기서 몇가지 작업을 수행해야 합니다.

Hint
파일 이름/시간/키/값 쌍을@파일 해시에 추가할 수 있습니다.
time = Time.now
@files[filename] = time

1. 컴퓨터 클래스 내에서 단일 매개 변수 파일 이름을 사용하여 만들기라는 메서드를 정의합니다.

내부 작성에서 시간이라고 하는 변수를 선언하고 현재 시간과 동등하게 설정합니다(Time.now사용).

그런 다음 만들기 내부에서@파일 해시에 새 키/값 쌍을 추가합니다. 파일 이름 키를 사용하여 값 시간을 저장합니다.

생성의 마지막 단계를 위해 사용자에게 새 파일이 생성되었음을 알리는 메시지를 표시하십시오. 원하는 정보를 얼마든지 입력하십시오. 연습 1에서 사용했던 정보가 파일 이름, 사용자 이름 및 시간을 인쇄했습니다.

class Computer 
  @@users = {} 
  def initialize(username, password) 
    @username = username 
    @password = password 
    @@users[username] = password 
    @files = {} 
  end 
  
  def create(filename)
    time = Time.now
    @files[filename] = time
    puts "#{filename} and #{time} by #{@username}. "
  end
end

>> password.txt and 2018-07-29 13:53:39 +0000 by Dr. Cham. 
>> blastoff.txt and 2018-07-29 13:53:39 +0000 by Dr. Cham. 


2-6. Who are the Users?
완벽해! 하지만 이제 생각해 보니, 우리는 파일을 만들 때마다 수많은 사용자들이 파일을 만들 수 있습니다. 그리고 우리는 우리의 users class 사용자 클래스 변수에 도달할 방법이 없습니다! 우리는 그것에 도달하기 위한 방법을 만들어야 할 것이다.

@@users는 클래스 변수이므로 클래스 메서드를 사용하여 클래스를 캡처합니다. 지금까지 살펴본 방법의 대부분은 인스턴스 방법으로,"matz"또는"blixy"와 같은 특정 인스턴스에 대한 작업을 수행합니다. 클래스 메서드는 클래스 자체에 속하며, 이러한 이유로 클래스 이름 앞에 붙습니다.
class Machine
  def Machine.hello
      puts "Hello from the machine!"
    end
end
이것을 위한 지름길이 있다. 우리는 나중에 배울 것이다.

Hint 코드는 이러해야 합니다.
def ClassName.method_name
    @@class_variable
end
여기서 ClassName은 Computer, method_name은 get_user이며, @@class_variable은 @@users입니다.

1. 컴퓨터 클래스에 새 클래스 메서드를 추가합니다.get_user. 매개 변수가 없어야 합니다.
    새 컴퓨터.get_user메서드는 @ . 사용자 클래스 변수를 반환해야 합니다.

class Computer  
  @@users = {}  
  def initialize(username, password)  
    @username = username  
    @password = password  
    @@users[username] = password  
    @files = {}  
  end  
   
  def create(filename) 
    time = Time.now 
    @files[filename] = time 
    puts "#{filename} and #{time} by #{@username}. "
  end 
  
  def Computer.get_users
    return @@users
  end
end


2-7. Instantiation Nation
잘 했어요 마지막 단계:컴퓨터 클래스의 인스턴스를 만듭니다.

전에도 해 본 적이 있지만, 재교육 활동이 있습니다.
class Person
    def initialize(name)
      @name = name
    end
end

emma = Person.new("emma")

1. 위의 예에서는 먼저 초기화 방법을 사용하여 사용자 클래스를 정의합니다.
2. 그런 다음 새로운 사람의 인스턴스를 만들어 엠마라는 새로운 변수에 저장합니다.

Hint 명심할 것은 다음과 같은 수업을 실시한다는 것입니다.
my_instance = ClassName.new(arguments)

1. 수업이 끝나면 새 컴퓨터 인스턴스를 만들어 my_computer라는 새 변수에 저장합니다. 당신의 주장에 당신이 좋아하는 사용자 이름과 비밀 번호를 자유롭게 사용하세요!

class Computer  
  @@users = {}  
  def initialize(username, password)  
    @username = username  
    @password = password  
    @@users[username] = password  
    @files = {}  
  end  
   
  def create(filename) 
    time = Time.now 
    @files[filename] = time 
    puts "#{filename} and #{time} by #{@username}. "
  end 
  
  def Computer.get_users
    return @@users
  end
end

my_computer = Computer.new("killer", "hunter")


2-8. You Did it!
잘했어! 가상 컴퓨터 인스턴스를 생성하는 컴퓨터 클래스를 가지고 있습니다.

수업 시간에 자유롭게 어울려라. 파일을 업데이트하는 방법을 추가하면 어떻게 됩니까? 아니면 삭제할까요? 초기화하거나 생성하기 위해 추가 매개 변수를 추가하려면 어떻게 해야 합니까?

컴퓨터가 원하는 대로 작동하면 실행을 클릭하여 이 프로젝트를 완료합니다.

class Computer  
  @@users = {}  
  def initialize(username, password)  
    @username = username  
    @password = password  
    @@users[username] = password  
    @files = {}  
  end  
   
  def create(filename) 
    time = Time.now 
    @files[filename] = time 
    puts "#{filename} and #{time} by #{@username}. "
  end 
  
  def Computer.get_users
    return @@users
  end
end

my_computer = Computer.new("killer", "hunter")


10. Object-Oriented Programming, Part ll

1. Object-Oriented Programming ll

이 과정에서는 정보 숨기기, 모듈, 혼합 등 루비의 OOP에 대한 보다 진보된 측면을 다룰 것입니다.

1-1. Need-to-Know Basis
당신은 우리가 루비에 왜 정보를 숨겼는지 궁금할 것이다. 루비 프로그램의 모든 부분이 다른 부분이 무엇을 하고 있는지 아는 것은 괜찮지 않나요?
소프트웨어를 쓰고 사용하는 유일한 사람이라면 가능합니다. 하지만 다른 사람들이 여러분의 프로그램을 작업하거나 사용할 때, 그들은 여러분의 프로그램의 다른 부분들이 그들의 일을 하는 방식을 가지고 빈둥거리려고 할 지도 모릅니다. 당신은 그것을 원하지 않아요!
이러한 이유로 루비는 당신이 몇몇 방법을 공공연히 그리고 다른 사람들을 비공개로 만들 수 있게 한다. 대중적인 방법들은 프로그램의 나머지 부분들과 접할 수 있게 해준다; 그들은 말한다, "이봐! 내 수업이나 수업의 예에 대해 알고 싶은 게 있는지 물어봐."
반면에, 개인적인 방법은 당신의 학급이 방해받지 않고 그들 자신의 일을 하는 것이다. 그들은 누군가가 그들에게 어떤 것도 물어보는 것을 원하지 않기 때문에, 그들은 그들 자신에게 다가갈 수 없습니다!

편집기에서 코드를 확인하십시오. about_me 방법에 대한 공개적인 방법과 개인 은행_account_number 방법을 만들었습니다. 클래스 외부에서 bank_account_number 메서드를 호출할 때 발생하는 작업을 보려면 실행을 클릭하십시오.

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end
  
  public    # This method can be called from outside the class.
  
  def about_me
    puts "I'm #{@name} and I'm #{@age} years old!"
  end
  
  private   # This method can't!
  
  def bank_account_number
    @account_number = 12345
    puts "My bank account number is #{@account_number}."
  end
end

eric = Person.new("Eric", 26)
eric.about_me
eric.bank_account_number

>> I'm Eric and I'm 26 years old!


1-2. Quick Review: Building a Class (빠른 검토 클래스 만들기)
우리 수업을 만들자!
class ClassName
    def method_name(parameter)
      @class_Variable = parameter
    end
end
1. 먼저 Ruby에게 ClassName을 구성하기를 원한다고 말합니다. 수업 끝내는 것을 잊지 마세요!
2. ClassName에서는 방법을 정의합니다. 여기에는 MethodName 다음에 (parameter), 이 방법을 사용할 때 MethodName("hello!")이 표시됩니다.
3. 위의 매개 변수가 "안녕하세요!"인 경우 다음 라인에 있는 변수 @classVariable에 할당됩니다.
4. 다시, MethodName을 종료하는 것을 잊지 마세요!

1.처음, Dog라는 클래스를 만듭니다.
클래스 Dog 내에 초기화 방법을 만듭니다.
초기화 방법이 이름과 품종이라는 두 가지 매개 변수를 수락하도록 허용합니다.
초기화 방법 내부에서는 이 두 매개 변수를 각각 @name 및 @breced 변수에 할당합니다.

class Dog
  def initialize(name, breed)
    @name = name
    @breed = breed
    end
end


1-3. Going Public (공개)
잘했어! 이제 공적인 방법과 사적인 방법에 대해 자세히 알아보겠습니다.
Ruby에서는 메서드가 기본적으로 공개되므로 공용 또는 개인 방법을 지정하지 않으면 메서드가 공개됩니다. 그러나 이 경우, 우리는 어떤 방법이 공공적인지 우리의 코드를 읽는 사람들에게 분명히 하고 싶다. 이를 위해 방법 정의에 다음과 같이 공개합니다.
class ClassName
    # Some class stuff
    public
    def public_method
       # public_method stuff
    end
end
다른 말을 하지 않으면 공개 키워드 뒤에 클래스 정의가 끝날 때까지 모든 내용이 공개됩니다. (다음 연습에서는 다르게 말할 것입니다.)

1. 우선 개 짖는 방법만 들어보자. 나무껍질 방법은 "우프!"를 넣어야 한다.

class Dog
  def initialize(name, breed)
    @name = name
    @breed = breed
  end
  
  public
  def public_bark
   puts "Woof!"
  end
end


1-4. Private! Keep Out! (보호 출입금지!)
완벽해! 그러나 우리의 루비 방법이 모두 공개되어서는 안 된다.
공개를 사용하여 공개 방법을 발표하는 것과 마찬가지로 비공개 방식을 사용하여 개인 방식을 지정합니다.
#뭐 요건 줄여서 이렇게 사용할 수 있다고 설명하는 거네.
class ClassName
    # Some class stuff

    public
    # Public methods go here
    def public_method; end

    private
    # Private methods go here
    def private_method; end
end
개인 방법은 다음과 같습니다.
정칙의 즉, 내부 다른 코드에서만 이 방법을 호출할 수 있습니다.
목적 이것을 말하는 또 다른 방법은 그 방법을 명시적 수신자로 호출할 수 없다는 것이다. 당신은 수신기를 계속 사용해 왔군요. 이런 것들이 메서드라고 불리는 객체들이에요! 개체를 호출할 때마다method, object는 method의 수신기이다.
개인 정보에 접근하기 위해서는, 우리는 그것을 얻는 법을 아는 공공적인 방법을 만들어야 한다. 이것은 공개 인터페이스와 개인적인 구현을 구분하고, 우리는 다음 두 가지 연습에서 이것을 더 자세히 검토할 것입니다.

class Dog
  def initialize(name, breed)
    @name = name
    @breed = breed
  end
  
  public
  def bark
   puts "Woof!"
  end


private
def id
    @id_number = 12345
  end
end


1-5. attr_reader, attr_writer
우리는 루비가 속성에 접근하기 위해 방법이 필요하다는 교훈을 보았다. 예를 들어 @name 인스턴스(instance) 변수에 액세스하려면
def name
    @name
end
이제 그만! attra_reader를 사용하여 변수에 액세스하고 attrar_writer를 사용하여 변수를 변경할 수 있습니다. 만약 우리가 쓴다면
class Person
    attr_reader :name
    attr_writer :name
    def initialize(name)
      @name = name
    end
end
Ruby는 자동으로 다음과 같은 작업을 수행합니다.
def name
    @name
end

 def name=(value)
    @name= value
end
마법처럼, 우리는 원하는 대로 변수를 읽고 쓸 수 있습니다! 인스턴스 변수(기호)를 attra_reader 또는 attacher_writer에 전달합니다.
그 이름은 우습게 보일 수도 있지만, 메서드 이름에 = 기호를 넣을 수도 있습니다. 그것은 단지 루비 컨벤션입니다.

Hint
이름과 작업= 메서드를 클래스에서 완전히 제거한 다음 :name에 대해 attacher를 추가하고 attr_writer에 대해 :job을 추가합니다. 예를 들어, attacher_reader는 다음과 같습니다.
class Person 
   attr_reader :name 
   # All the other class stuff 
end

1.우리는 @name을 얻는 방법과 @job을 변경하는 방법을 통해 사용자 클래스를 다시 불러왔습니다. 계속하여 이름 및 작업= 메서드를 제거하고 :name에 대한 attra_reader와 :job에 대한 attrier_writer를 추가합니다.

class Person
  def initialize(name, job)
    @name = name
    @job = job
  end
  
  attr_reader :name
  attr_writer :job
end


1-6. attr_accessor
특정 변수를 읽고 쓰려면 attra_reader 및 attributor_writer보다 훨씬 짧은 바로 가기가 있습니다. attr_accessor를 사용하여 변수를 한 번에 읽을 수 있고 쓸 수 있도록 할 수 있습니다.

1.여기서는 attra_reader와 attrar_writer가 있습니다. 계속하여 attrier_accessor로 대체하십시오!

class Person
  attr_accessor :name
  attr_accessor :job
  
  def initialize(name, job)
    @name = name
    @job = job
  end
end


1-7. What's a Mudule?
모듈은 설정된 방법과 상수를 포함하는 도구 상자로 생각할 수 있습니다. 당신이 사용하고 싶어하는 루비 툴이 아주 많지만, 그것은 그들을 항상 주변에 두기 위해 통역관을 혼란스럽게 할 것이다. 그렇기 때문에 모듈 안에 있는 상수와 방법이 필요할 때만 모듈 도구 상자를 당깁니다!
모듈은 클래스와 매우 유사하며 모듈만 인스턴스를 만들 수 없으며 하위 클래스를 가질 수 없습니다. 그것들은 그냥 물건을 저장하는 데 사용돼요!

편집기에서 예제 모듈을 확인하십시오. PI에 저장된 pi 근사치 및 원의 원주 및 면적을 계산하는 일련의 방법을 확인하십시오.
계속하려면 을 클릭하십시오.

module Circle

  PI = 3.141592653589793
  
  def Circle.area(radius)
    PI * radius**2
  end
  
  def Circle.circumference(radius)
    2 * PI * radius
  end
end


1-8. Module Syntax
기존 모듈(얼마지막!)을 꺼낼 수 있지만 직접 만들 수도 있습니다. 모듈은 매우 쉽게 만들 수 있습니다! 다음과 같이 모듈 키워드만 사용합니다.
module ModuleName
    # Bits 'n pieces
end
클래스 이름과 마찬가지로 모듈 이름은 lowercase_with_underscore가 아닌 CapitalizedCamelCase로 작성됩니다.
변수는 (정의에 따라) 변하기 때문에(또는 변하기 때문에) 모듈에 변수를 포함하는 것은 이치에 맞지 않습니다. 그러나 상수는 항상 동일하게 유지되기 때문에 모듈에 유용한 상수를 포함하는 것은 좋은 생각이다.
루비가 초기화되면 상수 값을 동일하게 유지하지 않지만 변경하려고 하면 경고가 표시됩니다. 루비 상수는 ALL_CAPS로 작성되며 단어가 두 개 이상인 경우 밑줄로 구분됩니다.
Ruby 상수의 예로는 수학 모듈에 살고 있고 대략 3.141592653589793과 동일한 PI가 있습니다. 우리는 이전 연습에서 우리만의 PI를 만들었지만 걱정하지 마세요. 왜냐하면 루비는 그것들을 분리시키는 것을 알고 있습니다.

1. 오른쪽의 편집기에서 MyLibrary라는 고유한 모듈을 만듭니다. FAVE_BOOK라는 상수를 포함시키고 가장 좋아하는 책의 이름을 지정하는 문자열과 동일하게 설정하십시오!

module MyLibrary
  FAVE_BOOK = "Rich Book"
end


1-9. Resolve to keep Learning (학습 유지에 대한 해결)
모듈의 주요 목적 중 하나는 방법과 상수를 지정된 공간으로 구분하는 것이다. 이것은 이름표현이라고 불리며 루비가 수학:PI와 원:PI를 혼동하지 않는 방법입니다.
방금 사용한 이중 결장 보이세요? 이를 스코프 해상도 오퍼레이터라고 합니다. 루비에게 특정 코드를 원하는 위치를 알려주는 멋진 방법입니다. 수학:PI라고 말하면, 루비는 수학 모듈 안을 들여다보고 다른 PI(원에서 만든 PI 등)를 받는 것이 아닙니다.
기존의 루비 모듈인 수학에 대해 연습해 봅시다.

Hint
To get to PI in Math, you'll just need Math::PI!

1. 1.범위 분해능 연산자를 사용하여 수학 모듈에서 콘솔로 PI 값을 입력합니다.

puts Math::PI
>> 3.141592653589793


1-10. A Few Requirements (몇 가지 요구 사항)
완벽해!
수학 같은 몇몇 모듈들은 이미 통역관에 있다. 하지만 다른 것들은 분명히 도입되어야 하고 우리는 요구조건을 이용해서 할 수 있다. 우리는 이것을 타이핑으로 간단히 할 수 있다.
require 'module'
오늘 날짜를 표시하기 위해 Ruby Date 모듈을 사용하고 싶지만, 아직 필요하지 않습니다!

1. 계속 진행하여 1번 회선에 '날짜'를 입력해야 3번 회선에 있는 코드가 작동할 수 있습니다.
require 'date'

puts Date.today
>> 2018-08-11


1-11. Feeling Included
하지만, 우리는 단지 모듈을 필요로 하는 것 이상을 할 수 있다. 우리는 또한 그것을 포함할 수 있습니다!
특정 모듈을 포함하는 모든 클래스는 이러한 모듈의 방법을 사용할 수 있습니다!
이 방법의 좋은 효과는 더 이상 모듈 이름으로 상수와 메서드를 선행할 필요가 없다는 것입니다. 모든 것을 끌어 넣었으므로 수학:PI 대신 PI를 쓰면 됩니다.

 1.In의 경우, 우리는 수학을 사용하고 싶지만, 수학::
2번 라인에 수학을 포함시켜 주세요.

class Angle
  include Math
  attr_accessor :radians
  
  def initialize(radians)
    @radians = radians
  end
  
  def cosine
    cos(@radians)
  end
end

acute = Angle.new(1)
acute.cosine


1-12. The Marriage of Modules Classes
우리가 지난 연습에서 한 일은 여러분들에게 낯설지 않은 것처럼 보일 수도 있지만 생각해 보세요: 우리는 수업과 모듈의 행동을 함께 했습니다!
모듈이 추가 동작과 정보를 클래스에 혼합하는 데 사용될 때 이를 혼합이라고 합니다. 혼합을 사용하면 코드를 다시 쓰지 않고도 클래스를 사용자 지정할 수 있습니다! mixin

편집기에서 코드를 확인하십시오. 동작 모듈에서 점프 방법을 정의한 다음 토끼와 크리켓 클래스에 혼합하는 방법을 확인합니다. 실행을 클릭하여 효과를 확인하십시오!


1-13. Imitating Multiple Inheritance (다중 상속 무시)
이제 여러분은 우리가 왜 혼합이 한 개 이상의 클래스로부터 물려받은 것을 흉내낼 수 있는 능력을 줄 수 있다고 말했는지 이해하실 거예요: 필요에 따라 다양한 모듈의 특성들을 섞음으로써, 우리가 좋아하는 우리 클래스에 어떤 행동 조합도 추가할 수 있어요!

1.MartialArts 모듈을 만듭니다.
안에서, "나는 검객이다"라고 말하는 방법을 정의하세요.
닌자 내부 첫 번째 줄과 사무라이 내부의 첫 번째 줄에는, 이것을 닌자와 사무라이 클래스 둘 다에 섞기 위해 마르티알 아르츠가 포함되어 있기 때문에, 그들에게 검객 방법을 제공한다.

module MartialArts
  def swordsman
    puts "I'm a swordsman."
  end
end


class Ninja
   include MartialArts
  def initialize(clan)
    @clan = clan
  end
end

class Samurai
   include MartialArts
  def initialize(shogun)
    @shogun = shogun
  end
end


1-14. Extend Your Knowledge (지식 확장)
여기에는 모듈의 방법이 인스턴스(instance) 수준에서 혼합되는 반면(특정 클래스의 인스턴스가 방법을 사용하도록 허용) 확장 키워드는 모듈의 메소드를 클래스 수준에서 혼합합니다. 이는 클래스 자체가 클래스의 인스턴스와는 반대로 메서드를 사용할 수 있음을 의미합니다.

편집기에서 코드를 확인하십시오. 우리는 The WereAnd를 ThePresent와 함께 확장했고, 그것이 지금 방법을 사용할 수 있도록 했다. 실행을 클릭하여 효과를 확인하십시오!

module ThePresent
  def now
    puts "It's #{Time.new.hour > 12 ? Time.new.hour - 12 : Time.new.hour}:#{Time.new.min} #{Time.new.hour > 12 ? 'PM' : 'AM'} (GMT)."
  end
end

class TheHereAnd
  extend ThePresent
end

TheHereAnd.now
>> It's 2:45 PM (GMT).


1-15. A Matter of Public Knowledge (공공 지식의 문제)
좋아! 공적인 방법으로 약간의 연습을 하자.

Hint
우리가 명시적으로 공개하기 위해 해야 할 일은
class ClassName
    public
    def public_method
    end
end

1. 편집기에서 애플리케이션 클래스를 설정했습니다. print_status라는 공용 방법을 "모든 시스템이 작동한다!"라는 제목의 응용 프로그램에 추가합니다. 공용 키워드를 사용하는 것을 잊지 마세요!

class Application
  attr_accessor :status
  def initialize; end
  public
  def print_status
    puts "All systems go!"
  end
end


1-16. Private Affairs
좋아! 이제 개인적인 방법을 시도해 보자.

Hint
기억하라, 우리는 개인적으로
class ClassName
    private
    def private_method
    end
end

1.공용 메서드를 사용하여 암호라는 개인 메서드를 추가하여 슈퍼 비밀 암호 12345를 반환합니다.

class Application
  attr_accessor :status
  def initialize; end
  private
  def password
    return 12345
  end
  
  public
  def print_status
    puts "All systems go!"
  end
  
end


1-17. Module Magic
훌륭해. 모듈들로 넘어가자!

Hint 모듈 요렇게 만듬
module ModuleName
end

1.오른쪽 편집기에서 언어라고 하는 모듈을 만듭니다. FAVE라는 상수를 포함시키고 가장 좋아하는 프로그래밍 언어를 명명하는 문자열과 동일하게 설정하십시오!

module Languages
  FAVE = "C"
end
>> Your favorite language isn't Ruby?? For shame! # ㅋㄷㅋㄷ


1-18. Mixin for the Win (승리를 위한 Mixin)
거의 다 됐어! 우리의 리뷰는 약간의 마술이 없이는 완벽하지 않을 것이다.

Hint
class ClassName
    include ModuleName
end

1. 마지막으로, 우리가 가장 좋아하는 언어가 콘솔에 인쇄될 수 있도록 언어 모듈을 마스터 클래스(온라인 6)에 포함시킵니다.

module Languages
  FAVE = "Ruby"  # 이거 전에 입력한거 맞죠? :D
end

class Master
include Languages
  def initialize; end
  def victory
    puts FAVE
  end
end

total = Master.new
total.victory


2. Banking on Ruby

이제 Ruby에서 정보를 숨기는 것에 대한 모든 것을 알았으니, 우리의 새로운 기술을 적용하여 은행 계좌 잔고를 저장하고 업데이트하고 보여줄 수 있는 프로그램을 만들자.

2-1. What You'll Be Building
좋아! 이제 루비 수업에서 프라이버시 수준을 조절하는 법을 알았으니, 우리는 그것을 사물을 만들 때 우리의 장점으로 사용할 수 있다. 이 경우, 저희는 잔액을 표시하고 자금을 이전하는 공개 방법을 사용하여 계정 개체를 만들 예정이지만, 거래를 승인하기 전에 사용자의 PIN(개인 식별 번호)이 정확한지 확인하기 위해 개인 방법에 의존합니다.
참고: 우리는 단지 은행업무를 예로 들 수 있습니다. 왜냐하면 그것은 실제와 아주 흡사하기 때문입니다. 이것은 진짜 은행을 위한 것이 아니니까, 진짜 은행 정보를 사용하지 마세요!

편집기에서 코드를 확인하십시오. 사용자 및 개인과 상호 작용하는 공개 방법을 통해 PIN을 확인하는 방법을 확인할 수 있습니다. 코드를 실행하여 작동 방식을 확인하십시오!

class Account
  attr_reader :name, :balance
  def initialize(name, balance=100)
    @name = name
    @balance = balance
  end
  
  def display_balance(pin_number)
    puts pin_number == pin ? "Balance: $#{@balance}." : pin_error
  end
  
  def withdraw(pin_number, amount)
    if pin_number == pin
      @balance -= amount
      puts "Withdrew #{amount}. New balance: $#{@balance}."
    else
      puts pin_error
    end
  end
  
  private
  
  def pin
    @pin = 1234
  end
  
  def pin_error
    "Access denied: incorrect PIN."
  end
end

my_account = Account.new("Eric", 1_000_000)
my_account.withdraw(11, 500_000)
my_account.display_balance(1234)
my_account.withdraw(1234, 500_000)
my_account.display_balance(1234)


2-2. Creating the Acount Class
먼저 계정 클래스를 만들겠습니다. 하지만 먼저, 여러분은 아마도 마지막 연습에서 이런 우쭐함을 눈치챘을 것이다.
def initialize(name, balance=100)
    @name = name
    @balance = balance
그 잔액은 어떻게 됩니까? 선택적 매개 변수를 나타냅니다. Ruby는 초기화를 위해 하나 또는 두 개의 인수를 전달할 수 있다고 말합니다. 두 개의 인수를 통과하면 밸런스를 @balance로 설정하고, 이름만 전달하면 잔액은 100으로 기본 값을 얻습니다.
1_000_000(백만)에서 밑줄을 사용한 것도 알고 계실 것입니다. 루비는 이것을 허용하고, 큰 숫자를 읽는 것을 더 쉽게 해줘요! 멋지지 않니?

Hint
변수 읽기 전용으로 만들기 위해 attr_reader :variable을 사용할 수 있습니다.

1. 편집기에서 계정 클래스를 만듭니다. :name 및 :balance 특성은 읽을 수 있어야 합니다(쓰기 가능은 아님!). 클래스의 초기화 메서드는 이름과 밸런스라는 두 개의 매개 변수를 사용하고 밸런스 매개 변수는 기본적으로 100으로 설정해야 합니다.
마지막으로, @name과 @balance 인스턴스 변수에 매개변수를 저장합니다.

class Account
  attr_reader :name, :balance
  def initialize(name, balance=100)
   @name = name
    @balance = balance
  end
end


2-3. Private Affairs
그럼 이제 개인 방법을 만들어 보겠습니다. (우리의 공공 방법은 이러한 방법에 의존하므로 먼저 이러한 방법을 만드는 것이 좋습니다.

1. 계정 클래스에 두 가지 개인 메서드를 추가합니다. 핀과 pin은 인수를 사용하지 않고 PIN 번호 1234와 동일한 인스턴스 변수 @pin을 설정해야 합니다.
pin_error는 인수를 하지 않아야 하며 "Access remended: 잘못된 PIN" 문자열만 반환해야 합니다.

class Account
  attr_reader :name, :balance
  def initialize(name, balance=100)
   @name = name
    @balance = balance
  end
  
  private
  
  def pin
    @pin = 1234
  end
 
  def pin_error  
    "Access denied: incorrect PIN."
  end

end


2-4. Displaying the Balance
완벽해! 이제 첫 번째 공개 방법인 show_balance에 대해 살펴보겠습니다. 이 방법은 현재 계정 잔액을 표시하는 데 사용됩니다.

Hint
유의해야 할 사항: 공개 메서드를 명시적으로 선언하거나 공개 메서드를 생략할 수 있으며 기본적으로 공개 메서드는 공개됩니다. 하지만! 공용을 사용하지 않는 경우 공용 키워드가 표시된 후 모든 메서드에 영향을 미치기 때문에 공용 메서드를 개인 키워드 앞에 두어야 합니다. 만약 여러분이 공공 기법에 대해 비밀로 하고 공공 기구에 라벨을 붙이지 않는다면, 그것들도 사적이 될 거예요!

1. 계정 클래스에 공용 display_balance 메서드를 정의합니다. pin_number라는 단일 매개 변수를 사용해야 합니다.
방법의 본문은 pin_number가 pin과 동일한지 여부를 확인해야 합니다(private pin method 호출 결과).
이 경우 Display_balance는 "균형: $#{@balance}"를 입력해야 합니다.
그렇지 않으면(그렇다면) pin_error (in_error 메시지)를 입력해야 합니다.

class Account
  attr_reader :name, :balance
  def initialize(name, balance=100)
   @name = name
    @balance = balance
  end
  
  private
  
  def pin
    @pin = 1234
  end
 
  def pin_error  
    "Access denied: incorrect PIN."
  end
  
  public
  
  def display_balance(pin_number)
    if pin_number == @pin
     puts "Balance: $#{@balance}."
    else
      puts pin_error
    end
  end
  
end


2-5. Making a Withdrawal (탈퇴)
잘 했다! 이제 저희 계좌에서 돈을 인출할 수 있는 두 번째 공적 방법을 추가해 보겠습니다.
여기서 비결은 @balance가 클래스 내에서만 액세스할 수 있으므로 @balance -= 양을 사용하여 균형을 일정 양만큼 줄이는 것입니다.
1. pin_number와 금액의 두 가지 매개 변수를 사용하는 공개 취소 방법을 클래스에 추가합니다. pin_number가 핀과 일치하면 메서드는 밸런스에서 양을 뺀 다음 "Withdrew #{amount}"를 입력합니다. 새 잔액: $#{@balance}." 그렇지 않으면 pin_error가 발생해야 합니다.

class Account  
  attr_reader :name, :balance  
  def initialize(name, balance=100)  
   @name = name  
    @balance = balance  
  end  
 
  
  public  
  def display_balance(pin_number)  
    if pin_number == @pin  
     puts "Balance: $#{@balance}."  
    else  
      puts pin_error  
    end  
  end 
   
  def withdraw(pin_number, amount) 
    if pin_number == @pin 
      @balance -= amount 
      puts "Withdrew #{amount}. New balance: $#{@balance}." 
    else 
      puts pin_error 
    end 
  end 
  
  
private  
  def pin  
    @pin = 1234  
  end  
   
  def pin_error    
    "Access denied: incorrect PIN."  
  end  
    
end
>> Access denied: incorrect PIN.


2-6. Opening an Account (계정 열기)
거의 다 했어요. 이제 은행 업무를 진행할 수 있도록 계정 인스턴스를 만들어야 합니다.
1.마지막 단계: checking_account라는 계정 클래스의 인스턴스를 만듭니다. 당신이 좋아하는 이름과 시작 균형!

class Account
  attr_reader :name
  attr_reader :balance
  def initialize(name, balance=100)
    @name = name
    @balance = balance
  end
  
  public
  def display_balance(pin_number)
    if pin_number == @pin
      puts "Balance: $#{@balance}."
    else
      puts pin_error
    end
  end
  
  def withdraw(pin_number,amount)
    if pin_number == @pin
      @balance -= amount
      puts "Withdrew #{amount}."
    else
      puts pin_error
    end
  end

  private
  def pin
    @pin = 1234
  end
  def pin_error
    return "Access denied: incorrect PIN."
  end 
end

checking_account = Account.new("Akali", 100)


2-7. Well Done!
훌륭해요! 사용자는 자신의 계정 클래스와 check_account 인스턴스를 공용 및 개인 방법으로 모두 사용할 수 있습니다.
어서 교실 밖에서 네 핀으로 들어가도록 해. 쉽지 않죠?

어떻게 이 수업을 향상시킬 수 있습니까? 다음을 수행할 수 있습니다.
: 계좌에 돈을 추가할 수 있는 예금 방법 포함
: 사용자가 계정 과장을 방지하는 오류 검사 포함
: 계정에서 상속되는 CheckingAccounts 또는 SavingsAccounts 생성

원하는 대로 작동할 때까지 얼마든지 코드를 추가하십시오. 그런 다음 실행을 클릭하여 이 프로젝트를 완료합니다.

 

 

 

 

 

 

 

Proc : Unix유사 운영 체제의 프로세스 정보에 액세스 하기 위한 특수 파일 시스템(일반적으로/proc에 탑재됨)




오래된 것들의 새로운 이름
http://ruby-doc.org/docs/Tutorial/part_01/objects.html



Prime 이란? : 모든 소수의 집합
https://ruby-doc.org/stdlib-1.9.3/libdoc/prime/rdoc/Prime.html
|| = (or-equals)는 Ruby에서 무엇을 의미합니까?
https://code.i-harness.com/ko/q/f3109
[파이썬&루비] 반복문(Iterator) - for
http://new93helloworld.tistory.com/199
.to_i 설명
https://apidock.com/ruby/String/to_i