Rotate a Bitmap with Shearing
as paulHK said:

One fundamental issue here is you're rotating in destination space rather than source space (e.g. apply the shear on source coordinates and output a rectangle). This way you can guarantee every pixel in the output is drawn once and only once and there are no gaps in between.

and the line that's causing the 180 problem is this line:
tangent=math.tan(angle/2)
If the angle is 180, the tan of 90 will be basically infinity.
This is a graph of 1 / (cos(rotation) ^ 2), one of the shearing calculations the narrator at datagenetics.com uses:

That means his method stalls at certain angles.
In all the code i wrote, I never needed to call tan(x).
Use cos(x) and sin(x) instead, also use as few divisions as possible that could create infinity. Most rendering engines tackle this problem by limiting the angle of the camera to 89 degrees.
To get unaliased rotated images, i suggest a better drawing method, which computer graphics use today:
Use a 3x3 rotation matrix and a translation matrix , and loop over the pixels image that you want to draw on:
cos(angle) -sin(angle) + offset x 
sin(angle) cos(angle)  + offset y 
0          0           1 
to get this matrix, multiply first: 
1 0 -[rotation centre x]  
0 1 -[rotation centre y]  
0 0 1 
then: 
cos(angle) -sin(angle) 0 
sin(angle) cos(angle)  0 
0          0           1
and then: 
1 0 [rotation centre x]  
0 1 [rotation centre y]  
0 0 1 
and then(if needed to translate): 
1 0 [translation x]  
0 1 [translation y]  
0 0 1 
Multiply the position on the target image by the INVERSE of the combined matrix to get the position on the source image.
If the position is in the bounds of the source image,
fill the target pixel with the source pixel at that location.