王筝的博客
ruby学习

https://git-scm.com/book/zh/v1/Git-%E5%9F%BA%E7%A1%80-%E6%92%A4%E6%B6%88%E6%93%8D%E4%BD%9C

 

撤消操作

任何时候,你都有可能需要撤消刚才所做的某些操作。接下来,我们会介绍一些基本的撤消操作相关的命令。请注意,有些撤销操作是不可逆的,所以请务必谨慎小心,一旦失误,就有可能丢失部分工作成果。

修改最后一次提交

有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交:

$ git commit --amend

此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。

启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。

如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。

取消已经暂存的文件

接下来的两个小节将演示如何取消暂存区域中的文件,以及如何取消工作目录中已修改的文件。不用担心,查看文件状态的时候就提示了该如何撤消,所以不需要死记硬背。来看下面的例子,有两个修改过的文件,我们想要分开提交,但不小心用 git add . 全加到了暂存区域。该如何撤消暂存其中的一个文件呢?其实,git status 的命令输出已经告诉了我们该怎么做:

$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   README.txt
        modified:   benchmarks.rb

就在 “Changes to be committed” 下面,括号中有提示,可以使用 git reset HEAD <file>... 的方式取消暂存。好吧,我们来试试取消暂存 benchmarks.rb 文件:

$ git reset HEAD benchmarks.rb
Unstaged changes after reset:
M       benchmarks.rb
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   README.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   benchmarks.rb

这条命令看起来有些古怪,先别管,能用就行。现在 benchmarks.rb 文件又回到了之前已修改未暂存的状态。

取消对文件的修改

如果觉得刚才对 benchmarks.rb 的修改完全没有必要,该如何取消修改,回到之前的状态(也就是修改之前的版本)呢?git status 同样提示了具体的撤消方法,接着上面的例子,现在未暂存区域看起来像这样:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   benchmarks.rb

在第二个括号中,我们看到了抛弃文件修改的命令(至少在 Git 1.6.1 以及更高版本中会这样提示,如果你还在用老版本,我们强烈建议你升级,以获取最佳的用户体验),让我们试试看:

$ git checkout -- benchmarks.rb
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   README.txt

可以看到,该文件已经恢复到修改前的版本。你可能已经意识到了,这条命令有些危险,所有对文件的修改都没有了,因为我们刚刚把之前版本的文件复制过来重写了此文件。所以在用这条命令前,请务必确定真的不再需要保留刚才的修改。如果只是想回退版本,同时保留刚才的修改以便将来继续工作,可以用下章介绍的 stashing 和分支来处理,应该会更好些。

记住,任何已经提交到 Git 的都可以被恢复。即便在已经删除的分支中的提交,或者用 --amend 重新改写的提交,都可以被恢复(关于数据恢复的内容见第九章)。所以,你可能失去的数据,仅限于没有提交过的,对 Git 来说它们就像从未存在过一样。

视频分析    http://v.youku.com/v_show/id_XMTY1MTMzNjAyNA==.html

 

(1)定义两个指针

    ListNode fast = head;

    ListNode slow = head; 

(2)将快指针向前移动N步

(3.1)判断此时快指针是否已经到达尽头,如果是,头节点就是要删除的节点,返回head.next。

 

(3.2)将快慢两个指针同时以相同的速度往前移动,当快指针走到尽头的时候,慢指针的下一个位置就是倒数第N个节点,将慢指针next指向next.next.

public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
       
        
        ListNode fast = head;
        ListNode slow = head;
        
        for(int i=0;i<n;i++){
            fast = fast.next;
        }
        
        if(fast == null){
            head = head.next;
            return head;
        }
        
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        
        slow.next = slow.next.next;
        return head;
    }
}

import java.io.*;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
class test  
{
    public static void main (String[] args) throws java.lang.Exception
    {
        int[] B = {6,7,8,9,1,2,3,4,5};
        int[][] c = {{1,   3,  5,  7},{10, 11, 16, 20}, {23, 30, 34, 50}};

        System.out.println(search_mini(B));
        System.out.println(search(B,1));
        System.out.println(Arrays.toString(search_2d_matrix(c,30)));
    }
    
    public static int[] search_2d_matrix(int[][] matrix, int target){
        int row = matrix.length, column = matrix[0].length;
        int begin = 0, end = row * column ;
        int[] result = {-1, -1};
        
        while (begin + 1 < end) {
            int mid = (begin +  end) / 2;
            int number = matrix[mid / column][mid % column];
            if (number == target) {
                result[0] = mid / column;
                result[1] = mid % column;
                return result;
            } else if (number < target) {
                begin = mid;
            } else {
                end = mid;
            }
        }
        return result;
    }
    
    
    public static int search_mini(int[] A){
        int begin = 0, end = A.length - 1; 
        while (begin < end && A[begin] >= A[end]) {
            int mid = (begin + end) / 2;  
            if (A[mid] > A[end]) { 
                begin = mid + 1;  
            } else if (A[mid] < A[begin]) {  
                end = mid;  
            } else {   // A[begin] == A[mid] == A[end] 
             begin = begin + 1;
            } 
        }
         return A[begin];  
    }
    
    public static int search(int[] A, int target){
        int begin = 0;
        int end = A.length ;
        while(begin < end){
            int p = (end + begin) / 2;
            if(A[p] == target) return p;
            else if(A[p] > A[begin]  ){
                if(target >= A[begin] && target < A[p]){
                    end = p;
                }
                else begin = p + 1;
            }
            else{
                if(target > A[p] && target <= A[end - 1] ){
                    begin = p + 1;
                }
                else end = p;
            }
            
        }
        return -1;
    }
}

 

 

Numeric Inputs

Numbers are even easier to validate than text. For number input types, the HTML5 spec gives youattributes like minmax, and step. Each of these do pretty much what you would expect.

min and max set the minimum and maximum values that the arrows in the input will allow. stepsets the increments for between possible values. There’s also value, which sets the starting value of the input.

Of course, you’ll probably notice that users can still type whatever number they want into numeric inputs. If you want to really limit possible values, consider a range instead.

Range Inputs

The range input type creates a slider on the page. It also has minmaxstep and value attributes. If you want to display the current value of the range when it changes, you’ll need to use some JavaScript to pull the value from the range. Here’s an example:

  // grab <input id="range-example" type="range" min="0" max="5" step="1"> from the page
    var rangeInput = document.querySelector('input#range-example');

    // grab <p id="output"></p> to display the output
    var output = document.querySelector('p#output');

    // update the display when the range changes
    rangeInput.onchange = function() {
        output.innerHTML = this.value;
    };
<input type=number>
<input type=number min=100 max=999 step=5>

 

http://guides.rubyonrails.org/v3.0.8/active_record_validations_callbacks.html#on

在特定的action里使用validates

The :on option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be run on save (both when you’re creating a new record and when you’re updating it). If you want to change it, you can use :on => :create to run the validation only when a new record is created or :on => :update to run the validation only when a record is updated.

class Person < ActiveRecord::Base
  # it will be possible to update email with a duplicated value
  validates_uniqueness_of :email, :on => :create
 
  # it will be possible to create the record with a non-numerical age
  validates_numericality_of :age, :on => :update
 
  # the default (validates on both create and update)
  validates_presence_of :name, :on => :save
end

 

 

pry(main)> puts “showlastupdate:{\”$gte\”:\”#{Date.today.to_s(:number)}\”}”
showlastupdate:{“$gte”:”20160601″}

flash.now[:error] = ""
render :new


flash[:error] = ""
redirect videos_path

http://guides.rubyonrails.org/action_controller_overview.html

The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for passing error messages etc.

It is accessed in much the same way as the session, as a hash (it’s a FlashHash instance).

Let’s use the act of logging out as an example. The controller can send a message which will be displayed to the user on the next request:

class LoginsController < ApplicationController
  def destroy
    session[:current_user_id] = nil
    flash[:notice] = "You have successfully logged out."
    redirect_to root_url
  end
end

Note that it is also possible to assign a flash message as part of the redirection.

You can assign :notice:alert or the general purpose :flash:

redirect_to root_url, notice: "You have successfully logged out."
redirect_to root_url, alert: "You're stuck here!"
redirect_to root_url, flash: { referral_code: 1234 }

The destroy action redirects to the application’s root_url, where the message will be displayed. Note that it’s entirely up to the next action to decide what, if anything, it will do with what the previous action put in the flash. It’s conventional to display any error alerts or notices from the flash in the application’s layout:

<html>
  <!-- <head/> -->
  <body>
    <% flash.each do |name, msg| -%>
      <%= content_tag :div, msg, class: name %>
    <% end -%>
 
    <!-- more content -->
  </body>
</html>

This way, if an action sets a notice or an alert message, the layout will display it automatically.

You can pass anything that the session can store; you’re not limited to notices and alerts:

<% if flash[:just_signed_up] %>
  <p class="welcome">Welcome to our site!</p>
<% end %>

If you want a flash value to be carried over to another request, use the keep method:

class MainController < ApplicationController
  # Let's say this action corresponds to root_url, but you want
  # all requests here to be redirected to UsersController#index.
  # If an action sets the flash and redirects here, the values
  # would normally be lost when another redirect happens, but you
  # can use 'keep' to make it persist for another request.
  def index
    # Will persist all flash values.
    flash.keep
 
    # You can also use a key to keep only some kind of value.
    # flash.keep(:notice)
    redirect_to users_url
  end
end
5.2.1 flash.now

By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request.

For example, if the create action fails to save a resource and you render the new template directly,

that’s not going to result in a new request, but you may still want to display a message using the flash.

To do this, you can use flash.now in the same way you use the normal flash:

class ClientsController < ApplicationController
  def create
    @client = Client.new(params[:client])
    if @client.save
      # ...
    else
      flash.now[:error] = "Could not save client"
      render action: "new"
    end
  end
end

 

今天存储数据的时候报错,发现是3435065640超出了常规int的存储长度,

RangeError (3435065640 is out of range for ActiveRecord::Type::Integer with limit 4)

$ bundle exec rails db -p
mysql> desc recommended_videos;
+-------------------------+--------------+------+-----+---------+----------------+
| Field                   | Type         | Null | Key | Default | Extra          |
+-------------------------+--------------+------+-----+---------+----------------+
| id                      | int(11)      | NO   | PRI | NULL    | auto_increment |
| video_id                | varchar(255) | YES  |     |         |                |
| res_desc                | text         | YES  |     | NULL    |                |
| state                   | int(11)      | YES  |     | 0       |                |
| created_at              | datetime     | YES  |     | NULL    |                |           |
+-------------------------+--------------+------+-----+---------+----------------+

http://dev.mysql.com/doc/refman/5.7/en/integer-types.html

12.2.1 Integer Types (Exact Value) – INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT

MySQL supports the SQL standard integer types INTEGER (or INT) and SMALLINT. As an extension to the standard, MySQL also supports the integer types TINYINTMEDIUMINT, and BIGINT. The following table shows the required storage and range for each integer type.


Type Storage Minimum Value Maximum Value
(Bytes) (Signed/Unsigned) (Signed/Unsigned)
TINYINT 1 -128 127
0 255
SMALLINT 2 -32768 32767
0 65535
MEDIUMINT 3 -8388608 8388607
0 16777215
INT 4 -2147483648 2147483647
0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807
0 18446744073709551615
int的存储上限是2147483647,
所以change_column
class ChangeTotalVvTypeToRecommendedVideos < ActiveRecord::Migration
  def change
    change_column :recommended_videos, :total_vv, :integer, :limit => 8
  end 
end
mysql> desc recommended_videos;
+-------------------------+--------------+------+-----+---------+----------------+
| Field                   | Type         | Null | Key | Default | Extra          |
+-------------------------+--------------+------+-----+---------+----------------+
| id                      | int(11)      | NO   | PRI | NULL    | auto_increment |
| state                   | int(11)      | YES  |     | 0       |                |
| sequence                | int(11)      | YES  |     | 1       |                |
| created_at              | datetime     | YES  |     | NULL    |                |
| updated_at              | datetime     | YES  |     | NULL    |                |
| total_vv                | bigint(20)   | YES  |     | NULL    |                |
+-------------------------+--------------+------+-----+---------+----------------+

 

When you first started coding, errors were probably the last thing you wanted to see.

After all, it’s not a far stretch to associate “error” with “I messed up”.

Hopefully by now you’ve come to appreciate the value of a good error message. Take a look at the two following errors:

one + 3
NameError: undefined local variable or method 'one' for main:Object
one + 3
TypeError: no implicit conversion of Fixnum into String

Both errors were triggered by the same line of code. Each is a totally different error message, though.

The first, NameError, lets you know that one is a variable that hasn’t been defined. To fix this, you’ll have to actually define the variable one.

The second, TypeError, lets you know that you’re trying to add a Fixnum to a String.

Here, there’s a good chance that one is a variable that is already set to a String.

Because these errors were meaningful errors, they allowed you to debug your program painlessly, and ideally also provided a learning opportunity.

Inheriting an Exception

In Ruby, just about everything is an object, including errors. Turns out that NameError andTypeError are simply the class names for these errors!

All errors inherit their functionality from the Exception class.

There are about twenty or so default errors baked into Ruby (read more about them here) and some indicate more serious issues than others.

Issues that deal with problems in your code (as opposed to your computer being on fire) all inherit from StandardError. This includes errors like NameError and TypeError.

This means that if you’ve got a custom error that you’d like to create, like anInvalidPasswordError, you can easily create one by inheriting from StandardError.

class InvalidPasswordError < StandardError
end

It’s really that easy. You don’t even need anything inside this class!

To manually trigger an exception or error, which can be described as “raising” or “throwing” an exception, use the raise keyword.

raise InvalidPasswordError
InvalidPasswordError: InvalidPasswordError

Easy enough. Now you know that you can raise this InvalidPasswordError whenever it’s appropriate.

May I suggest you use it when a password is… invalid?

But this still isn’t super descriptive. Luckily, you can raise an error with an additional message.

raise InvalidPasswordError, "The password you entered is invalid."
InvalidPasswordError: The password you entered is invalid.

That’s more like it. Now it’s explicit what went wrong when this particular exception was thrown.

This is by no means a comprehensive guide to throwing errors and exceptions.

This material could fill a course by itself, and it is a topic we will return to later in this material.

This is, however, the most common way you’ll see exceptions and errors being thrown in the wild.

Exceptional Errors

When other developers are using your code, it’s a good idea to bake meaningful errors right into your public API.

Let’s see how you might be able to use this InvalidPasswordError in the context of the examples from earlier in the lesson.

class InvalidPasswordError < StandardError
end

class Customer
  attr_reader :funds

  def initialize(funds, password)
    @password = password
    @funds = funds
  end

  def withdraw_securely(amount, password)
    if password == @password
      remove_funds(amount)
    else
      raise InvalidPasswordError, "'#{password}' is not the correct password."
    end
  end

  private

  def remove_funds(amount)
    @funds -= amount
  end
end

Now, if the correct password was entered, the funds are removed as expected.

But this time, if the incorrect password is entered, your new InvalidPasswordError is thrown with a useful little message.

 

kim = Customer.new(1000, "coolpassword")
# => #<Customer:0x007faabc8012b8 @password="coolpassword", @funds=1000>
kim.withdraw_securely(200, "coolpassword")
# => 800
kim.withdraw_securely(150, "badpassword")
InvalidPasswordError: 'badpassword' is not the correct password.

That’s so useful!

 

Often, classes will have shared characteristics with other classes.

Rewriting the same methods for each class over and over again can be pretty cumbersome, and not always necessary.

class BankTeller
  def get_paid
    # method stuff...
  end

  def come_to_work
    # method stuff...
  end

  def go_on_vacation!
    # method stuff...
  end

  def do_bank_teller_stuff
    # method stuff...
  end
end

class LoanSpecialist
  def get_paid
    # method stuff...
  end

  def come_to_work
    # method stuff...
  end

  def go_on_vacation!
    # method stuff...
  end

  def do_loan_specialist_stuff
    # method stuff...
  end
end

I mean, just look at these two classes! They’re nearly identical!

The only differences are thedo_bank_teller_stuff and do_loan_specialist_stuff methods.

Both of these classes have characteristics that are shared across all employees.

Being redundant like this works, but will quickly cause problems if you decide that employees should be paid bi-weekly instead of on a fixed day of the month.

You’d have to update the get_paid method for every single employee class! Right now you’ve only got two,

but what if you had 30 different roles in the company. No thank you.

Here, you can use inheritance to share traits across various classes.

class Employee
  def get_paid
    # method stuff...
  end

  def come_to_work
    # method stuff...
  end

  def go_on_vacation!
    # method stuff...
  end
end

class BankTeller < Employee
  def do_bank_teller_stuff
    # method stuff...
  end
end

class LoanSpecialist < Employee
  def do_loan_specialist_stuff
    # method stuff...
  end
end

You can use the < when defining these classes to indicate that LoanSpecialist and BankTellerare the children of Employee.

When this happens, they inherit all the methods of the parent class. You can continue to define new methods for the child class as you normally would.

Note that a child can only have one parent class.

This technique of inheritance is a handy way to reduce code duplication and logically separate out the concerns of your code.

Feeling Protected

We previously mentioned that in addition to the public and private keywords, there is also aprotected keyword.

private and protected are similar in many ways, with one key difference: private methods are not shared through inheritance,

whereas protected methods are shared across all children classes.