【问题标题】:How would I go about allowing the user to specify the number of coordinates?我将如何允许用户指定坐标数?
【发布时间】:2021-12-27 22:53:46
【问题描述】:

如何根据用户想要的数量创建变量(由一开始的简单问题定义)?

import random as ran
from random import *
import matplotlib
import matplotlib.pyplot as plt

coordonei = ran.randint(0,15)
coordoneii = ran.randint(0,15)

coordtwoi = ran.randint(coordonei, coordonei + 5)
coordtwoii = ran.randint(coordoneii, coordoneii + 5)

coordthreei = ran.randint(coordtwoi, coordtwoi + 5)
coordthreeii = ran.randint(coordtwoii, coordtwoii + 5) 

print("(",coordonei,",",coordoneii,")",
"(",coordtwoi,",",coordtwoii,")",
"(",coordthreei,",",coordthreeii,")")

plt.xlim(0, 20)
plt.ylim(0, 20)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")

x_values = [coordonei, coordtwoi, coordthreei]
y_values = [coordoneii, coordtwoii, coordthreeii]
plt.plot(x_values, y_values)

plt.plot(coordonei, coordoneii, '.r-')
plt.plot(coordtwoi, coordtwoii, '.r-')
plt.plot(coordthreei, coordthreeii, '.r-')

plt.show()

这个简单的代码每次只生成一个完整的随机折线图。我希望能够选择该图中有多少个坐标。

【问题讨论】:

  • 好吧,你会读到带有count = int(input"How many coordinates?")) 的号码。然后使用该值来调整数组的大小。对吗?
  • 此问题未正确关闭。你们都是根据标题采取的行动,并没有阅读问题,这与动态创建变量无关。

标签: python


【解决方案1】:

这是一个相当干净和简单的解决方案,和你做的一样,但更pythonic:

from random import randint
import matplotlib.pyplot as plt

# n can be any number of course
n = 10

# start a list of tuples with a first tuple of coordinates (x, y)
cs = [(randint(0, 15), randint(0, 15))]
# create n-1 more of them after it
for __ in range(n - 1):
    # cs[-1] is the last tuple in the list, so cs[-1][0] is the x of that tuple
    cs.append((randint(cs[-1][0], cs[-1][0] + 5), randint(cs[-1][1], cs[-1][1] + 5)))

# these are handy for plotting, see below for nicer solution
x_values = [x for x, __ in cs]
y_values = [y for __, y in cs]


# the limits of the plot will be set to 3 beyond the maximum values
plt.xlim(0, max(x_values)+3)
plt.ylim(0, max(y_values)+3)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")

plt.plot(x_values, y_values)

# add the marks
for x, y in cs:
    plt.plot(x, y, '.r-')

plt.show()

如果你问我,那就更好了:

from random import randint
import matplotlib.pyplot as plt

n = 10

cs = [(randint(0, 15), randint(0, 15))]
for __ in range(n - 1):
    # I changed this for readability, doesn't even need a comment
    cx, cy = cs[-1]
    cs.append((randint(cx, cx + 5), randint(cy, cy + 5)))

plt.xlim(0, max(x for x, __ in cs)+3)
plt.ylim(0, max(y for __, y in cs)+3)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")

# this zips up all the tuples into a tuple of lists of x's and y's 
# and then unpacks that tuple 
plt.plot(*zip(*cs))

# add the marks
for x, y in cs:
    plt.plot(x, y, '.r-')

plt.show()

我认为这更好,因为它避免了创建数据的副本,将所有坐标保存在一个漂亮而简单的 x 和 y 对(元组)列表中。所有操作仅引用该列表cs,这意味着它可能非常长,并且您的脚本仍然可以快速运行并且不会浪费空间(或引入意外更改一个副本但忘记另一个副本的机会)。

啊,要完成你的问题的答案,你要开始:

n = int(input('Any positive number:'))

如果您想查看数据在图表中的最终位置:

for i, (x, y) in enumerate(cs):
    plt.annotate(f'{i}:{(x, y)}', xy=(x, y), xytext=(x + 1, y - .5))

【讨论】:

  • 以第一个坐标为基值的初始列表既可用作填充种子,也可用作默认值(返回)。 max(x for x, __ in cs) 及其 y 对应物的视觉清晰度和代码对称性读起来很漂亮。
【解决方案2】:

您可以为它们使用一个列表,就像您使用 x_values 和 y_values 一样

然后你可以像这样向用户询问坐标:

number = input("How many coordinates do you want to create? ")
number = int(number)

x_values = []
y_values = []

while number:
    cor = input("Enter coordinate (x y): ")
    x, y = cor.split(" ")
    print("(" + str(x) + ", " + str(y) + ")")

    x_values.append(x)
    y_values.append(y)
    number -= 1

最后你可以重新设计最后一部分,使用 for 循环来实现函数:

plt.plot(x_values, y_values)

for x, y in zip(x_values, y_values):
    plt.plot(x, y, '.r-')

完整的代码如下所示:

import random as ran
from random import *
import matplotlib
import matplotlib.pyplot as plt

number = input("How many coordinates do you want to create? ")
number = int(number)

x_values = []
y_values = []

while number:
    cor = input("Enter coordinate (x y): ")
    x, y = cor.split(" ")
    print("(" + str(x) + ", " + str(y) + ")")

    x_values.append(x)
    y_values.append(y)
    number -= 1

plt.xlim(0, 20)
plt.ylim(0, 20)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")

plt.plot(x_values, y_values)

for x, y in zip(x_values, y_values):
    plt.plot(x, y, '.r-')

plt.show()

【讨论】:

    【解决方案3】:

    您可以将它们存储在列表中:

    numVar = input('How many variables?')
    numVar = int(numVar)
    
    myVars = [ varFunc() for i in range(numVar)] #varFunc would be a function that returns random variables in your case.
        
    

    【讨论】:

    【解决方案4】:

    成分

    分解成3个成分(功能):

    1. 通过input从用户那里读取int的坐标数
    2. 实现一个返回元组列表的generate_random_coords(num) 函数 - 一对(x,y) 代表一个坐标
    3. 将坐标传递给自定义绘图函数

    另见:

    大纲

    from random import randint
    import matplotlib.pyplot as plt
    
    # define the 3 ingredients (functions)
    
    if __name__ == '__main__':
        num_coords = read_num_coords()
        coords = generate_random_coords(num_coords)
        print(coords)
        plot(coords)
    

    配方

    def read_num_coords():
        return int(input("Please enter number of coordinates to plot (e.g. 3):"))
    
    
    def generate_random_coords(num_coords):
        coords = []
        for i in range(num_coords):
            add = 5 * (i+1)   # starts with 5, then increases by 5
            (prev_x, prev_y) = coords[i-1] if i > 0 else (0,0)  # more than previous 
            x = randint(prev_x, 10+add)
            y = randint(prev_y, 10+add)
            coords.append((x,y))
        return coords
    
    
    def plot(coords):
        max_x = max([c[0] for c in coords])  # maximum of x values
        plt.xlim(0, max_x+5)  # fix min: 0, max: add 5 more
        plt.xlabel("X Axis")
        max_y = max([c[1] for c in coords])  # maximum of y values
        plt.ylim(0, max_y+5)  # fix min: 0, max: add 5 more
        plt.ylabel("Y Axis")
    
        plt.plot(*zip(*coords))
        plt.plot(*zip(*coords), '.r-')
    
        plt.show()
    

    奖励:坐标生成器

    简短但有用的answer of Ryan Fu 启发了使用generator 函数。像range(n) 这样可以返回一个迭代器来构建一个list 的坐标。

    以下生成器函数可用于列表理解(如[i in range(3)])和生成器表达式(如i in range(3)) :

    def random_coordinates(count, max_x, max_y):
            x = randint(0, max_x)
            y = randint(0, max_y)
            yield (x,y)
    

    使用coords = [c for c in random_coordinates(num_coords, 20, 10)] 作为上述代码配方中coords = generate_random_coords(num_coords) 的替代品。

    注意:虽然之前的 list-factory generate_random_coords 使用前一个坐标作为下一个使用步长 5 的偏移量,但此生成器不跟踪间距。相反,我们使用从 (0,0) 到 (max_x, max_y) 的完整区域来随机生成坐标。

    现在我们使用参数 max_x = 20max_y = 10 显式预定义绘图的 x 和 y 轴的最大值。

    【讨论】:

    • 额外问题:(1) num_coords 的合理默认值是多少? (2) 哪个用户输入会导致剧情崩溃? (3) 关于 (x,y) 的最小值的(隐式)假设是什么?
    • 谢谢你,你的代码的某些部分我从来没有想过,非常聪明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2022-07-25
    相关资源
    最近更新 更多