Skip to content

Commit 170c3e8

Browse files
authored
Merge pull request #19 from devopshq/develop
Preparing release 1.3.
2 parents c8bc77a + 0c68734 commit 170c3e8

106 files changed

Lines changed: 1353 additions & 3781 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
language: python
2+
python: '3.6'
3+
branches:
4+
only:
5+
- master
6+
- develop
7+
install:
8+
- pip install pytest coverage codacy-coverage
9+
script:
10+
- printenv
11+
- ls -la
12+
- coverage run -m py.test tests
13+
- coverage xml
14+
- python-codacy-coverage -r coverage.xml
15+
deploy:
16+
provider: pypi
17+
user: devopshq
18+
password:
19+
secure: "c59mB1I6teHzX5vSs1k2VfEyntkQU8Y7o7pwAusygj/5M9sIPeKcveOfbIHj2E1ltQFpPT3wF8quHmyETYvKPXdfggZsm7pxdx+KfrveiMpGwnxaGVPjIXSTA4FC2pXP7DQK3+yzc61U7OM1k0skGg8N6Qs7fdFWAGKL+o3S6uW5cYgutTaj8uh8L4a7rxxR5VxvfK3jw5yLLnd7EWMN9tngVm4L1jUZsUvDKis7i+MNNynhgO0bln5s/uj/IPt+5rghcsiqFIgnmcVH0Nxe/f8iYnzMXFVqVISpj+XcV0EQBMw0xGjEdNGrc2rkCy9zw2GmNxM+JaUyXV+eEln+4vGz7tbZrdwMdasre2AKQMX+4jlt38W6nUV26txwTFkQ03oRcntSR8acYy/9WxOufkRT9Br/E10F6Axoadwn2zzdQEc6iuzZ32BvgqmS/AV+IutLFbmqwu5Gma9jzWQ1olE6me68ZZYEqTFf+iDe8uzfLPHmSUeCqXiehlN8v8tNjKjk1JSrOmuAWvoPxr2DGHBImEPCGM8TxOLx9IoqDMF0nEwuOqTmlvtJqv+JrA8q+rpkjeqnXUCXuRfM8eDP//b4syMdC9D2w4TV9eMg7FIgXvB3zMLKxGxZHXdNiFFpg5PvWithxdZf1YNIgyGknL6A+OrUSqIAhw3vxTXSZRg="
20+
distributions: sdist bdist_wheel
21+
on:
22+
all_branches: true
23+
skip_cleanup: true
24+
after_script:
25+
- echo "Deploy to PyPI finished."
26+
env:
27+
global:
28+
- secure: "jEMGwLJ8Ri1Ik3gvDUYuYsOWLJ8F7Ta3MmbeX//FasbDHtVrcIunnCI9q1ispBGjU+fXNmCK4Booysvv5FPt2YbgUbEejp2Nfp/FnWGyHl0htDLeE3pBd9nzs6JD6swnLiAz0r6Ds1fsPloMcJwbAKEjEjwqBsPKZ51n1z28xt1960ybIt0fMXsZzCne4bCqpA2EeLMX2oWP5f+l5+18nJK5hog6L8+zAgxJU3OAscv7IqkMlgcqw6X+DQ2q9IZYdPEJy5fc/zuKgHJK6PbjDLm82jYYbr125W60G9McuP8VSC1rtc2WoWPgL70C5DD7Ba9NOszbTSxyDvx/DUtMQsCiR5KBAFap/BJvaZiFuATU6mwvU/VsPVNrltEDjdlXIpYar9X97Ue8hW+HuCp+l1CKNIM01QrPgLs3W1FxIYyufG1BDqzsGgYJnfjaw/zW9fX4CNUunkba4yC3C3913ef3qY11EIgVfMlQh/hdtWAvuwExBFnm21afhRtHkyVrKeI3oFB/Ws3CAqCSL/AWZoHARjfcRiUXFW2t2b75bEKXUoEbZ8hFr5GmUAC53zFNeMz8YQdzYqbS9r6lImlVESgixiMRgqDxpBUh+uBPalqqWKR/YRuKOoB2SluY6NtgizSZCapItfl7hK++lHHEk3w48h9cQ5pya9Lv1GVMpnQ="

FuzzyClassificator.py

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,57 @@
1717
from FCLogger import *
1818

1919

20+
def Version(onlyPrint=False):
21+
"""
22+
Return current version of FuzzyClassificator build
23+
"""
24+
import pkg_resources # part of standart setuptools
25+
26+
try:
27+
version = pkg_resources.get_distribution('FuzzyClassificator').version
28+
29+
except Exception:
30+
return 'unknown'
31+
32+
if onlyPrint:
33+
FCLogger.level = 50
34+
print(version)
35+
36+
return version
37+
38+
2039
# Constants and Global variables:
2140

22-
ethalonsDataFile = 'ethalons.dat' # file with ethalon data samples by default
23-
candidatesDataFile = 'candidates.dat' # file with candidates data samples by default
24-
neuroNetworkFile = 'network.xml' # file with Neuro Network configuration
25-
reportDataFile = 'report.txt' # Report file with classification analysis
26-
bestNetworkFile = 'best_nn.xml' # best network
27-
bestNetworkInfoFile = 'best_nn.txt' # information about best network
41+
__version__ = Version() # set version of current FuzzyClassificator build
42+
43+
ethalonsDataFile = 'ethalons.dat' # File with ethalon data samples.
44+
candidatesDataFile = 'candidates.dat' # File with candidates data samples.
45+
neuroNetworkFile = 'network.xml' # File with Neuro Network configuration.
46+
reportDataFile = 'report.txt' # Report file with classification analysis.
47+
bestNetworkFile = 'best_nn.xml' # Best network during the learns.
48+
bestNetworkInfoFile = 'best_nn.txt' # File with information about best network during the learns.
2849

29-
epochsToUpdate = 5 # epochs between error status updated
50+
epochsToUpdate = 5 # Epochs between error status updated.
3051

3152
ignoreColumns = [] # List of ignored columns in input files.
3253
ignoreRows = [1] # List of ignored rows in input files.
33-
sepSymbol = '\t' # tab symbol used as separator by default
54+
sepSymbol = '\t' # Separator symbol.
3455

35-
reloadNetworkFromFile = False # reload or not Neuro Network from file before usage
36-
noFuzzyOutput = False # show results with fuzzy values if False, otherwise show real values
56+
reloadNetworkFromFile = False # Reload or not Neuro Network from file before usage.
57+
noFuzzyOutput = False # Show results with fuzzy values if False, otherwise show real values.
58+
showExpected = False # Show expected results in Classify mode. WARNING! Use only if your dat-file contains columns with expected results to avoid errors!
3759

3860

39-
def ParseArgsMain():
61+
def ParseArgsMain(notAPI=True):
4062
"""
4163
Function get and parse command line keys.
4264
"""
4365
parser = argparse.ArgumentParser() # command-line string parser
4466

45-
parser.description = 'This program uses neural networks to solve classification problems, and uses fuzzy sets and fuzzy logic to interpreting results.'
46-
parser.epilog = 'See examples on GitHub: https://github.com/Tim55667757/FuzzyClassificator FuzzyClassificator using Pyzo, http://www.pyzo.org - free and open-source computing environment, based on Python 3.3.2., and PyBrain library: http://pybrain.org'
67+
parser.description = 'FuzzyClassificator version: {}. This program uses neural networks to solve classification problems, and uses fuzzy sets and fuzzy logic to interpreting results. FuzzyClassificator provided under the MIT License.'.format(__version__)
68+
parser.epilog = 'See examples on GitHub: https://devopshq.github.io/FuzzyClassificator/'
69+
70+
parser.add_argument('-v', '--version', action='store_true', help='Show current version of FuzzyClassificator.')
4771

4872
parser.add_argument('-l', '--debug-level', type=str, help='Use 1, 2, 3, 4, 5 or DEBUG, INFO, WARNING, ERROR, CRITICAL debug info verbosity, INFO (2) by default.')
4973
parser.add_argument('-e', '--ethalons', type=str, help='File with ethalon data samples, ethalons.dat by default.')
@@ -57,14 +81,15 @@ def ParseArgsMain():
5781
parser.add_argument('-ir', '--ignore-row', type=str, help='Row indexes in input files that should be ignored. Use only dash and comma as separator numbers, other symbols are ignored. 1st raw always set as ignored. Example (no space after comma): 2,4-7')
5882
parser.add_argument('-sep', '--separator', type=str, help='Separator symbol in raw data files. SPACE and TAB are reserved, TAB used by default.')
5983
parser.add_argument('--no-fuzzy', action='store_true', help='Do not show fuzzy results, only real. False by default.')
84+
parser.add_argument('--show-expected', action='store_true', help='Show expected results in Classify mode. WARNING! Use only if your dat-file contains columns with expected results!')
6085
parser.add_argument('--reload', action='store_true', help='Reload network from file before usage, False by default.')
6186
parser.add_argument('-u', '--update', type=int, help='Update error status after this epochs time, 5 by default. This parameter affected training speed.')
6287

6388
parser.add_argument('--learn', type=str, nargs='+', help='Start program in learning mode with options (no space after comma): config=<inputs_num>,<layer1_num>,<layer2_num>,...,<outputs_num> epochs=<int_number> rate=<float_num> momentum=<float_num> epsilon=momentum=<float_num> stop=momentum=<float_num>')
6489
parser.add_argument('--classify', type=str, nargs='+', help='Start program in classificator mode with options (no space after comma): config=<inputs_num>,<layer1_num>,<layer2_num>,...,<outputs_num>')
6590

6691
cmdArgs = parser.parse_args()
67-
if (cmdArgs.learn and cmdArgs.classify) or (not cmdArgs.learn and not cmdArgs.classify):
92+
if notAPI and not cmdArgs.version and ((cmdArgs.learn and cmdArgs.classify) or (not cmdArgs.learn and not cmdArgs.classify)):
6893
parser.print_help()
6994
sys.exit()
7095

@@ -96,7 +121,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
96121
# Parsing Neural Network Config parameter that looks like "config=inputs,layer1,layer2,...,outputs":
97122
config = tuple(int(par) for par in kwargs['config'].split(',')) # config for FuzzyNeuroNetwork
98123

99-
except:
124+
except Exception:
100125
noErrors = False
101126
FCLogger.error(traceback.format_exc())
102127
FCLogger.error('Incorrect neural network config! Parameter config must looks like tuple of numbers: config=inputs,layer1,layer2,...,outputs')
@@ -105,7 +130,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
105130
try:
106131
epochs = int(kwargs['epochs'])
107132

108-
except:
133+
except Exception:
109134
noErrors = False
110135
FCLogger.error(traceback.format_exc())
111136
FCLogger.error('Epoch parameter might be an integer number greater or equal 1!')
@@ -114,7 +139,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
114139
try:
115140
rate = float(kwargs['rate'])
116141

117-
except:
142+
except Exception:
118143
noErrors = False
119144
FCLogger.error(traceback.format_exc())
120145
FCLogger.error('Rate parameter might be a float number greater than 0 and less or equal 1!')
@@ -123,7 +148,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
123148
try:
124149
momentum = float(kwargs['momentum'])
125150

126-
except:
151+
except Exception:
127152
noErrors = False
128153
FCLogger.error(traceback.format_exc())
129154
FCLogger.error('Momentum parameter might be a float number greater than 0 and less or equal 1!')
@@ -132,7 +157,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
132157
try:
133158
epsilon = float(kwargs['epsilon'])
134159

135-
except:
160+
except Exception:
136161
noErrors = False
137162
FCLogger.error(traceback.format_exc())
138163
FCLogger.error('Epsilon parameter might be a float number greater than 0 and less or equal 1!')
@@ -141,7 +166,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
141166
try:
142167
stop = float(kwargs['stop'])
143168

144-
except:
169+
except Exception:
145170
noErrors = False
146171
FCLogger.error(traceback.format_exc())
147172
FCLogger.error('Stop parameter might be a float number greater than 0 and less or equal 100!')
@@ -192,7 +217,7 @@ def LMStep1CreatingNetworkWithParameters(**kwargs):
192217
for line in str(fNetwork.scale).split('\n'):
193218
FCLogger.debug(line)
194219

195-
except:
220+
except Exception:
196221
noErrors = False
197222
FCLogger.error(traceback.format_exc())
198223
FCLogger.error('Failed to initialize the fuzzy network!')
@@ -313,6 +338,7 @@ def LearningMode(**inputParameters):
313338
successFinish = False # success Learning Mode finish flag
314339

315340
FCLogger.info(sepLong)
341+
FCLogger.info('FuzzyClassificator version: {}'.format(__version__))
316342
FCLogger.info('Learning mode activated.')
317343
FCLogger.info('Log file: {}'.format(os.path.abspath(fileLogHandler.baseFilename)))
318344

@@ -359,7 +385,7 @@ def CMStep1CreatingPyBrainNetwork(**kwargs):
359385
# Parsing Neural Network Config parameter that looks like "config=inputs,layer1,layer2,...,outputs":
360386
config = tuple(int(par) for par in kwargs['config'].split(',')) # config for FuzzyNeuroNetwork
361387

362-
except:
388+
except Exception:
363389
noErrors = False
364390
FCLogger.error(traceback.format_exc())
365391
FCLogger.error('Incorrect neural network config! Parameter config must looks like tuple of numbers: config=inputs,layer1,layer2,...,outputs')
@@ -391,7 +417,7 @@ def CMStep1CreatingPyBrainNetwork(**kwargs):
391417
for line in str(fNetwork.scale).split('\n'):
392418
FCLogger.debug(line)
393419

394-
except:
420+
except Exception:
395421
noErrors = False
396422
FCLogger.error(traceback.format_exc())
397423
FCLogger.error('Failed to initialize the fuzzy network!')
@@ -451,7 +477,7 @@ def CMStep4ActivatingNetworkForAllCandidateInputVectors(fNetwork):
451477
FCLogger.info(sepShort)
452478
FCLogger.info('Step 4. Activating network for all candidate input vectors.')
453479

454-
results = fNetwork.ClassificationResults(fullEval=True, needFuzzy=not(noFuzzyOutput), showExpectedVector=False)
480+
results = fNetwork.ClassificationResults(fullEval=True, needFuzzy=not(noFuzzyOutput), showExpectedVector=showExpected)
455481

456482
return results
457483

@@ -484,6 +510,7 @@ def ClassifyingMode(**inputParameters):
484510
successFinish = False # success Classifying mode finish flag
485511

486512
FCLogger.info(sepLong)
513+
FCLogger.info('FuzzyClassificator version: {}'.format(__version__))
487514
FCLogger.info('Classificator mode activated.')
488515
FCLogger.info('Log file: {}'.format(os.path.abspath(fileLogHandler.baseFilename)))
489516

@@ -510,11 +537,36 @@ def ClassifyingMode(**inputParameters):
510537
return successFinish
511538

512539

513-
if __name__ == "__main__":
514-
args = ParseArgsMain() # get and parse command-line parameters
540+
def Main(learnParameters=None, classifyParameters=None):
541+
"""
542+
Main function for classification routines.
543+
learnParameters and classifyParameters are dictionaries with the same parameters as used in CLI. Examples:
544+
learnParameters = {"config": "3,3,2,2", "epochs": 100, "rate": 0.5, "momentum": 0.5, "epsilon": 0.75, "stop": 1}
545+
classifyParameters = {"config": "3,3,2,2"}
546+
If parameters are not defined then CLI-parameters are used.
547+
"""
548+
global ethalonsDataFile
549+
global candidatesDataFile
550+
global neuroNetworkFile
551+
global reportDataFile
552+
global bestNetworkFile
553+
global bestNetworkInfoFile
554+
global ignoreColumns
555+
global ignoreRows
556+
global sepSymbol
557+
global noFuzzyOutput
558+
global showExpected
559+
global reloadNetworkFromFile
560+
global epochsToUpdate
561+
562+
notAPI = False if learnParameters or classifyParameters else False # check if API or CLI work mode
563+
args = ParseArgsMain(notAPI) # parse another CLI parameters if they was
515564
exitCode = 0
516565

517566
try:
567+
if args.version:
568+
Version(onlyPrint=True) # Show current version of FuzzyClassificator
569+
518570
if args.debug_level:
519571
SetLevel(args.debug_level) # set up FCLogger level
520572

@@ -548,25 +600,45 @@ def ClassifyingMode(**inputParameters):
548600
if args.no_fuzzy:
549601
noFuzzyOutput = True
550602

603+
if args.show_expected:
604+
showExpected = True
605+
551606
if args.reload:
552607
reloadNetworkFromFile = args.reload # reload neural network from given file before usage
553608

554609
if args.update:
555610
epochsToUpdate = args.update # epochs before error status updating
556611

557-
if args.learn:
558-
exitCode = int(not(LearningMode(**dict(kw.split('=') for kw in args.learn)))) # Learning mode
612+
# Execute Learning mode if API or CLI used:
613+
if learnParameters:
614+
exitCode = int(not(LearningMode(**learnParameters)))
559615

560-
elif args.classify:
561-
exitCode = int(not(ClassifyingMode(**dict(kw.split('=') for kw in args.classify)))) # Classifying mode
616+
elif args.learn:
617+
exitCode = int(not(LearningMode(**dict(kw.split('=') for kw in args.learn))))
562618

563-
except:
564-
exitCode = 1
565-
FCLogger.error(traceback.format_exc())
619+
# Execute Classifying mode if API or CLI used:
620+
else:
621+
if classifyParameters:
622+
exitCode = int(not(ClassifyingMode(**classifyParameters)))
566623

567-
finally:
568-
FCLogger.info('FuzzyClassificator work finished.')
624+
elif args.classify:
625+
exitCode = int(not(ClassifyingMode(**dict(kw.split('=') for kw in args.classify))))
626+
627+
except Exception:
628+
FCLogger.error(traceback.format_exc())
629+
FCLogger.info('FuzzyClassificator work finished with exitCode = 1')
569630
FCLogger.info(sepLong)
570631

632+
FCLogger.info('FuzzyClassificator work finished with exitCode = {}'.format(exitCode))
633+
FCLogger.info(sepLong)
634+
635+
if notAPI:
571636
DisableLogger(fileLogHandler)
572-
sys.exit(exitCode)
637+
sys.exit(exitCode)
638+
639+
else:
640+
return exitCode
641+
642+
643+
if __name__ == "__main__":
644+
Main()

0 commit comments

Comments
 (0)