I would like to print the following pattern in Python 3.5 (I'm new to coding):
*
***
*****
*******
*********
*******
*****
***
*
But I only know how to print the following using the code below, but not sure how to invert it to make it a complete diamond:
n = 5
print("Pattern 1")
for a1 in range (0,n):
for a2 in range (a1):
print("*", end="")
print()
for a1 in range (n,0,-1):
for a2 in range (a1):
print("*", end="")
print()
*
**
***
****
*****
****
***
**
*
Any help would be appreciated!
Since the middle and largest row of stars has 9 stars, you should make n equal to 9. You were able to print out half of the diamond, but now you have to try to make a function that prints a specific number of spaces, then a specific number of stars. So try to develop a pattern with the number of spaces and stars in each row,
Row1: 4 spaces, 1 star, 4 spaces
Row2: 3 spaces, 3 stars, 3 spaces
Row3: 2 spaces, 5 stars, 2 spaces
Row4: 1 space, 7 stars, 1 space
Row5: 0 spaces, 9 stars, 0 spaces
Row6: 1 space, 7 stars, 1 space
Row7: 2 spaces, 5 stars, 2 spaces
Row8: 3 spaces, 3 stars, 3 spaces
Row9: 4 spaces, 1 star, 4 spaces
So what can you deduce? From row 1 to (n+1)/2, the number of spaces decreases as the number of stars increase. So from 1 to 5, the # of stars = (row number * 2) - 1, while # of spaces before stars = 5 - row number.
Now from row (n+1)/2 + 1 to row 9, the number of spaces increase while the number of stars decrease. So from 6 to n, the # of stars = ((n+1 - row number) * 2) - 1, while # of spaces before stars = row number - 5.
From this information, you should be able to make a program that looks like this,
n = 9
print("Pattern 1")
for a1 in range(1, (n+1)//2 + 1): #from row 1 to 5
for a2 in range((n+1)//2 - a1):
print(" ", end = "")
for a3 in range((a1*2)-1):
print("*", end = "")
print()
for a1 in range((n+1)//2 + 1, n + 1): #from row 6 to 9
for a2 in range(a1 - (n+1)//2):
print(" ", end = "")
for a3 in range((n+1 - a1)*2 - 1):
print("*", end = "")
print()
Note that you can replace n with any odd number to create a perfect diamond of that many lines.
Here is a solution base on height equals to top to the middle, or half of the height. For example, height is entered as 4(7) or 5(9) below. This method will yield odd number actual height
h = int(input("please enter diamond's height:"))
for i in range(h):
print(" "*(h-i), "*"*(i*2+1))
for i in range(h-2, -1, -1):
print(" "*(h-i), "*"*(i*2+1))
# please enter diamond's height:4
# *
# ***
# *****
# *******
# *****
# ***
# *
#
# 3, 2, 1, 0, 1, 2, 3 space
# 1, 3, 5, 7, 5, 3, 1 star
# please enter diamond's height:5
# *
# ***
# *****
# *******
# *********
# *******
# *****
# ***
# *
#
# 4, 3, 2, 1, 0, 1, 2, 3, 4 space
# 1, 3, 5, 7, 9, 7, 5, 3, 1 star
Here is another solution base on height equals to top to the bottom, or the actual total height. For example, height is entered as 7 or 9 below. When the user enters an even number for height, the diamond will be slightly slanted.
h = int(input("please enter diamond's height:"))
for i in range(1, h, 2):
print(" "*(h//2-i//2), "*"*i)
for i in range(h, 0, -2):
print(" "*(h//2-i//2), "*"*i)
# please enter diamond's height:7
# *
# ***
# *****
# *******
# *****
# ***
# *
#
# 3, 2, 1, 0, 1, 2, 3 space
# 1, 3, 5, 7, 5, 3, 1 star
#
# please enter diamond's height:9
# *
# ***
# *****
# *******
# *********
# *******
# *****
# ***
# *
#
# 4, 3, 2, 1, 0, 1, 2, 3, 4 space
# 1, 3, 5, 7, 9, 7, 5, 3, 1 star
I learned a very simple solution today and would like to share it. :)
num = 9
for i in range(1, num+1):
i = i - (num//2 +1)
if i < 0:
i = -i
print(" " * i + "*" * (num - i*2) + " "*i)
The logic is the following:
(A space is represented as "0" here.)
# i = 1 | new i = 1 - 5 = -4 | * : 9 - 8 = 1 | 0000 + * + 0000
# i = 2 | new i = 2 - 5 = -3 | * : 9 - 6 = 3 | 000 + *** + 000
# i = 3 | new i = 3 - 5 = -2 | * : 9 - 4 = 5 | 00 + ***** + 00
# i = 4 | new i = 4 - 5 = -1 | * : 9 - 2 = 7 | 0 + ******* + 0
# i = 5 | new i = 5 - 5 = 0 | * : 9 - 0 = 9 | *********
# i = 6 | new i = 6 - 5 = 1 | * : 9 - 2 = 7 | 0 + ******* + 0
# i = 7 | new i = 7 - 5 = 2 | * : 9 - 4 = 5 | 00 + ***** + 00
# i = 8 | new i = 8 - 5 = 3 | * : 9 - 6 = 3 | 000 + *** + 000
# i = 9 | new i = 9 - 5 = 4 | * : 9 - 8 = 1 | 0000 + * + 0000
The result would be the following:
*
***
*****
*******
*********
*******
*****
***
*
As pointed out by Martin Evans in his post: https://stackoverflow.com/a/32613884/4779556 a possible solution to the diamond pattern could be:
side = int(input("Please input side length of diamond: "))
for x in list(range(side)) + list(reversed(range(side-1))):
print('{: <{w1}}{:*<{w2}}'.format('', '', w1=side-x-1, w2=x*2+1))
Simplest Answer
n=5
for i in range(1,n+1):
print ((n-i)*(" ")+(i*" *"))
for i in range(n-1,0,-1):
print((n-i)*(" ")+(i*" *"))
Hope this helps some one
Another possibility. Depending on which (space or star) one uses, (I used space) convert it to absolute value. This implementation doesn't require splitting the diamond into two loops (upper and lower halves).
def diamond(n):
star = 1
main = ''
# if required to manage zero or negative n
if n%2 == 0:
return None
if n<0:
return None
else:
for i in range(1,n+1):
string = ''
space = abs(i - int((n+1)/2))
star = n - 2 * space
string = space * ' ' + star * '*' + '\n'
main += string
# not necessary but useful to visualize diamond
#print(main)
return(main)
There are two version of this
Space between Stars
Without Space between Stars
Space between Stars
n = 4
for i in range(n):
print(' '*(n-i-1) + '* '*(i+1) )
for i in range(n):
print(' '*(i+1) + '* '*(n-i-1))
Without Space between Stars
n = 4
for i in range(n):
print(' '*(n-i-1) + '*'*((2*i)+1) )
for i in range(n):
print(' '*(i+1) + '*'*((2*((n-1)-i))-1))
side = int(input("side length: "))
count = 0
bl = 0
while count < side:
x = side - count
print (x * " ", (count * "*") * 2)
count += 2
while count >= 0:
print (bl * " ", (count * "*") * 2)
count -= 1
bl += 1
if you want both upper part and down side to be same change the count += 2 to count += 1
#author Tahir Baku
#have fun
print "\nWelcome to diamond builder"
print "\n----D.I.A.M.O.N.D B.U.I.L.D----"
diagonal=int(input("Give me the diagonal: "))
s=1
h1=1
h=(diagonal-1)/2
diagonal1=diagonal-2
while s<=diagonal:
print (' '*h+'*'*s+' '*h)
h=h-1
s=s+2
while diagonal1>=0:
print (' '*h1+'*'*diagonal1+' '*h1)
h1=h1+1
diagonal1=diagonal1-2
print('This is in python 3.7')
h=eval(input('Enter the diagonal?'))
j=1
for i in range(h,h//2,-1):
print(' '*(i-(h//2)-1),'*'*j)
j+=2
j-=4
for i in range(1,(h//2)+1,1):
print(' '*i,'*'*(j))
j-=2
simple way ...
n= 11 #input is even number 1,3,5,...
a = 1
b = 1
for a in range(n+1):
if a%2 != 0:
val = (n - a) // 2
print (" "*val + "*"*(a) + " "*val ,end = "\n")
for b in range(n-1,0,-1):
if b%2 != 0:
val2 = (n-b)//2
print (" "*val2 + "*"*(b) + " "*val2 ,end = "\n")
Output:
*
***
*****
*******
*********
***********
*********
*******
*****
***
*
Or using reverse method, first one is diamond, second one is series of diamond
import copy
n = 10 #input: size of diamon
raw = []
lst = []
re_lst = []
for a in range(n+1):
if a%2 != 0:
val = (n - a) // 2
raw = ''.join(" "*val + "*"*(a) + " "*val)
lst.append(raw)
re_lst = copy.deepcopy(lst)
lst.reverse()
#print diamond
for i in re_lst:
print(i)
for i in lst:
print(i)
print("\n")
#print series of diamond
for i in re_lst:
print(i)
for i in lst:
print(i)
a = 10
for x in range (a):
print(" " * (a - x) + "*" * (x+1) + "*" *(x))
#+ this = diamond
for x in reversed(range(a-1)):
print(" " * (a - x) + "*" * (x) + "*" *(x+1))
def pattern2(row):
s=1
c = row / 2
d = int(c)-1
for i in range(1,row+1):
if i<c:
print(" "*d,star(s))
s+=2
d-=1
elif i==(c+0.5):
print(star(row))
s=s-2
d=0
else:
print(" "*d,star(s))
s=s-2
d+=1
def star(s):
return '*'*s
def main():
row=int(input("enter the no. of row but the rows should be odd \n#special case of pattern"))
try:
a=row%2
assert a!=0 and row!=0
pattern2(row)
except:
print('Worng selection of rows for the perfect diamond.')
if __name__=="__main__":
main()
#maybe it could help
height = eval ( input ( 'How high? ' ) )
height = int (height//2)
for i in range(1, height+1):
print(' ' *(height-i+1), '*'*i + '*' * (i-1) )
for i in range (height+1, 0, -1):
print (' ' * (height+1-i), '*' * i + '*' * (i-1))
First find logic from the dressing table, then I think it's easier above all (n=11, m=(n+1)/2 = 6) :
n = int(input("Input odd number of layers: "))
m = (n+1)/2
i = 1
while i<=n :
if(i < m):
b = m-i
s = 2*i -1
else:
b = i-m
s = 2*(n-i)+1
j = 1
while j <= b:
print('.',end="") # dot or space
j += 1
j = 1
while j <= s:
print('*',end="")
j+=1
print()
i += 1
h = int(input('Height -> '))
for i in range(h):
if i <= (h // 2):
print(' ' * (h // 2 - i), end='')
print('*' * (i + 1), end='')
print('*' * (i + 1))
else:
print(' ' * abs((h // 2 - i)), end='')
print('*' * (h - i), end='')
print('*' * (h - i))
length = 5
for i in range(1,length,2):
space = length//2 -i//2
print(" "*space, end="")
print('*'*i)
for j in range(length, 0, -2):
space = length//2 - j//2
print(" "*space, end="")
print('*'*j)
#coder_rishabh_darmwal
#it_is_a_simple_codewith_an_easy_logic
row=int(input('enter the no. of rows')
for i in range(row):
if i<=row//2:
for j in range(row//2-i):
print(" ",end='')
for k in range(i*2-1):
print("*",end="")
print()
else:
for j in range(i-row//2):
print(" ",end="")
for k in range((row-i)*2-1):
print("*",end="")
print()
#the output will be
[output for row=30][1]
#i also wrote a programme fro hollow diamonds
row=int(input('enter the no. of rows')
for i in range(row):
if i<=row//2:
for j in range(row//2-i):
print(" ",end='')
for k in range(i*2-1):
if k==0 or k==i*2-2:
print("*",end="")
else:
print(' ',end='')
print()
else:
for j in range(i-row//2):
print(" ",end="")
for k in range((row-i)*2-1):
if k==0 or k==(row-i)*2-2:
print("*",end="")
else:
print(' ',end="")
print()
[out for hollow rhombus row=20
][2]
[1]: https://i.stack.imgur.com/3j0bx.png
[2]: https://i.stack.imgur.com/tCxI3.png
Related
I keep getting blank lines when executing my code, I'm using a for loop to create this pattern , but i need to get rid of the spaces between the printed lines.
This is the code im using
n = int(input())
a = "_"
b = "|"
for i in range(0,n,1):
if i == 0:
print(" " * (2*n - 1) + "_*_")
print(" " * 2*((n - 1)) + b + " " * 3 + b)
else:
print(" " * ((2*n - 1) - 2*i) + a + (" " * ((i + 1) * 4 - 3) ) + a)
print(" " * ((2*(n-1)) - 2*i) + b + (" " * ((i + 1)*4 - 1)) + b)
Lets break this down a bit and come up with some equations. First lets examine a possible output to see what the padding needs to be on the outer and inner parts of the pyramid.
_*_ n=5, i=0, outer=7, inner=0
_| |_ n=5, i=1, outer=5, inner=3
_| |_ n=5, i=2, outer=3, inner=7
_| |_ n=5, i=3, outer=1, inner=11
| | n=5, i=4, outer=0, inner=15
For the inner, if i == 0 then inner = 0 otherwise inner = (4 * i) - 1
For the outer, if n - i == 1 then outer = 0 otherwise outer = (2 * (n - i - 1)) - 1
Now we can code this together:
for i in range(n):
outer = " " * ((2 * (n - i - 1)) - 1)
inner = " " * ((4 * i) - 1)
if i == 0:
# inner is 0
print(outer + "_*_")
elif n - i == 1:
# outer is 0
print("|" + inner + "|")
else:
print(outer + "_|" + inner + "|_")
To add to flakes' answer, this is because the print() prints on a new line. This is why there is a space : instead of being on the same line, both caracters are on a separate line. As such, you should have a and b in the same print statement as shown by flakes
I'm trying to hone my Python 3 (specifically, nested loops) with the good old triangle exercises (which only takes an odd input for now). However, I have come across a problem I can't warp my head around with.
user_input = 7
x = 1
temp = user_input
spaces = " "
stars = ""
y = temp - 2
t = 0
while x < temp:
while y > t:
stars = "*" * x
spaces = spaces * y
print(spaces + stars)
spaces= " "
y -= 1
x += 2
I have a user_input (which is 7 for now so I don't have to give an input each time I run).
A variable x and t used for the while loop
Another temporary variable that holds my user_input (in case I decrement it as not to 'damage' the original variable).
A variable spaces and another variable stars (which should be self explanatory as I'm trying to draw a triangle based on asterisks).
I have a variable y which is equal to temp - 2
Expected output of 7 should be like this:
*
***
*****
*******
The reason I have made y equal to temp - 2 is because the first row has spaces equal to user_input - 2.
So let's say our input was 7, first row's amount of spaces is 5.
If our input is 9, first row's amount of spaces is 7
The first while loop will loop from 1 to 7 (1, 3 , 5, 7) which is why I made x equal to 1.
The second while loop should loop from input - 2 until 0.
Weird thing is, that if my user_input is equal to 5, it outputs just how I expected it to be.
*
***
*****
But once I enter something like 7, it builds a triangle from 1 to 9 (1, 3, 5, 7, 9)
*
***
*****
*******
*********
But I expect it to end right before the last row, it should output as many asterisks as my input.
Is my thought process wrong? If so, where did I end up wrong?
I hope I have clarified everything as much as possible.
Thanks a bunch.
Seems overly complicated. Why not just:
input = 7
i = 1
while i <= input:
spaces = ' ' * ((input-i) // 2)
stars = '*' * i
print(spaces + stars)
i += 2
*
***
*****
*******
Or even simpler, using str.center:
while i <= input:
print(('*' * i).center(input))
i += 2
Let's clarify a bit your code a bit :
t is useless since it holds only 0 and never changes, use 0 instead
user_input is never used except to make temp = user_input, use user_input instead of temp. As for decrementing it, it doesn't happen, and anyway you never return it to the user so it would be ok.
that's kind of a typo so it's ok, but avoid letting your debugging prints like print(x,y) when you show some code on Stack Overflow, it's harder for us to understand the whole code.
If you change back spaces = " " at the end of the while, just use spaces = " " * y.
You do nothing between the two while so you can "merge" them with an and on conditions.
So now we have :
user_input = 9
x = 1
y = user_input - 2
while x < user_input and y > 0:
stars = "*" * x
spaces = " " * y
print(spaces + stars)
y -= 1
x += 2
As you can see, you have two stopping conditions on your while when only one would be clearer. The reason behind your code works with 7 and not more is because 7 is the limit between when one condition stops loop and when the other does.
I would suggest to change your code to :
user_input = 3
x = 0
while x < user_input//2:
stars = "*" * (x * 2 + 1)
spaces = " " * (user_input//2 - x)
print(spaces + stars)
x += 1
There is a bug in your code. Here is the rectified code.
user_input = 7
x = 1
temp = user_input
spaces = " "
stars = ""
y = temp - 2
t = 0
while x <= temp:
stars = "*" * x
spaces = spaces * y
print(spaces + stars)
spaces= " "
y -= 1
x += 2
It is not necessary to check y>0 since your first while loop is enough to meet the requirement. Because of that extra while loop you are getting ambiguous values of (x,y).
The lazy solution using the builtin center() and the format mini language:
user_input = [5,7,9]
def getStars(num):
return ('*' * i for i in range(1,num+1,2))
def sol1(num):
for s in getStars(num):
print(s.center(num))
def sol2(num):
stars = getStars(num)
for s in stars:
print( ("{:^"+str(num)+"}").format(s))
for s in user_input:
sol1(s)
sol2(s)
Output:
*
***
*****
*
***
*****
*
***
*****
*******
*
***
*****
*******
*
***
*****
*******
*********
*
***
*****
*******
*********
Currently I have the following lists:
counter = [13]
instruments = ['3\t ---', '2\t / \\', '1\t / \\', '0\t--- \\ ---', '-1\t \\ /', '-2\t \\ /', '-3\t ---']
score = ['|*************|']
What I am trying to do is to replace the characters in the instruments list with the characters from the score list (excluding the |).
I am currently experiencing the following issues
The characters are being replaced row by row, rather than column by column.
Instrument List:
3 ---
2 / \
1 / \
0 --- \ ---
-1 \ /
-2 \ /
-3 ---
Score List:
|*************|
EXPECTED OUTPUT:
3 ***
2 * *
1 * *
0 *** *
-1 *
-2 *
-3
Current Output:
3 ***
2 * *
1 * *
0 *** * **
-1
-2
-3
This is how I am currently replacing the characters in the instruments list:
for elements in counter:
current_counter = elements
count = 0
for elements in instrument_wave:
amplitude, form = elements.split('\t')
for characters in form:
if characters in ['-', '/', '\\']:
form = form.replace(characters, '*', 1)
count += 1
if count == current_counter:
break
for characters in form:
if characters in ['-', '/', '\\']:
form = form.replace(characters, '')
if '-' not in amplitude:
amplitude = ' ' + amplitude
new_wave = amplitude + "\t" + form
waveform.append(new_wave)
Any help would be appreciated, especially with regards to how I should fix my replace character to make it go column by column rather than row by row.
To solve your first issue, you need to iterate via columns.
If you zip the lists (via itertools.zip_longest(), as they are not all the same length), you can then go through them in order and truncate the result:
import itertools
cols = list(itertools.zip_longest(*lst, fillvalue=" "))
for i in range(3, 17): # skip negative signs
cols[i] = "".join(cols[i]).replace('-', '*', 1)
cols[i] = "".join(cols[i]).replace('/', '*', 1)
cols[i] = "".join(cols[i]).replace('\\', '*', 1)
fixed = map("".join, zip(*cols[:17])) # no need to zip longest
for l in fixed:
print(l)
See a working example on repl.it, which outputs:
3 ***
2 * *
1 * *
0 *** *
-1 *
-2 *
-3
Note it does pad the lists out with spaces, so you may want to .strip() the results if it isn't just for printing. Adapting that to your score input I'll leave up to you.
Another option, which is probably clearer:
def convert_and_truncate(lst, cutoff):
result = []
for str in lst:
str = str[0] + str[1:].replace('-', '*') # skip the negative signs
str = str.replace('/', '*')
str = str.replace('\\', '*')
result.append(str[:cutoff]) # truncate
return result
Because we're truncating the rest of the list, it doesn't matter that replace is changing them all.
Without itertools, instead self padding to longest part in list:
counter = [16]
instruments = ['3\t ---', '2\t / \\', '1\t / \\', '0\t--- \\ ---', '-1\t \\ /', '-2\t \\ /', '-3\t ---']
score = ['|*************|']
# get longes part list
maxL = max ( len(p) for p in instruments)
#enlarge all to max length
instrum2 = [k + ' '* (maxL-len(k)) for k in instruments]
# mask out leading - to ~ (we reverse it later)
instrum3 = [k if k[0] != '-' else '~'+''.join(k[1:]) for k in instrum2]
# transpose and join to one lengthy sentence, #### are where we later split again
trans = '####'.join(map(''.join,zip(*instrum3)))
# replace the right amount of /-\ with * after that, replace with space instead
cnt = 0
maxCnt = score[0].count('*')
result = []
for t in trans:
if t in '/-\\':
if cnt < maxCnt:
result.append('*')
cnt+=1
else:
result.append(' ')
else:
result.append(t)
# resultlist back to string and split into columns again
result2 = ''.join(result)
trans2 = result2.split('####')
# transpose back to rows and make - correct
trans3 = [''.join(k).replace('~','-') for k in zip(*trans2 )]
for p in trans3:
print(p)
Output:
3 ***
2 * *
1 * *
0 *** *
-1 *
-2 *
-3
I'm trying to make a pyramid with numbers without reassigning.
I was able to do this with symbols (see below):
def print_pyramid_step_3(heightNum):
ctr = 1
while(ctr <= heightNum):
row_spaces = " " * (heightNum - ctr)
row = (2*ctr-1) * "$"
print(row_spaces + row)
ctr = ctr +1
# Get the input to get the height of the pyramid
heightNum = int(input("Enter the height of the pyramid: "))
print("----"*50)
print("Printing the pyramid by adding spaces to the row")
print("----"*50)
print_pyramid_step_3(heightNum)
Output:
$
$$$
$$$$$
$$$$$$$
$$$$$$$$$
The desired output Im trying to get looks like this when a user types in a pyramid height of 5 and the starting number is 1.
Desired Output:
1
234
56789
10111213141516
171819202122232425
try this:
j = 1
for i in range(height):
for k in range(1,height + i+1):
if (k < height - i):
print(" ", end='')
else:
print(j, end='')
j+=1
print()
Hi I have been experimenting for some time to try and total 7 variables at once. I am trying to calculate the 8th number for GTIN 8 codes. I have tried many things and so far I am using float. I Don't know what it does but people say use it. I need to times the 1,3,5,7 number by 3 and 2,4,6 number by 1. Then find the total of all of them added together. I have looked everywhere and I cant find anything. Anything will help. Thanks Ben
code = input ("enter 7 digit code? ")
sum1 = 3 * (code[0] + ',')
sum2 = code[1] + ','
sum3 = 3 * (code[2] + ',')
sum4 = code[3] + ','
sum5 = 3 * (code[4] + ',')
sum6 = code[5] + ','
sum7 = 3 * (code[6] + ',')
checksum_value = sum1 + sum2 + sum3+ sum4 + sum5+ sum6 + sum7
b = str(checksum_value)
print(b)
Quick solution:
x = "1234567"
checksum_value = sum(int(v) * 3 if i in (0,2,4,6) else int(v) for (i, v) in enumerate(x[:7]))
# (1*3) + 2 + (3*3) + 4 + (5*3) + 6 + (7*3)
# ==
# 3 + 2 + 9 + 4 + 15 + 6 + 21
# ==
# sum(int(v) * 3 if i in (0,2,4,6) else int(v) for (i, v) in enumerate(x[:7]))
Explanation:
# Sum the contained items
sum(
# multiply by three if the index is 0,2,4 or 6
int(v) * 3 if i in (0,2,4,6) else int(v)
# grab our index `i` and value `v` from `enumerate()`
for (i, v) in
# Provide a list of (index, value) from the iterable
enumerate(
# use the first 7 elements
x[:7]
)
)
`enter code here`code = input ("enter 7 digit code? ")
sum1 = 3 * (code[0] + ',')
sum2 = code[1] + ','
sum3 = 3 * (code[2] + ',')
sum4 = code[3] + ','
sum5 = 3 * (code[4] + ',')
sum6 = code[5] + ','
sum7 = 3 * (code[6] + ',')
checksum_value = sum1 + sum2 + sum3+ sum4 + sum5+ sum6 + sum7
b = str(checksum_value)
print(b)
GS1 codes come in different lengths, ranging from GTIN-8 (8 digits) to SSCC (2 digit application ID + 18 digits). Here's a simple, general Python formula that works for any length GS1 identifier:
cd = lambda x: -sum(int(v) * [3,1][i%2] for i, v in enumerate(str(x)[::-1])) % 10
Explanation:
Convert input to string, so input can be numeric or string - just a convenience factor.
Reverse the string - simple way to align the 3x/1x pattern with variable-length input.
The weighting factor is selected based on odd and even input character position by calculating i mod 2. The last character in the input string (i=0 after the string has been reversed) gets 3x.
Calculate the negative weighted sum mod 10. Equivalent to the (10 - (sum mod 10)) mod 10 approach you'd get if you follow the GS1 manual calculation outline exactly, but that's ugly.
Test Cases
## GTIN-8
>>> cd(1234567)
0
>>> cd(9505000)
3
## GTIN-12
>>> cd(71941050001)
6
>>> cd('05042833241')
2
## GTIN-13
>>> cd(900223631103)
6
>>> cd(501234567890)
0
## GTIN-14
>>> cd(1038447886180)
4
>>> cd(1001234512345)
7
## SSCC (20 digits incl. application identifier)
>>> cd('0000718908562723189')
6
>>> cd('0037612345000001009')
1