I'm looking for some feedback on my first 'real' Python program. Started with Python a few days ago and wanted to get right into it and make something hands on.
Currently the program lets you download audio and video for a YouTube video using Pytube. It allows you specify the location to save the download, whether to download Audio or Video and what resolution to download videos at.
#global variables
yt = None
res = None
stream = None
file_path = None
av_swtich = None
#see if the user wants to download audio or video
def av_select():
global av_switch
print('Would you like to download Video or Audio:')
while True:
av_switch = input('Please enter \'1\' for Video and \'2\' for Audio\n')
if av_switch not in ('1', '2'):
print('Pleae make a valid selection')
continue
else:
break
#Download Audio Stream
def audio_download():
global yt
global file_path
print('The Video has the following audio streams')
print(*yt.streams.filter(only_audio=True), sep='\n')
while True:
itag = input('Please Enter the Itag of the stream you want to download:\n')
try:
yt.streams.get_by_itag(str(itag)).download(output_path=str(file_path), filename_prefix='Audio-')
print('The audio stream has been downloaded')
return True
except:
print('You have entered an invalid Itag')
continue
#Define Download location
def download_location():
global file_path
while True:
file_path = input('Please enter the Folder to save the Video in:\n')
x = os.path.exists(path = str(file_path))
if x == True:
break
else:
print('The specified Folder does not exit')
continue
#Select the video that the user wants to use
def video_select():
global yt
while True:
video = input('Please enter the video URL:\n')
try:
yt = YouTube(video)
print('The title of the video you selected is: ' + yt.title)
return False
except:
print('The URL is not Valid\n')
continue
#Select resoultion and display possible stings
def resoultion_select():
global res
global res_list
while True:
res = input('Please enter a Resoultion:\n')
try:
res_list = yt.streams.filter(resolution= str(res))
return False
except:
print('You have entered an invalid resoultion')
continue
#Select the stream to download based on the itag
def download_stream():
global file_path
global yt
global res_list
print('The Video has the following streams')
print(*res_list, sep='\n')
while True:
itag = input('Please Enter the Itag of the stream you want to download:\n')
try:
yt.streams.get_by_itag(str(itag)).download(str(file_path))
print('The video has been downloaded')
return True
except:
print('You have entered an invalid Itag')
continue
def Main():
global av_switch
print('Welcome to the Youtube Video Downloader\n')
download_location()
video_select()
av_select()
if av_switch == '1':
resoultion_select()
download_stream()
else:
audio_download()
Main()
-
1\$\begingroup\$ "using Pytube" nowhere in the code I see pytube being imported. please provide a complete program. \$\endgroup\$hjpotter92– hjpotter922020年12月15日 05:29:23 +00:00Commented Dec 15, 2020 at 5:29
-
\$\begingroup\$ it is seen that on function download_stream(), the line "yt.streams.get_by_itag(str(itag)).download(str(file_path))" downloads the stream into "file_path" . 'hope it helps \$\endgroup\$Ruperto– Ruperto2020年12月15日 14:49:06 +00:00Commented Dec 15, 2020 at 14:49
-
\$\begingroup\$ Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers . \$\endgroup\$Mast– Mast ♦2020年12月15日 18:06:48 +00:00Commented Dec 15, 2020 at 18:06
2 Answers 2
Global variables
- one major suggestion - don't (over)use global variables, it's generally not a good practice and it will make more difficult to test the code. For example if you'd like to add a functionality for downloading multiple items at the same time you'll have a hard time with it.
So instead of this:
def av_select():
global av_switch # this function is setting value for this variable
def Main():
global av_switch # this function is reading this variable
av_select()
do this:
def av_select():
while True:
av_switch = input('Please enter \'1\' for Video and \'2\' for Audio\n')
if av_switch not in ('1', '2'):
print('Please make a valid selection')
continue
return av_switch # add return statement with the value
def Main():
av_switch = av_select() # use the value returned from function
if av_switch == '1':
same applies to other global variables.
Python coding guidelines
follow PEP 8 guidelines, in this case the name of the function
Main
is violating it - function names should be lowercase.recommended way how to do code comments is to use docstrings. Instead of this:
#Define Download location
def download_location():
do this:
def download_location():
"""define download location"""
this way the comment can be accessed as download_location.__doc__
and a lot of tools (eg. for generating documentation) can work with it.
Code flow
- the following one is probably a matter of taste, but it feels like you're overusing
while True:
loops in places where you can rely on other variables you are "waiting" for. For exampleav_select()
- I'd use theaw_switch
variable as a condition of the loop this way:
def av_select():
av_switch = None
while av_switch not in ('1', '2'):
av_switch = input('Please enter \'1\' for Video and \'2\' for Audio\n')
# outside the while loop, av_switch finally matches '1' or '2'
return av_switch
Please add these imports at first and 2nd line of the code:
import os
from pytube import YouTube
Also, the full path of the destination folder needs to be entered when code asks 'Please enter the Folder to save the Video in'.