Skip to content

Instantly share code, notes, and snippets.

@GRGSIBERIA
Created December 15, 2014 18:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GRGSIBERIA/a7c35bb69d32a506ef44 to your computer and use it in GitHub Desktop.
Save GRGSIBERIA/a7c35bb69d32a506ef44 to your computer and use it in GitHub Desktop.
halstead volume measure
#-*- 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