logo-small-small-high-res.png

Marian Stiehler

Student

Informatik
Philosophie Psychologie Kunstwissenschaft

Primes.app

Primes.app

Bildschirmfoto 2018-01-07 um 19.21.35.png

Primes.app

Auf einem mobilen Gerät liest sich dieser Beitrag wegen der langen Code-Zeilen am besten im Querformat.

Diese App soll den Einstieg in die iOS-Programmierung zeigen – und dabei etwas komplexer als »Hello World!« sein. Dieser Blog-Beitrag ist allerdings kein ausführliches Tutorial, sondern eher eine Anregung, was man mit iOS für den Anfang so tun kann. Er ist nur für Leser geeignet, die sich mit iOS-Development auskennen.

Das User Interface stellt man in Xcode zusammen. Ich habe verschiedene Varianten ausprobiert:

Von einem User-Interface-Standpunkt aus ist die dritte Variante sicher die beste.

Der Code für die "Stepper" (so nennt iOS das Kontrollelement) ist denkbar simpel. Zunächst definiert man sich globale Variablen mit Startwerten. Ich habe den Rechner absichtlich auf einen Zahlenbereich von 1 bis 65.000 begrenzt. Im Sinne der Ressourcensparsamkeit auf einem mobilen Gerät reichen also Datenspeicher vom Typ UInt16 aus.

    var upper_limit: UInt16 = 10
    var lower_limit: UInt16 = 1

Dann folgen ihre Funktionen. Dabei wird sichergestellt, dass das obere Limit immer größer als das untere Limit ist. Das Maximum der Stepper (65.000) stellt man in Xcode ein.

     // Stepper
    // upper
    @IBOutlet weak var lblStepperUpper: UILabel!
    @IBOutlet weak var stepperUpper: UIStepper!
    @IBAction func stepperUpper(_ sender: UIStepper) {
            upper_limit = UInt16(stepperUpper.value)
            lblStepperUpper.text = String(upper_limit)
        
        if upper_limit < lower_limit {
            lower_limit = upper_limit - 9
            stepperLower.value = Double(lower_limit)
            lblStepperLower.text = String(lower_limit)
        }
    }
    // lower
    @IBOutlet weak var lblStepperLower: UILabel!
    @IBOutlet weak var stepperLower: UIStepper!
    @IBAction func stepperLower(_ sender: UIStepper) {
            lower_limit = UInt16(stepperLower.value)
            lblStepperLower.text = String(lower_limit)

        if lower_limit > upper_limit {
            upper_limit = lower_limit + 9
            stepperUpper.value = Double(upper_limit)
            lblStepperUpper.text = String(upper_limit)
        }
    }

Schließlich folgt hier mein Code für die Durchführung und die Ausgabe der Primzahlberechnung. Dabei ist viel wert auf eine sichere Ausführung und auf die Selbstständigkeit der Candidate-Klasse gelegt; es werden daher manche Fehler mehrfach abgefangen.

        @IBAction func primeButtonTouch(_ sender: Any) {
            
            // MARK: Functions
            
            func doPrimeCalculation() -> [UInt16]  {
                
                enum MyErrors : Error {
                    case negative
                    case tooHigh
                    case even
                }
                
                struct Candidate {
                    let number: UInt16          // to store the number
                    var prime: Bool = true      // assume Candidate is prime
                    
                    init(number: UInt16) throws {
                        self.number = number    // store the number
                        
                        // ensure number is odd
                        guard self.number % 2 != 0 else { throw MyErrors.even }
                        // ensure number is positive
                        guard self.number > 0 else { throw MyErrors.negative }
                        
                        // check if number can be divided through any odd number
                        // between 2 and (not including) itself
                        for i in stride(from: 3, to: number-1, by: 2) {
                            if number % i == 0 {
                                self.prime = false
                                break
                            }
                        }
                    }
                }
                
                
                // Limits
                func checkLimits(lower_limit: UInt16, upper_limit: UInt16) throws {
                    guard lower_limit > 0, upper_limit > 0 else {
                        throw MyErrors.negative
                    }
                    guard upper_limit <= 65_000 else {
                        throw MyErrors.tooHigh
                    }
                }
                
                
                do {
                    try checkLimits(lower_limit: lower_limit, upper_limit: upper_limit)
                }
                catch MyErrors.negative{
                    print("Limits can't be negative in this implementation. Aborting.")
                }
                catch MyErrors.tooHigh{
                    print("Upper limit cannot exceed 65,535 in this implementation. Aborting.")
                } catch {
                    print("Error")
                }
                
                
                var primes: [UInt16]  = []  // array to store the found primes in
                // reserve some capacity to speed up appends
                primes.reserveCapacity(Int((upper_limit-lower_limit) / 5))
                
                var loopStart: UInt16 = lower_limit
                
                switch lower_limit {
                case 1, 2:
                    // handle exceptional cases 1 and 2; 2 is prime, 1 is not; start algorithm with 3
                    loopStart = 3
                    primes.append(2)
                default:
                    // ensure loopStart is odd number (even numbers aren't prime)
                    if loopStart % 2 == 0 { loopStart += 1 }
                }
                
                // check every odd number between lower_limit and upper_limit
                for candidate: UInt16 in stride(from: loopStart, to: upper_limit, by: 2) {
                    do {
                        let tocheck = try Candidate(number: candidate)
                        if tocheck.prime { primes.append(tocheck.number) }
                    }
                    catch MyErrors.even {
                        print("Candidate has been given an even number.")
                    }
                    catch MyErrors.negative {
                        print("Number to check is negative.")
                    }   catch {
                        print("Error")
                    }

                }
                return primes
            }
            
        
            func doPrint(primes: [UInt16] ) {
                // prints an array of numbers into textView
                
                var count: UInt16 = 0
                var result: String = ""
                for prime in primes {
                    count += 1
                    result += String(prime)
                    if count != primes.count {
                        result += ", "
                    }
                }
                textView.text? = result
            }
            
            
            func run() {
                // do calculation and print it
                
                textView.text? = ""     // clear text field
                let primes : [UInt16]  = doPrimeCalculation()
                doPrint(primes: primes)
            }
            
            // MARK: main
            
            // optional warning
            if (upper_limit-lower_limit <= 5_000) {
           
                run()   // do calculation and print it
                
            } else {
                let alertTitle = NSLocalizedString("Warning", comment: "warning")
                let alertMessage = NSLocalizedString("With such a large range of numbers to calculate it could take a little longer", comment: "range warning")
                let alertCancel = NSLocalizedString("Cancel", comment: "cancel")
                let alertContinue = NSLocalizedString("Continue", comment: "continue")
                
                let alert = UIAlertController(
                    title: alertTitle,
                    message: alertMessage,
                    preferredStyle: .alert)
                
                alert.addAction(UIAlertAction(title: alertCancel, style: .cancel, handler: {(_) in }))
                
                alert.addAction(UIAlertAction(title: alertContinue, style: .default, handler:  { (_) in run()}))
                
                present(alert, animated: true, completion: { () in })
            }
        }

 

 

Herzfrequenzanalyse mit Mathematica

Herzfrequenzanalyse mit Mathematica

Der Tod des PC

Der Tod des PC