2
\$\begingroup\$

I made a little application (for windows, but easily compatible with linux by just changing some lines) for displaying a little network graph using Tkinter and Python. I basically draw lines higher and higher while the ping is still running, and when the soft receive the ping response I reset the line height.

My issue is while updating my canvas. Basically the code make a Tk.after call, but I think it might be a little bit too slow/random. I am looking for a way to be sure this function will run exactly every n milliseconds. I saw something like this on PyGame and maybe I am not doing it right.

#!/usr/bin/env python2
# -*- coding:utf-8 -*-
"""
Graphic network graph.
Displays a simple network graph representing how fast your ping is. This tool
is useful for people having some random connection and looking for a tool to
represent the state of their ping.
"""
from Tkinter import *
import socket
import threading
import random
import time
import subprocess
__author__ = "Axel Martin"
__copyright__ = "Copyright 2016, Axel Martin"
__credits__ = ["Axel Martin"]
__licence__ = "GPL"
__version__ = "0.1"
__maintainer__ = "Axel Martin"
__status__ = "Prototype"
class Config:
 """Configuration container."""
 hostname = "foobar.fr"
 updater_rate = 5 # in milliseconds
 ticks = 2
 low_bound, high_bound = 50, 100
class Pingger:
 """Ping tool.
 The purpose of this class is to give abstraction of the ping command line.
 """
 def __init__(self, config):
 self.config = config
 self.reseted = False
 self.alive = True
 self.thread = threading.Thread(target=self.pinger)
 self.thread.start()
 def has_been_reset(self):
 if self.reseted:
 self.reseted = False
 return True
 return False
 def stop(self):
 self.alive = False
 def pinger(self):
 while True:
 subprocess.check_output(["ping", "-n", "1", self.config.hostname])
 self.reseted = True
class App:
 """Tkinter application handler
 Create the window and manage the display on the canvas.
 """
 HEIGHT, WIDTH = 75, 75
 def __init__(self, config):
 self.config = config
 # Interface setup
 self.root = Tk()
 self.canvas = Canvas(self.root, width=self.WIDTH, height=self.HEIGHT)
 self.canvas.pack()
 self.canvas.create_line(0, self.config.low_bound, self.WIDTH - 1, self.config.low_bound, fill="orange", width=2)
 # Drawer helper
 self.pingger = Pingger(self.config)
 self.last_tick_height = 0
 # Updater setup
 self.alive = True
 self.thread = threading.Thread(target=self.update)
 self.thread.start()
 def update(self):
 for offset in range(self.config.ticks + 1, 1, -1):
 self.draw_line(offset)
 # Lines moving
 lines = list(self.canvas.find_withtag("spike"))
 while len(lines) > self.WIDTH:
 self.canvas.delete(lines.pop(0))
 for l in lines:
 x0, y0, x1, y1 = self.canvas.coords(l)
 self.canvas.coords(l, x0 - self.config.ticks, y0, x1 - self.config.ticks, y1)
 # Recall in 10ms
 if self.alive:
 self.root.after(self.config.updater_rate, self.update)
 def draw_line(self, offset):
 if self.pingger.has_been_reset():
 self.last_tick_height = 0
 self.last_tick_height += 1
 if self.last_tick_height * self.config.updater_rate < self.config.low_bound:
 fill = "green"
 elif self.last_tick_height * self.config.updater_rate > self.config.high_bound:
 fill = "red"
 else:
 fill = "orange"
 self.canvas.create_line(self.WIDTH - offset, self.HEIGHT - 1, self.WIDTH - offset,
 self.HEIGHT - self.last_tick_height, tag="spike", fill=fill)
 def stop(self):
 self.alive = False
 self.pingger.stop()
 def start(self):
 self.root.mainloop()
c = Config()
a = App(c)
a.start()
# Passing this point the application closed.
a.stop()
asked Jul 6, 2016 at 9:34
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Modyifing the object while getting a value

def has_been_reset(self):
 if self.reseted: 
 self.reseted = False 
 return True
 return False

The method name looks like a question "has the Pinger been reset?" bit it also changes the reset flag going against expactation and single responsability principle.

answered Jul 8, 2016 at 19: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.