Syntax Comparison: Swift vs Python
Sharing my notes that I prepared to remember the python syntax from already known language syntax. (Swift 4.2; Python 3.7)
“The Loci method is one of the most ancient memorization tools known, and is based on attaching individual items you need to remember, to individual points on a route you are familiar with, so you can easily recall the items as you “walk” that route in your mind.”
- Basics
- Collection Types
- Class, Struct
- Closures
- Exception Handling
- Unit Testing
Import Modules
Swift
import Foundation
typealias a module
typealias SMSomeStruct = SomeModule.SomeStruct
Import only parts from a module
import struct SomeModule.SomeStruct
import class SomeModule.SomeClass
import func SomeModule.someFunc
Python
import calculator
typealias a module
import calculator as calc
Import only parts from a module
from calculator import multiply# usage
result = multiply(2, 4)
Constants
Swift
let maximumHeight = 50
Python
Create constant.py file (global file)
PI = 3.14
GRAVITY = 9.8
MAXIMUM_HEIGHT = 50
Usage:
import constantconstant.MAXIMUM_HEIGHT
Variables
Swift
var userName = "Sit Bibendum"
userName = "Malesuada Mollis"
Python
userName = "Sit Bibendum"
userName = "Malesuada Mollis"# Assigning multiple values to multiple variables
a, b, c = 5, 3.2, "Hello"# to assign the same value to multiple variables at once
x = y = z = 1000
Comments
Swift
// single comment/* multi line comment */
Python
# python comment, no multiline comment
Swift
let id = 525
let name = "Porta Tortor"print(id, name) // 525 Porta Tortor
print(id, name, separator: ", ") // 525, Porta Tortor
Python
id = 525
name = "Porta Tortor"print(id, name) # 525 Porta Tortor
print(id, name, sep=', ') # 525, Porta Tortor
Print Terminator Usage
Swift
for i in 1 ..< 10 {
print(i, terminator: " ")
if i % 3 == 0 {
print()
}
}output: 1 2 3 4 5 6 7 8 9
Python
for i in range(1, 10):
print(i, end=' ')
if i % 3 == 0:
print()output: 1 2 3 4 5 6 7 8 9
Multiline Strings
Swift
let html =
"""
<html>
<body> </body>
</html>
"""
Python
html = """
<html>
<body> </body>
</html>
"""
(or) using single quotes
html2 = '''
<html>
<body> </body>
</html>
'''
String Interpolation
Swift
let id = 525
let name = "Porta Tortor"let msg = "\(id): \(name)" // 525: Porta Tortor
Python
id = 525
name = "Porta Tortor"msg = "%d: %s" % (id, name) # 525: Porta Tortormsg = "{}: {}".format(id, name) # 525: Porta Tortormsg = "{0}: {1}".format(id, name) # 525: Porta Tortor
String Concatenation
Swift
let userID = 525
let firstName = "Cursus"
let lastName = "Dolor"let text = firstName + " " + lastName + " (" + String(userID) + ")."output: Cursus Dolor (525).
Python
userID = 525
firstName = "Cursus"
lastName = "Dolor"text = firstName + " " + lastName + " (" + str(userID) + ")."output: Cursus Dolor (525).
How to get object type ?
Swift
let height = 5.7
type(of: height) // Double.Typeif height is Int {
// ..
}
Python
height = 5.7
type(height) # <type 'float'>if (type(height) is float):
# ..
String to Int
Swift
let userIDString = "525"
let userID = Int(userIDString)
Python
user_id_string = "525"
user_id = int(user_id_string)
Binary to Number
Swift
let binary = "11001"
let number = Int(binary, radix: 2) // 25
Python
binary = "11001"
number = int(binary,2) // 25
Boolean
Swift
var isEnabled = true // false
Python
isEnabled = True # False
Tuples
Swift
let http404Error = (404, "Not Found")let code = http404Error.0
let message = http404Error.1
// or
let (statusCode, statusMessage) = http404Error
Python
http404Error = (404, "Not Found")code = http404Error[0]
message = http404Error[1]
Nil, None
Swift
var email: String? = nil
Python
email = None
del Statement
Swift
// ??
Python
name = Mattis Ridiculus
del name # object will be deleted completly
print(name) # NameError: "name 'name' is not defined"
If Statement
Swift
var email: String? = nil// Optional wrap
if let email = email {
print(email)
} else {
print("n/a")
}// Force unwrap
if email != nil {
print(email!)
} else {
print("n/a")
}Output: n/a
Python
email = Noneif email is not None:
print(email)
else:
print("n/a")
or
if email != None:
print(email)
else:
print("n/a")
Output: n/a
If with Multiple Conditions
Swift
if self.x == other.x && self.y == other.y {
return true
} else {
return false
}
Python
if (self.x == other.x and self.y == other.y):
return True
else:
return False
Escape characters
Swift
let text = "one\ntwo\nthree"let regExp = "Language: \"Swift\", version: \"4.2\""
Python
text = "one\ntwo\nthree"regExp = "Language: \"Python\", version: \"3.7\""# one two three
# Language: "Python", version: "3.7"
Counting Characters
Swift
let text = "abc 123"
text.count // 7
Python
text = "abc 123"
len(text) # 7
Enum
Swift
enum Color: Int {
case red = 1
case green
case blue
var name: String {
switch self {
case .red:
return "red"
case .green:
return "green"
case .blue:
return "blue"
}
}
}// Usage:
Color.green
Color.green.name
Color.green.rawValuelet selectedColor = Color.greenif case Color.green = selectedColor {
print("Selected right color")
} else {
print("Wrong color selected \(selectedColor.name)")
}
Python
from enum import Enumclass Color(Enum):
red = 1
green = 2
blue = 3
Color.green # Color.green
Color.green.name # green
Color.green.value # 2# Usage:
selectedColor = Color.greenif selectedColor is Color.green:
print("Selected Right color")
else:
print("Wrong color selected: {}".format(selectedColor.name))
Switch
Swift
switch input {
case 0:
//..
case 1:
break
case 2:
//..
}
Python
python does not have any switch case statement.
Alternatively we use dictionary mapping.
Pass by reference
Swift
func swapInts(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}var a = 50
var b = 100
swapInts(a: &a, b: &b)
print(a, b)
Python
There are no variables in Python. There are names and objects in - Python and together they appear like variables
Decorators
Swift
// TODO: ??
Python
def validateInputs(input_function):
def validation(a, b):
if b == 0:
print("Can't divide by 0")
return
return input_function(a, b) # call input function
return validation
@validateInputs
def div(a, b):
return a / bdiv(10,0)# need to check how to achieve Decorator Pattern using python decorators. (ie.. without modifying the source code file)
Yield (instead of return), Next
Swift
// achieve using closures
func makeIncrementer(_ amount: Int) -> () -> Int {
var runningTotal = 0 func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}let incrementByTen = makeIncrementer(10)
incrementByTen()
incrementByTen()for _ in 0..<10 {
print(incrementByTen())
}
Python
def makeIncrementer(amount):
runningTotal = 0
while True:
runningTotal += amount
yield runningTotal
incrementerByTen = makeIncrementer(10)
next(incrementerByTen) # 10
next(incrementerByTen) # 20for i in range(10):
print(next(incrementerByTen)) # 30 40 ... 120
Collection Types
Array
Array Operations
Swift
var hetro: [Any] = ["one", 10, 2.5]hetro[0]
// Negative Indexing not allowedhetro[1] = "100"hetro.remove(at: 0)hetro.append("five")
hetro.append(4.9)
hetro.append("five")// No inbuilt method to remove an element directlyhetro.insert(10000, at: 1)
Python
hetro = ["one", 10, 2.5]hetro[0] # one
# reverse index
hetro[-1] # 2.5
hetro[-2] # 10hetro[1] = "100"# pop at index
hetro.pop(0)# append
hetro.append("five")
hetro.append(4.9)
hetro.append("five")# remove first occurances
hetro.remove("five")# insert at index
hetro.insert(1, "100000")
Empty array
Swift
var list = [Any]()
Python
list = []
Multidimensional arrays
Swift
let matrix = [[1,2,3], [4,5,6], [7,8,9]]
matrix[0][0]
matrix[2][2]
Python
matrix = [[1,2,3], [4,5,6], [7,8,9]]
matrix[0][0]
matrix[2][2]
Array Length
Swift
let list = ["zero", "one", "two", "three", "four"]
list.count
Python
list = ["zero", "one", "two", "three", "four"]
len(list)
Array Slicing
Swift
let list = ["zero", "one", "two", "three", "four"]list[1...4]
list[..<2]
list[2...]
Python
list = ["zero", "one", "two", "three", "four"]list[1:4] # ['one', 'two', 'three']
list[ :2] # ['zero', 'one']
list[2: ] # ['two', 'three', 'four']
list[start: end-1] understanding-pythons-slice-notation
Array with a Default Value
Swift
var countArray = Array(repeating: 0, count: 10)
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Python
countArray = [0] * 10
# or
countArray = [0 for i in range(10)] # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Set
Swift
var basket: Set = ["one", "two", "three"]let isExists = basket.contains("one")basket.insert("four")basket.update(with: "four") // if aleady contains will return `input`; else returns nil;// there is no inbuild method for appending listbasket.remove("four")basket.popFirst()basket.removeAll()
Python
basket = { "one", "two", "three"}
# or
basket = set({ "one", "two", "three"})isExists = "one" in basketbasket.add("four")basket.update(["five", "six"])basket.remove("six")basket.discard("six") # If the item to remove does not exist, discard() will NOT raise an error.# take random element
random = basket.pop() # threebasket.clear() # set([])
Empty Set
Swift
var basket = Set<AnyHashable>() // Set([])
Python
basket = set() # set([])
Dictionaries
Swift
var info:[String: Any] = [
"name": "Elit Vestibulum",
"age": 43
]let name = info["name"]info["age"] = 54info["country"] = "Cursus Elit"
info.updateValue("Nibh Dapibus", forKey: "city")info.valuesinfo.keysinfo.removeValue(forKey: "age")info.removeAll()
Python
info = {
"name" : "Elit Vestibulum",
"age": 43
}# get
name = info["name"]
name = info.get("name")# update
info["age"] = 54# add new pairs
info["country"] = "Cursus Elit"
info.update({"city": "Nibh Dapibus"}) # get all values
values = info.values() # get all keys
keys = info.keys()# remove pair
info.pop("age")info.clear() # {}
Empty Dictionary
Swift
var info = [String: Any]() // [:]
Python
info = dict() # {}
Class
Hello World
Swift
class MyClass {
init() {
print("Hello World")
}
}let myObject = MyClass()
Python
class MyClass:
def __init__(self):
print("Hello World")
myObject = MyClass()
Basic Math Class Example
Swift
class Math {
let pi = 3.14
func areaOfCircle(radius r: Double) -> Double {
return pi * (r * r)
}
func sum(a: Int, b: Int) -> Int {
return a + b
}
}let math = Math()
let area = math.areaOfCircle(radius: 10)
let sum = math.sum(a: 5, b: 2)
Python
class Math:
pi = 3.14 # default initializer; to access `self` is required (ie. self.pi)
def areaOfCircle(self, radius: float) -> float:
return self.pi * (radius * radius)
def sum(self, a, b):
return a + b
# Function annotations are completely optional metadata information about the types used by user-defined functions
def substract(self, a: int, b: int) -> int:
return a - b
math = Math()
area = math.areaOfCircle(10) # 314.0
sum = math.sum(2, 5) # 7
result = math.substract(2, 5) # -3
Init Params
Swift
class Table {
let multipler: Int
init(input: Int) {
self.multipler = input
}
func printTable(limit: Int = 10) {
for i in 1 ... limit {
print("\(multipler) * \(i) = \(i * multipler)")
}
print()
}
}let table2 = Table(input: 2)
table2.printTable()
table2.printTable(limit: 5)
Python
class Table:
def __init__(self, input):
self.multipler = input
def printTable(self, limit = 10):
for i in range(1, limit):
print("%d * %d = %d" % (self.multipler, i,
self.multipler * i))
print()
table_2 = Table(2)
table_2.printTable()
table_2.printTable(5)output:
2 * 1 = 2 ..... 2 * 9 = 18
2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 2 * 4 = 8
Class Inheritance, Overriding Methods
Swift
class Employee {
let id: Int
let name: String init(id: Int, name: String) {
self.id = id
self.name = name
} func printDetails() {
print("id: \(id)")
print("name: \(name)")
}
}class Technician: Employee {
let labId: String
init(id: Int, name: String, labId: String) {
self.labId = labId
super.init(id: id, name: name)
} override func printDetails() {
super.printDetails()
print("labId: \(labId)")
}
}let technician = Technician(id: 2693, name: "Nibh Fringilla", labId: "LAB001")
Python
class Employee:
def __init__(self, id, name):
self.id = id
self.name = name
def printDetails(self):
print("id: %s" % (self.id))
print("name: %s" % (self.name))class Technician(Employee):
def __init__(self, id, name, labID):
self.labID = labID
super().__init__(id, name) # Override method
def printDetails(self):
super().printDetails()
print("labID: %s" % (self.labID))
technician = Technician(2693, "Nibh Fringilla", "LAB001")
professor.printDetails()output:
id: 2693 name: Nibh Fringilla labID: LAB001
Private
Swift
class Hacker {
private var name = "Amet Lorem"
private func details() {
print(name)
}
func publicDetails() {
print("random name")
}
}let hacker = Hacker()
hacker.publicDetails() // random name
Python
class Hacker:
__name = "Amet Lorem" def __details(self):
print(self.__name)
def publicDetails(self):
print("random name")
hacker = Hacker()
hacker.publicDetails() # random name# "'Hacker' object has no attribute '..'" -- error for below commands
hacker.name
hacker.__name
hacker.details()
hacker.__details()
Structs, Data Classes
Swift
struct Center {
let x: Float
let y: Float
}// Equatable ~= __eq__
// Hashable ~= __hash__
// CustomStringConvertible ~= __repr__
Python
from dataclasses import dataclass@dataclass
class Center:
x: float
y: float
c1 = Center(4,5)
print(c1) # Center(x=4, y=5)
Adventage of Data Classses: Auto generated _init_, _repr_, _eq_, ..
ref: https://medium.com/mindorks/understanding-python-dataclasses-part-1-c3ccd4355c34
@dataclass(frozen = True) # immutable# To control the auto generated methods
@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
same functionality using class:
class Center:
def __init__(self, x, y):
self.x = x
self.y = y def __eq__(self, other):
if (self.x == other.x and self.y == other.y):
return True
else:
return False def __repr__(self):
return 'Point(x=%s, y=%s)' % (self.x, self.y) # .. have to implement all functions manually
Closures
Basic
Swift
var addTen = { $0 + 10 }
addTen(5) # 15
Python
lambda arguments: expression
Note: Only one expression (a + 10
) is allowed with lambda functions.
addTen = lambda a: a + 10
addTen(5) # 15# or use `def` if cannot achieve in single expressiondef addTen(a):
..
..
return a + 10
Multiple inputs
Swift
var product: ((Int, Int) -> (Int)) = { a, b in
return a * b
}product(5, 10)
Python
product = lambda a, b: a * bproduct(5, 10) # 50
Lambda function
Swift
func makeNTimes(_ n: Int) -> ((Int) -> Int) {
return { a in return a * n }
}var doubler = makeNTimes(2)
doubler(10)
var tripler = makeNTimes(3)
tripler(10)
Python
def makeNTimes(n):
return lambda a: a * n
doubler = makeNTimes(2)
doubler(10) # 20tripler = makeNTimes(3)
tripler(10) # 30
Map
Swift
let numbers = [1, 2, 3, 4, 5]let result = numbers.map { $0 * 2 }
Python
map(function, iterables)
numbers = [1, 2, 3, 4, 5]multiply2 = lambda x: x * 2result = list(map(multiply2, numbers)) # orresult = list(map(lambda x: x * 2, [1, 2, 3, 4, 5]))output:
[2, 4, 6, 8, 10]
Filter
Swift
let numbers = [1, 2, 3, 4, 5, 6]let result = numbers.filter { $0 % 2 == 0 }
Python
filter(function, iterable)
numbers = [1, 2, 3, 4, 5, 6]result = list(filter(lambda x : x % 2 == 0, numbers)) # [2, 4, 6]
Reduce
Swift
let numbers = [1, 2, 3, 4, 5, 6]let res = numbers.reduce(1) { (result, value) -> Int in
return result * value
}
Python
reduce(function, iterable)
from functools import reducenumbers = [1, 2, 3, 4, 5, 6]exp = lambda x: x * 2product = reduce(exp, numbers)
# 720
Exception Handling
User-defined Exceptions
Swift
enum InputValidationError: Error {
case invalidInput(String)
}func validateAge(_ age: Int) throws {
if age < 0 {
throw InputValidationError.invalidInput("Only positive integers are allowed")
}
}
do {
try validateAge(-2)
} catch InputValidationError.invalidInput(let message) {
print("Exception: ", message)
}
Python
class InputValidationError(Exception):
def __init__(self, message):
self.message = messagedef validateAge(age):
if age < 0:
raise InputValidationError('Only positive integers are allowed')
try:
validateAge(-1)
except InputValidationError as error:
print("Exception: ", error.message)
except:
print("something is wrong")
Example
Swift
enum CommonError: Error {
case divisionByZero
}func divide(_ a: Int, by b: Int) throws -> Int {
if b == 0 {
throw CommonError.divisionByZero
}
return a / b
}
var result: Int
do {
result = try divide(10, by: 0)
} catch CommonError.divisionByZero {
print("division by zero!")
} catch {
//
}Note:
- In Swift there is no functionality to catch arbitrary runtime errors.
- no `finally` in swift, so make use of `defer`
Python
def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("result is ", result)
finally:
print(".. executing finally")
>> divide(2, 1)
output:
result is 2.0
.. executing finally>> divide(2, 0)
division by zero!
.. executing finally
Unit Tests
Example
Swift
import XCTest
@testable import AppTargetclass AppHelperTests: XCTestCase {
let calculator = Calculator()
override func setUp() {
super.setUp()
// ..
}
override func tearDown() {
// ..
super.tearDown()
}
func testAdd() {
let result = calculator.add(2, 3)
XCTAssertEqual(result, 5)
}
func testMultiply() {
let result = calculator.multiply(2, 3)
XCTAssertEqual(result, 6)
}
}
Python
calculator.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
import unittest
import calculatorclass TestCalculator(unittest.TestCase): def setUp(self):
pass
def tearDown(self):
pass
def test_add(self):
result = calculator.add(2, 3)
self.assertEqual(result, 5)
def test_multiply(self):
result = calculator.multiply(2, 3)
self.assertEqual(result, 6)
Running Tests
if __name__ == '__main__':
unittest.main()
# Console output:
..
--------------------------------------------------------------------
Ran 2 tests in 0.000sOK
pass Statement:
used when a statement is required syntactically but you do not want any command or code to execute.
List of assets: ref: https://docs.python.org/2/library/unittest.html
Corrections are welcome :). Thank You.