这个内容,来源自两个问答内容,其实也可以算作一个,分别是:
https://ask.csdn.net/questions/7914036
https://ask.csdn.net/questions/7903438/54117172?spm=1001.2014.3001.5501
这两个问答的内容其实是一致的,所以老顾偷懒直接粘贴网址回答了,另一个则实实在在的去实现了一遍。
题目内容:
使用设置好的字符宽度、高度,用星号显示指定的数字字符串
嗯,之前的题目由于是 js 里的,所以这两位题主也就没要求可以编辑的,即无需再控制台输出,无需在 textarea 里使用。所以老顾的实现其实有些想多了。
但是,这个题目还是比较有意思的,所以老顾准备拿过来用 python 再实现一遍。
我们拿到了任何题目,都需要先做一遍需求分析,并把逻辑摆顺了,才能进行开发,老顾希望所有看到老顾文章的读者们,都能自主的完成需求分析。
下边就是老顾的分析过程了。先说说 js 第一版的内容。
可以看到,我们需要按照液晶计算器的方式来展现数字,那么,我们就按照液晶计算器的数字格式,来区分数字需要显示的内容
在问答里,老顾给出了两个方式
numObj = {
0 : ['***'
,'* *'
,'* *'
,'* *'
,'***'],
1 : [' *'
,' *'
,' *'
,' *'
,' *'],
2 : ['***'
,' *'
,'***'
,'* '
,'***'],
3 : ['***'
,' *'
,'***'
,' *'
,'***'],
4 : ['* *'
,'* *'
,'***'
,' *'
,' *'],
5 : ['***'
,'* '
,'***'
,' *'
,'***'],
6 : ['***'
,'* '
,'***'
,'* *'
,'***'],
7 : ['***'
,' *'
,' *'
,' *'
,' *'],
8 : ['***'
,'* *'
,'***'
,'* *'
,'***'],
9 : ['***'
,'* *'
,'***'
,' *'
,'***']
}
这种方式其实就是很直观的,自己按照最小尺寸写了一遍
而另一种,则简略的多了
numObj = {
0 : [1,1,1,0,1,1,1],
1 : [0,0,1,0,0,1,0],
2 : [1,0,1,1,1,0,1],
3 : [1,0,1,1,0,1,1],
4 : [0,1,1,1,0,1,0],
5 : [1,1,0,1,0,1,1],
6 : [1,1,0,1,1,1,1],
7 : [1,0,1,0,0,1,0],
8 : [1,1,1,1,1,1,1],
9 : [1,1,1,1,0,1,1]
}
什么意思呢?那是因为液晶数字,一共有7个线段组成了,按照顺序书写其位置是否需要显示,则可以转成上边的数组了。
嗯,不管那一种方式,其实都是用了七个位置的信息,这个稍后再说
宽度很容易,设置多少,就宽多少,高度则会影响到腰的位置,比如高度5,腰的索引就是 2,高度7,腰就在3 了,那么如果是6呢?根据问答题主的意思,就是腰要高一点,腿要长一点,那么,高度6,腰的位置也在2
例如
**** **** ****
* * * * * *
**** **** * *
* * * * ****
**** * * * *
**** * *
****
那么有了数字的描述,有了高矮胖瘦和腰,那么我们就可以列出数字的点阵了。
有兴趣的小伙伴可以看看 js 的实现,这里老顾先实现一次 python 的,这里老顾使用第二种方式的数组。
num = ['1110111','0010010','1011101','1011011','0111010','1101011','1101111','1010010','1111111','1111011']
w = 5
h = 7
s = '0123456789'
由于有了宽和高,所以,每个数字所使用的区域其实就已经确定了,一定是宽乘高个点,那么我们可以直接生成一个宽乘高的二维列表,默认全是空格即可。
r = [[' ' for _ in range(w)] for _ in range(h)]
然后根据我们每个数字的使用的区域,来重新替换到相应为止的空格变成星号。
# 假设当前数字是 8,那么所有7个位置都需要替换成星号
p = '1111111'
for i in range(7):
if p[i] == '1':
if i == 1:
for j in range((h - 1) // 2):
r[j][0] = '*'
elif i == 2:
for j in range((h - 1) // 2):
r[j][-1] = '*'
elif i == 4:
for j in range((h - 1) // 2,h):
r[j][0] = '*'
elif i == 5:
for j in range((h - 1) // 2,h):
r[j][-1] = '*'
elif i == 0:
r[0] = ['*'] * w
elif i == 3:
r[(h - 1) // 2] = ['*'] * w
elif i == 6:
r[-1] = ['*'] * w
for row in r:
print(''.join(row)
现在问题来了,多个数字的话,我们应该怎么定义数字转点阵的自定义函数呢?
是返回成为点阵的内容,还是返回完整数组的内容,还是。。。嗯h行字符串的列表呢?
上一篇我们讲到了函数的定义,这次就是实战了。
我们来分析一下:
1、返回已经拼接成点阵的字符串
这个时候,我们还需要再到调用过程中,从新按照换行切割一下,否则我们很难实现将数字显示在同一行这个要求
2、返回完整的二维数组
嗯,这个时候,我们如果显示多个数字,我们只需要将每个数字转成二维数组,然后按高循环一遍,拿出所有返回结果中对应的行,然后拼接就好,这个时候,有点小问题,数字和数字之间的间隔还需要从新单独定义一下
3、返回高度行的字符串列表
这个方式,老顾觉得很赞,在按照高度循环拿出对应行的数据时,我只需要再次 join 一个间隔就很nice的完成了同一行现实的方式了。
num = ['1110111','0010010','1011101','1011011','0111010','1101011','1101111','1010010','1111111','1111011']
w = 5
h = 7
s = '0123456789'
def numPoint(n,w,h):
r = [[' ' for _ in range(w)] for _ in range(h)]
p = num[int(n)]
for i in range(7):
if p[i] == '1':
if i == 1:
for j in range((h - 1) // 2):
r[j][0] = '*'
elif i == 2:
for j in range((h - 1) // 2):
r[j][-1] = '*'
elif i == 4:
for j in range((h - 1) // 2,h):
r[j][0] = '*'
elif i == 5:
for j in range((h - 1) // 2,h):
r[j][-1] = '*'
elif i == 0:
r[0] = ['*'] * w
elif i == 3:
r[(h - 1) // 2] = ['*'] * w
elif i == 6:
r[-1] = ['*'] * w
return [''.join(row) for row in r]
for i in s:
print(numPoint(i,w,h))
ps = []
for i in s:
ps.append(numPoint(i,w,h))
for i in range(h):
print(' '.join([n[i] for n in ps]))
然后,我们就可以显示我们定制的数字字符了
num = ['1110111','0010010','1011101','1011011','0111010','1101011','1101111','1010010','1111111','1111011']
def numPoint(n):
r = [[' ' for _ in range(w)] for _ in range(h)]
p = num[int(n)]
for i in range(7):
if p[i] == '1':
if i == 1:
for j in range((h - 1) // 2):
r[j][0] = c
elif i == 2:
for j in range((h - 1) // 2):
r[j][-1] = c
elif i == 4:
for j in range((h - 1) // 2,h):
r[j][0] = c
elif i == 5:
for j in range((h - 1) // 2,h):
r[j][-1] = c
elif i == 0:
r[0] = [c] * w
elif i == 3:
r[(h - 1) // 2] = [c] * w
elif i == 6:
r[-1] = [c] * w
return [''.join(row) for row in r]
def showNumPoint(s):
ps = []
for i in s:
ps.append(numPoint(i))
for i in range(h):
print(' '.join([n[i] for n in ps]))
w = 5
h = 7
s = '5201314'
c = '♥'
showNumPoint(s)
其实任何问题,我们需要自己去寻找到解决方案,而解决方案则是根据你的分析内容得出来的,需求分析永远是开发人员绕不过去的第一步,如果这一步都做不好,逻辑无法理顺,那么后续的开发一定是错漏百出的。
记得在一篇小说中看到了这样的文字,老顾分享给初学者们。
知识重要吗?
大家都觉得知识很重要吗?”
“错!”
“在现在的社会,最廉价的就是知识,你去度娘上搜一搜,各种你想要的知识应有尽有。更重文献,稍微花个十几二十块,注册个会员,都是可以查询下载的。”
可是这有用吗?”
解决问题
“学习知识的目的,就是为了解决现实中的问题,你们拥有了解决问题的能力,你们自己才对别人有价值。”
“而在大学,真正要学习的,并不是枯燥,乏味,单一,和没有竞争壁垒的知识。”
“因为在这个社会,这些东西很快就会被人工智能所替代,而只有一样东西是人工智能永远无法替代的,那就是解决问题的能力!”
“知识只是原材料,架构在知识之上的解决问题的能力,才是核心竞争力!这才是大学真正要学习的东西。”
学科思维
“当春运的时候,火车票买不到,经济学就会认为:提高票价,就是解决问题的唯一办法,用价格来筛选需求。”
“这,就是经济学的学科思维。”
“为什么很多人学会计,他们赚钱的方式是做假账,把自己成功的快递到了监狱里面。”
“但真正的精英,却可以用会计知识,进行资产重组,税务包装。”
“这就是会计学的学科思维。”
以上文字摘自一个小说,嗯,名字很羞耻《颠覆了,这是皇帝聊天群》,第255章内容。话虽然白了点,也略有偏激,但意思其实还真是这个意思。
各位既然进入了编程的学习,那么我想大家的目的并不是当一个纯粹的码农吧,那么解决问题的能力就很重要了,而解决问题的第一步,就是分析问题,并罗列其中的关系、顺序、解决方式等等。这才是一个开发人员所应具备的第一个能力,而不是写代码。
望各位都能学会自己解决问题。