Skip to content

Commit 14bbc68

Browse files
authored
Merge pull request #120 from arnav-mandal1234/stats
Adds Stat class and calculates additional statistics
2 parents 69a607c + 3185f25 commit 14bbc68

7 files changed

Lines changed: 234 additions & 3 deletions

File tree

src/deltacode/__init__.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ def __init__(self, new_path, old_path, options):
5252
self.options = options
5353
self.deltas = []
5454
self.errors = []
55+
self.stats = Stat(self.new.files_count, self.old.files_count)
5556

5657
if self.new.path != '' and self.old.path != '':
5758
self.determine_delta()
5859
self.determine_moved()
5960
self.license_diff()
6061
self.copyright_diff()
62+
self.stats.calculate_stats()
6163
# Sort deltas by score, descending, i.e., high > low, and then by
6264
# factors, alphabetically. Run the least significant sort first.
6365
self.deltas.sort(key=lambda Delta: Delta.factors, reverse=False)
@@ -106,6 +108,7 @@ def determine_delta(self):
106108
except KeyError:
107109
delta = Delta(100, new_file, None)
108110
delta.status = 'added'
111+
self.stats.num_added += 1
109112
self.deltas.append(delta)
110113
continue
111114

@@ -117,11 +120,13 @@ def determine_delta(self):
117120
if new_file.sha1 == f.sha1:
118121
delta = Delta(0, new_file, f)
119122
delta.status = 'unmodified'
123+
self.stats.num_unmodified += 1
120124
self.deltas.append(delta)
121125
continue
122126
else:
123127
delta = Delta(20, new_file, f)
124128
delta.status = 'modified'
129+
self.stats.num_modified += 1
125130
self.deltas.append(delta)
126131

127132
# now time to find the added.
@@ -138,6 +143,7 @@ def determine_delta(self):
138143
except KeyError:
139144
delta = Delta(0, None, old_file)
140145
delta.status = 'removed'
146+
self.stats.num_removed += 1
141147
self.deltas.append(delta)
142148
continue
143149

@@ -181,6 +187,9 @@ def update_deltas(self, added, removed):
181187
"""
182188
delta = Delta(0, added.new_file, removed.old_file)
183189
delta.status = 'moved'
190+
self.stats.num_moved += 1
191+
self.stats.num_added -= 1
192+
self.stats.num_removed -= 1
184193
self.deltas.append(delta)
185194
self.deltas.remove(added)
186195
self.deltas.remove(removed)
@@ -312,3 +321,48 @@ def to_dict(self):
312321
('new', new_file),
313322
('old', old_file),
314323
])
324+
325+
class Stat(object):
326+
"""
327+
Contains all the stats for the file changes in the new directory
328+
with respect to the old directory.
329+
"""
330+
def __init__(self, new_files_count, old_files_count):
331+
self.new_files_count = new_files_count
332+
self.old_files_count = old_files_count
333+
self.num_added = 0
334+
self.num_removed = 0
335+
self.num_moved = 0
336+
self.num_modified = 0
337+
self.num_unmodified = 0
338+
self.percent_added = 0
339+
self.percent_removed = 0
340+
self.percent_moved = 0
341+
self.percent_modified = 0
342+
self.percent_unmodified = 0
343+
344+
def calculate_stats(self):
345+
"""
346+
Calculates the percentage change of new directory with respect to
347+
the old directory.
348+
"""
349+
self.percent_added = utils.calculate_percent(self.num_added, self.old_files_count)
350+
self.percent_removed = utils.calculate_percent(self.num_removed, self.old_files_count)
351+
self.percent_moved = utils.calculate_percent(self.num_moved, self.old_files_count)
352+
self.percent_modified = utils.calculate_percent(self.num_modified, self.old_files_count)
353+
self.percent_unmodified = utils.calculate_percent(self.num_unmodified, self.old_files_count)
354+
355+
def to_dict(self):
356+
"""
357+
Return an OrderedDict comprising all the percent attributes of the object.
358+
"""
359+
return OrderedDict([
360+
('old_files_count', self.old_files_count),
361+
('new_files_count', self.new_files_count),
362+
('percent_added', self.percent_added),
363+
('percent_removed', self.percent_removed),
364+
('percent_moved', self.percent_moved),
365+
('percent_modified', self.percent_modified),
366+
('percent_unmodified', self.percent_unmodified),
367+
])
368+

src/deltacode/cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def write_json(deltacode, outfile, all_delta_types=False):
4848
('deltacode_version', __version__),
4949
('deltacode_errors', collect_errors(deltacode)),
5050
('deltas_count', len([d for d in deltas(deltacode, all_delta_types)])),
51+
('delta_stats', deltacode.stats.to_dict()),
5152
('deltas', deltas(deltacode, all_delta_types))
5253
])
5354

src/deltacode/utils.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# Visit https://github.com/nexB/deltacode/ for support and download.
2424
#
2525

26-
from __future__ import absolute_import
26+
from __future__ import absolute_import, division
2727

2828
from collections import defaultdict
2929

@@ -182,14 +182,19 @@ def deltas(deltacode, all_delta_types=False):
182182
elif not delta.is_unmodified():
183183
yield delta.to_dict()
184184

185+
def calculate_percent(value, total):
186+
"""
187+
Return the rounded value percentage of total.
188+
"""
189+
ratio = (value / total) * 100
190+
return round(ratio, 2)
185191

186192
class AlignmentException(Exception):
187193
"""
188194
Named exception for alignment errors.
189195
"""
190196
pass
191197

192-
193198
def align_trees(a_files, b_files):
194199
"""
195200
Given two sequences of File objects 'a' and 'b', return a tuple of
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.",
3+
"scancode_version": "2.9.0b1.post8.2a658c314",
4+
"scancode_options": {
5+
"input": "C:\\code\\nexb\\dev\\codebase01\\sorting\\sorted01_new",
6+
"--copyright": true,
7+
"--info": true,
8+
"--json-pp": "C:\\code\\nexb\\dev\\deltacode\\tests\\data\\deltacode\\scan_sorted01_new.json",
9+
"--license": true,
10+
"--package": true
11+
},
12+
"files_count": 6,
13+
"files": [
14+
{
15+
"path": "new/a.txt",
16+
"type": "file",
17+
"name": "a.txt",
18+
"size": 100,
19+
"sha1": "abtrbt",
20+
"licenses": [
21+
]
22+
},
23+
{
24+
"path": "new/b.txt",
25+
"type": "file",
26+
"name": "b.txt",
27+
"size": 100,
28+
"sha1": "dasdas",
29+
"licenses": [
30+
]
31+
},
32+
{
33+
"path": "new/c.txt",
34+
"type": "file",
35+
"name": "c.txt",
36+
"size": 110,
37+
"sha1": "avfvf",
38+
"licenses": [
39+
]
40+
},
41+
{
42+
"path": "new/d.txt",
43+
"type": "file",
44+
"name": "d.txt",
45+
"size": 110,
46+
"sha1": "avfvf",
47+
"licenses": [
48+
]
49+
},
50+
{
51+
"path": "new/e2.txt",
52+
"type": "file",
53+
"name": "e2.txt",
54+
"size": 210,
55+
"sha1": "avfvvrvf",
56+
"licenses": [
57+
]
58+
},
59+
{
60+
"path": "new/f2.txt",
61+
"type": "file",
62+
"name": "f2.txt",
63+
"size": 110,
64+
"sha1": "ivfvvrvf",
65+
"licenses": [
66+
]
67+
}
68+
]
69+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"scancode_notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.",
3+
"scancode_version": "2.9.0b1.post8.2a658c314",
4+
"scancode_options": {
5+
"input": "C:\\code\\nexb\\dev\\codebase01\\sorting\\sorted01_old",
6+
"--copyright": true,
7+
"--info": true,
8+
"--json-pp": "C:\\code\\nexb\\dev\\deltacode\\tests\\data\\deltacode\\scan_sorted01_old.json",
9+
"--license": true,
10+
"--package": true
11+
},
12+
"files_count": 7,
13+
"files": [
14+
{
15+
"path": "old/a.txt",
16+
"type": "file",
17+
"name": "a.txt",
18+
"size": 100,
19+
"sha1": "abtrbt",
20+
"licenses": [
21+
]
22+
},
23+
{
24+
"path": "old/b.txt",
25+
"type": "file",
26+
"name": "b.txt",
27+
"size": 100,
28+
"sha1": "dasdas",
29+
"licenses": [
30+
]
31+
},
32+
{
33+
"path": "old/c.txt",
34+
"type": "file",
35+
"name": "c.txt",
36+
"size": 100,
37+
"sha1": "awd",
38+
"licenses": [
39+
]
40+
},
41+
{
42+
"path": "old/a/d.txt",
43+
"type": "file",
44+
"name": "d.txt",
45+
"size": 110,
46+
"sha1": "avfvf",
47+
"licenses": [
48+
]
49+
},
50+
{
51+
"path": "old/e1.txt",
52+
"type": "file",
53+
"name": "e1.txt",
54+
"size": 110,
55+
"sha1": "cegr",
56+
"licenses": [
57+
]
58+
},
59+
{
60+
"path": "old/f1.txt",
61+
"type": "file",
62+
"name": "f1.txt",
63+
"size": 310,
64+
"sha1": "gkbme",
65+
"licenses": [
66+
]
67+
},
68+
{
69+
"path": "old/g.txt",
70+
"type": "file",
71+
"name": "g.txt",
72+
"size": 410,
73+
"sha1": "btbtg",
74+
"licenses": [
75+
]
76+
}
77+
]
78+
}

tests/data/deltacode/scan_sorted01_new.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"--license": true,
1010
"--package": true
1111
},
12-
"files_count": 5,
12+
"files_count": 4,
1313
"files": [
1414
{
1515
"path": "sorted01_new",

tests/test_deltacode.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,3 +1592,27 @@ def test_DeltaCode_permissive_add_public_domain(self):
15921592
assert [d.status for d in deltas_object if d.new_file.path == 'a1.py'] == ['modified']
15931593
assert [d.factors for d in deltas_object if d.new_file.path == 'a2.py'].pop() == []
15941594
assert [d.status for d in deltas_object if d.new_file.path == 'a2.py'] == ['unmodified']
1595+
1596+
def test_Stat_calculation_and_ordering(self):
1597+
new_scan = self.get_test_loc('deltacode/all_stat_order_check_new.json')
1598+
old_scan = self.get_test_loc('deltacode/all_stat_order_check_old.json')
1599+
1600+
options = OrderedDict([
1601+
('--all-delta-types', True)
1602+
])
1603+
1604+
expected = OrderedDict([
1605+
('old_files_count', 7),
1606+
('new_files_count', 6),
1607+
('percent_added', 28.57),
1608+
('percent_removed', 42.86),
1609+
('percent_moved', 14.29),
1610+
('percent_modified', 14.29),
1611+
('percent_unmodified', 28.57)
1612+
])
1613+
1614+
deltacode_object = DeltaCode(new_scan, old_scan, options)
1615+
1616+
stats_object = deltacode_object.stats.to_dict()
1617+
1618+
assert stats_object == expected

0 commit comments

Comments
 (0)