human
(3) 成员访问方法
接下来介绍一些处理对象访问的方法，这些方法允许你创建自己的序列或者映射。   
基本的序列和映射规则很简单，但如果要实现它们全部功能就需要实现很多特殊函数。下面将会说到：
基本的序列和映射规则     
序列和映射是对象的集合。为了实现它们基本的行为（规则），如果对象是不可变的（如字符串和元组）。那么就需要使用两个特殊方法，如果是可变的（列表和字典），则需要使用4个。
a. __len__(self):这个方法返回集合中所含对象的数量。对于序列来说，这就是元素的个数；对于映射来说，则是键-值对的数量。
b. __getitem__(self,key):这个方法返回与所给键对应的值。对于序列来说，键应该是一个0~n-1的整数（或者像后面所说的负数）；对于映射来说，可以使用任何种类的键。
c. __setitem__(self,key,value):这个方法按一定的方式存储和key关联的value，该值随后可使用 __getitem__来获取。当然，只能为可以修改的对象定义这个方法。
d. __delitem__(self,key):这个方法在对一部分对象使用del语句时被调用，同时删除和键关联的值。这个方法也是为可修改的对象定义的。     
对这些方法的附件要求：   
a. 对于一个序列来说，如果键是负整数，那么要从末尾开始计数。换句话说就是x[-n]和x[len(x)-n]是一样的；  
b. 如果键是不合适的类型（例如，对序列使用字符串作为键），会引发一个TypeError异常.
   
c. 如果序列的索引是正确的类型，但超出了范围，会引发一个IndexError异常。   
让我们实践一下—看看如果创建一个无穷序列，会发生什么："
Please write code following the instructions in jupyter notebook style.

=====
Give me a code to (3) 成员访问方法 and the other steps required?
assistant
#Here is code to (3) 成员访问方法 and the other steps required.

def checkIndex(key):
    """所给的键能接受索引吗？
    为了能被接受，键应该是一个非负的整数，如果它不是一个整数，比如是字符串，会引发TypeError;
    如果它是负数，则会引发IndexError（因为序列是无限长的）。
    """
    if not isinstance(key,(int,long)):
        raise TypeError
    if key<0:
        raise IndexError
class ArithmeticSequence:
    def __init__(self,start=0,step=1):
        """初始化算数序列
        初始值-序列中的第一个值
        步长-两个相邻值之间的差别
        改变-用户修改的值的字典
        """
        self.start=start
        self.step=step
        self.changed={}  #没有项被修改
    def __getitem__(self,key):
        """Get an item from the arithmetic sequence.
        """
        checkIndex(key)
        try:
            return self.changed[key]             #修改了吗？
        except KeyError:                         #否则...
            return self.start+key*self.step      #...计算值
    def __setitem__(self,key,value):
        """修改算术序列中的一个项
        """
        checkIndex(key)
        self.changed[key]=value
s=ArithmeticSequence(1,2)
s[4]

s[4]=2
s[4]

s[5]