Created
December 15, 2014 18:23
-
-
Save GRGSIBERIA/a7c35bb69d32a506ef44 to your computer and use it in GitHub Desktop.
halstead volume measure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-*- encoding: utf-8 | |
operator_list = [ | |
/\>\>\=/, /\<\<\=/, /\.\.\./, /\|\|/, /\!\=/, /\%\=/, /\&\&/, /\-\-/, /\-\=/, | |
/\&\=/, /\*\=/, /\+\+/, /\+\=/, /\-\>/, /\^\=/, /\|\=/, | |
/\/\=/, /\:\:/, /\<\</, /\<\=/, /\=\=/, /\>\=/, /\>\>/, | |
/\*/, /\+/, /\(/, /\)/, /\!/, /\%/, /\&/, | |
/\,/, /\-/, /\./, /\//, /\:/, /\=/, /\>/, /\</, | |
/\?/, /\[/, /\]/, /\^/, /\{/, /\}/, /\|/, /\~/, /\;/ | |
] | |
reserved_list = [ | |
/asm/, /break/, /case/, /class/, | |
/continue/, /default/, /delete/, | |
/do/, /else/, /enum/, /for/, /goto/, | |
/if/, /new/, /operator/, /private/, | |
/protected/, /public/, /return/, | |
/sizeof/, /struct/, /switch/, | |
/this/, /union/, /while/, | |
/namespace/, /using/, /try/, | |
/catch/, /throw/, /const_cast/, | |
/static_cast/, /dynamic_cast/, | |
/reinterpret_cast/, /typeid/, | |
/template/, /explicit/, /true/, | |
/false/, /typename/, /#include/, | |
/#define/, /auto/, /extern/, | |
/inline/, /register/, /static/, | |
/typedef/, /virtual/, /mtuable/, | |
/const/, /friend/, /volatile/ | |
] | |
def MakeFileList() | |
dir_list = ["rtaudio", "port-audio", "tinyasio", "asio-sdk"] | |
file_list = [] | |
for dir in dir_list | |
file_list << ["./tool/#{dir}/test1.cpp", dir] | |
file_list << ["./tool/#{dir}/test2.cpp", dir] | |
end | |
file_list | |
end | |
def InitHash(hash, list) | |
for name in list | |
hash[name] = 0 | |
end | |
end | |
def RemoveComment(str) | |
str.gsub(/\/\*[\s\S]*?\*\/|\/\/.*/, " ") | |
end | |
def WriteResult(fname, result) | |
name = File::split(fname[0])[1] | |
name = File::basename(name, ".*") | |
open("./tool/#{fname[1]}/#{name}.csv", "w").write(result) | |
end | |
def Counting(list, hash, str) | |
count = 0 | |
for name in list | |
name = name.class == Array ? name[0] : name | |
cnt = str.scan(name).size | |
count += cnt | |
hash[name] += cnt > 0 ? 1 : 0 | |
str.gsub!(name, "") | |
end | |
count | |
end | |
def CountOperator(a, b, aa, bb, str) | |
Counting(a, aa, str) + Counting(b, bb, str) | |
end | |
def UniqueOperand(hash, reg) | |
for r in reg | |
hash[r] ||= 0 | |
hash[r] += 1 | |
end | |
end | |
def CountOperand(hash, str) | |
literal = str.scan(/\d+/) | |
str.gsub!(/\d+/, " ") | |
identifier = str.scan(/\w+/) | |
str.gsub!(/\w+/, " ") | |
UniqueOperand(hash, literal) | |
UniqueOperand(hash, identifier) | |
literal.size + identifier.size | |
end | |
def CountUniqueOperator(a, b) | |
count = 0 | |
count += a.values.inject{|sum, v| sum + (v > 0 ? 1 : 0)} | |
count += b.values.inject{|sum, v| sum + (v > 0 ? 1 : 0)} | |
count | |
end | |
def OpenFile(fname) | |
str = open(fname, "r").read | |
str.encode!("UTF-8", "Shift_JIS", { | |
invalid: :replace, undef: :replace, replace: ""}) | |
RemoveComment(str) | |
end | |
file_list = MakeFileList() | |
for fname in file_list | |
operator_hash = Hash.new | |
reserved_hash = Hash.new | |
operand_hash = Hash.new | |
InitHash(operator_hash, operator_list) | |
InitHash(reserved_hash, reserved_list) | |
str = OpenFile(fname[0]) | |
puts fname[0] | |
operator = CountOperator(reserved_list, operator_list, reserved_hash, operator_hash, str) | |
operand = CountOperand(operand_hash, str) | |
unique_operator = CountUniqueOperator(operator_hash, reserved_hash) | |
unique_operand = operand_hash.size | |
program_length = operator + operand | |
vocabulary_size = unique_operator + unique_operand | |
program_volume = program_length * Math.log2(vocabulary_size) | |
difficulty_level = (unique_operator / 2.0) * (operand / unique_operand) | |
effort_to_implement = program_volume * difficulty_level | |
program_level = 1.0 / difficulty_level | |
time_to_implement = effort_to_implement / 18.0 | |
number_of_delivered_bugs = (effort_to_implement ** (2.0/3.0)) / 3000.0 | |
calculated_program_length = unique_operator * Math.log2(unique_operator) + unique_operand * Math.log2(unique_operand) | |
result = "" | |
result += "Total Operator, #{operator}\n" | |
result += "Total Operand, #{operand}\n" | |
result += "Unique Operator, #{unique_operator}\n" | |
result += "Unique Operand, #{unique_operand}\n" | |
result += "Program Length, #{program_length}\n" | |
result += "Vocabulary Size, #{vocabulary_size}\n" | |
result += "Program Volume, #{program_volume}\n" | |
result += "Difficulty, #{difficulty_level}\n" | |
result += "Effort, #{effort_to_implement}\n" | |
result += "Program Level, #{program_level}\n" | |
result += "Time to Implement, #{time_to_implement}\n" | |
result += "Number of Delivered Bugs, #{number_of_delivered_bugs}\n" | |
result += "Calculated Program Length, #{calculated_program_length}\n" | |
WriteResult(fname, result) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment