Fixed a ton of Python lint errors, enabled python lint checking.
BUG= Review URL: https://webrtc-codereview.appspot.com/1166004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3627 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Sample output from the video_quality_measurment program, included only for
|
||||
# reference. Geneate your own by running with the --python flag and then change
|
||||
# the filenames in main.py
|
||||
|
||||
test_configuration = [{'name': 'name', 'value': 'VP8 hardware test'},
|
||||
{'name': 'description', 'value': ''},
|
||||
{'name': 'test_number', 'value': '0'},
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# Sample output from the video_quality_measurment program, included only for
|
||||
# reference. Geneate your own by running with the --python flag and then change
|
||||
# the filenames in main.py
|
||||
|
||||
test_configuration = [{'name': 'name', 'value': 'VP8 software test'},
|
||||
{'name': 'description', 'value': ''},
|
||||
{'name': 'test_number', 'value': '0'},
|
||||
|
@@ -17,17 +17,17 @@ class DataHelper(object):
|
||||
|
||||
def __init__(self, data_list, table_description, names_list, messages):
|
||||
""" Initializes the DataHelper with data.
|
||||
|
||||
|
||||
Args:
|
||||
data_list: List of one or more data lists in the format that the
|
||||
data_list: List of one or more data lists in the format that the
|
||||
Google Visualization Python API expects (list of dictionaries, one
|
||||
per row of data). See the gviz_api.DataTable documentation for more
|
||||
per row of data). See the gviz_api.DataTable documentation for more
|
||||
info.
|
||||
table_description: dictionary describing the data types of all
|
||||
columns in the data lists, as defined in the gviz_api.DataTable
|
||||
documentation.
|
||||
names_list: List of strings of what we're going to name the data
|
||||
columns after. Usually different runs of data collection.
|
||||
columns after. Usually different runs of data collection.
|
||||
messages: List of strings we might append error messages to.
|
||||
"""
|
||||
self.data_list = data_list
|
||||
@@ -36,29 +36,29 @@ class DataHelper(object):
|
||||
self.messages = messages
|
||||
self.number_of_datasets = len(data_list)
|
||||
self.number_of_frames = len(data_list[0])
|
||||
|
||||
|
||||
def CreateData(self, field_name, start_frame=0, end_frame=0):
|
||||
""" Creates a data structure for a specified data field.
|
||||
|
||||
Creates a data structure (data type description dictionary and a list
|
||||
of data dictionaries) to be used with the Google Visualization Python
|
||||
|
||||
Creates a data structure (data type description dictionary and a list
|
||||
of data dictionaries) to be used with the Google Visualization Python
|
||||
API. The frame_number column is always present and one column per data
|
||||
set is added and its field name is suffixed by _N where N is the number
|
||||
set is added and its field name is suffixed by _N where N is the number
|
||||
of the data set (0, 1, 2...)
|
||||
|
||||
|
||||
Args:
|
||||
field_name: String name of the field, must be present in the data
|
||||
structure this DataHelper was created with.
|
||||
start_frame: Frame number to start at (zero indexed). Default: 0.
|
||||
end_frame: Frame number to be the last frame. If zero all frames
|
||||
end_frame: Frame number to be the last frame. If zero all frames
|
||||
will be included. Default: 0.
|
||||
|
||||
|
||||
Returns:
|
||||
A tuple containing:
|
||||
- a dictionary describing the columns in the data result_data_table below.
|
||||
This description uses the name for each data set specified by
|
||||
names_list.
|
||||
|
||||
This description uses the name for each data set specified by
|
||||
names_list.
|
||||
|
||||
Example with two data sets named 'Foreman' and 'Crew':
|
||||
{
|
||||
'frame_number': ('number', 'Frame number'),
|
||||
@@ -66,36 +66,36 @@ class DataHelper(object):
|
||||
'ssim_1': ('number', 'Crew'),
|
||||
}
|
||||
- a list containing dictionaries (one per row) with the frame_number
|
||||
column and one column of the specified field_name column per data
|
||||
set.
|
||||
|
||||
column and one column of the specified field_name column per data
|
||||
set.
|
||||
|
||||
Example with two data sets named 'Foreman' and 'Crew':
|
||||
[
|
||||
{'frame_number': 0, 'ssim_0': 0.98, 'ssim_1': 0.77 },
|
||||
{'frame_number': 1, 'ssim_0': 0.81, 'ssim_1': 0.53 },
|
||||
]
|
||||
"""
|
||||
|
||||
|
||||
# Build dictionary that describes the data types
|
||||
result_table_description = {'frame_number': ('string', 'Frame number')}
|
||||
result_table_description = {'frame_number': ('string', 'Frame number')}
|
||||
for dataset_index in range(self.number_of_datasets):
|
||||
column_name = '%s_%s' % (field_name, dataset_index)
|
||||
column_type = self.table_description[field_name][0]
|
||||
column_description = self.names_list[dataset_index]
|
||||
result_table_description[column_name] = (column_type, column_description)
|
||||
|
||||
# Build data table of all the data
|
||||
# Build data table of all the data
|
||||
result_data_table = []
|
||||
# We're going to have one dictionary per row.
|
||||
# We're going to have one dictionary per row.
|
||||
# Create that and copy frame_number values from the first data set
|
||||
for source_row in self.data_list[0]:
|
||||
row_dict = { 'frame_number': source_row['frame_number'] }
|
||||
result_data_table.append(row_dict)
|
||||
|
||||
|
||||
# Pick target field data points from the all data tables
|
||||
if end_frame == 0: # Default to all frames
|
||||
end_frame = self.number_of_frames
|
||||
|
||||
|
||||
for dataset_index in range(self.number_of_datasets):
|
||||
for row_number in range(start_frame, end_frame):
|
||||
column_name = '%s_%s' % (field_name, dataset_index)
|
||||
@@ -105,14 +105,14 @@ class DataHelper(object):
|
||||
self.data_list[dataset_index][row_number][field_name]
|
||||
except IndexError:
|
||||
self.messages.append("Couldn't find frame data for row %d "
|
||||
"for %s" % (row_number, self.names_list[dataset_index]))
|
||||
"for %s" % (row_number, self.names_list[dataset_index]))
|
||||
break
|
||||
return result_table_description, result_data_table
|
||||
|
||||
def GetOrdering(self, table_description):
|
||||
def GetOrdering(self, table_description): # pylint: disable=R0201
|
||||
""" Creates a list of column names, ordered alphabetically except for the
|
||||
frame_number column which always will be the first column.
|
||||
|
||||
|
||||
Args:
|
||||
table_description: A dictionary of column definitions as defined by the
|
||||
gviz_api.DataTable documentation.
|
||||
@@ -121,9 +121,9 @@ class DataHelper(object):
|
||||
remaining columns are sorted alphabetically.
|
||||
"""
|
||||
# The JSON data representation generated from gviz_api.DataTable.ToJSon()
|
||||
# must have frame_number as its first column in order for the chart to
|
||||
# must have frame_number as its first column in order for the chart to
|
||||
# use it as it's X-axis value series.
|
||||
# gviz_api.DataTable orders the columns by name by default, which will
|
||||
# gviz_api.DataTable orders the columns by name by default, which will
|
||||
# be incorrect if we have column names that are sorted before frame_number
|
||||
# in our data table.
|
||||
columns_ordering = ['frame_number']
|
||||
@@ -132,8 +132,8 @@ class DataHelper(object):
|
||||
if column != 'frame_number':
|
||||
columns_ordering.append(column)
|
||||
return columns_ordering
|
||||
|
||||
def CreateConfigurationTable(self, configurations):
|
||||
|
||||
def CreateConfigurationTable(self, configurations): # pylint: disable=R0201
|
||||
""" Combines multiple test data configurations for display.
|
||||
|
||||
Args:
|
||||
@@ -175,9 +175,9 @@ class DataHelper(object):
|
||||
for configuration in configurations:
|
||||
data = {}
|
||||
result_data.append(data)
|
||||
for dict in configuration:
|
||||
name = dict['name']
|
||||
value = dict['value']
|
||||
for values in configuration:
|
||||
name = values['name']
|
||||
value = values['value']
|
||||
result_description[name] = 'string'
|
||||
data[name] = value
|
||||
return result_description, result_data
|
||||
|
@@ -7,8 +7,6 @@
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
__author__ = 'kjellander@webrtc.org (Henrik Kjellander)'
|
||||
|
||||
import unittest
|
||||
import webrtc.data_helper
|
||||
|
||||
@@ -16,13 +14,13 @@ class Test(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# Simulate frame data from two different test runs, with 2 frames each.
|
||||
self.frame_data_0 = [{'frame_number': 0, 'ssim': 0.5, 'psnr': 30.5},
|
||||
self.frame_data_0 = [{'frame_number': 0, 'ssim': 0.5, 'psnr': 30.5},
|
||||
{'frame_number': 1, 'ssim': 0.55, 'psnr': 30.55}]
|
||||
self.frame_data_1 = [{'frame_number': 0, 'ssim': 0.6, 'psnr': 30.6},
|
||||
{'frame_number': 0, 'ssim': 0.66, 'psnr': 30.66}]
|
||||
self.all_data = [ self.frame_data_0, self.frame_data_1 ]
|
||||
|
||||
# Test with frame_number column in a non-first position sice we need to
|
||||
|
||||
# Test with frame_number column in a non-first position sice we need to
|
||||
# support reordering that to be able to use the gviz_api as we want.
|
||||
self.type_description = {
|
||||
'ssim': ('number', 'SSIM'),
|
||||
@@ -66,13 +64,13 @@ class Test(unittest.TestCase):
|
||||
self.assertEquals(1, row['frame_number'])
|
||||
self.assertEquals(0.55, row['ssim_0'])
|
||||
self.assertEquals(0.66, row['ssim_1'])
|
||||
|
||||
description, data_table = helper.CreateData('psnr')
|
||||
|
||||
description, data_table = helper.CreateData('psnr')
|
||||
self.assertEqual(3, len(description))
|
||||
self.assertTrue('frame_number' in description)
|
||||
self.assertTrue('psnr_0' in description)
|
||||
self.assertTrue('psnr_1' in description)
|
||||
self.assertEqual(0, len(messages))
|
||||
self.assertTrue('psnr_1' in description)
|
||||
self.assertEqual(0, len(messages))
|
||||
|
||||
self.assertEquals(2, len(data_table))
|
||||
row = data_table[0]
|
||||
@@ -83,21 +81,21 @@ class Test(unittest.TestCase):
|
||||
self.assertEquals(1, row['frame_number'])
|
||||
self.assertEquals(30.55, row['psnr_0'])
|
||||
self.assertEquals(30.66, row['psnr_1'])
|
||||
|
||||
|
||||
def testGetOrdering(self):
|
||||
""" Tests that the ordering help method returns a list with frame_number
|
||||
""" Tests that the ordering help method returns a list with frame_number
|
||||
first and the rest sorted alphabetically """
|
||||
messages = []
|
||||
helper = webrtc.data_helper.DataHelper(self.all_data, self.type_description,
|
||||
self.names, messages)
|
||||
description, data_table = helper.CreateData('ssim')
|
||||
description, _ = helper.CreateData('ssim')
|
||||
columns = helper.GetOrdering(description)
|
||||
self.assertEqual(3, len(columns))
|
||||
self.assertEqual(0, len(messages))
|
||||
self.assertEqual('frame_number', columns[0])
|
||||
self.assertEqual('ssim_0', columns[1])
|
||||
self.assertEqual('ssim_1', columns[2])
|
||||
|
||||
|
||||
def testCreateConfigurationTable(self):
|
||||
messages = []
|
||||
helper = webrtc.data_helper.DataHelper(self.all_data, self.type_description,
|
||||
@@ -110,6 +108,6 @@ class Test(unittest.TestCase):
|
||||
self.assertTrue(description.has_key('input_filename'))
|
||||
self.assertEquals('Test 0', data[0]['name'])
|
||||
self.assertEquals('Test 1', data[1]['name'])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@@ -7,30 +7,28 @@
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
__author__ = 'kjellander@webrtc.org (Henrik Kjellander)'
|
||||
|
||||
import os
|
||||
import gviz_api
|
||||
import webrtc.data_helper
|
||||
|
||||
def main():
|
||||
"""
|
||||
This Python script displays a web page with test created with the
|
||||
This Python script displays a web page with test created with the
|
||||
video_quality_measurement program, which is a tool in WebRTC.
|
||||
|
||||
|
||||
The script requires on two external files and one Python library:
|
||||
- A HTML template file with layout and references to the json variables
|
||||
- A HTML template file with layout and references to the json variables
|
||||
defined in this script
|
||||
- A data file in Python format, containing the following:
|
||||
- test_configuration - a dictionary of test configuration names and values.
|
||||
- frame_data_types - a dictionary that maps the different metrics to their
|
||||
- frame_data_types - a dictionary that maps the different metrics to their
|
||||
data types.
|
||||
- frame_data - a list of dictionaries where each dictionary maps a metric to
|
||||
it's value.
|
||||
- frame_data - a list of dictionaries where each dictionary maps a metric to
|
||||
it's value.
|
||||
- The gviz_api.py of the Google Visualization Python API, available at
|
||||
http://code.google.com/p/google-visualization-python/
|
||||
|
||||
The HTML file is shipped with the script, while the data file must be
|
||||
|
||||
The HTML file is shipped with the script, while the data file must be
|
||||
generated by running video_quality_measurement with the --python flag
|
||||
specified.
|
||||
"""
|
||||
@@ -48,78 +46,78 @@ def main():
|
||||
page_template = f.read()
|
||||
f.close()
|
||||
except IOError as e:
|
||||
ShowErrorPage('Cannot open page template file: %s<br>Details: %s' %
|
||||
ShowErrorPage('Cannot open page template file: %s<br>Details: %s' %
|
||||
(page_template_filename, e))
|
||||
return
|
||||
|
||||
|
||||
# Read data from external Python script files. First check that they exist.
|
||||
for filename in data_filenames:
|
||||
if not os.path.exists(filename):
|
||||
messages.append('Cannot open data file: %s' % filename)
|
||||
data_filenames.remove(filename)
|
||||
|
||||
|
||||
# Read data from all existing input files.
|
||||
data_list = []
|
||||
test_configurations = []
|
||||
names = []
|
||||
|
||||
|
||||
for filename in data_filenames:
|
||||
read_vars = {} # empty dictionary to load the data into.
|
||||
execfile(filename, read_vars, read_vars)
|
||||
|
||||
|
||||
test_configuration = read_vars['test_configuration']
|
||||
table_description = read_vars['frame_data_types']
|
||||
table_data = read_vars['frame_data']
|
||||
|
||||
|
||||
# Verify the data in the file loaded properly.
|
||||
if not table_description or not table_data:
|
||||
messages.append('Invalid input file: %s. Missing description list or '
|
||||
'data dictionary variables.' % filename)
|
||||
continue
|
||||
|
||||
|
||||
# Frame numbers appear as number type in the data, but Chart API requires
|
||||
# values of the X-axis to be of string type.
|
||||
# Change the frame_number column data type:
|
||||
# Change the frame_number column data type:
|
||||
table_description['frame_number'] = ('string', 'Frame number')
|
||||
# Convert all the values to string types:
|
||||
# Convert all the values to string types:
|
||||
for row in table_data:
|
||||
row['frame_number'] = str(row['frame_number'])
|
||||
|
||||
|
||||
# Store the unique data from this file in the high level lists.
|
||||
test_configurations.append(test_configuration)
|
||||
data_list.append(table_data)
|
||||
# Name of the test run must be present.
|
||||
test_name = FindConfiguration(test_configuration, 'name')
|
||||
if not test_name:
|
||||
messages.append('Invalid input file: %s. Missing configuration key '
|
||||
messages.append('Invalid input file: %s. Missing configuration key '
|
||||
'"name"', filename)
|
||||
continue
|
||||
names.append(test_name)
|
||||
|
||||
|
||||
# Create data helper and build data tables for each graph.
|
||||
helper = webrtc.data_helper.DataHelper(data_list, table_description,
|
||||
helper = webrtc.data_helper.DataHelper(data_list, table_description,
|
||||
names, messages)
|
||||
|
||||
|
||||
# Loading it into gviz_api.DataTable objects and create JSON strings.
|
||||
description, data = helper.CreateConfigurationTable(test_configurations)
|
||||
configurations = gviz_api.DataTable(description, data)
|
||||
json_configurations = configurations.ToJSon()
|
||||
|
||||
|
||||
description, data = helper.CreateData('ssim')
|
||||
ssim = gviz_api.DataTable(description, data)
|
||||
json_ssim_data = ssim.ToJSon(helper.GetOrdering(description))
|
||||
|
||||
|
||||
description, data = helper.CreateData('psnr')
|
||||
psnr = gviz_api.DataTable(description, data)
|
||||
json_psnr_data = psnr.ToJSon(helper.GetOrdering(description))
|
||||
|
||||
|
||||
description, data = helper.CreateData('packets_dropped')
|
||||
packet_loss = gviz_api.DataTable(description, data)
|
||||
json_packet_loss_data = packet_loss.ToJSon(helper.GetOrdering(description))
|
||||
|
||||
json_packet_loss_data = packet_loss.ToJSon(helper.GetOrdering(description))
|
||||
|
||||
description, data = helper.CreateData('bit_rate')
|
||||
# Add a column of data points for the desired bit rate to be plotted.
|
||||
# (uses test configuration from the last data set, assuming it is the same
|
||||
# (uses test configuration from the last data set, assuming it is the same
|
||||
# for all of them)
|
||||
desired_bit_rate = FindConfiguration(test_configuration, 'bit_rate_in_kbps')
|
||||
if not desired_bit_rate:
|
||||
@@ -135,12 +133,12 @@ def main():
|
||||
|
||||
# Format the messages list with newlines.
|
||||
messages = '\n'.join(messages)
|
||||
|
||||
|
||||
# Put the variables as JSon strings into the template.
|
||||
print page_template % vars()
|
||||
|
||||
def FindConfiguration(configuration, name):
|
||||
""" Finds a configuration value using it's name.
|
||||
""" Finds a configuration value using it's name.
|
||||
Returns the first configuration with a matching name. Returns None if no
|
||||
matching configuration is found. """
|
||||
return_value = None
|
||||
@@ -152,6 +150,6 @@ def FindConfiguration(configuration, name):
|
||||
|
||||
def ShowErrorPage(error_message):
|
||||
print '<html><body>%s</body></html>' % error_message
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
Reference in New Issue
Block a user