diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..723ef36f4e4f32c4560383aa5987c575a30c6535 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/chess_floor_ethan.py b/chess_floor_ethan.py deleted file mode 100644 index 1256f7feca764213dee67e4dbd623e4da2e344f2..0000000000000000000000000000000000000000 --- a/chess_floor_ethan.py +++ /dev/null @@ -1,27 +0,0 @@ -import turtle as t -t.setup(500, 500) -t.speed('fastest') -def block(size, filled): - if filled == True: - t.begin_fill() - for c in range(4): - t.forward(size) - t.right(90) - if filled == True: - t.end_fill() - -size = 10 -num = 8 -filled = True -for c in range(1, num*num+1): - block(size, filled) - if c%num == 0: - t.sety(t.ycor()-size) - t.setx(0) - else: - t.forward(size) - if filled == True: - filled = False - else: - filled = True -t.done() \ No newline at end of file diff --git a/queens_charlie.py b/ex131.py similarity index 41% rename from queens_charlie.py rename to ex131.py index b3e61a69a4dc9ce59d6a12db39f7450060eab55f..e14d614b13df1f6e41727d2c644e35d0147f9d16 100644 --- a/queens_charlie.py +++ b/ex131.py @@ -1,43 +1,38 @@ import turtle -stage = turtle.Screen() t = turtle.Turtle() +stage = turtle.Screen() stage.setup(1000, 800) -def draw_square(color, size=75): +def draw_square(color, x=0, y=0): + t.setpos(x, y) t.begin_fill() t.fillcolor(color) + for i in range(4): - t.forward(size) t.left(90) + t.forward(50) t.end_fill() -def draw_mosaic(size): +for i in range(2): + t.pendown() draw_square('white') t.left(180) - draw_square('white') + +for l in range(4): t.seth(90) + t.forward(50) draw_square('black') t.seth(270) - t.forward(size) - t.left(90) - draw_square('black') + t.forward(50) t.hideturtle() + draw_square('black') +t.showturtle() +t.pencolor('green') +t.pendown() +t.forward(50) - def plate(sides): - lines = [1, 7, 0, 2, 5, 3, 6, 4] - q1 = turtle.Turtle() - q2 = turtle.Turtle() - q3 = turtle.Turtle() - q4 = turtle.Turtle() - q5 = turtle.Turtle() - q6 = turtle.Turtle() - q7 = turtle.Turtle() - q8 = turtle.Turtle() - - -draw_mosaic(75) -stage.mainloop() +stage.mainloop() \ No newline at end of file diff --git a/graph_charlie.py b/graph_charlie.py deleted file mode 100644 index d6733a1e96720c96cdb74302c79a50e5da8ed723..0000000000000000000000000000000000000000 --- a/graph_charlie.py +++ /dev/null @@ -1,33 +0,0 @@ -# Coded by Charlie - -import turtle -from time import sleep as wait - -t = turtle.Pen() -stage = turtle.Screen() - - -def draw_polygon(sides, size, color): - t.begin_fill() - t.fillcolor(color) - for counter in range(sides): - t.forward(size) - t.left(360 / sides) - t.end_fill() - - -draw_polygon(70, 10, 'DODGER BLUE') -t.penup() -t.goto(0, 100) -t.write('is it a circle??????', font=('Times', 20)) -wait(2) -t.goto(0, -100) -t.write('NO, IT\'S NOT', font=('Arial', 30)) -wait(1) -t.sety(-150) -t.write('It is a polygon with 70 sides', font=('Times', 20)) -t.sety(-175) -t.write('with 10 step a side.', font=('Times', 17)) - - -stage.mainloop() diff --git a/queens_solution.py b/queens_solution.py new file mode 100644 index 0000000000000000000000000000000000000000..b6696f2b5c691acc9fc3bee872960aaec077393d --- /dev/null +++ b/queens_solution.py @@ -0,0 +1,131 @@ +import random +import turtle + +NUM_QUEENS = 8 +BOARD_HEIGHT = 400 + +# 子问题 1:检查解法是否正确 +# TODO: validate a solution +def validate(v): + for i in range(len(v)): + for j in range(i+1, len(v)): + if (j-i) == abs(v[j] - v[i]): + return False + return True + + +# 子问题 2:获得一个解法 +# TODO: get a random solution +def get_example(): + for _ in range(10000): + v = list(range(NUM_QUEENS)) + random.shuffle(v) + if validate(v): + return v + return None +# print(get_example()) + + +# 子问题 3:画出解法 +# TODO: draw chessboard & queens +def board(v, side_height): + global chess, queen + + # 画棋盘的一个格子,如果格子上有皇后(occupied),一起画出来 + def draw_tile(x, y, height, color, occupied): + chess.penup() + chess.goto(x, y) + chess.pendown() + chess.fillcolor(color) + chess.begin_fill() + for _ in range(4): + chess.forward(height) + chess.right(90) + chess.end_fill() + if occupied: + queen.goto(x, y-height*1.1) + queen.write('\u265b', align='left', font=('Arial', int(height*.75), 'normal')) + + # 显示当前/总计解法数量 + score.undo() + score.goto(0, BOARD_HEIGHT / 2) + score.write('%i/%i' % (counter, len(solutions)), + align='center', font=('Consolas', int(BOARD_HEIGHT / 12), 'normal')) + + # 画Grid的一般方法,固定左上角坐标,之后用双重循环或单循环取模换行(见Ethan解法) + tile_size = side_height / NUM_QUEENS + x_base, y_base = - tile_size * NUM_QUEENS / 2, tile_size * NUM_QUEENS / 2 + + black_white = ['black', 'white'] + for row in range(NUM_QUEENS): + for col in range(NUM_QUEENS): + draw_tile(x_base + col * tile_size, + y_base - row * tile_size, + tile_size, + black_white[(row+col) % 2], + v[row] == col) + +# vec = [5, 2, 6, 1, 7, 4, 0, 3] +# print(vec) +# board(vec, 400) + +# TODO: find all solutions +def solve(v, num=0): + global solutions + if num == len(v): + solutions.append(list(v)) + return + for col in range(len(v)): + v[num], flag = col, True + for row in range(num): + if v[row] == col or abs(col - v[row]) == num - row: + flag = False + break + if flag: + solve(v, num + 1) + + +def restart(): + global counter + counter = 0 + + solve([None] * 8) + + queen.penup() + queen.color('gold') + score.penup() + chess.speed(0) + + update() + stage.onkey(update, 'space') + + +# TODO: update the screen +def update(): + stage.onkey(None, 'space') + global counter + if counter >= len(solutions): + restart() + return + + counter += 1 + board(solutions[counter], BOARD_HEIGHT) + + stage.onkey(update, 'space') + + +# initialize turtle graphics objects +chess = turtle.Turtle('blank') +score = turtle.Turtle('blank') +queen = turtle.Turtle('blank') + +stage = turtle.Screen() +stage.setup(600, 600) +stage.tracer(False) + +counter = 0 +solutions = [] +restart() + +stage.listen() +stage.mainloop() \ No newline at end of file diff --git a/story.txt b/story.txt index 5e7e5952271a47014d7fd247afadec8cf52b41a2..811812c421450ef70fb9abf9a246e398e281a121 100644 --- a/story.txt +++ b/story.txt @@ -1,2 +1 @@ [W] 我睁开眼, 发现自己站在一个巨大的鼻孔里. -[Judy] 突然,鼻孔的主人打了一个喷嚏。 diff --git a/week12/README_FIRST.txt b/week12/README_FIRST.txt new file mode 100644 index 0000000000000000000000000000000000000000..e98d9b20cc23a9e071d754130015ad2b29e9bb57 --- /dev/null +++ b/week12/README_FIRST.txt @@ -0,0 +1,25 @@ +第十二周训练 + +本周学习的中心内容是程序设计五步法。 + +通过本周的学习,同学们将: +1. 理解计划设计对编写出高质量程序的重要性 +2. 熟悉进行程序设计应遵循的五个基本步骤 +3. 学会在PyCharm中添加# TODO:注释 + +** 案例学习 ** + +为了介绍程序设计五步法,我们借助了一个阴阳鱼的程序例子。 + +1. 阅读"第十二周教学导读.pdf",了解五步法的详细内容以及阴阳鱼例子 +2. 阅读以yinyang_为文件名前缀的三个程序文件: + - yinyang_todo_3.py:对应五步法的第三步 + - yinyang_knowledge_4.py:对应五步法的第四步 + - yinyang_final_6.py:最终完成程序 + +** 训练内容 ** + +1. 观看视频Video 12.1程序设计五步法 +2. 尝试自己绘制课上介绍的等角螺线(也称黄金螺线) +3. 完成课后作业Ex12.1飞翔的小鸟 +4. 鼓励完成课后作业Ex12.2键盘控制 diff --git a/week12/bg1.gif b/week12/bg1.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d2576abb68d9b7d8bb4ef4bafec66d3635f9da3 Binary files /dev/null and b/week12/bg1.gif differ diff --git a/week12/bg2.gif b/week12/bg2.gif new file mode 100644 index 0000000000000000000000000000000000000000..b289a74c24ca8af2c3b3939f1547606cf6e83dcb Binary files /dev/null and b/week12/bg2.gif differ diff --git a/week12/bird0.gif b/week12/bird0.gif new file mode 100644 index 0000000000000000000000000000000000000000..0fa3f0e3d4dbe44c9bf0655f9d7d5b99c0c5dcc7 Binary files /dev/null and b/week12/bird0.gif differ diff --git a/week12/bird1.gif b/week12/bird1.gif new file mode 100644 index 0000000000000000000000000000000000000000..9836e809ceaeabc313d1444ce7cbfa511129cfbc Binary files /dev/null and b/week12/bird1.gif differ diff --git a/week12/bird2.gif b/week12/bird2.gif new file mode 100644 index 0000000000000000000000000000000000000000..5351d8a91561a85f82c57412c4fd1c381ea94bfa Binary files /dev/null and b/week12/bird2.gif differ diff --git a/week12/bird_control.py b/week12/bird_control.py new file mode 100644 index 0000000000000000000000000000000000000000..4cca69d73562b5aa4721bab696bce749167b746b --- /dev/null +++ b/week12/bird_control.py @@ -0,0 +1,76 @@ +import turtle +from time import time, sleep +import random + +# TODO: 准备舞台 +stage = turtle.Screen() +stage.bgcolor('azure2') + +# TODO: 导入所有造型 +stage.register_shape('cloud.gif') +costume = ['bird%i.gif' % i for i in range(3)] +for i in range(3): + stage.register_shape(costume[i]) + +# TODO: 生成小鸟 +bird = turtle.Turtle(costume[0]) +bird.penup() +bird.speed(0) + +# TODO: 生成云朵 +cloud = turtle.Turtle('cloud.gif') +cloud.hideturtle() +cloud.penup() +cloud.speed(0) + +# TODO: 设置小鸟的起飞位置为屏幕最左边 +stage_width, stage_height = stage.screensize() + +update_interval = 0.01 # 更新小鸟造型和位置的时间间隔, 单位:秒 +flapping_retarder = 3 # 拍翅膀减速器, 数值越大翅膀挥动地越慢 + +# TODO: 让小鸟向上飞 +def bird_up(): + global y_delta + y_delta = 3 + +def bird_down(): + global y_delta + y_delta = -3 + +stage.onkey(bird_up, 'Up') +stage.onkey(bird_down, 'Down') +stage.listen() + +# TODO: 让角色飞舞起来 + +bird_start_x, bird_speed = -stage_width, 5 +cloud_start_x, cloud_speed = stage_width, 3 + +cloud.seth(180) +cloud_y = random.randint(stage_height/3, stage_height-20) +cloud.goto(cloud_start_x, cloud_y) +cloud.showturtle() + +bird_y = 0 +y_delta = 0 +t = 0 +while True: + bird.shape(costume[int(t/flapping_retarder) % len(costume)]) + bird_y += y_delta + bird.goto(bird_start_x + t * bird_speed, bird_y) + cloud.forward(cloud_speed) + + if cloud.xcor() < -stage_width: + cloud_y = random.randint(stage_height/3, stage_height-20) + cloud.goto(cloud_start_x, cloud_y) + + # 如果飞出屏幕,则重置计时器t,让小鸟回到屏幕最左边的起点 + if bird.xcor() > stage_width: + t = 0 + sleep(update_interval) + t += 1 + + +stage.mainloop() + diff --git a/week12/bird_fly.py b/week12/bird_fly.py new file mode 100644 index 0000000000000000000000000000000000000000..2c718e9d42f4f5b15ac31510e194c7f965d85f84 --- /dev/null +++ b/week12/bird_fly.py @@ -0,0 +1,38 @@ +import turtle +from time import time, sleep + +# TODO: 准备舞台 +stage = turtle.Screen() +stage.bgcolor('azure') + +# TODO: 导入小鸟的所有造型 +costume = ['bird%i.gif' % i for i in range(3)] +for i in range(3): + stage.register_shape(costume[i]) + +# TODO: 生成小鸟 +bird = turtle.Turtle(costume[0]) +bird.penup() +bird.speed(0) +speed = 5 # 小鸟的飞行速度 + +# TODO: 设置小鸟的起飞位置为屏幕最左边 +stage_width, stage_height = stage.screensize() +start_x = - stage_width + +update_interval = 0.01 # 更新小鸟造型和位置的时间间隔, 单位:秒 +flapping_retarder = 3 # 拍翅膀减速器, 数值越大翅膀挥动地越慢 + +# TODO: 让小鸟飞舞起来 +t = 0 +while True: + bird.shape(costume[int(t/flapping_retarder) % len(costume)]) + bird.setx(start_x + t * speed) + # 如果飞出屏幕,则重置计时器t,让小鸟回到屏幕最左边的起点 + if bird.xcor() > stage_width: + t = 0 + sleep(update_interval) + t += 1 + +stage.mainloop() + diff --git a/week12/bird_fly_template.py b/week12/bird_fly_template.py new file mode 100644 index 0000000000000000000000000000000000000000..c8f0569f174d5b58c6fc61dba549fed8dacc9ecf --- /dev/null +++ b/week12/bird_fly_template.py @@ -0,0 +1,18 @@ +import turtle +from time import time, sleep + +# TODO: 准备舞台 + + +# TODO: 导入小鸟的所有造型 + + +# TODO: 生成小鸟 + + +# TODO: 设置小鸟的起飞位置为屏幕最左边 + + +# TODO: 让小鸟飞舞起来 + + diff --git a/week12/bird_jump.py b/week12/bird_jump.py new file mode 100644 index 0000000000000000000000000000000000000000..3cd280d9a1d9ee2d6275abf488766b181f000c4f --- /dev/null +++ b/week12/bird_jump.py @@ -0,0 +1,37 @@ +import turtle +from time import time, sleep + +# TODO: 准备舞台和小鸟 +stage = turtle.Screen() +stage.bgcolor('light blue') +bird = turtle.Turtle('blank') +bird.penup() +bird.speed(0) + +start_x, start_y = -200, 100 +bird.setpos(start_x, start_y) + +# TODO: 注册小鸟的造型 +costume = ['bird%i.gif' % i for i in range(3)] +for i in range(3): + stage.register_shape(costume[i]) +bird.shape(costume[0]) + +# TODO: 让小鸟飞翔 +speed = 200 +def jump(): + t0 = time() + y = start_y + # 掉到窗口下面时退出 + while y > - stage.window_height()/2: + t = time() - t0 + bird.shape(costume[int(y) % 3]) + # bird.setpos(start_x + speed * t, y) + # y = start_y + speed * t * (1 - t) + bird.setpos(start_x + speed * t, y) + y = start_y + speed * t * (1 - t) + +stage.onkey(jump, 'space') +stage.listen() +stage.mainloop() + diff --git a/week12/cloud.gif b/week12/cloud.gif new file mode 100644 index 0000000000000000000000000000000000000000..05f1c86b2b74f899236479d9f0fc5c832c5cac4c Binary files /dev/null and b/week12/cloud.gif differ diff --git a/week12/golden_spiral.py b/week12/golden_spiral.py new file mode 100644 index 0000000000000000000000000000000000000000..f03c021a7a89a932ecfe1710efead3f8f86d4c9b --- /dev/null +++ b/week12/golden_spiral.py @@ -0,0 +1,34 @@ +import turtle + +# TODO: 创建 Fibonacci 数列 +fib = [1, 1] +for i in range(2, 20): + fib.append(fib[i-1] + fib[i-2]) + +# TODO: 初始化海龟和舞台 +stage = turtle.Screen() +stage.setup(1200, 800) +stage.colormode(255) +stage.bgcolor('light gray') +t = turtle.Turtle('triangle') +t.speed(0) + +# TODO: 以数列值为半径,连续绘制的 90° 实色饼图 +size = 25 +colors = ['orange', 'light green', 'light yellow', 'light blue', 'gray'] +# colors = [(255,0,0),(255,255,0),(0,0,255)] +for i in range(0, len(fib)): + radius = size * fib[i] + t.circle(radius, 90) + + # 设置颜色 + t.fillcolor(colors[i%len(colors)]) + t.begin_fill() + for _ in range(2): + t.left(90) + t.forward(radius) + t.left(90) + t.circle(radius, 90) + t.end_fill() + +stage.mainloop() \ No newline at end of file diff --git a/week12/ground.gif b/week12/ground.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ccdc58d9b70d0096b32fe4fda74bc18ebba2512 Binary files /dev/null and b/week12/ground.gif differ diff --git a/week12/tube1.gif b/week12/tube1.gif new file mode 100644 index 0000000000000000000000000000000000000000..6642ed29e89cd8d93bb7208fcc1eee71f04816fc Binary files /dev/null and b/week12/tube1.gif differ diff --git a/week12/tube2.gif b/week12/tube2.gif new file mode 100644 index 0000000000000000000000000000000000000000..944f720a45e8426010828be078c5e274ddc1e4d9 Binary files /dev/null and b/week12/tube2.gif differ diff --git a/week12/yinyang.py b/week12/yinyang.py new file mode 100644 index 0000000000000000000000000000000000000000..303ec3c6ba345e2e29ba8540f0cc0adeed25c807 --- /dev/null +++ b/week12/yinyang.py @@ -0,0 +1,52 @@ +# TODO: 初始化舞台和海龟 +import turtle +stage = turtle.Screen() +t = turtle.Turtle('blank') +t.speed(0) + +def draw_fish(r, color1, color2): + # TODO: 设置海龟的填充色 + t.fillcolor(color1) + t.begin_fill() + + # TODO: 画一个半径为r的半圆 + t.circle(r, extent=180) + + # TODO: 画一个半t.circle(r, extent=180)径为2*r的半圆 + t.circle(2*r, extent=180) + + # TODO: 倒着画一个半径为r的半圆 + # extent的值为正时,海龟逆时针画圆;而extent的值为负时,海龟顺时针画圆 + t.circle(r, extent=-180) + + t.end_fill() + + # TODO: 向上移动r*2/3的距离,然后面向右 + # 方法一:不使用坐标 - forward(), left() / right(), penup() / pendown() + t.penup() + t.right(90) + t.forward(r*2/3) + t.right(90) + t.pendown() + + # 方法二:引入坐标概念 - setpos(), setheading() + # 略 + + # TODO: 画一个半径为r/3的圆,填成白色 + t.fillcolor(color2) + t.begin_fill() + t.circle(r/3) + t.end_fill() + + # TODO: 向下移动r*2/3的距离,然后面向左 + t.penup() + t.right(90) + t.forward(r*2/3) + t.right(90) + t.pendown() + +draw_fish(100, 'black', 'white') +draw_fish(100, 'white', 'black') + +# TODO: 结束程序 +stage.mainloop() \ No newline at end of file diff --git a/week12/yinyang_knowledge_4.py b/week12/yinyang_knowledge_4.py new file mode 100644 index 0000000000000000000000000000000000000000..ca664994befb657657636787fcac54de49a95e70 --- /dev/null +++ b/week12/yinyang_knowledge_4.py @@ -0,0 +1,33 @@ +# TODO: 初始化舞台和海龟 + +def draw_fish(r, color1, color2): + # TODO: 设置海龟的填充色 + + t.begin_fill() + # TODO: 画一个半径为r的半圆 + circle(radius, extent=180) + + # TODO: 画一个半径为2*r的半圆 + 同上 + + # TODO: 倒着画一个半径为r的半圆 + circle(radius, extent=-180) + extent的值为正时,海龟逆时针画圆;而extent的值为负时,海龟顺时针画圆 + + t.end_fill() + + # TODO: 向上移动r*2/3的距离,然后面向右 + 方法一:不使用坐标 - forward(), left() / right(), penup() / pendown() + 方法二:引入坐标概念 - setpos(), setheading() + + # TODO: 画一个半径为r/3的圆,填成白色 + circle(), color + filling + + # TODO: 向下移动r*2/3的距离,然后面向左 + 参考以上 + +draw_fish(100, 'black', 'white') +draw_fish(100, 'white', 'black') + +# TODO: 结束程序 diff --git a/week12/yinyang_todo_3.py b/week12/yinyang_todo_3.py new file mode 100644 index 0000000000000000000000000000000000000000..d2bc437a89c0dbd30eb2277a1ec6f549bcd1ff35 --- /dev/null +++ b/week12/yinyang_todo_3.py @@ -0,0 +1,15 @@ +# TODO: 画一个半径为r的半圆 + +# TODO: 画一个半径为2*r的半圆 + +# TODO: 倒着画一个半径为r的半圆 + +# TODO: 将阴阳鱼填成黑色 + +# TODO: 向上移动r*2/3的距离,然后面向右 + +# TODO: 画一个半径为r/3的圆,填成白色 + +# TODO: 向下移动r*2/3的距离,然后面向左 + +# TODO: 重复执行上面的步骤一遍,但交换身体和眼睛的颜色 \ No newline at end of file diff --git a/week12/yiyang_final_6.py b/week12/yiyang_final_6.py new file mode 100644 index 0000000000000000000000000000000000000000..474ab79bc7494ad0aabcc7d2230810144bdba57b --- /dev/null +++ b/week12/yiyang_final_6.py @@ -0,0 +1,51 @@ +# TODO: 初始化舞台和海龟 +import turtle +stage = turtle.Screen() +t = turtle.Turtle() +t.speed(10) +def draw_fish(r, color1, color2): + # TODO: 设置海龟的填充色 + t.fillcolor(color1) + t.begin_fill() + + # TODO: 画一个半径为r的半圆 + t.circle(r, extent=180) + + # TODO: 画一个半t.circle(r, extent=180)径为2*r的半圆 + t.circle(2*r, extent=180) + + # TODO: 倒着画一个半径为r的半圆 + # extent的值为正时,海龟逆时针画圆;而extent的值为负时,海龟顺时针画圆 + t.circle(r, extent=-180) + + t.end_fill() + + # TODO: 向上移动r*2/3的距离,然后面向右 + # 方法一:不使用坐标 - forward(), left() / right(), penup() / pendown() + t.penup() + t.right(90) + t.forward(r*2/3) + t.right(90) + t.pendown() + + # 方法二:引入坐标概念 - setpos(), setheading() + # 略 + + # TODO: 画一个半径为r/3的圆,填成白色 + t.fillcolor(color2) + t.begin_fill() + t.circle(r/3) + t.end_fill() + + # TODO: 向下移动r*2/3的距离,然后面向左 + t.penup() + t.right(90) + t.forward(r*2/3) + t.right(90) + t.pendown() + +draw_fish(100, 'black', 'white') +draw_fish(100, 'white', 'black') + +# TODO: 结束程序 +stage.mainloop() \ No newline at end of file diff --git "a/week12/\347\254\254\345\215\201\344\272\214\345\221\250\346\225\231\345\255\246\345\257\274\350\257\273.pdf" "b/week12/\347\254\254\345\215\201\344\272\214\345\221\250\346\225\231\345\255\246\345\257\274\350\257\273.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..af75fde0912b17fde3f8b9240dcd5bba1787bcb5 Binary files /dev/null and "b/week12/\347\254\254\345\215\201\344\272\214\345\221\250\346\225\231\345\255\246\345\257\274\350\257\273.pdf" differ diff --git a/week13/README_FIRST.txt b/week13/README_FIRST.txt new file mode 100644 index 0000000000000000000000000000000000000000..71c066cceed822569c1c51862c886b3802c2561d --- /dev/null +++ b/week13/README_FIRST.txt @@ -0,0 +1,14 @@ +第十三周训练 + +本周学习的主要内容是代码仓库和Git命令操作。 + +通过本周的学习,同学们将: +1. 熟悉软件开发世界最常用而且重要的工具——代码仓库 +2. 形成对Git工作流的初步理解 +3. 获得与他人在线分享交流代码的能力 + +** 训练内容 ** +1. 在家里电脑安装Git软件,并完成PyCharm的插件安装和配置(参见教学视频Video 13.1) +2. 通过教学视频,巩固课上学习的Fork+Pull工作流(参见教学视频Video 13.2-13.3[1/2]) +3. 完成ex13.1-13.3三个编程任务,并通过代码仓库提交 +4. 完成ex13.4中的课后游戏 \ No newline at end of file diff --git "a/week13/ex13_1 \345\233\233\346\226\271\346\240\274.txt" "b/week13/ex13_1 \345\233\233\346\226\271\346\240\274.txt" new file mode 100644 index 0000000000000000000000000000000000000000..036a0bb5aa2307b338d99aeae6ccedbddb715872 --- /dev/null +++ "b/week13/ex13_1 \345\233\233\346\226\271\346\240\274.txt" @@ -0,0 +1,24 @@ +知识点: 填充色、多重循环 + +Ex13.1 四方格 +============= + +同学们都能轻轻松松画出一个正方形,甚至给它填充颜色,所以这道习题我们增加一点难度。 + +** 任务描述 ** + +1. 用海龟作图绘制一个2*2的四方格 +2. 把左上角和右下角的两个格子涂成黑色 +3. 保留右上角和左下角两个格子的白色 + +** 提交方式 ** + +1. 将程序文件名保存为square_.py,其中是你的名字。例如square_cindy.py +2. 将程序提交(commit)到本地仓库 +3. 将这个提交推送(push)到你的码云仓库 +4. 创建一个Pull Request(PR)到 Moleqode/pratice 项目的exercise分支 + +** 提交截止时间 ** + +请于下周四(12/19)晚8点前提交你的作业。 +参考答案将在当晚8:30,在Moleqode/practice的master分支上发布。 \ No newline at end of file diff --git "a/week13/ex13_2 \346\225\260\345\255\246\345\233\276\345\275\242.txt" "b/week13/ex13_2 \346\225\260\345\255\246\345\233\276\345\275\242.txt" new file mode 100644 index 0000000000000000000000000000000000000000..2dcbd64c5e7d421d1cf82144fea6db1050a4c48d --- /dev/null +++ "b/week13/ex13_2 \346\225\260\345\255\246\345\233\276\345\275\242.txt" @@ -0,0 +1,21 @@ +Ex13.2 数学图形 + +** 任务描述 ** + +使用海龟作图,任意创作一个你喜爱的数学图形。 + +要求: +1. 使用到填色和多边形 +2. 用注释解释与图形相关的数学知识 + +** 提交方式 ** + +1. 将程序文件名保存为graph_.py,其中是你的名字。例如graph_cindy.py +2. 将程序提交(commit)到本地仓库 +3. 将这个提交推送(push)到你的码云仓库 +4. 创建一个Pull Request(PR)到 Moleqode/pratice 项目的exercise分支 + +** 提交截止时间 ** + +请于下周四(12/19)晚8点前提交你的作业。 + diff --git "a/week13/ex13_3 \345\233\275\351\231\205\350\261\241\346\243\213\347\233\230.txt" "b/week13/ex13_3 \345\233\275\351\231\205\350\261\241\346\243\213\347\233\230.txt" new file mode 100644 index 0000000000000000000000000000000000000000..49275d0a5a44a6a26984ad39bebfe40bc680ae37 --- /dev/null +++ "b/week13/ex13_3 \345\233\275\351\231\205\350\261\241\346\243\213\347\233\230.txt" @@ -0,0 +1,35 @@ +知识点: 填充色、多重循环 + +本题目为可选作业,你需要预先完成Ex13.1四方格练习题。 + +Ex13.3 国际象棋盘 +================ + +将四方格程序扩展成一个8x8国际象棋盘。 + +** 任务描述 ** + +1. 用海龟作图绘制一个横纵方向均为8个正方格、黑白格相间的国际象棋盘 +2. 每个格子的边长为50像素 +3. 左上角格子颜色为黑色 + +** 解法提示 ** + +使用程序设计五步法(参见教学视频12.1): +1. 观察、发现国际象棋盘的画法中隐藏的规律 +2. 思考如何决定每个格子的位置和颜色 +3. 开始编程前,尝试描述你的解法思路。鼓励绘制出流程图 + +** 提交方式 ** + +1. 将程序文件名保存为chessboard_.py,其中是你的名字。例如chessboard_cindy.py +2. 将程序提交(commit)到本地仓库 +3. 将这个提交推送(push)到你的码云仓库 +4. 创建一个Pull Request(PR)到 Moleqode/pratice 项目的exercise分支 + +** 提交截止时间 ** + +请于下周四(12/19)晚8点前提交你的作业。 +参考答案将在当晚8:30,在Moleqode/practice的master分支上发布。 + + diff --git "a/week13/ex13_4 \345\207\273\351\274\223\344\274\240\350\212\261\346\270\270\346\210\217.txt" "b/week13/ex13_4 \345\207\273\351\274\223\344\274\240\350\212\261\346\270\270\346\210\217.txt" new file mode 100644 index 0000000000000000000000000000000000000000..39ea31c8d1e8fac360bb5f51c3c838d15c091dcb --- /dev/null +++ "b/week13/ex13_4 \345\207\273\351\274\223\344\274\240\350\212\261\346\270\270\346\210\217.txt" @@ -0,0 +1,25 @@ +知识点:Pull Request、合并冲突 + +Ex13.4 击鼓传花游戏 + +** 游戏规则 ** + +1. 每个同学把自己的名字加入到names.txt文件中,然后提交PR给Moleqode管理员。 +2. 每天管理员只接受收到的前2个PR请求,而关闭后面的请求。 +3. PR未被接受的同学,应重新提交PR,直到被管理员批准为止。 + +游戏结束后按PR被批准的先后次序排名。 + +** 游戏准备 ** + +添加 Moleqode/practice 仓库为Remote,命名为upstream + +** 游戏步骤 ** + +1. Pull upstream:game 分支的最新内容 +2. 打开names.txt,在文件末尾另起一行,加入自己的名字 +3. Commit/Push结果到你在码云上的仓库Origin +4. 提交一个PR到game分支 +5. 每隔一段时间重新执行第1步,直到收到新的更新为止 + +如果你的PR已经被接受,游戏通过;否则重复执行第2-5步,重新修改names.txt文件并提交PR请求 \ No newline at end of file diff --git "a/week13/ex13_5 \345\205\253\347\232\207\345\220\216\351\227\256\351\242\230.txt" "b/week13/ex13_5 \345\205\253\347\232\207\345\220\216\351\227\256\351\242\230.txt" new file mode 100644 index 0000000000000000000000000000000000000000..e0f359b948607a2f37e7ada99511c7406d030bfe --- /dev/null +++ "b/week13/ex13_5 \345\205\253\347\232\207\345\220\216\351\227\256\351\242\230.txt" @@ -0,0 +1,33 @@ +(这是一道宝藏题目,有兴趣的学生可以尝试挑战) + +知识点:算法 + +Ex13.5 八皇后问题 + +在国际象棋的玩法中,皇后可以在横、纵、斜方向上,不受距离限制地吃掉直接遇到地任何棋子。 + +** 任务描述 ** + +请把八个皇后放到国际棋盘上,使任何两个皇后之间都不能吃到对方。 + +创建长度为8的pos[row_idx]列表,其中row_idx代表行标,pos[row_idx]代表在一行上的位置,也就是列标。 +例如:[5, 2, 0, 7, 4, 1, 3, 6] + +1. [初级难度] 编程验证一种解法是否正确 +2. [初级难度] 编程找出一种正确的解法 +3. [中级难度] 用海龟作图绘制出一种给定的解法 +4. [高级难度] 统计共有几种解法 + +** 提交方式 ** + +同学只需要思考初级难度的题目,中高级均超出本课程的难度范围。 + +1. 将程序文件名保存为queens_.py,其中是你的名字。例如queens_cindy.py +2. 将程序提交(commit)到本地仓库 +3. 将这个提交推送(push)到你的码云仓库 +4. 创建一个Pull Request(PR)到 Moleqode/pratice 项目的exercise分支 + +** 提交截止时间 ** + +请于下周四(12/19)晚8点前提交你的作业。 +参考答案将在当晚8:30,在Moleqode/practice的master分支上发布。 \ No newline at end of file diff --git a/week13/queens_solution.py b/week13/queens_solution.py new file mode 100644 index 0000000000000000000000000000000000000000..ece478c95b675c0ad2f8ec1e58726037c615dd03 --- /dev/null +++ b/week13/queens_solution.py @@ -0,0 +1,131 @@ +import random +import turtle + +NUM_QUEENS = 8 +BOARD_HEIGHT = 400 + +# 子问题 1:检查解法是否正确 +# TODO: validate a solution +def validate(v): + for i in range(len(v)): + for j in range(i+1, len(v)): + if (j-i) == abs(v[j] - v[i]): + return False + return True + + +# 子问题 2:获得一个解法 +# TODO: get a random solution +def get_example(): + for _ in range(10000): + v = list(range(NUM_QUEENS)) + random.shuffle(v) + if validate(v): + return v + return None +# print(get_example()) + + +# 子问题 3:画出解法 +# TODO: draw chessboard & queens +def board(v, side_height): + global chess, queen + + # 画棋盘的一个格子,如果格子上有皇后(occupied),一起画出来 + def draw_tile(x, y, height, color, occupied): + chess.penup() + chess.goto(x, y) + chess.pendown() + chess.fillcolor(color) + chess.begin_fill() + for _ in range(4): + chess.forward(height) + chess.right(90) + chess.end_fill() + if occupied: + queen.goto(x, y-height*1.1) + queen.write('\u265b', align='left', font=('Arial', int(height*.75), 'normal')) + + # 显示当前/总计解法数量 + score.undo() + score.goto(0, BOARD_HEIGHT / 2) + score.write('%i/%i' % (counter, len(solutions)), + align='center', font=('Consolas', int(BOARD_HEIGHT / 12), 'normal')) + + # 画Grid的一般方法,固定左上角坐标,之后用双重循环或单循环取模换行(见Ethan解法) + tile_size = side_height / NUM_QUEENS + x_base, y_base = - tile_size * NUM_QUEENS / 2, tile_size * NUM_QUEENS / 2 + + black_white = ['black', 'white'] + for row in range(NUM_QUEENS): + for col in range(NUM_QUEENS): + draw_tile(x_base + col * tile_size, + y_base - row * tile_size, + tile_size, + black_white[(row+col) % 2], + v[row] == col) + +# vec = [5, 2, 6, 1, 7, 4, 0, 3] +# print(vec) +# board(vec, 400) + +# TODO: find all solutions +def solve(v, num=0): + global solutions + if num == len(v): + solutions.append(list(v)) + return + for col in range(len(v)): + v[num], flag = col, True + for row in range(num): + if v[row] == col or abs(col - v[row]) == num - row: + flag = False + break + if flag: + solve(v, num + 1) + + +def restart(): + global counter + counter = 0 + solutions = [] + solve([None] * 8) + + queen.penup() + queen.color('gold') + score.penup() + chess.speed(0) + + update() + stage.onkey(update, 'space') + + +# TODO: update the screen +def update(): + stage.onkey(None, 'space') + global counter + if counter >= len(solutions): + restart() + return + + counter += 1 + board(solutions[counter], BOARD_HEIGHT) + + stage.onkey(update, 'space') + + +# initialize turtle graphics objects +chess = turtle.Turtle('blank') +score = turtle.Turtle('blank') +queen = turtle.Turtle('blank') + +stage = turtle.Screen() +stage.setup(600, 600) +stage.tracer(False) + +counter = 0 +solutions = [] +restart() + +stage.listen() +stage.mainloop() \ No newline at end of file diff --git a/week13/week13_demo.py b/week13/week13_demo.py new file mode 100644 index 0000000000000000000000000000000000000000..2b42d7c201a37b1cad162e8e6c120a2aff3b20f8 --- /dev/null +++ b/week13/week13_demo.py @@ -0,0 +1,24 @@ +# 知识点:Fork+Pull工作流 +# +# Demo 13.1 +# ========== +# +# 这是个Demo任务,目的是演示Fork+Pull工作流。 +# +# ** 任务描述 ** +# +# 新建一个蓝底白字的窗口,在屏幕中心显示"DEMO"。 +# +# ** 提交 ** +# 1. 添加remote仓库Moleqode/practice,起名为upstream。 +# 2. 以Pull Request的方式提交到 upstream: exercise 分支。 +import turtle + +t = turtle.Turtle('blank') +stage = turtle.Screen() + +stage.bgcolor('navy') +t.pencolor('white') +t.write('DEMO', align='center', font=('Cambria', 100, 'bold')) + +stage.mainloop() \ No newline at end of file diff --git a/week14/README_FIRST.md b/week14/README_FIRST.md new file mode 100644 index 0000000000000000000000000000000000000000..5438e3421f115bfe88d37103219500bfb43a4bf7 --- /dev/null +++ b/week14/README_FIRST.md @@ -0,0 +1,26 @@ +第十四周训练 + +本周课程将学习计算机如何表示和存储数值型数据和文本符号数据,这是核心的计算机科学知识。 + +上半部分先快速介绍数制简史,同学们将一起认识历史上曾经使用过或依然在使用的不同数制; +接下来重点介绍进位(Place Value)、二进制和十六进制数字的表示以及与十进制之间的相互转换。 + +下半部分将继续介绍文本字符的存储,重点放在字符编码集和编解码的讲解上。 +同学们将学习新数据类型bytes以及它与str类型之间的转换关系。 + +此外,本周同学们还将完成以下练习: + +1. 使用Python内置函数在不同数制之间进行转换 +2. 编程获得自己中英文名字的Unicode编码,以二进制和十六进制输出 +3. 在Unicode字符集中找到国际象棋棋子的符号,用Turtle Graphics画出来 +4. 使用六种字符集对同样的句子进行编码,比较编码结果的长度 +5. 尝试用不同字符集解码一个bytes类型列表,破解它的编码方式 + +通过学习,同学们将获得以下洞见: + +1. 不同的数制和字符编码集,只不过是相同信息的不同表示,就像是信息的多件外衣(或造型) +2. 人有十个手指,所以习惯十进制,而对计算机最方便的是二进制,二进制是计算机的最爱 +3. 我们在屏幕上看到的一切符号,包括数字,最终都被编码并以二进制存储在计算机里 +4. 因为人有不同偏好,而且计算机也有偏好,所以产生了数制转换和编码转换的需求 +5. 为了获得需要的信息,我们需要结合使用观察能力和搜索策略 +6. 一种常用的搜索策略是用粗调和微调不断收缩搜索范围,近似的例子是操作显微镜观察微生物 \ No newline at end of file diff --git "a/week14/ex14_1 \344\272\214\350\277\233\345\210\266\347\232\204\346\225\260\344\275\215.md" "b/week14/ex14_1 \344\272\214\350\277\233\345\210\266\347\232\204\346\225\260\344\275\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..415dfe354d03e514f04b19a5ea03dda5984d1f99 --- /dev/null +++ "b/week14/ex14_1 \344\272\214\350\277\233\345\210\266\347\232\204\346\225\260\344\275\215.md" @@ -0,0 +1,36 @@ +知识点:数制、进位、二进制计数法 + +作业:二进制的数位 +================== + +** 任务描述 ** + +请牢记2的0次方到10方的10进制数字,以及对应的二进制数字。 + + + +** 参考阅读 ** + +一个数字可以用很多种数制表示。有的数制有进位,比如我们最熟悉的阿拉伯数字,而有的数字没有进位,一个典型的例子是罗马数字。 + +在有进位的数制中,数字所在的位置如果变化,它的值也会变化。举个例子,阿拉伯数字中的18,如果对调它的两个位数变成81,得到的就已经不是原来的数字了。而罗马数字中表示18的XVIII,即使改变书写顺序变成IIIVX,依然表示18,因为81的写法是LXXXI(说明:注意IIIVX并不是合法的罗马数字表示,即使位置对数值没有影响,罗马人依然规定了书写顺序,也许是为了好看吧。。。不管如何,没有进位和零的罗马数字,最终还是被强大的阿拉伯数字打败了) + +不同的进制差别在于基数。十进制的基数是10,表示逢十进一位,而二进制的基数是2,就要逢二进一。10在十进制中表示十,而在二进制中只是二。 + +无论采用哪种进制计数法,数字背后代表的数量关系却不会变化。十进制数字18,与二进制10010,或者十六进制数0x12,它们表示的都是相同的数量,吃10010个苹果并不比吃18个多。计数法只是数量的外衣,根据使用场合的需要,可以得体地改变。 + +| 二进制 | 十进制 | 次方 | +| :-----------: | :----: | :-------: | +| 1 | 1 | 2的0次方 | +| 10 | 2 | 2的1次方 | +| 100 | 4 | 2的2次方 | +| 1000 | 8 | 2的3次方 | +| 1 0000 | 16 | 2的4次方 | +| 10 0000 | 32 | 2的5次方 | +| 100 0000 | 64 | 2的6次方 | +| 1000 0000 | 128 | 2的7次方 | +| 1 0000 0000 | 256 | 2的8次方 | +| 10 0000 0000 | 512 | 2的9次方 | +| 100 0000 0000 | 1024 | 2的10次方 | + +上表是二进制计数法中各个数位对应的十进制数字。表中的数量关系,可以用一句话概括:1后面有几个0,就是2的几次方。TIPS:大家要注意区分乘法和次方运算。乘法2*4实质意义是4个2相加,而2的4次方(2**4)则表示4个2相乘。 diff --git "a/week14/ex14_2 \347\214\234\347\214\234\346\210\221\346\230\257\350\260\201.md" "b/week14/ex14_2 \347\214\234\347\214\234\346\210\221\346\230\257\350\260\201.md" new file mode 100644 index 0000000000000000000000000000000000000000..b25632f20e51c80c78ba70285c17d60222ae0480 --- /dev/null +++ "b/week14/ex14_2 \347\214\234\347\214\234\346\210\221\346\230\257\350\260\201.md" @@ -0,0 +1,31 @@ +知识点:二进制表示、字符编解码 + +## Ex14.2 猜猜我是谁 + +吃过晚饭,你像往常一样急忙忙坐在电脑前,毕竟一天里你也只有这么一个小时可以玩儿电脑。 + +突然,屏幕上跳出了一条神秘的消息: + +> Hello, my name is +> +> 01010100 01111001 01110010 01100001 01111001 + +这是谁?什么人?TA要干什么? + +你脑海中灵光一现,这明明就是一串二进制码,莫非它能够解码成文字? + +你的思路清楚了,下面是你需要做的... + +** 任务描述 ** + +1. 创建一个整型列表,存储这五个二进制数字 +2. 用chr()函数解码每个数字 +3. 把解码的结果依次追加到一个类型为str的name变量末尾 +4. 完成全部解码后,输出最终结果 + +** 提交方式 ** + +1. 将程序文件名保存为decode_.py,其中是你的名字。例如decode_cindy.py +2. 将程序提交(commit)到本地仓库 +3. 将这个提交推送(push)到你的码云仓库 +4. 创建一个Pull Request(PR)到 Moleqode/pratice 项目的exercise分支 \ No newline at end of file diff --git "a/week14/ex14_3 \345\233\276\345\275\242\347\254\246\345\217\267.md" "b/week14/ex14_3 \345\233\276\345\275\242\347\254\246\345\217\267.md" new file mode 100644 index 0000000000000000000000000000000000000000..99136758f5214bd9feebfeb4dbf37e2bd6f092e4 --- /dev/null +++ "b/week14/ex14_3 \345\233\276\345\275\242\347\254\246\345\217\267.md" @@ -0,0 +1,27 @@ +知识点:Unicode、编解码 + +## Ex14.3 图形符号 + +在课上国际象棋的例子里,同学们发现Unicode字符表简直就是个大宝库,里面有各种各样有趣的图形符号。这样同学们可以通过在文字中插入图形符号,来丰富自己的表达。 + +** 任务描述 ** + +1. 编程显示出Unicode编码表中的图形字符 +2. 创作一段故事,故事中应恰当地使用图形字符 + +** 提示 ** + +1. 多数图形字符的编码是在`0x2000-0x33ff`之间 +2. print()函数默认会在显示完结果后自动换行。如果想在屏幕上显示一个字符后,不换行继续显示下一个字符,你需要在print()函数中使用一个参数end。下面的示范代码把end参数的值设定为空字符串`''`,这样程序会在屏幕上逐个输出`'abcdef'`中的字符。 + +```python +for c in 'abcdedf': + print(c, end='') +``` + +** 提交方式 ** + +1. 将程序文件名保存为emoji_.py,其中是你的名字。例如emoji_cindy.py +2. 将程序提交(commit)到本地仓库 +3. 将这个提交推送(push)到你的码云仓库 +4. 创建一个Pull Request(PR)到 Moleqode/pratice 项目的exercise分支 \ No newline at end of file diff --git a/week14/homework/emoji_charlie.py b/week14/homework/emoji_charlie.py new file mode 100644 index 0000000000000000000000000000000000000000..c76907684b47969e24d1f21331b1cfd3796520be --- /dev/null +++ b/week14/homework/emoji_charlie.py @@ -0,0 +1,80 @@ +import time + + +def locate_pieces(code_range, words_per_line): + for idx in code_range: + if (idx+1) % words_per_line == 0: + print() + print(hex(idx), ' ', end='') + print(chr(idx), end='') + + +locate_pieces(range(0x2000, 0x33ff), 10) + + +def tell_story(): + print(''' + Once upon a time, there is a student in TAS named +\'supercalifragilisticexpialedocious\'.I will tell you guys about his day. + On %s, he will wake up.Then, he will go eat 早餐and brush his teeth .''' % (chr(0x335e))) + time.sleep(7) # part1 + + print(''' + After that, he will go to school with Mr.Timmy Hu. When +we arrived at school, it will be: + +def in_school():''') + time.sleep(5) # part2 + + print(''' for i in range(8): + work() + time.sleep(45*60) +in_school()''') + time.sleep(5) # part3 + + print(''' + AFTER in_school()......um, I THINK i FORGET sth......''') + time.sleep(5) # part4 + + print('AAAAAAHHHHHHHHAAAAAAAAHHHHHHHHH!!!!!!!') + time.sleep(5) # part5 + + print(''' + IN lapsdjos class, he learned many languages,like...... +''') + time.sleep(3) # part6 + + print(chr(0x3303), chr(0x3304), chr(0x3305), chr(0x3306), + chr(0x3307), chr(0x3308), chr(0x3309), chr(0x330a)) + print(chr(0x30a1), chr(0x3a02), chr(0x3a03), chr(0x3a04), chr(0x3a07)) + time.sleep(3) # part7 + + print(''' +He also learned a''', chr(0x3299), '''密,that is:''') + time.sleep(5) # part8 + + print(''''CHINESE!!!!!!!!lIKE: +''') + time.sleep(3) + print(chr(0x3281), chr(0x3282), chr(0x3283), chr(0x3284), + chr(0x3285), chr(0x3286), chr(0x3287), chr(0x3286), + chr(0x3287)) # part9 + + print('''IN night, he will eat dinner with his family +members. And After that, it will be:''') + time.sleep(6) # part10 + + print(''' +def after_dinner(): + 刷牙() + 洗澡() + 睡觉(9.5*60*60) +after_dinner()''') + time.sleep(3) # part11 + + for i in range(20): + print(chr(0x2b5b), end='') # end + + +tell_story() + diff --git a/week14/test.py b/week14/test.py new file mode 100644 index 0000000000000000000000000000000000000000..bf4e118ea0ce6f4d387f442e6b8cd86de72d49b0 --- /dev/null +++ b/week14/test.py @@ -0,0 +1,15 @@ +# name = 'Charlie' +# +# for o in range(7): +# i = ord(name[o]) +# a = bin(i) +# print(a) + + # ''' a = int(i, 16)''' + + +for i in range(0x265f, 0x265a): + if (i+1)%80 == 0: + print() + print(i, ' ', end='') + print(chr(i), end='') \ No newline at end of file diff --git a/week14/week14_demo.py b/week14/week14_demo.py new file mode 100644 index 0000000000000000000000000000000000000000..6c7e2e7e0dde733287fd9a372d3e64f95af49193 --- /dev/null +++ b/week14/week14_demo.py @@ -0,0 +1,42 @@ +# 英文名字转二进制 +def name2bin(name): + binary_name = '' + for n in name.encode(): + binary_name += bin(n)[2:] + ' ' + return binary_name + +# names = ['Cathy', 'Jude', 'Grace'] +# for s in names: +# print(s, name2bin(s)) + + +# 查找国际象棋棋子的unicode编码 +def locate_pieces(code_range, words_per_line): + for idx in code_range: + if (idx+1) % words_per_line == 0: + print() + print(hex(idx), ' ', end='') + print(chr(idx), end='') + + +locate_pieces(range(0x2654, 0x2660), 80) + +# 绘制国际象棋棋子 + + +def chess_pieces(): + import turtle + t = turtle.Turtle('blank') + base = 0x2654 + s = "" + for i in range(12): + # print(chr(base+i), end="") + s += chr(base + i) + if (i+1) % 6 == 0: + s += "\n" + t.penup() + t.sety(-240) + t.write(s, align='center', font=('Arial',80,'normal')) + turtle.exitonclick() + +chess_pieces() diff --git "a/week14/\346\213\223\345\261\225\351\230\205\350\257\273-\345\255\227\347\254\246\351\233\206.md" "b/week14/\346\213\223\345\261\225\351\230\205\350\257\273-\345\255\227\347\254\246\351\233\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..a8fd666831b55ff50c4b8b0e68a692c087b2326c --- /dev/null +++ "b/week14/\346\213\223\345\261\225\351\230\205\350\257\273-\345\255\227\347\254\246\351\233\206.md" @@ -0,0 +1,51 @@ +# [转载] ASCI,Unicode,GBK和UTF-8字符编码 + +很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为"字节"。再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去。他们看到这样是好的,于是就称这机器为"计算机"。 + +#### ASCII + +开始计算机只在美国用。八位的字节一共可以组合出256(2的8次方)种不同的状态。他们把其中的编号从0开始的32种状态(0x00-0x19)分别规定了特殊的用途,一但终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作。遇上0x10,终端就换行,遇上0x07,终端就向人们嘟嘟叫,遇上0x1b,打印机就打印反白的字,或者终端就用彩色显示字母。他们看到这样很好,于是就把这些0x20以下的字节状态称为"控制码"。他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127号(0xFF),这样计算机就可以用不同字节来存储英语的文字了。大家看到这样,都感觉很好,于是大家都把这个方案叫做ANSI的"ASCII"编码(American StandardCode for Information Interchange,美国信息互换标准代码)。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。 + +#### GB2312 + +后来,就像建造巴比伦塔一样,世界各地都开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128到255这一页的字符集被称"扩展字符集"。从此之后,贪婪的人类再没有新的状态可以用了,美帝国主义可能没有想到还有第三世界国家的人们也希望可以用到计算机吧! + +等中国人民得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存呢。但是这难不倒智慧的中国人民,我们不客气地把那些127号之后的奇异符号们直接取消掉,并规定:一个小于127号的字符的意义与原来相同,但两个大于127号的字符连在一起时,就表示一个汉字,前面的一个字节(称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编了进去,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。中国人民看到这样很不错,于是就把这种汉字方案叫做"GB2312"。GB2312是对ASCII的中文扩展。 + +#### GBK & GB18030 + +但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,特别是某些很会麻烦别人的国家领导人。于是我们不得不继续把 GB2312没有用到的码位找出来不客气地用上。后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为GBK标准,GBK包括了GB2312的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK扩成了GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了。中国的程序员们看到这一系列汉字编码的标准是好的,于是通称他们叫做"DBCS"(Double Byte CharecterSet 双字节字符集)。在DBCS系列标准里,最大的特点是两字节长的汉字字符和一字节长的英文字节并存于同一套编码方案里,因此他们写的程序为了支持中文处理,必须要注意字串里的每一个字节的值,如果这个值是大于127的,那么就认为一个双字节字符集里的字符出现了。那时候凡是受过加持、会编程的计算机僧侣们都要每天念下面这个咒语数百遍:"一个汉字算两个英文字符!一个汉字算两个英文字符。" + +#### BIG5 + +因为当时各个国家都像中国这样搞出一套自己的编码标准,结果互相之间谁也不懂谁的编码,谁也不支持别人的编码,连大陆和台湾这样只相隔了150海里,使用着同一种语言的兄弟地区,也分别采用了不同的DBCS编码方案。当时的中国人想让电脑显示汉字,就必须装上一个"汉字系统",专门用来处理汉字的显示、输入的问题,但是那个由台湾的愚昧封建人士写的算命程序就必须加装另一套支持BIG5编码的什么"倚天汉字系统"才可以用,装错了字符系统,显示就会乱了套!这怎么办?何况世界民族之林中还有那些一时用不上电脑的穷苦人民,他们的文字又怎么办? 真是计算机的巴比伦塔命题啊! + +#### Unicode + +正在这时,大天使加百列及时出现了——一个叫ISO(国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、字母和符号的编码!他们打算叫它"Universal Multiple-Octet Coded Character Set",简称UCS,俗称"Unicode"。 + +Unicode开始制订时,计算机的存储器容量极大地发展了,空间再也不是问题。于是ISO就直接规定必须用两个字节,也就是16位来统一表示所有的字符,对于ASCII里的那些"半角"字符,Unicode包持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。由于"半角"英文符号只需要用到低8位,所以其高8位永远是0,因此这种大气的方案在保存英文文本时会多浪费一倍的空间。 + +这时候,从旧社会里走过来的程序员开始发现一个奇怪的现象:他们的strlen函数靠不住了,一个汉字不再是相当于两个字符了,而是一个!是的,从Unicode开始,无论是半角的英文字母,还是全角的汉字,它们都是统一的"一个字符"!同时,也都是统一的"两个字节",请注意"字符"(WORD)和"字节"(BYTE)两个术语的不同,"字节"是一个8位的物理存贮单元,而"字符"则是一个文化相关的符号。在Unicode中,一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。 + +Unicode同样也不完美,这里就有两个的问题:第一个是,如何才能区别Unicode和ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费,文本文件的大小会因此大出二三倍,这是难以接受的。 + +#### UTF-8 & UTF-16 + +Unicode在很长一段时间内无法推广,直到互联网的出现,为解决Unicode如何在网络上传输的问题,于是面向传输的众多UTF(UCS Transfer Format)标准出现了,顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。UTF-8是在互联网上使用最广的一种Unicode的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。 + +UTF-8最大的一个特点,就是它是一种变长的编码方式。它使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分(需要注意的是Unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节)。从Unicode到UTF-8并不是直接的对应,而是要过一些算法和规则来转换。 + +Unicode符号范围 | UTF-8编码方式 + +----------------------------------------------------- + +(十六进制) | (二进制) + +0000 0000-0000 007F | 0xxxxxxx + +0000 0080-0000 07FF | 110xxxxx 10xxxxxx + +0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + +0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx \ No newline at end of file diff --git a/week15/README_FIRST.md b/week15/README_FIRST.md new file mode 100644 index 0000000000000000000000000000000000000000..10719a4714315b956b966ba1a377ffe3af330f9b --- /dev/null +++ b/week15/README_FIRST.md @@ -0,0 +1,36 @@ +## 第十五周训练 + + +本周将结束编程知识的学习,也是编程校队本学期的倒数第二节课。下周最后一节课我们将总结回顾整个学期学过的知识内容。 + +本周的主题是迎难而上,我们要来研究分析编程中遇到的各种错误。 + +上半部分,同学们将从全然不同的角度重新理解那些让你焦急恼火的程序错误。为什么我们要重视程序错误?有哪三种类型的程序错误?从错误中我们又能学习和获得什么?最终你将意识到,设计程序和修复错误原本就是硬币的两面,是编程学习不可分割的两个方面。 + +下半部分,我们将解码异常消息和常见的异常类型。你需要亲自动手修复一个支离破碎的彩虹程序,让它正确地呈现出彩虹的七色光。你还将学习使用try/except指令来捕捉和修理那些隐藏最深的异常。通过实践活动,你将体会和领悟发现问题、分析问题和解决问题的一般性问题解决过程。 + +##### ** 学习目标 ** + +通过本周学习,同学们将: + +- 树立面对编程错误的正确态度 +- 重新认识Python中常见的异常 +- 了解应对一般异常的基本方法 +- 掌握使用try/except/else/finally来捕捉和处理异常 + +##### ** 实践操作 ** + +1. 尽可能多地发现和修复彩虹程序中的问题 +2. 为输入程序添加异常处理保护 +3. 相互检查邻桌同学程序中的隐患 +4. 为修复程序创建git分支 + +##### ** 拓展主题 ** + +对于想了解更多关于程序测试和调试的知识与技巧的同学,下面的主题可以作为你的自学研究课题。 + +- PyCharm调试器的使用方法 +- 抛出异常指令raise和异常对象Exception +- 生成日志logging +- 断言指令assert +- 单元测试类unittest diff --git a/week15/ex15_1 rainbow.py b/week15/ex15_1 rainbow.py new file mode 100644 index 0000000000000000000000000000000000000000..aadc55eaa94ac9b5b74f18e52ef8a0cd32f50cc9 --- /dev/null +++ b/week15/ex15_1 rainbow.py @@ -0,0 +1,30 @@ +rainbow_color = ['red', 'orange', 'yellow', 'green', 'indigo', 'blue', 'violet'] +for i in range(7): + print(rainbow_color[i]) +print('My favorite color is', rainbow_color[0]) + +import turtle as t +from time import sleep +def rainbow(): + try: + y = float(input('Input y coordinate: ')) + x = float(input('Input x coordinate: ')) + except ValueError: + print('Nope') + rainbow() + + t.setpos(x, y) + t.penup() + t.write("I'll give you some color see see. heiheihei~~~", align='center', + font=('Arial', 30)) + t.penup() + t.goto(-200, 200) + t.write("Ready...Go!", font=('Arial', 50)) + for i in range(7): + sleep(1) + t.bgcolor(rainbow_color[i]) + + t.mainloop() + + +rainbow() diff --git a/week15/week15_demo.py b/week15/week15_demo.py new file mode 100644 index 0000000000000000000000000000000000000000..2b49cfde3be6a429c6ea667e7c8db663392fe20a --- /dev/null +++ b/week15/week15_demo.py @@ -0,0 +1,46 @@ +# Ex15.2 二进制小测验 + +from random import randint +from time import time + +score = 0 +num_q = 5 + +for _ in range(num_q): + n = randint(0, 10) + if n == 1: + word = "1st" + elif n == 2: + word = "2nd" + else: + word = str(n) + "th" + start_time = time() + if 2**n == int(input("What is 2 to the " + word + " power? ")): + finish_time = time() + score += 1 + print('Correct! You used %f seconds.' % (finish_time - start_time)) + input('\nPress Enter to continue ...\n') + else: + print('Wrong answer... The correct answer is %i.' % 2**n) + +print('Your total score is %i.' % score) + + +# Ex15.3 (Python编程快速上手, Ex10.8) + +# import random +# +# guess = '' +# while guess not in ('heads', 'tails'): +# print('Guess the coin toss! Enter heads or tails:') +# guess = input() +# toss = random.randint(0, 1) # 0 is tails, 1 is heads +# if toss == guess: +# print('You got it!') +# else: +# print('Nope! Guess again!') +# guess = input() +# if toss == guess: +# print('You got it!') +# else: +# print('Nope! You are really bad at this game.') \ No newline at end of file