You want to trim the value of $i after the last dot in the string.
You can do this like so:
i=${i%.*}
This removes the shortest suffix string from $i that matches the filename globbing pattern .* (a dot followed by any string).
If you know you want to trim off .py specifically:
i=${i%.py}
This means you could write your cp command like so:
cp -v ~/Desktop/library/template.py "${i%.py}.py"
This would be the only command in the loop body and it would remove the .py filename suffix from $i, if the value had such a suffix, and then add .py. This ensures that the destination filename always has .py as the filename suffix and at the same time avoids doubling the suffix.
Suggestion for script:
#!/bin/sh
for string do
cp -v ~/Desktop/library/template.py "${string%.py}.py"
done
Or,
#!/bin/zsh
for string; cp -v ~/Desktop/library/template.py $string:r.py
... which uses the zsh shell, its alternative, shorter, form for the for loop, and its :r modifier to remove the filename extension before adding .py to the name.
You would call either script like so:
./script A B.py C D.py