Skip to content

Instantly share code, notes, and snippets.

@jutikorn
Created February 26, 2023 14:44
Show Gist options
  • Save jutikorn/7a6a8ccc5aeee8eda84457053c5f8dd8 to your computer and use it in GitHub Desktop.
Save jutikorn/7a6a8ccc5aeee8eda84457053c5f8dd8 to your computer and use it in GitHub Desktop.
Remove unused drawable in Android project, using Boyer Moore pattern matching algorithm (Bad Character Heuristic)
# Boyer Moore
# Python3 Program for Bad Character Heuristic
# of Boyer Moore String Matching Algorithm
# https://www.geeksforgeeks.org/boyer-moore-algorithm-for-pattern-searching/
NO_OF_CHARS = 256
def badCharHeuristic(string, size):
'''
The preprocessing function for
Boyer Moore's bad character heuristic
'''
# Initialize all occurrence as -1
badChar = [-1]*NO_OF_CHARS
# Fill the actual value of last occurrence
for i in range(size):
badChar[ord(string[i])] = i;
# return initialized list
return badChar
def search(txt, pat):
'''
A pattern searching function that uses Bad Character
Heuristic of Boyer Moore Algorithm
'''
m = len(pat)
n = len(txt)
# create the bad character list by calling
# the preprocessing function badCharHeuristic()
# for given pattern
badChar = badCharHeuristic(pat, m)
# s is shift of the pattern with respect to text
s = 0
while(s <= n-m):
j = m-1
# Keep reducing index j of pattern while
# characters of pattern and text are matching
# at this shift s
while j>=0 and pat[j] == txt[s+j]:
j -= 1
# If the pattern is present at current shift,
# then index j will become -1 after the above loop
if j<0:
'''
Shift the pattern so that the next character in text
aligns with the last occurrence of it in pattern.
The condition s+m < n is necessary for the case when
pattern occurs at the end of text
'''
print(f'Found {pat}')
return True
else:
'''
Shift the pattern so that the bad character in text
aligns with the last occurrence of it in pattern. The
max function is used to make sure that we get a positive
shift. We may get a negative shift if the last occurrence
of bad character in pattern is on the right side of the
current character.
'''
s += max(1, j-badChar[ord(txt[s+j])])
return False
def main():
files = list_all_res(drawable_path)
for file in files:
x = file.replace(".xml", "").replace(".png", "").replace(".webp", "").replace(".9.png", "")
print(f'searching: {x}')
if not search_in_path(code_path, x):
print(f'cannot find {x}')
delete_file(os.path.join(drawable_path, file))
if __name__ == '__main__':
main()
import os
code_path = '/Users/JutikornMac2015/Documents/PROJECT/app/src'
drawable_path = '/Users/JutikornMac2015/Documents/PROJECT/app/src/main/res/drawable'
def list_all_res(res_path):
res = []
for path in os.listdir(res_path):
if os.path.isfile(os.path.join(res_path, path)):
res.append(path)
return res
def search_in_path(path, pattern):
result = False
dir_list = os.listdir(path)
for p in dir_list:
full_path = os.path.join(path, p)
if os.path.isdir(full_path):
result = search_in_path(full_path, pattern)
else:
result = search_in_file(full_path, pattern)
if result:
return result
def search_in_file(filename, pattern):
result = False
if filename.endswith('.kt') or filename.endswith('.java') or filename.endswith('.xml'):
with open(filename, 'r', encoding='UTF-8') as file:
lines = [line.rstrip('\n') for line in file]
for l in lines:
result = search(l, pattern)
if result:
return result
return result
def delete_file(filename):
if os.path.exists(filename):
print(f'Deleting: {filename}')
os.remove(filename)
else:
print(f'cant delete: {filename}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment