diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..4e57dc7 --- /dev/null +++ b/Podfile @@ -0,0 +1,3 @@ +use_frameworks! +pod 'Parsimmon', '~> 0.4.0' +pod 'RealmSwift' \ No newline at end of file diff --git a/Text Classifier.xcodeproj/project.pbxproj b/Text Classifier.xcodeproj/project.pbxproj index 505a51e..8b682f4 100644 --- a/Text Classifier.xcodeproj/project.pbxproj +++ b/Text Classifier.xcodeproj/project.pbxproj @@ -15,6 +15,9 @@ 64F594A61C05D8E400C85067 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 64F594A41C05D8E400C85067 /* LaunchScreen.storyboard */; }; 64F594B11C05D8E400C85067 /* Text_ClassifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F594B01C05D8E400C85067 /* Text_ClassifierTests.swift */; }; 64F594BC1C05D8E500C85067 /* Text_ClassifierUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F594BB1C05D8E500C85067 /* Text_ClassifierUITests.swift */; }; + 64F594CB1C05DE7200C85067 /* ClassifierVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F594CA1C05DE7200C85067 /* ClassifierVC.swift */; }; + 64F594CD1C05DEEB00C85067 /* ClassifierCVCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F594CC1C05DEEB00C85067 /* ClassifierCVCell.swift */; }; + 64F594CF1C06681100C85067 /* CData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F594CE1C06681100C85067 /* CData.swift */; }; DC78CD3A98166EADE961CA99 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A97CABDDB315FB655C0447D3 /* Pods.framework */; }; /* End PBXBuildFile section */ @@ -50,6 +53,9 @@ 64F594B71C05D8E500C85067 /* Text ClassifierUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Text ClassifierUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 64F594BB1C05D8E500C85067 /* Text_ClassifierUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Text_ClassifierUITests.swift; sourceTree = ""; }; 64F594BD1C05D8E500C85067 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 64F594CA1C05DE7200C85067 /* ClassifierVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClassifierVC.swift; sourceTree = ""; }; + 64F594CC1C05DEEB00C85067 /* ClassifierCVCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClassifierCVCell.swift; sourceTree = ""; }; + 64F594CE1C06681100C85067 /* CData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CData.swift; sourceTree = ""; }; 6A4D34E8E2880D97291A13E8 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; A97CABDDB315FB655C0447D3 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A9B3DDD0EF7F568476336B37 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -115,6 +121,7 @@ 64F594971C05D8E400C85067 /* Text Classifier */ = { isa = PBXGroup; children = ( + 64F594C91C05DE4F00C85067 /* Classifier */, 64F594981C05D8E400C85067 /* AppDelegate.swift */, 64F5949A1C05D8E400C85067 /* ViewController.swift */, 64F5949C1C05D8E400C85067 /* Main.storyboard */, @@ -144,6 +151,16 @@ path = "Text ClassifierUITests"; sourceTree = ""; }; + 64F594C91C05DE4F00C85067 /* Classifier */ = { + isa = PBXGroup; + children = ( + 64F594CA1C05DE7200C85067 /* ClassifierVC.swift */, + 64F594CC1C05DEEB00C85067 /* ClassifierCVCell.swift */, + 64F594CE1C06681100C85067 /* CData.swift */, + ); + name = Classifier; + sourceTree = ""; + }; C3C8D0B6FBB73898D5AAB10D /* Frameworks */ = { isa = PBXGroup; children = ( @@ -337,6 +354,9 @@ 64F594A11C05D8E400C85067 /* Text_Classifier.xcdatamodeld in Sources */, 64F5949B1C05D8E400C85067 /* ViewController.swift in Sources */, 64F594991C05D8E400C85067 /* AppDelegate.swift in Sources */, + 64F594CF1C06681100C85067 /* CData.swift in Sources */, + 64F594CB1C05DE7200C85067 /* ClassifierVC.swift in Sources */, + 64F594CD1C05DEEB00C85067 /* ClassifierCVCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Text Classifier/Base.lproj/Main.storyboard b/Text Classifier/Base.lproj/Main.storyboard index 3a2a49b..cccd0e0 100644 --- a/Text Classifier/Base.lproj/Main.storyboard +++ b/Text Classifier/Base.lproj/Main.storyboard @@ -1,25 +1,240 @@ - + - + + + - - + + - + - - + + - + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Text Classifier/CData.swift b/Text Classifier/CData.swift new file mode 100644 index 0000000..4867da3 --- /dev/null +++ b/Text Classifier/CData.swift @@ -0,0 +1,15 @@ +// +// CData.swift +// Text Classifier +// +// Created by Jamone Alexander Kelly on 11/25/15. +// Copyright © 2015 Jamone Kelly. All rights reserved. +// + +import Foundation +import RealmSwift + +class CData: Object { + dynamic var text = "" + dynamic var category = "" +} diff --git a/Text Classifier/ClassifierCVCell.swift b/Text Classifier/ClassifierCVCell.swift new file mode 100644 index 0000000..1dfeb72 --- /dev/null +++ b/Text Classifier/ClassifierCVCell.swift @@ -0,0 +1,15 @@ +// +// ClassifierCVCell.swift +// Text Classifier +// +// Created by Jamone Alexander Kelly on 11/25/15. +// Copyright © 2015 Jamone Kelly. All rights reserved. +// + +import UIKit + +class ClassifierCVCell: UICollectionViewCell { + @IBOutlet var text: UILabel! + @IBOutlet var category: UILabel! + +} diff --git a/Text Classifier/ClassifierVC.swift b/Text Classifier/ClassifierVC.swift new file mode 100644 index 0000000..4b70a89 --- /dev/null +++ b/Text Classifier/ClassifierVC.swift @@ -0,0 +1,129 @@ +// +// ClassifierVC.swift +// Text Classifier +// +// Created by Jamone Alexander Kelly on 11/25/15. +// Copyright © 2015 Jamone Kelly. All rights reserved. +// + +import UIKit +import Parsimmon +import RealmSwift + +class ClassifierVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { + @IBOutlet var collectionView: UICollectionView! + @IBOutlet var trainButton: UIButton! + @IBOutlet var classifyButton: UIButton! + let realm = try! Realm() + @IBOutlet var trainTextField: UITextField! + @IBOutlet var trainCategoryField: UITextField! + @IBOutlet var classifyTextField: UITextField! + let classifier = NaiveBayesClassifier() + @IBOutlet var classifyResultTextField: UILabel! + var classifierData : Results? + + override func viewDidLoad() { + super.viewDidLoad() + + // populate our data + self.populate() + + self.collectionView.dataSource = self + self.collectionView.delegate = self + // Attach functions to our buttons + self.trainButton.addTarget(self, action: "trainClassifier:", forControlEvents: .TouchUpInside) + self.classifyButton.addTarget(self, action: "classify:", forControlEvents: .TouchUpInside) + } + + func populate() { + let data = realm.objects(CData) + + if data.count == 0 { + print("No data") + self.classifierData = nil + return + } + + self.classifierData = data + + // We have our data.. + guard let count = self.classifierData?.count else { + return + } + + // Our data is available.. lets train + for i in 0.. Int { + if self.classifierData == nil { + return 0 + } + + return (self.classifierData?.count)! + } + + func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { + return 1 + } + + func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! ClassifierCVCell + + if let cellData = self.classifierData?[indexPath.row] { + cell.text.text = cellData.text + cell.category.text = cellData.category + } + + return cell + } + + func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { + print("test") + } + + func trainClassifier(sender: UIButton) { + // Check for input + guard let trainingText = self.trainTextField.text where !trainingText.isEmpty else { + print("Missing training text") + return + } + + guard let trainingCategory = self.trainCategoryField.text where !trainingCategory.isEmpty else { + print("Missing training category") + return + } + // Train with input + self.classifier.trainWithText(trainingText, category: trainingCategory) + + try! realm.write { + let cData : CData = CData() + cData.text = trainingText + cData.category = trainingCategory + self.realm.add(cData) + } + + print("train pushed") + } + + func classify(sender: UIButton) { + // Check for input + guard let classifyText = self.classifyTextField.text where !classifyText.isEmpty else { + print("Missing classify text") + return + } + + let result = self.classifier.classify(classifyText) + self.classifyResultTextField.text = result + print("classify pushed") + } +}