Hour Glass in Python - python

I'm trying to code an hour glass in python with the following format:
Sample Input = 3
Sample Output:
1 0 2 0 3
0 2 0 3 0
0 0 3 0 0
0 2 0 3 0
1 0 2 0 3
My code:
#for input use:
inputString = int(input())
# For uper half
for i in range(1,inputString):
# printing i zeroes at the
# beginning of each row
for j in range(1,i):
print("0",end=" ")
for k in range(i,inputString+1):
print(k,"0",end=" ")
print()
# For lower half
for i in range(inputString , 0, -1):
# printing i spaces at the
# beginning of each row
for j in range(1, i):
print("0", end = " ")
# printing i to rows value
# at the end of each row
for k in range(i, inputString + 1):
print(k,"0",end = " ")
print()
My Output:
1 0 2 0 3 0
0 2 0 3 0
0 0 3 0
0 2 0 3 0
1 0 2 0 3 0
I experimented with the looping parameters but I'm not able to figure it out. But unfortunately i couldn't.
Please provide some inputs.

Here's my take to your problem:
def hourglass(n, pretty_print=True):
all_lines = []
for ii in range(n):
line = np.zeros((n*2-1))
line[[idx for idx in np.arange(ii, n*2-1-ii, 2)]] = np.arange(ii+1, n+1, 1)
all_lines.append(line)
all_lines = all_lines + all_lines[-2::-1]
if pretty_print:
str_lines = [[str(int(val)) for val in line] for line in all_lines]
[print(" ".join(line)) for line in str_lines]
return np.vstack(all_lines)
In the case of n=3:
hourglass(3, pretty_print=True)
which prints:
1 0 2 0 3
0 2 0 3 0
0 0 3 0 0
0 2 0 3 0
1 0 2 0 3

One solution with recursion:
def hourglass(n, n2=1, filler_char='0'):
if n == n2:
print(*'{:{filler}^{width}}'.format(filler_char.join('{}'.format(n)), width=n*2-1, filler=filler_char), sep=' ')
return
print(*'{:{filler}^{width}}'.format(filler_char.join(str(i) for i in range(n2, n+1)), width=n*2-1, filler=filler_char), sep=' ')
hourglass(n, n2+1, filler_char)
print(*'{:{filler}^{width}}'.format(filler_char.join(str(i) for i in range(n2, n+1)), width=n*2-1, filler=filler_char), sep=' ')
hourglass(7)
Prints:
1 0 2 0 3 0 4 0 5 0 6 0 7
0 2 0 3 0 4 0 5 0 6 0 7 0
0 0 3 0 4 0 5 0 6 0 7 0 0
0 0 0 4 0 5 0 6 0 7 0 0 0
0 0 0 0 5 0 6 0 7 0 0 0 0
0 0 0 0 0 6 0 7 0 0 0 0 0
0 0 0 0 0 0 7 0 0 0 0 0 0
0 0 0 0 0 6 0 7 0 0 0 0 0
0 0 0 0 5 0 6 0 7 0 0 0 0
0 0 0 4 0 5 0 6 0 7 0 0 0
0 0 3 0 4 0 5 0 6 0 7 0 0
0 2 0 3 0 4 0 5 0 6 0 7 0
1 0 2 0 3 0 4 0 5 0 6 0 7
With hourglass(7, filler_char=' ') it prints:
1 2 3 4 5 6 7
2 3 4 5 6 7
3 4 5 6 7
4 5 6 7
5 6 7
6 7
7
6 7
5 6 7
4 5 6 7
3 4 5 6 7
2 3 4 5 6 7
1 2 3 4 5 6 7

for k in range(i,inputString+1):
print(k,"0",end=" ")
print()
This section is your problem. Once it prints the final character (the 3 in your case), the loop tacks on another '0' and a whitespace and calls it a day. If you want whitespace instead of zeros this isn't a problem since they are visually indistinguishable, but an absence of any character obviously doesn't look the same as a '0' character. You can verify this by highlighting the sample output from the geeksforgeeks article in your browser; the leading whitespaces are there but the trailing whitespaces don't exist - after the 8 in each row is simply a whitespace then a newline character.

Related

Increment the value in a new column based on a condition using an existing column

I have a pandas dataframe with two columns:
temp_1 flag
1 0
1 0
1 0
2 0
3 0
4 0
4 1
4 0
5 0
6 0
6 1
6 0
and I wanted to create a new column named "final" based on :
if "flag" has a value = 1 , then it increments "temp_1" by 1 and following values as well. If we find value = 1 again in flag column then the previous value in "final" with get incremented by 1 , please refer to expected output
I have tired using .cumsum() with filters but not getting the desired result.
Expected output
temp_1 flag final
1 0 1
1 0 1
1 0 1
2 0 2
3 0 3
4 0 4
4 1 5
4 0 5
5 0 6
6 0 7
6 1 8
6 0 8
Just do cumsum for flag:
>>> df['final'] = df['temp_1'] + df['flag'].cumsum()
>>> df
temp_1 flag final
0 1 0 1
1 1 0 1
2 1 0 1
3 2 0 2
4 3 0 3
5 4 0 4
6 4 1 5
7 4 0 5
8 5 0 6
9 6 0 7
10 6 1 8
11 6 0 8
>>>

Replace values in df col - pandas

I'm aiming to replace values in a df column Num. Specifically:
where 1 is located in Num, I want to replace preceding 0's with 1 until the nearest Item is 1 working backwards or backfilling.
where Num == 1, the corresponding row in Item will always be 0.
Also, Num == 0 will always follow Num == 1.
Input and code:
df = pd.DataFrame({
'Item' : [0,1,2,3,4,4,0,1,2,3,1,1,2,3,4,0],
'Num' : [0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0]
})
df['Num'] = np.where((df['Num'] == 1) & (df['Item'].shift() > 1), 1, 0)
Item Num
0 0 0
1 1 0
2 2 0
3 3 0
4 4 0
5 4 1
6 0 0
7 1 0
8 2 0
9 3 0
10 1 0
11 1 0
12 2 0
13 3 0
14 4 1
15 0 0
intended output:
Item Num
0 0 0
1 1 1
2 2 1
3 3 1
4 4 1
5 4 1
6 0 0
7 1 0
8 2 0
9 3 0
10 1 0
11 1 1
12 2 1
13 3 1
14 4 1
15 0 0
First, create groups of the rows according to the two start and end conditions using cumsum. Then we can group by this new column and sum over the Num column. In this way, all groups that contain a 1 in the Num column will get the value 1 while all other groups will get 0.
groups = ((df['Num'].shift() == 1) | (df['Item'] == 1)).cumsum()
df['Num'] = df.groupby(groups)['Num'].transform('sum')
Result:
Item Num
0 0 0
1 1 1
2 2 1
3 3 1
4 4 1
5 4 1
6 0 0
7 1 0
8 2 0
9 3 0
10 1 0
11 1 1
12 2 1
13 3 1
14 4 1
15 0 0
You could try:
for a, b in zip(df[df['Item'] == 0].index, df[df['Num'] == 1].index):
df.loc[(df.loc[a+1:b-1, 'Item'] == 1)[::-1].idxmax():b-1, 'Num'] = 1

CAN FD Bit Rate Switch on Raspberry Pi 3

I am trying to get two RasPis with a CAN FD shield (MCP2517FD) to communicate via CAN FD. It actually works fine, but as soon as I set the BRS to TRUE, weird things happen and the messages are not sent out properly.
The setup I used for both Pis is pretty similiar to that one: https://github.com/GBert/misc/tree/master/RPi-MCP2517
I added the following lines to my /boot/config.txt:
core_freq=250
kernel=ms7/zImage
device_tree=ms7/bcm2710-rpi-3-b.dtb
overlay_prefix=ms7/overlays/
dtoverlay=mcp2517fd-can0
dtparam=interrupt=25
dtparam=oscillator=40000000
dtparam=spimaxfrequency=20000000
The send and receive files are written and python and pretty much copied from: https://github.com/skpang/PiCAN-FD-Python-examples
If I send messages without the BRS active I receive:
pi#raspberrypi:~/Desktop $ python receive.py
CAN Tx test
Bring up CAN0....
Ready
1585041201.788182 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.808952 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.830066 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.851458 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.872531 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.893586 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.914766 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.935900 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.957289 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.978357 1 0 123 8 1 2 3 4 5 6 7 8
1585041201.999257 1 0 123 8 1 2 3 4 5 6 7 8
1585041202.020625 1 0 123 8 1 2 3 4 5 6 7 8
1585041202.042069 1 0 123 8 1 2 3 4 5 6 7 8
1585041202.062888 1 0 123 8 1 2 3 4 5 6 7 8
1585041202.083847 1 0 123 8 1 2 3 4 5 6 7 8
1585041202.104733 1 0 123 8 1 2 3 4 5 6 7 8
Everythings fine so far.
Now I send the same messages but with the BRS set to True:
CAN Tx test
Bring up CAN0....
Ready
1585042868.352613 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.372650 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.372807 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.372949 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.373283 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.393287 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.393603 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.414106 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.414431 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.434750 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.435073 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.455482 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.455801 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.476293 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.476358 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.476461 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.476531 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.476863 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.497091 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.497158 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.497273 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.497595 1 1 123 8 1 2 3 4 5 6 7 8
1585042868.517904 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518014 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518133 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518226 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518320 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518439 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518558 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518678 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518815 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518870 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.518991 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.519087 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.519267 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.519425 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.519550 0 0 8 8 0 0 0 0 0 0 0 0
1585042868.519683 0 0 8 8 0 0 0 0 0 0 0 0
The result is different most of the times. I am sending 16 messages but only receive some of them (always a different number). Furthermore, if I send more messages from the same RasPi, I am getting the following error on the sending RasPi:
Traceback (most recent call last):
File "send.py", line 32, in <module>
bus.send(msg)
File "/home/pi/.local/lib/python2.7/site-packages/can/interfaces/socketcan/socketcan.py", line 626, in send
sent = self._send_once(data, msg.channel)
File "/home/pi/.local/lib/python2.7/site-packages/can/interfaces/socketcan/socketcan.py", line 649, in _send_once
raise can.CanError("Failed to transmit: %s" % exc)
can.CanError: Failed to transmit: [Errno 105] No buffer space available
Sometimes the RasPi freezes and I have to shut him down.
The bitrates and samplepoints of both configurations are the same.
Any ideas on how to get this running properly while the BRS is set or why this is happening?
Thank you very much in advance!

Reindex Panda Multiindex

I am trying to create a new index for a dataframe from created from a root file. I'm using uproot to bring in the file using the command
upfile_muon = uproot.open(file_prefix_muon + '.root')
tree_muon = upfile_muon['ntupler']['tree']
df_muon = tree_muon.pandas.df(['vh_sim_r','vh_sim_phi','vh_sim_z','vh_sim_tp1','vh_sim_tp2',
'vh_type','vh_station','vh_ring','vh_sim_theta'], entrystop=args.max_events)
This then creates a multiindex pandas dataframe with entries and subentries as my two indexes. I want to filter out all subentries of length 3 or less. I do that with the following command while creating vectors that slice the dataframe into the data that I need.
a = 0
bad_entries = 0
entries = []
nuindex = []
tru = 0
while(a < args.max_events):
if(df_muon.loc[(a),:].shape[0] > 3):
entries.append(a)
b = 0
while( b < df_muon.loc[(a),:].shape[0]):
nuindex.append(tru)
b = b + 1
tru = tru + 1
else:
bad_entries = bad_entries + 1
a = a + 1
df_muon = df_muon.loc[pd.IndexSlice[entries,:],:]
So now my dataframe looks like this
vh_sim_r vh_sim_phi vh_sim_z vh_sim_tp1 vh_sim_tp2 vh_type vh_station vh_ring vh_sim_theta
entry subentry
0 0 149.724701 -124.728081 793.598755 0 0 3 2 1 10.684152
1 149.236725 -124.180763 796.001221 -1 -1 3 2 1 10.618716
2 149.456131 -124.687302 796.001221 0 0 3 2 1 10.633972
3 92.405533 -126.913628 539.349976 0 0 4 1 1 9.721958
4 149.345184 -124.332527 839.810669 0 0 1 2 1 10.083608
5 176.544983 -123.978333 964.500000 0 0 2 3 1 10.372764
6 194.614502 -123.764595 1054.994995 0 0 2 4 1 10.451831
7 149.236725 -124.180763 796.001221 -1 -1 3 2 1 10.618716
8 149.456131 -124.687302 796.001221 0 0 3 2 1 10.633972
9 92.405533 -126.913628 539.349976 0 0 4 1 1 9.721958
10 149.345184 -124.332527 839.810669 0 0 1 2 1 10.083608
11 176.544983 -123.978333 964.500000 0 0 2 3 1 10.372764
12 194.614502 -123.764595 1054.994995 0 0 2 4 1 10.451831
1 0 265.027252 -3.324370 796.001221 0 0 3 2 1 18.415092
1 272.908997 -3.531896 839.903625 0 0 1 2 1 18.000479
2 299.305176 -3.531351 923.885132 0 0 1 3 1 17.950438
3 312.799255 -3.499015 964.500000 0 0 2 3 1 17.968519
4 328.321442 -3.530087 1013.620056 0 0 1 4 1 17.947645
5 181.831726 -1.668625 567.971252 0 0 3 1 1 17.752077
6 265.027252 -3.324370 796.001221 0 0 3 2 1 18.415092
7 197.739120 -2.073746 615.796265 0 0 1 1 1 17.802410
8 272.908997 -3.531896 839.903625 0 0 1 2 1 18.000479
9 299.305176 -3.531351 923.885132 0 0 1 3 1 17.950438
10 312.799255 -3.499015 964.500000 0 0 2 3 1 17.968519
11 328.321442 -3.530087 1013.620056 0 0 1 4 1 17.947645
12 356.493073 -3.441958 1065.694946 0 0 2 4 2 18.495964
2 0 204.523163 -124.065643 839.835571 0 0 1 2 1 13.686690
1 135.439163 -122.568153 567.971252 0 0 3 1 1 13.412345
2 196.380875 -123.940300 796.001221 0 0 3 2 1 13.858652
3 129.801193 -122.348656 539.349976 0 0 4 1 1 13.531607
4 224.134796 -124.194283 923.877441 0 0 1 3 1 13.636631
5 237.166031 -124.181770 964.500000 0 0 2 3 1 13.814683
6 246.809235 -124.196938 1013.871643 0 0 1 4 1 13.681540
7 259.389587 -124.164017 1054.994995 0 0 2 4 1 13.813211
8 204.523163 -124.065643 839.835571 0 0 1 2 1 13.686690
9 196.380875 -123.940300 796.001221 0 0 3 2 1 13.858652
10 129.801193 -122.348656 539.349976 0 0 4 1 1 13.531607
11 224.134796 -124.194283 923.877441 0 0 1 3 1 13.636631
12 237.166031 -124.181770 964.500000 0 0 2 3 1 13.814683
13 246.809235 -124.196938 1013.871643 0 0 1 4 1 13.681540
14 259.389587 -124.164017 1054.994995 0 0 2 4 1 13.813211
3 0 120.722900 -22.053474 615.786621 0 0 1 1 4 11.091969
1 170.635376 -23.190208 793.598755 0 0 3 2 1 12.134683
2 110.061127 -21.370941 539.349976 0 0 4 1 1 11.533570
3 164.784668 -23.263920 814.977478 0 0 1 2 1 11.430829
4 192.868652 -23.398684 948.691345 0 0 1 3 1 11.491603
5 199.817978 -23.325649 968.900024 0 0 2 3 1 11.652840
6 211.474625 -23.265354 1038.803833 0 0 1 4 1 11.506759
7 216.406830 -23.275047 1059.395020 0 0 2 4 1 11.545199
8 170.612457 -23.136520 793.598755 -1 -1 3 2 1 12.133101
5 0 179.913177 -14.877813 615.749207 0 0 1 1 1 16.287615
1 160.188034 -14.731569 565.368774 0 0 3 1 1 15.819215
2 240.671204 -15.410946 793.598755 0 0 3 2 1 16.870745
3 166.238678 -14.774992 586.454590 0 0 1 1 1 15.826117
4 241.036865 -15.400753 815.009399 0 0 1 2 1 16.475443
5 281.086792 -15.534301 948.707581 0 0 1 3 1 16.503710
6 288.768768 -15.577776 968.900024 0 0 2 3 1 16.596043
7 309.145935 -15.533208 1038.588745 0 0 1 4 1 16.576143
8 312.951233 -15.579374 1059.395020 0 0 2 4 1 16.457436
9 312.313416 -16.685022 1059.395020 -1 -1 2 4 1 16.425705
Now my goal is to find a way to change the 5 value in the entry index to a 4. I want to do this in a way that automates the process such that I can have a huge number of entries (~20,000), I can have my filter delete the unusable entries, then it renumbers all of the entries sequentially from 0 to the last unfiltered entry. I've tried all sorts of commands but I've had no luck. Is there a way to do this directly?
df_muon = (df_muon
.reset_index() # Get the multi-index back as columns
.replace({'entry': 5}, {'entry': 4}) # Replace 5 in column 'entry' with 4
.set_index(['entry', 'subentry']) # Go back to the multi-index
)

Finding efficiently pandas (part of) rows with unique values

Given a pandas dataframe with a row per individual/record. A row includes a property value and its evolution across time (0 to N).
A schedule includes the estimated values of a variable 'property' for a number of entities from day 1 to day 10 in the following example.
I want to filter entities with unique values for a given period and get those values
csv=',property,1,2,3,4,5,6,7,8,9,10\n0,100011,0,0,0,0,3,3,3,3,3,0\n1,100012,0,0,0,0,2,2,2,8,8,0\n2, \
100012,0,0,0,0,2,2,2,2,2,0\n3,100012,0,0,0,0,0,0,0,0,0,0\n4,100011,0,0,0,0,2,2,2,2,2,0\n5, \
180011,0,0,0,0,2,2,2,2,2,0\n6,110012,0,0,0,0,0,0,0,0,0,0\n7,110011,0,0,0,0,3,3,3,3,3,0\n8, \
110012,0,0,0,0,3,3,3,3,3,0\n9,110013,0,0,0,0,0,0,0,0,0,0\n10,100011,0,0,0,0,3,3,3,3,4,0'
from StringIO import StringIO
import numpy as np
schedule = pd.read_csv(StringIO(csv), index_col=0)
print schedule
property 1 2 3 4 5 6 7 8 9 10
0 100011 0 0 0 0 3 3 3 3 3 0
1 100012 0 0 0 0 2 2 2 8 8 0
2 100012 0 0 0 0 2 2 2 2 2 0
3 100012 0 0 0 0 0 0 0 0 0 0
4 100011 0 0 0 0 2 2 2 2 2 0
5 180011 0 0 0 0 2 2 2 2 2 0
6 110012 0 0 0 0 0 0 0 0 0 0
7 110011 0 0 0 0 3 3 3 3 3 0
8 110012 0 0 0 0 3 3 3 3 3 0
9 110013 0 0 0 0 0 0 0 0 0 0
10 100011 0 0 0 0 3 3 3 3 4 0
I want to find records/individuals for who property has not changed during a given period and the corresponding unique values
Here is what i came with : I want to locate individuals with property in [100011, 100012, 1100012] between days 7 and 10
props = [100011, 100012, 1100012]
begin = 7
end = 10
res = schedule['property'].isin(props)
df = schedule.ix[res, begin:end]
print "df \n%s " %df
We have :
df
7 8 9
0 3 3 3
1 2 8 8
2 2 2 2
3 0 0 0
4 2 2 2
10 3 3 4
res = df.apply(lambda x: np.unique(x).size == 1, axis=1)
print "res : %s\n" %res
df_f = df.ix[res,]
print "df filtered %s \n" % df_f
res = pd.Series(df_f.values.ravel()).unique().tolist()
print "unique values : %s " %res
Giving :
res :
0 True
1 False
2 True
3 True
4 True
10 False
dtype: bool
df filtered
7 8 9
0 3 3 3
2 2 2 2
3 0 0 0
4 2 2 2
unique values : [3, 2, 0]
As those operations need to be run many times (in millions) on a million rows dataframe, i need to be able to run it as quickly as possible.
(#MaxU) : schedule can be seen as a database/repository updated many times. The repository is then requested as well many times for unique values
Would you have some ideas for improvements/ alternate ways ?
Given your df
7 8 9
0 3 3 3
1 2 8 8
2 2 2 2
3 0 0 0
4 2 2 2
10 3 3 4
You can simplify your code to:
df_f = df[df.apply(pd.Series.nunique, axis=1) == 1]
print(df_f)
7 8 9
0 3 3 3
2 2 2 2
3 0 0 0
4 2 2 2
And the final step to:
res = df_f.iloc[:,0].unique().tolist()
print(res)
[3, 2, 0]
It's not fully vectorised, but maybe this clarifies things a bit towards that?

Categories

Resources