Python Learning Diary – Coordinate Movement
Preface
A month has passed since the semester started, and I've been busy with coursework, leaving little time to think deeply about much else. Reading, though, has been a regular habit—just not Python books. I've mostly been reading literature. The day before the holiday, after finishing my exams, I flipped through my Python book and picked up some things that were new to me. That inspired me to improve and upgrade the project I'd been working on before the semester began, and I ended up writing a coordinate movement program.
Output Preview
The parts marked with # are my explanations; they don't appear in the actual run
Tell me your X position:
10 # value I entered
Tell me your Y position:
0 # value I entered
Original X position is 10.0
Original Y position is 0.0.
Original position is (10.0,0.0).
New X position is 12.0
New Y position is -1.0
New position is ((12.0, -1.0))
Introduction rules
There are four cases in total
Spead: slow
Add 1 X position and reduce 2 Y position
Spead: medium
Add 2 X position and reduce 1 Y position
Spead: fast
Add 3 X position and add 3 Y position
Spead: veryfast
Add 4 X position and add 6 Y position
Full Code
############################
### Date 2021 October 1 ###
### Author Magneto ###
### Name 坐标移动 <——>
### Random True ###
### Language Python ###
############################
# 引入 random 模块
import random
# 定义 spead 内容 并进行随机处理
spead_0 = ['slow', 'medium', 'fast', 'veryfast']
spead_random = random.choice(spead_0)
# 用户输入X坐标
print("\nTell me your X position:")
your_x_position = input()
# 用户输入Y坐标
print("Tell me your Y position:")
your_y_position = input()
# 转化X坐标
x_position = float(your_x_position)
# 转化Y坐标(+1为初始位置)
y_position = float(your_y_position)
# 输出初始坐标值
print(f"\nOriginal X position is {x_position}"
f"\nOriginal Y position is {y_position}."
f"\nOriginal position is ({x_position},{y_position}).")
# if-elif-else语句
# 定义slow
if spead_random == 'slow':
# 算法
x_increment = x_position + 1
y_increment = y_position - 2
# 定义medium
elif spead_random == 'medium':
# 算法
x_increment = x_position + 2
y_increment = y_position - 1
# 定义fast
elif spead_random == 'fast':
# 算法
x_increment = x_position + 3
y_increment = y_position + 3
# 定义其它内容,假定其它内容速度为极快,达到仪表显示上限
else:
# 算法
x_increment = x_position + 4
y_increment = y_position + 6
# 输出移动后坐标
print(f"New X position is {x_increment}"
f"\nNew Y position is {y_increment}"
f"\nNew position is ({x_increment,y_increment})")
# 内容介绍定义
alien = {
'slow': 'Add 1 X position and reduce 2 Y position',
'medium': 'Add 2 X position and reduce 1 Y position',
'fast': 'Add 3 X position and add 3 Y position',
'veryfast': 'Add 4 X position and add 6 Y position'
}
print("\nIntroduction rules")
# 字符替换和介绍类型总数
if len(alien) == 4:
# 字符替换
The_number = 'four'
# 介绍类型总数
print(f"There are {The_number} cases in total")
# 其他类型
else:
# 输出空值
print("NULL")
# for语句输出
for spead_1, position in alien.items():
print(f"Spead: {spead_1}")
print(f"{position}")
Code Analysis
Analysis Notes
The code analysis will go through what each line does, with the line numbers including the lines taken up by comments.
The random Module
Line 9's import random brings the random module into the program. Its job is to pick a random value from the dictionary, which you can see in line 12. I wrote the dictionary contents in line 11, then used random to pick one at random. If you were to print it out at this point:
# 引入 random 模块
import random
# 定义 spead 内容 并进行随机处理
spead_0 = ['slow', 'medium', 'fast', 'veryfast']
spead_random = random.choice(spead_0)
# 输出数值
print(f"当前速度是{spead_random}")
It would pull any one value from spead_0 and print that, rather than always printing the first one.
Output
eg:
当前速度是medium
Before I improved the code, the program leaned on random quite a bit (see Python Learning Diary – The Story of an Outlaw). After the improvement, I switched the random value to manual input, which is even more random (not really).
The speed is still randomized, though, because that makes it easier to calculate rather than having to type it in.
Manual Input
Using input to enter values:
# 用户输入X坐标
print("\nTell me your X position:")
your_x_position = input()
# 用户输入Y坐标
print("Tell me your Y position:")
your_y_position = input()
Here, your_坐标类型_position corresponds to the next set of conversion logic. One thing worth noting: I didn't use code like this:
a = input("Tell me your X positison:")
Output
eg:
Tell me your X position:0 # 0是我输入的值
That's because running it that way makes the output look messy. A good program balances logic and aesthetics.
Solving the Arithmetic Problem
When you use input, the value you get back can't be used in arithmetic directly—it throws an error.
Example of Broken Code
a = input("Number is ")
b = a + 3
print(f"Now your number is {b}")
Error Message
b = a + 3
TypeError: can only concatenate str (not "int") to str
So what to do? I just went straight to copy-paste (not really). I looked at a little thing my friend had written and found you can use float() to process the input value and make it arithmetic-friendly. So it became this:
a = input("Number is ")
b= float(a)
c = b + 3
print(f"Now your number is {c}")
Output
eg:
Number is 1
4.0
I wrote two of these, one for the X coordinate input and one for the Y coordinate input:
# 转化X坐标
x_position = float(your_x_position)
# 转化Y坐标(+1为初始位置)
y_position = float(your_y_position)
At this point, the input value goes from being the floating value of your_坐标类型_position to the fixed value of 坐标类型_position, ready for the calculations that follow.
Printing the Original Coordinates
In the original code, it was written as
print(f"\nOriginal X position is {x_position}"
f"\nOriginal Y position is {y_position}."
f"\nOriginal position is ({x_position},{y_position}).")
Here, {坐标类型_position} is the value we entered. Since no calculation happens at this step, you could swap {坐标类型_position} for your_坐标类型_position and it would still display fine. But to save a few bytes (and because I had nothing better to do), I'd recommend using the {坐标类型_position} style to reference the value.
Inside print(), you don't have to use \n to break lines—you can just hit Enter to move to a new line. Of course, the \n approach works too.
Oh, right—in print(), if you're only outputting text, you can just use print() like this:
print("这是一段文字")
Output
eg:
这是一段文字
If you want to reference a value, you need to add an f in front, which stands for format (setting the format). It looks like this:
message = 文字
print(f"这是一段{message}")
Output
eg:
这是一段文字
当然,这是最基础的部分,我也不必再多说,这是某书第二章就讲过的问题。
The if-elif-else Statement
Let's look at the original code first
# if-elif-else语句
# 定义slow
if spead_random == 'slow':
# 算法
x_increment = x_position + 1
y_increment = y_position - 2
# 定义medium
elif spead_random == 'medium':
# 算法
x_increment = x_position + 2
y_increment = y_position - 1
# 定义fast
elif spead_random == 'fast':
# 算法
x_increment = x_position + 3
y_increment = y_position + 3
# 定义其它内容,假定其它内容速度为极快,达到仪表显示上限
else:
# 算法
x_increment = x_position + 4
y_increment = y_position + 6
This involves arithmetic, so I have to use the float() conversion I mentioned earlier before doing the math.
The numbers here can be written however you like. I made sure the smallest result wouldn't be negative, but after actually testing it, I found it doesn't matter whether it's negative or not—no bugs show up...
The most technical part here is the if-elif-else statement. Actually, it's not really technical—it's more of a logic thing.
I can translate the whole block into plain language, and then there's no need for more explanation.
# if-elif-else语句 #
# 定义slow #
if spead_random == 'slow': # 如果spead_random的值是slow,那么
# 算法 #
x_increment = x_position + 1 # x_increment(新建量)的值是x_position的值+1
y_increment = y_position - 2 # y_increment(新建量)的值是x_position的值-2
# 定义medium #
elif spead_random == 'medium': # 如果不是上几种而是spead_random的值是medium,那么
# 算法 #
x_increment = x_position + 2 # x_increment的值是x_position的值+2
y_increment = y_position - 1 # y_increment的值是x_position的值-1
# 定义fast #
elif spead_random == 'fast': # 如果不是上几种而是spead_random的值是fast,那么
# 算法 #
x_increment = x_position + 3 # x_increment的值是x_position的值+3
y_increment = y_position + 3 # y_increment的值是x_position的值+3
# 定义其它内容,假定其它内容速度为极快,达到仪表显示上限
else: # 其它情况
# 算法 #
x_increment = x_position + 4 # x_increment的值是x_position的值+4
y_increment = y_position + 6 # y_increment的值是x_position的值+6
And that's it. Here, I've treated else as the speed veryfast, but logically, any value that isn't slow, medium, or fast will run this logic. So if the current speed were, say, veryslow, the math would still be X+4, Y+6. But since the dictionary only has four cases, that problem never comes up.
Printing the New Coordinates
print(f"New X position is {x_increment}"
f"\nNew Y position is {y_increment}"
f"\nNew position is ({x_increment,y_increment})")
The coordinate values referenced here are the ones calculated by the if-elif-else block, so there's not much more to say.
The Introduction Section
Let's look at the code first
# 内容介绍定义
alien = {
'slow': 'Add 1 X position and reduce 2 Y position',
'medium': 'Add 2 X position and reduce 1 Y position',
'fast': 'Add 3 X position and add 3 Y position',
'veryfast': 'Add 4 X position and add 6 Y position'
}
print("\nIntroduction rules")
# 字符替换和介绍类型总数
if len(alien) == 4:
# 字符替换
The_number = 'four'
# 介绍类型总数
print(f"There are {The_number} cases in total")
# 其他类型
else:
# 输出空值
print("NULL")
# for语句输出
for spead_1, position in alien.items():
print(f"Spead: {spead_1}")
print(f"{position}"
This packs in a lot.
First, the alien = {……} part is a dictionary, where the first column is the speed and the second column is the description. The first column values are called key, and the second column values are called value.
Each key maps to one value, aligned horizontally.
The print() after that is the simplest kind of print statement, so no need to elaborate.
Starting from if, there's another piece of logic
# 字符替换和介绍类型总数
if len(alien) == 4:
# 字符替换
The_number = 'four'
# 介绍类型总数
print(f"There are {The_number} cases in total")
# 其他类型
else:
# 输出空值
print("NULL")
If the total number of entries in the alien dictionary is 4, it creates a new value, The_number = 'four', and prints the sentence There are four cases in total.
If not, it just prints the single word NULL.
This might be a bit hard to grasp, but that's the logic.
Finally, it prints out all the values in the alien dictionary
# for语句输出
for spead_1, position in alien.items():
print(f"Spead: {spead_1}")
print(f"{position}")
spead_1 corresponds to the key, and position corresponds to the value. It reads out the key and value and assigns them to spead_1 and position respectively.
Then it prints them out with print.
for is a loop: if not all the values have been printed yet, it keeps printing until every one has been output once.
Conclusion
So, is that it? This might be the most technical article I've written in nearly a year...