从浮动中创建一个带有全星和半星的命令行星级? Python 3
Create a command line star rating with full and half stars from a float? Python 3
所以我正在开发一个获取酒店详细信息的命令行应用程序,其中一个详细信息是他们的 "star rating"。我可以只列出我得到的字符串,但这并不好玩,我希望应用程序 真的 看起来不错。所以想自己打造星级的外观
我当时并不知道,这可能需要比我想象的更多的数学知识(它甚至可以成为一个很好的面试问题)。
详情如下:
- 我传入的数据如下所示:
3.7 stars
- 我想得到一个最接近的估计,在这个3.5就足够了。
- 我 return 它是一个字符串,看起来应该像“++-”,其中“+”表示满星,“-”表示半星
到目前为止我的代码:
def format_hotel_rating(self, rating):
rating_as_num = float(rating[:3]) # rating => "3.7 stars"
for i in range(0, new_rating * 10):
if i % 10 == 0:
new_rating += "+"
# still missing half star logic
到目前为止,我的逻辑是这样的:
- 取小数并乘以 10(这样可以更容易地迭代)
- 每第 10 次迭代,添加一个满星
- 当不能再有 10 的倍数时,在最后一个 10 的倍数和最后一次迭代之间计算次次迭代
- 例如10(满星)、20(满星)、30(满星)、31、32、33、34、35、 36、37
- 然后判断
37
更接近35
还是40
。如果接近35,则追加半星“-”,否则如果接近40,则追加全星“+”
几个小时以来,我一直在努力在脑海中解决这个问题(我想我什至无法通过自己的面试),但我还没有找到任何成功的方法。
我怎样才能做到这一点?
这是一个简单的两行:
a, b = divmod(rating, 1.0)
stars = int(a) * '+' + ('-' if b >= 0.5 else '')
其中 rating
是您的浮点值。
编辑:更改了数字。
为什么不完全在浮点域中工作来替换最后一个 for 循环?
pure_rating = int(rating_as_num)
decimal_part = rating_as_num - pure_rating
final_score = "+" * pure_rating
if decimal_part >= 0.75:
final_score += "+"
elif decimal_part >= 0.25:
final_score += "-"
第一行查找评分的整数部分 (3.7 -> 3)。
第二行通过减去两个找到小数部分。 (3.7 - 3 -> 0.7)
最后,您首先创建 pure_rating
个 "+"
个字符。然后根据小数部分添加"+"
或"-"
(无论是在0.5-0.75
范围内还是在0.75-0.99
范围内)
rating = 3.5 #or whatever the rating is
for i in range(int(3.5)) #int truncates decimal... get "whole" stars
print('+', end='')
decimal = rating % 1 #gets how much "partial star" left over
if decimal >= .7: #close enough to be full star
print('+')
else:
print('-')
def extract_rating_from_string(rating_string):
"""
eg. rating_string = '3.7 stars'
"""
return float(rating_string.split()[0])
def round_rating_to_half(rating):
"""
Round to nearest half
"""
return round(rating * 2) / 2
def get_rating_stars(rating_string):
"""
Main function to return stars from string
"""
full_star = '+'
half_star = '-'
rating_float = extract_rating_from_string(rating_string)
rounded_rating = round_rating_to_half(rating_float)
if divmod(rounded_rating, 1)[1] == 0.5:
return int(rounded_rating)*full_star + half_star
else:
return int(rounded_rating)*full_star
输出:
>>> get_rating_stars('3.7 stars')
'+++-'
>>> get_rating_stars('3.1 stars')
'+++'
>>> get_rating_stars('4.9 stars')
'+++++'
所以我正在开发一个获取酒店详细信息的命令行应用程序,其中一个详细信息是他们的 "star rating"。我可以只列出我得到的字符串,但这并不好玩,我希望应用程序 真的 看起来不错。所以想自己打造星级的外观
我当时并不知道,这可能需要比我想象的更多的数学知识(它甚至可以成为一个很好的面试问题)。
详情如下:
- 我传入的数据如下所示:
3.7 stars
- 我想得到一个最接近的估计,在这个3.5就足够了。
- 我 return 它是一个字符串,看起来应该像“++-”,其中“+”表示满星,“-”表示半星
到目前为止我的代码:
def format_hotel_rating(self, rating):
rating_as_num = float(rating[:3]) # rating => "3.7 stars"
for i in range(0, new_rating * 10):
if i % 10 == 0:
new_rating += "+"
# still missing half star logic
到目前为止,我的逻辑是这样的:
- 取小数并乘以 10(这样可以更容易地迭代)
- 每第 10 次迭代,添加一个满星
- 当不能再有 10 的倍数时,在最后一个 10 的倍数和最后一次迭代之间计算次次迭代
- 例如10(满星)、20(满星)、30(满星)、31、32、33、34、35、 36、37
- 然后判断
37
更接近35
还是40
。如果接近35,则追加半星“-”,否则如果接近40,则追加全星“+”
几个小时以来,我一直在努力在脑海中解决这个问题(我想我什至无法通过自己的面试),但我还没有找到任何成功的方法。
我怎样才能做到这一点?
这是一个简单的两行:
a, b = divmod(rating, 1.0)
stars = int(a) * '+' + ('-' if b >= 0.5 else '')
其中 rating
是您的浮点值。
编辑:更改了数字。
为什么不完全在浮点域中工作来替换最后一个 for 循环?
pure_rating = int(rating_as_num)
decimal_part = rating_as_num - pure_rating
final_score = "+" * pure_rating
if decimal_part >= 0.75:
final_score += "+"
elif decimal_part >= 0.25:
final_score += "-"
第一行查找评分的整数部分 (3.7 -> 3)。
第二行通过减去两个找到小数部分。 (3.7 - 3 -> 0.7)
最后,您首先创建 pure_rating
个 "+"
个字符。然后根据小数部分添加"+"
或"-"
(无论是在0.5-0.75
范围内还是在0.75-0.99
范围内)
rating = 3.5 #or whatever the rating is
for i in range(int(3.5)) #int truncates decimal... get "whole" stars
print('+', end='')
decimal = rating % 1 #gets how much "partial star" left over
if decimal >= .7: #close enough to be full star
print('+')
else:
print('-')
def extract_rating_from_string(rating_string):
"""
eg. rating_string = '3.7 stars'
"""
return float(rating_string.split()[0])
def round_rating_to_half(rating):
"""
Round to nearest half
"""
return round(rating * 2) / 2
def get_rating_stars(rating_string):
"""
Main function to return stars from string
"""
full_star = '+'
half_star = '-'
rating_float = extract_rating_from_string(rating_string)
rounded_rating = round_rating_to_half(rating_float)
if divmod(rounded_rating, 1)[1] == 0.5:
return int(rounded_rating)*full_star + half_star
else:
return int(rounded_rating)*full_star
输出:
>>> get_rating_stars('3.7 stars')
'+++-'
>>> get_rating_stars('3.1 stars')
'+++'
>>> get_rating_stars('4.9 stars')
'+++++'