Simple python histogram - python

result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
def histogram (list1,list2):
for i in range (len(list1)):
print(list1[i])
for j in range (list2[i]):
print("","*")
histogram(result1,result2)
I'm trying to get the output like this, but I can't seem to get that.
Progress Progress(MT) ModuleRT Excluded
* * * *
*

Using center(), you can build the columns with the width corresponding to their respective title size. The histogram itself will need as many lines as the maximum value in result2. Each column should only print a star if the line index is less than the corresponding value.
result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
print(*result1)
for i in range(max(result2)):
print(*( " *"[i<r].center(len(t)) for t,r in zip(result1,result2)))
Progress Progress(MT) ModuleRT Exclude
* * * *
* * * *
* * * *
* *
*
The histogram would look better if the columns were above the titles. You can do this by simply reversing the order of the line index:
for i in reversed(range(max(result2))):
print(*( " *"[i<r].center(len(t)) for t,r in zip(result1,result2)))
print(*result1)
*
* *
* * * *
* * * *
* * * *
Progress Progress(MT) ModuleRT Exclude
Converted to a function:
def histogram(titles,values):
print(*titles)
for i in range(max(values)):
print(*( " *"[i<v].center(len(t)) for t,v in zip(titles,values)))

Hello Alex and welcome on the Stackoverflow
I assume that, you want to get something like this below:
Progress * * *
Progress(MT) * * * *
ModuleRT * * *
Exclude * * * * *
Then, you have to modify your code, so that the print method does not add a new line after every * printed. To do so, you use end argument and set it to an empty character, like this: print("some string", end='')
So your new code would be:
result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
def histogram (list1,list2):
for i in range (len(list1)):
print(list1[i], end='') # here is the end added
for j in range (list2[i]):
print("","*", end='') # here is the end added
histogram(result1,result2)
Nevertheless, it won't end-up in something like this:
Progress * * *Progress(MT) * * * *ModuleRT * * *Exclude * * * * *
The thing is, that there's no new line character after first outer for loop iteration. So you print a new line with an empty print at the end of the outer loop like this print("").
So finally your code would look like this:
result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
def histogram (list1,list2):
for i in range (len(list1)):
print(list1[i], end='')
for j in range (list2[i]):
print("","*", end='')
print("") # here is the print
histogram(result1,result2)

Related

how to make my horizontal histogram to vertical

this is a part of my program which generates * patterns from 4 user inputs
total= progresscount + trailercount + retrivercount + excludecount
print("....................................................")
print("Histogram")
print("Progress",progresscount,":" , "*" * progresscount)
print("Trailer",trailercount,":" , "*" * trailercount)
print("Retriver",retrivercount,":" , "*" * retrivercount)
print("Excluded",excludecount ,":" , "*" * excludecount )
print("....................................................")
if I run my whole program and enter 2 3 1 and 2 for each input requests, output looks like this
....................................................
Histogram
Progress 2 : **
Trailer 3 : ***
Retriver 1 : *
Excluded 2 : **
....................................................
and I want to make a vertical version like this
....................................................
Progress Trailing Retriever Excluded
* * * *
* * *
*
....................................................
help me to figure this out?
You can create a custom function like below:
def display_vhist(data):
cell_len = max([len(k) for k in data]) + 2
max_val = max(data.values())
# display header
print(*[h.center(cell_len) for h in data.keys()], sep='')
# display histogram
for i in range(1, max_val+1):
for v in data.values():
c = '*' if i <= v else ' '
print(c.center(cell_len), end='')
print()
Usage:
data = {'Progress': 2, 'Trailer': 3, 'Retriver': 1, 'Excluded': 1}
display_vhist(data)
# Output
Progress Trailer Retriver Excluded
* * * *
* *
*

Python pandas how to use a lamda function to convert duplicated code in 1 line

I have a pandas python code like this:
def mul3(df):
df['mul31'] = df['tpx1'].values * df['tqy1'].values * df['vtin1'].values * df[
'slife1'].values
df['mul32'] = df['tpx2'].values * df['tqy2'].values * df['vtin2'].values * df[
'slife1'].values
df['mul33'] = df['tpx3'].values * df['tqy3'].values * df['vtin3'].values * df[
'slife1'].values
df['mul34'] = df['tpx4'].values * df['tqy4'].values * df['vtin4'].values * df[
'slife1'].values
df['mul35'] = df['tpx5'].values * df['tqy5'].values * df['vtin5'].values * df[
'slife1'].values
return df
Is there anyway I can use a lamda function to replace it to 1 line code?
Any friend can help?
You could probably do it like this:
N = 5
df[[f'mul3{i}' for i in range(1, N+1)]] = [df[f'tpx{i}'].values * df[f'tqy{i}'].values * df[f'vtin{i}'].values * df['slife1'].values for i in range(1, N+1)]
This is exactly like #richardec's solution. The only difference is it uses a dict comprehension and assign.
df = df.assign(**{f'mul3{i}': df[f'tpx{i}'] * df[f'tqy{i}'] * df[f'vtin{i}'] * df['slife1'] for i in range(1,6)})
Not a one-liner but much more readable
func = lambda df, num : df[f'tpx{num}'].values * df[f'tqy{num}'].values * df[f'vtin{num}'].values * df[f'slife1'].values
for i in range(5):
df[f'mul3{i}'] = func(df, i)

Calculation problem in a function in Python

I'm trying to calculate something in a function with numbers from an imported list.
def calculate_powers(velocities_list):
power_list = []
for i in velocities_list:
power = 8/27 * 1.225 * i * 8659
power_list.append(power)
print(power_list)
However, I get the following error:
File "C:\Users\Omistaja\PycharmProjects\7_1\wind_turbine.py", line 6, in calculate_powers
power = 8/27 * 1.225 * i * 8659
TypeError: can't multiply sequence by non-int of type 'float'
What to do?
try this :
def calculate_powers(velocities_list):
power_list = []
for i in velocities_list:
power = float(8/27) * 1.225 * float(i) * float(8659)
power_list.append(power)
print(power_list)
your variable 'i' is probably string, you need to cenvert it to number(float or int,..)
power = 8/27 * 1.225 * float(i) * 8659
can you provide example of your velocities_list?

Access list items -python

result1 = [prg_count,prg_mt_count,dnt_prg_count,excld_count]
total_students = prg_count + prg_mt_count + dnt_prg_count + excld_count
result2 = ["Progress", "Progress(MT)", "Do not Progress(MT)", "Exclude"]
def histogram (list1):
for i in range (len(list1)):
for j in range (list1[i]):
print("*",end="")
print("")
print('_' * 30)
print("Horizontal Histogram")
histogram (result1)
print(total_students, "outcomes in total")
print('_' * 30)
I want to print the items in the result2 list, one by one with their histogram value.
Histogram value changes according to user inputs and they're assigned to result1 list items.
what I'm trying to get;
Progress : *
Progress(MT) : *
Do not Progress(MT) : **
Excluded 1 : *
Did some improvements to your code, instead of loop for * printing I used '*' * count, same like you did for horizontal line '_' * 30, also printed names of histogram keys as you wished in your Question, plus used string's method .ljust(21) which adds extra spaces to align several strings to the same width.
Also as an example I showed histogram values 1, 5, 2, 3, see my Output after code below.
Try it online!
prg_count, prg_mt_count, dnt_prg_count, excld_count = 1, 5, 2, 3
result1 = [prg_count,prg_mt_count,dnt_prg_count,excld_count]
total_students = prg_count + prg_mt_count + dnt_prg_count + excld_count
result2 = ["Progress", "Progress(MT)", "Do not Progress(MT)", "Exclude"]
def histogram (list1, list2):
for a, b in zip(list1, list2):
print(b.ljust(21) + '*' * a)
print('=' * 30)
print("Horizontal Histogram")
print('-' * 30)
histogram(result1, result2)
print('-' * 30)
print(total_students, "outcomes in total")
print('=' * 30)
Output:
==============================
Horizontal Histogram
------------------------------
Progress *
Progress(MT) *****
Do not Progress(MT) **
Exclude ***
------------------------------
11 outcomes in total
==============================
Your question is not clear, but I think I know what you are saying. If you want to print the titles to the values (as I think your desired output says) you need to pass your titles in.
result1 = [5, 4, 2, 3]
total_students = sum(result1)
result2 = ["Progress","Progress(MT)","Do not Progress(MT)","Exclude"]
def histogram(result2, result1):
for i in range(len(result2)):
print(result2[i], end=" ")
for j in range(result1[i]):
print('*', end="")
print('')
print('_' * 30)
print("Horizontal Histogram")
histogram (result2, result1)
print(total_students, "outcomes in total")
print('_' * 30)
If you want to make it more succinct you can do this instead.
output = zip(result2, result1)
def histogram(list1):
for title, value in list1:
print(f"{title:20} {''.join(['*' for i in range(value)])}\n")
histogram(output)

Python nested dictionaries into reStructuredText bullet list

I have this dictionary:
d = {'B': {'ticket': ['two', 'three'], 'note': ['nothing to report']}, 'A': {'ticket': ['one'], 'note': ['my note']}, 'C': {'ticket': ['four'], 'note': ['none']}}
and I'm trying to convert it into a .rst document as a bullets list, like:
* A
* ticket:
* one
* note
* my note
* B
* ticket:
* two
* three
* note:
* nothing to report
* C
* ticket:
* four
* note:
* none
I read this approach but I cannot translate it into a bullet list
Thanks to all
For something like your specific example, what about this:
>>> for key, value in d.items():
... print('* {}'.format(key))
... for k, v in value.items():
... print(' * {}:'.format(k))
... for i in v:
... print(' * {}'.format(i))
...
* B
* note:
* nothing to report
* ticket:
* two
* three
* A
* note:
* my note
* ticket:
* one
* C
* note:
* none
* ticket:
* four
A more of less generic solution to your problem would be a recursive function:
def bullet_list(elements, level=0, indent_size=4):
try:
items = elements.items()
except AttributeError:
for bullet_point in elements:
yield '{}* {}'.format(' ' * (indent_size * level), bullet_point)
else:
for bullet_point, sub_points in items:
yield '{}* {}'.format(' ' * (indent_size * level), bullet_point)
yield from bullet_list(sub_points, level=level + 1, indent_size=indent_size)
for line in bullet_list(d):
print(line)
outputs:
* A
* note
* my note
* ticket
* one
* C
* note
* none
* ticket
* four
* B
* note
* nothing to report
* ticket
* two
* three
​Note however that the ordered is not guaranteed in dictionaries until very recent versions of python.
Ugly and dirty
def bullet(d, depth=1):
for k,v in d.items():
print(''.join([depth * ' ', '* ', k]))
if isinstance(v, dict):
bullet(v, depth+1)
else:
for e in v:
print(''.join([depth * ' ', ' * ', e]))
I would break the task down into three steps:-
1 - Sort the dictionary - as this is impossible it would be best to create a list of keys, sort this list then iterate through them
2 - Check if ticket exists and the for item in ticket to print them
3 - Check if note exists then print each item for note.

Categories