AppAcademy是北美比较有名的Coding Bootcamp(集训班),教授以ruby on rails为工具搭建webapp的方法,我之前在国内是英语老师,前段时间决定随家人来美国发展,一时间觉得自己的技能包都没什么用了,在爱人的鼓励下决定另辟蹊径,学学编程,于是报名了这个训练营,我想尽力把每天学的内容写在这里,算是个日记,也供大家参考。
前三周都是远程授课,用的是Zoom,instructor会提前发给同学们上课的zoom网上聊天室的链接,注册Zoom账号,点击链接,就可以上课了,每天会做三次考勤,早上9:00,中午1:30,下午4:00,如果考勤不到,会记一次Strike,十振出局,也就是有十次考勤未到,或是有其他违反规则,则有可能被开除,要求听起来是蛮严的。
今天第一天,早上9:00,连到zoom,Darren Eid是上半场的主讲老师,主要介绍了一下AppAcademy的概况,和一些基本原则,没有讲code。讲了大概两个小时,换上Ronil,开始讲解ruby语言的一些基础。
1. Array的 inject 方法
arr = [1, 2, 3, 4]
arr.inject(optional_starter) do |accumulator, element|
#就是进行一个叠加操作,optional_starter可以是一个起始值,也可以为空,如果是空值,那么就从arr的第一个数字,也就是“1”开始叠加,这个操作是一个iteration,arr中的每一个元素都会被叠加,当然,inject也能解决除了叠加以外的其他操作,max,min都可以
# if accumulator < element then element else accumulator 这个就是max操作,反之则是min操作。
accumulator + element
end
类似的方法还有map,select,reduce 等,reduce和inject比较牛的地方就是他有两个参数,可以记录一个accumulator的值。
2. BubbleSort
Time Complexity is O(n^2) , 效率比较低,但是比较容易理解
ruby的BubbleSort可以这样写
arr = [5,4,3,2,1]
def bubble_sort(arr)
sorted = false
while !sorted
sorted = true
arr.each_with_index do |ele, ind|
arr.each_with_index do |e, i|
if e < ele && i > ind
arr[i], arr[ind] = arr[ind], arr[i]
sorted = false
end
end
end
end
return arr
end
两层loop,用sorted作为flag,确定是否所有的element都已经被排列好。有点难理解的是两层循环处,他们都从 ind = 0, ele = 5开始跑,但是由于有if statement,所以只会跑出我们需要的结果。当出现前后两个ele错位(e < ele && i > ind)时,进行替换,ruby的替换这个很简单,也不用swap function,只需要代码arr[i], arr[ind] = arr[ind], arr[i]即可。
3. compress
def compress_str(str)
arr = str.split("")
counter = 1
res = []
arr.each_with_index do |el, ind|
if el == arr[ind + 1]
counter += 1
else
counter == 1 ? counter : res << counter
res << arr[ind]
counter = 1
end
end
return res.join("")
end
p compress_str("aaabbc") # => "3a2bc"
p compress_str("xxyyyyzz") # => "2x4y2z"
p compress_str("qqqqq") # => "5q"
p compress_str("mississippi") # => "mi2si2si2pi"
我认为我的这个code应该还有空间
def compress_str(str)
res = []
counter = 1
str.each_char.with_index {|el, ind| el == str[ind + 1] ?
counter += 1 : ((counter == 1 ? counter : res << counter);
res << str[ind]; counter = 1) }
res.join("")
end
但是改成这样的话就读不懂了。readability也非常重要。
3. Peak finder
def peak_finder(arr)
arr.length - 1 > 0 ? (last = arr.length - 1) : (return arr)
arr.select.with_index do |e, i|
e if (i == 0 && arr[i] > arr[i + 1]) ||
(i != last && arr[i] > arr[i -1] && arr[i] > arr[i + 1]) ||
(i == last && arr[last] > arr[last - 1])
end
end
p peak_finder([1, 3, 5, 4]) # => [5]
p peak_finder([4, 2, 3, 6, 10]) # => [4, 10]
p peak_finder([4, 2, 11, 6, 10]) # => [4, 11, 10]
p peak_finder([1, 3]) # => [3]
p peak_finder([3, 1]) # => [3]
p peak_finder([1])
p peak_finder([])
想到了只有一个元素的array和空array的情况,这个code的readablity也不好,有的时候要牺牲code的形式,增加可读性。
4. Grid
def grid(n, m)
Array.new(n) {Array.new(m)}
end
result_1 = grid(2, 3)
p result_1 # => [[nil, nil, nil], [nil, nil, nil]]
result_1[0][0] = "X"
p result_1 # => [["X", nil, nil], [nil, nil, nil]]
result_2 = grid(4, 2)
p result_2 # => [[nil, nil], [nil, nil], [nil, nil], [nil, nil]]
result_2[0][0] = "Q"
p result_2 # => [["Q", nil], [nil, nil], [nil, nil], [nil, nil]]
def grid(n, m)
Array.new(n) {Array.new(m)}
end
result_1 = grid(2, 3)
p result_1 # => [[nil, nil, nil], [nil, nil, nil]]
result_1[0][0] = "X"
p result_1 # => [["X", nil, nil], [nil, nil, nil]]
result_2 = grid(4, 2)
p result_2 # => [[nil, nil], [nil, nil], [nil, nil], [nil, nil]]
result_2[0][0] = "Q"
p result_2 # => [["Q", nil], [nil, nil], [nil, nil], [nil, nil]]
这主要涉及到ruby的一个知识点,就是ruby没有功能来构建二维数组,或是更高维数组,但是在建立多维数组时要注意,如果直接使用 2darr = Array.new(3, Array(3)),看上去是建立了一个二维的全nil数组,但是在运行过程中会发现,2darr[0][0] = 0 的赋值后,2darr[1][0], 2darr[2][0]都会发生变化,也就是说,我们根据一个地址,建立了三个数组,而对任意一个数组的重新赋值,都会影响到其他的两个数组,所以我们要擅用 block, Array.new(3) { Array.new(3) },这样一来,2darr会执行三次Array.new(3),每个新生成的数组有独立地址。
arr = Array.new(3, 1)
arr[2] = 2
p arr # ==> [1, 1, 2]
arr = Array.new(3, Array.new(3))
arr[2] = [2,3,1]
arr[0] += [10]
arr[1] << 28
p arr # ==> [[nil, nil, nil, 10], [nil, nil, nil, 28], [2, 3, 1]]
读懂了上面这两段code,就应该明了了,这个我自己也会回来常看一下。
5. 还有一些小的知识点
“aeiou".include?"iou" ==> true
"aeiou".include?"uoi" ==> false
###string.include?string 要注意顺序要对,并不是所有字符都有了就可以。
### def func(*args) 这种情况在method内部,调用args时就不能再加*了,只能用args
### (-5..-2) ==> [-5, -4, -3]
###(0..-2) ==> []
### a = 3 ? b = 5 : b = 8 英文中称之为ternary
### arr.inject do |acc, ele|
if ele > 5
ele + acc
p acc
else
acc
p acc
end
end
###这段代码的错误就是,本来会把ele + acc 或者是 acc 的值存入acc以备之后使用,但是p acc这个function会返回一个值,p acc == acc,这样一来,原本应该存入的信息,都被改写成了acc的值,所以会错。ruby是不需要return的,有时最后一行代码的返回值就是return值。
今天的难点就这么多,学习的重点是一些基本的array function,简单算法,Array.new的注意事项。
App Academy的日程还是比较紧的,据说每天想保持八个小时的睡眠都很困难。为自己加油!!!