6
\$\begingroup\$

This program calculates up and downspeed of a given connection for as long as it is running.

#upspeed/downspeed indicator
#written by Chubak -> [email protected]
import requests
import time
import os
def get_seconds(datetime):
 time = datetime.split(' ')[3].split(':')
 time_hours = int(time[0])
 time_minutes = int(time[1])
 time_seconds = int(time[2])
 return time_hours*360 + time_minutes*60 + time_seconds
def downspeed():
 url = "http://speedtest.ftp.otenet.gr/files/test100k.db"
 current_seconds = get_seconds(time.asctime())
 file = requests.get(url)
 headers = file.headers
 file_size = int(headers['Content-Length'])/1000
 dl_seconds = get_seconds(time.asctime())
 time_difference = dl_seconds - current_seconds
 return round(file_size / time_difference)
def upspeed():
 current_seconds = get_seconds(time.asctime())
 dummy_file = os.path.join(os.getenv('APPDATA'), 'dummy.txt')
 post_url = 'http://httpbin.org/post'
 with open(dummy_file, 'wb') as dummy:
 for i in range (1500):
 dummy.write(str.encode('This is a dummy text. Its sole propose is being uploaded to a server. '))
 dummy.close()
 files = {'file' : open(dummy_file, 'rb')}
 request = requests.post(post_url, data=files)
 headers = request.headers
 file_size = int(headers['Content-Length'])/1000
 dl_seconds = get_seconds(time.asctime())
 time_difference = dl_seconds - current_seconds
 return round(file_size / time_difference)
if __name__ == '__main__':
 while True:
 up = None
 down = None
 if up == None and down == None:
 up = upspeed()
 down = downspeed()
 print('At {0} your Downspeed is: {1}, and your Upspeed is: {2}'.format(time.asctime(), down, up))
 time.sleep(5)
 up = None
 down = None

I'd appreciate it if your dropped any hints about turning this into a desktop widget.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Aug 22, 2016 at 1:53
\$\endgroup\$
2
  • 2
    \$\begingroup\$ You forgot to mention that the APPDATA environment variable is required. \$\endgroup\$ Commented Aug 22, 2016 at 2:04
  • 1
    \$\begingroup\$ Using bigger files (especially for upload), usually around 10mb will allow the speed to settle. For example when I start uploading something, it is at 50mbps but falls to 10mbps in a few secinds. \$\endgroup\$ Commented Aug 22, 2016 at 2:07

2 Answers 2

5
\$\begingroup\$

Your whole function get_seconds is not needed at all. You can use the function time.time(), which gives you the seconds since epoch (Jan 1, 1970 0:00:00). Subtracting two such times will yield the number of seconds passed in between. I would also do the time measurement exclusively around the actual download, otherwise you add the (small) overhead of reading the header for the file-size.

def downspeed():
 url = "http://speedtest.ftp.otenet.gr/files/test100k.db"
 start = time.time()
 file = requests.get(url)
 end = time.time()
 time_difference = end - start
 file_size = int(file.headers['Content-Length'])/1000 
 return round(file_size / time_difference)

You should also report the units of your speeds measured. As it is, they will be KB/s, with the K denoting 1000 (as you divide by that). You should be aware that there is also a different unit, sometimes written KiB/s, where Ki stands for 1024. You should probably use the same definition, which speedtest uses, when it says the file is 100kb big.

answered Aug 22, 2016 at 7:39
\$\endgroup\$
4
\$\begingroup\$

I don't know if this is the best way to measure internet speed or not. I won't comment whether this is the right approach. There are, however, some stylistic improvements that can be made.

You should run your code through pylint. Some issues could easily be addressed such as too many newlines between get_seconds and downspeed. pylint enforces two newlines.

This isn't English class, you don't have to double space your functions.

def downspeed():
 url = "http://speedtest.ftp.otenet.gr/files/test100k.db"
 current_seconds = get_seconds(time.asctime())
 file = requests.get(url)
 headers = file.headers
 file_size = int(headers['Content-Length'])/1000
 dl_seconds = get_seconds(time.asctime())
 time_difference = dl_seconds - current_seconds
 return round(file_size / time_difference)

Just do:

def downspeed():
 url = "http://speedtest.ftp.otenet.gr/files/test100k.db"
 current_seconds = get_seconds(time.asctime())
 file = requests.get(url)
 headers = file.headers
 file_size = int(headers['Content-Length'])/1000
 dl_seconds = get_seconds(time.asctime())
 time_difference = dl_seconds - current_seconds
 return round(file_size / time_difference)

Every once in a while you can add an additional newline for clarity, but don't over do it.

You don't need to define as many variables as you have. Consider:

def get_seconds(datetime):
 time = datetime.split(' ')[3].split(':')
 time_hours = int(time[0])
 time_minutes = int(time[1])
 time_seconds = int(time[2])
 return time_hours*360 + time_minutes*60 + time_seconds

Seeing something like int(time[0]) might be intimidating but adding comments to explain this stuff will

def get_seconds(datetime):
 """
 Takes a time of day and converts it to seconds.
 Args:
 datetime: Time of day as HH:MM:SS
 """
 time = datetime.split(' ')[3].split(':')
 # Hours + Minutes + Seconds
 return int(time[0])*360 + int(time[1])*60 + int(time[2])

Furthermore, you don't need the headers variables:

def downspeed():
 url = "http://speedtest.ftp.otenet.gr/files/test100k.db"
 current_seconds = get_seconds(time.asctime())
 file = requests.get(url)
 file_size = int(file.headers['Content-Length'])/1000
 dl_seconds = get_seconds(time.asctime())
 time_difference = dl_seconds - current_seconds
 return round(file_size / time_difference)

And:

def upspeed():
 current_seconds = get_seconds(time.asctime())
 dummy_file = os.path.join(os.getenv('APPDATA'), 'dummy.txt')
 post_url = 'http://httpbin.org/post'
 with open(dummy_file, 'wb') as dummy:
 for i in range(1500):
 dummy.write(str.encode('This is a dummy text. Its sole propose is being uploaded to a server. '))
 dummy.close()
 files = {'file' : open(dummy_file, 'rb')}
 request = requests.post(post_url, data=files)
 file_size = int(request.headers['Content-Length'])/1000
 dl_seconds = get_seconds(time.asctime())
 time_difference = dl_seconds - current_seconds
 return round(file_size / time_difference)

By convention when you don't use a variable in a loop, you use _. So:

for _ in range(1500):
 dummy.write(str.encode('This is a dummy text. Its sole propose is being uploaded to a server. '))

time_difference is often expressed as dt or ellapsed. Consider changing it.

Maybe make the url variables a default argument?

answered Aug 22, 2016 at 3:12
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.