Python程序设计 作业2(上)

简介: Python程序设计 作业2

1. 完成课程讲义中状态机的实现:


fe08e3006c284663b4f7695c55214bd9.png


(1) 累加器 Accumulator


例子:列表[-1, 2, 3, -2, 5, 6]中的数字相加,我们得到和是 13。


output = Accumulator().transduce([-1,2,3,-2,5,6]) #output=[-1, 1, 4, 2, 7, 13]


(2) 二进制相加 Binary_Addition


例子:011 和 001 相加我们得到 100。

output = Binary_Addition().transduce([(1,1),(1,0),(0,0)]) #output=[0, 0, 1]


(3) 反向器 Reverser


实现一个反向器,逆向输出一个序列。输入的形式如下:

sequence1 + [‘end’] + sequence2

其中 sequence1 是字符串列表,‘end’表示 sequence1 的终结,sequence2 为任意序列。反向器的作用如下:当 sequence1 里的每个元素输入时,反向器输出 None。当[‘end’]和 sequence2 的每个元素输入时,反向器依次反向输出 sequence1 中的元素;当没有元素输出时,则输出 None。


例子:

output = Reverser().transduce([‘foo’,’ ', ‘bar’] + [‘end’] + list(range(5))) #output = [None, None, None, ‘bar’, ’ ', ‘foo’, None, None, None]

解释:输出中前三个 None 为输入 sequence1 时输出。从输入‘end’开始,sequence1 中的元素开始反向输出。sequence1 输出完毕后,继续输出 None。(即输入 list(range(5))中的 2,3,4 时)。


更多测试例子:

①output=Reverser().transduce([‘foo’, ’ ', ‘bar’] + [‘end’] + [‘end’]*3+list(range(2)))
#output = [None, None, None, ‘bar’, ’ ', ‘foo’, None, None, None]
②output = Reverser().transduce(list(‘the’) + [‘end’] + list(range(3)))
#output = [None, None, None, ‘e’, ‘h’, ‘t’, None]
③output=Reverser().transduce([] + [‘end’] + list(range(5)))
#output = [None, None, None, None, None, None]
④output=output=Reverser().transduce(list(‘nehznehS evol I’) + [‘end’]+ list(range(15)))
#output = [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ‘I’, ’ ', ‘l’, ‘o’, ‘v’, ‘e’, ’ ', ‘S’, ‘h’, ‘e’, ‘n’, ‘z’, ‘h’, ‘e’, ‘n’, None]

实现要求:

(1) 不同的状态机子类继承父类 SM;

(2) 补充父类的 transduce 函数,子类不能重写 transduce 函数;

(3) 补充每个子类的 transition_fn 和 output_fn 函数,其中累加器的实现代码如下:

class Accumulator(SM): 
    start_state = 0
    def transition_fn(self, s, x): 
        return s + x
    def output_fn(self, s): 
        return s

建议:利用累加器的代码实现父类的 transduce 函数,再实现二进制相加和反向器的 transition_fn 和 output_fn 函数。


【解题思路】

①定义状态机:

首先定义一个状态机,设置初始状态用于传递运行状态。然后定义初始状态转移函数与输出函数。只在父类中定义基本的方法即可,并只需实现状态转移的transduce方法即可,其他方法在子类中实现即可。


②定义累加器类:

累加器类是继承于状态机类的子类。对于累加器类,可以根据下一状态都等于上一状态加上传入的参数的特性编写状态转移函数。对于输出函数,只需直接返回累加完的当前状态表示结果即可。


③定义二进制加法类:

二进制加法类是继承于状态机类的子类。对于二进制加法类,采取一个元组表示当前状态值,元组的第一个元素表示进位值,即记录低一位是否产生进位。元组的第二个元素表示已经计算的当前结果,由于二进制是逆序存储的,故对于每次加法,只需将计算出来的结果append到列表的结尾即可。

对于每次加法,一共有4种可能情况,穷举4种情况,依次进行判断即可。

最后的输出函数,需要再对最终是否产生进位进行一次判断,如果不产生进位,则直接返回元组的第二个参数即可;如果产生进位,则先执行append(1)后,再返回元组的第二个元素即可。


④定义反相器:

反相器类是继承于状态机类的子类。对于反相器类,采取的方法是记录‘end’的位置,最后统一进行计算的方法。状态值是一个四元元组分别表示是否结束,len的位置,seq1的长度和已经输入的列表。在输出中直接处理即可。


【编程实现】

# 定义状态机
class StateMachine:
    def __init__(self):
        self.start_state = None  # default start state
    def transition_fn(self, s, x):
        pass
    def output_fn(self, s):
        pass
    def transduce(self, input_seq):
        for i in range(len(input_seq)):
            self.start_state = self.transition_fn(self, self.start_state, input_seq[i])
        print(self.output_fn(self, self.start_state))
# 定义累加器
class Accumulator(StateMachine):
    start_state = 0
    def transition_fn(self, s, x):
        return s + x
    def output_fn(self, s):
        return s
# 定义二进制相加器
class Binary_Addition(StateMachine):
    start_state = (0, [])  # (carry,digit)
    def transition_fn(self, s, x):
        temp = s[1]
        # 分情况判断进位
        if s[0] + x[0] + x[1] == 3:
            temp.append(1)
            s = (1, temp)
        elif s[0] + x[0] + x[1] == 2:
            temp.append(0)
            s = (1, temp)
        elif s[0] + x[0] + x[1] == 1:
            temp.append(1)
            s = (0, temp)
        else:
            temp.append(0)
            s = (0, temp)
        return s
    def output_fn(self, s):
        # 判断最高位进位
        if s[0] == 1:
            s[1].append(1)
        return s[1]
# 定义反相器
class Reverser(StateMachine):
    start_state = (0, 0, 0, [])  # isEnd,len(seq1),total lenth
    def transition_fn(self, s, x):
        # 不断刷新state中的值
        temp = s[3]
        temp.append(x)
        if s[0] == 1:
            return 1, s[1], s[2] + 1, temp
        if x == 'end':
            return 1, s[1], s[2] + 1, temp
        else:
            return 0, s[1] + 1, s[2] + 1, temp
    def output_fn(self, s):
        # 循环获取输出
        res = []
        for i in range(s[2]):
            if i < s[1]:
                res.append(None)
            elif s[1] <= i <= 2 * s[1] - 1:
                res.append(s[3][2 * s[1] - 1 - i])
            else:
                res.append(None)
        return res

首先定义状态机父类,定义构造函数,输出函数,状态转换函数,以及transduce函数。通过仔细观察几个输入样例,不难发现,输入的list中的项数跟需要操作的次数相同,因此可以直接使用循环循环插传入list的长度,然后调用输出函数即可。


累加器类是继承于状态机类的子类。对于累加器类,可以根据下一状态都等于上一状态加上传入的参数的特性编写状态转移函数。对于输出函数,只需直接返回累加完的当前状态表示结果即可。


二进制加法类是继承于状态机类的子类。对于二进制加法类,采取一个元组表示当前状态值,元组的第一个元素表示进位值,即记录低一位是否产生进位。元组的第二个元素表示已经计算的当前结果,由于二进制是逆序存储的,故对于每次加法,只需将计算出来的结果append到列表的结尾即可。对于每次加法,一共有4种可能情况,即产生进位与否,当前位是0还是1。依次进行判断即可。最后的输出函数,需要再对最终是否产生进位进行一次判断,如果不产生进位,则直接返回元组的第二个参数即可;如果产生进位,则先执行append(1)后,再返回元组的第二个元素即可。


反相器类是继承于状态机类的子类。对于反相器类,采取的方法是记录‘end’的位置,最后统一进行计算的方法。状态值是一个四元元组分别表示是否结束,len的位置,seq1的长度和已经输入的列表。在输出中直接处理即可。最后输出时,只需首先输出seq1的长度个None,然后依次进行反向输出,最后再补齐None即可。


【测试结果】

(1)累加器:

输入:


2399109d172544ebb2475743648a0450.png

输出:

3e3deb16d20c4e49a73cf424d4524d2d.png

(2)二进制加法器:

输入:

62286f322ee643b491b760b112efc197.png


输出:

ca3c29ee992845a1928b8d94305a4a96.png


(3)反相器:

输入:

6f9238e96ba64d829bcdd02e36a74c78.png


输出:

0c71717d175346fc971398d543494a3a.png


输入:

84b03382fada46d2bf5dfb04ef6d5c38.png

输出:

3271e7f935d440dba8babda7311ada75.png


输入:

e76f8393c7444e25b2521cb731ab5796.png

输出:

c8c6c980a4ae4ae78a632cc78dbab8af.png

输入:

d3bc275ec76e43a2a8e734db24a5e11c.png

输出:

93e534fb41784639a6613408359b6651.png

[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ‘I’, ’ ', ‘l’, ‘o’, ‘v’, ‘e’, ’ ', ‘S’, ‘h’, ‘e’, ‘n’, ‘z’, ‘h’, ‘e’, ‘n’, None]


相关文章
|
9月前
|
Python
Python编程作业五:面向对象编程
Python编程作业五:面向对象编程
90 1
|
7月前
|
人工智能 数据挖掘 大数据
爆赞!GitHub首本标星120K的Python程序设计人工智能案例手册
为什么要学习Python? Python简单易学,且提供了丰富的第三方库,可以用较少的代码完成较多的工作,使开发者能够专注于如何解决问题而只花较少的时间去考虑如何编程。此外,Python还具有免费开源、跨平台、面向对象、胶水语言等优点,在系统编程、图形界面开发、科学计算、Web开发、数据分析、人工智能等方面有广泛应用。尤其是在数据分析和人工智能方面,Python已成为最受开发者欢迎的编程语言之一,不仅大量计算机专业人员选择使用Python进行快速开发,许多非计算机专业人员也纷纷选择Python语言来解决专业问题。 由于Python应用广泛,关于Python的参考书目前已经有很多,但将Pytho
|
7月前
|
分布式计算 NoSQL 物联网
麻省理工IOT教授撰写的1058页Python程序设计人工智能实践手册!
Python是世界上最流行的语言之一,也是编程语言中使用人数增长最快的一种。 开发者经常会很快地发现自己喜欢Python。他们会欣赏Python的表达力、可读性、简洁性和交互性,也会喜欢开源软件开发环境,这个开源环境正在为广泛的应用领域提供快速增长的可重用软件基础。 几十年来,一些趋势已经强有力地显现出来。计算机硬件已经迅速变得更快、更便宜、更小;互联网带宽已经迅速变得越来越大,同时也越来越便宜;优质的计算机软件已经变得越来越丰富,并且通过“开源”方式免费或几乎免费;很快,“物联网”将连接数以百亿计的各种可想象的设备。这将导致以快速增长的速度和数量生成大量数据。 在今天的计算技术中,最新的创新
|
7月前
|
分布式计算 NoSQL 物联网
麻省理工IOT教授撰写的1058页Python程序设计人工智能实践手册!
Python是世界上最流行的语言之一,也是编程语言中使用人数增长最快的一种。 开发者经常会很快地发现自己喜欢Python。他们会欣赏Python的表达力、可读性、简洁性和交互性,也会喜欢开源软件开发环境,这个开源环境正在为广泛的应用领域提供快速增长的可重用软件基础。
|
8月前
|
人工智能 数据挖掘 大数据
538个代码示例!麻省理工教授的Python程序设计+人工智能案例实践
Python简单易学,且提供了丰富的第三方库,可以用较少的代码完成较多的工作,使开发者能够专注于如何解决问题而只花较少的时间去考虑如何编程。 此外,Python还具有免费开源、跨平台、面向对象、胶水语言等优点,在系统编程、图形界面开发、科学计算、Web开发、数据分析、人工智能等方面有广泛应用。 尤其是在数据分析和人工智能方面,Python已成为最受开发者欢迎的编程语言之一,不仅大量计算机专业人员选择使用Python进行快速开发,许多非计算机专业人员也纷纷选择Python语言来解决专业问题。 由于Python应用广泛,关于Python的参考书目前已经有很多,但将Python编程与数据分析、人工智
|
8月前
|
Python
选择程序设计(python)
选择程序设计(python)
|
8月前
|
存储 Python
顺序结构程序设计(python)
顺序结构程序设计(python)
|
9月前
|
数据安全/隐私保护 Python
python作业
python作业
48 2
|
8月前
|
人工智能 数据挖掘 大数据
538个代码示例!麻省理工教授的Python程序设计+人工智能案例实践
Python简单易学,且提供了丰富的第三方库,可以用较少的代码完成较多的工作,使开发者能够专注于如何解决问题而只花较少的时间去考虑如何编程。 此外,Python还具有免费开源、跨平台、面向对象、胶水语言等优点,在系统编程、图形界面开发、科学计算、Web开发、数据分析、人工智能等方面有广泛应用。 尤其是在数据分析和人工智能方面,Python已成为最受开发者欢迎的编程语言之一,不仅大量计算机专业人员选择使用Python进行快速开发,许多非计算机专业人员也纷纷选择Python语言来解决专业问题。 由于Python应用广泛,关于Python的参考书目前已经有很多,但将Python编程与数据分析、人工智
|
9月前
|
存储 传感器 Python
Python编程作业四:文件操作
Python编程作业四:文件操作
116 0

热门文章

最新文章