FP Unit 3

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 105

Functional Programming

Prepared By
Ms.Afreen Fatima
Mohammed
Ms.Deepika
Recursive Functions/
Higher-Order Functions/Dealing with Types
Unit - 3
Objectives
• Defining recursion and how it works
• Using recursion to perform advanced tasks and Mixing recursion with functions
• Understanding common recursion errors
• Defining the kinds of data manipulation
• Changing dataset size using slicing, dicing and content using mapping, filtering
• Organizing your data
• Understanding , Creating and managing types
• Fixing type errors
• Using types in code
Using Recursive Functions
• Performing Tasks More than Once
• Understanding Recursion
Performing Tasks More than Once
Defining the need for repetition
•Performing a task a set number of times
•Performing a task a variable number of times until a condition is met
•Performing a task a variable number of times until an event occurs
•Polling for input
•Creating a message pump
•Breaking a large task into smaller pieces and then executing the pieces
•Obtaining data in chunks from a source other than the application
•Automating data processing using various data structures as input
Understanding Recursion
• Considering basic recursion
• Performing tasks using lists
• Upgrading to set and dictionary
Understanding Recursion
• Haskell provides the forM function, which actually has to do with performing I/O
• Control.Monad library contains functions that implement repetition using data
structures as input
• forM processes a list containing four values, passing it to the lambda function that
follows
• The lambda function simply outputs the values using putStrLn and show a
Understanding Recursion in Haskell
• First lets see how a function can be declared in haskell
Considering basic recursion:Haskell
• The technique is the same as the Python example
• The function accepts two inputs,x (the number to append) and n (the number of
times to append it)
• When n is 0,the Haskell code returns an empty list.
• Otherwise, Haskell appends x to the list and returns the appended list.
basic recursion:Haskell
• a
basic recursion:Python
• a
Upgrading to Set and dictionary
Python Haskell

part of the initial environment must load the Data.Set library

the sets are stored as hashes. sets can’t contain any duplicates and are generally presented
as ordered
myList = [1, 4, 8, 2, 3, 3, 5, 1, 6] import Data.Set as Set
mySet = set(myList) myList = [1, 4, 8, 2, 3, 3, 5, 1, 6]
mySet mySet = Set.fromList(myList)
mySet
{1, 2, 3, 4, 5, 6, 8} fromList [1,2,3,4,5,6,8]

myDic = {"a": 1, "b": 2, "c": 3, "d": 4} let myDic = [("a", 1), ("b", 2), ("c", 3), ("d", 4)]

Python uses a form of index to access individual values, such In Haskell, you might use the lookup function: lookup "b"
as myDic["b"], which also accesses the value 2. myDic, to find that b is associated with 2
myDic = {"A":{"A": 1, "B":{"B": 2, "C":{"C": 3}}}, "D": 4}
Set in Haskell
Set in Python
Dictionary in Python
• a
Using Recursion on Lists:Working with Haskell

• The following code shows how to find the next and previous values in a list:
Using Recursion on Lists:Working with Python
Passing Functions Instead of Variables
• The following code shows the use of Haskell signatures to good effect when
creating functions that accept functions as input:
• The first function simply adds two values; the second subtracts them
• Next step is create the cmp100 function, which accepts a function as the first input
• The next part of the signature shows that the function will receive two integers as
input and provide an order as output
• Next, compare is called with 100 as the first value and the result of whatever
happens in the called function as the second inputFigure 8-9 shows the example
code in action
• Notice that the two numeric input values provide different results, depending on
which function you provide
Passing Functions in Haskell

Depending on the function you pass, the same


numbers produce different results.
Passing Functions in Python
• The one big difference is that Python doesn’t provide a compare function that
provides the same sort of output as the Haskell compare function
• In this case, a lambda function performs the comparison and provides the proper
output.

…contd
Passing Functions in Python

Python makes performing the comparison a bit harder


Common Recursion Errors
• Developers still do make some common errors when using recursion, and the
following sections give you some examples
• Forgetting an ending
• Passing data incorrectly
• Defining a correct base instruction
Forgetting an ending
• Recursive routines are harder because you can’t see the ending. All you really see is
a function that calls itself, and you know where the beginning is because it’s where
the function is called initially.
• you need to exercise caution when using recursion to ensure that the recursion will
end before the host system runs out of stack space to support the recursive
routine.
Forgetting an ending
Passing data incorrectly
• The problem isn’t with understanding the need to pass data, it’s with
understanding the need to pass the correct data
• This ability to write code for the present but work with data in the future can make
it difficult to understand precisely what to pass to the next level when the function
calls itself again.
Defining a correct base instruction
• Many recursion processes fail because the developer looks at the wrong end first.
You need to think about the conclusion of the task first, and then work on
progressively more complex parts of the data after that
Advancing with Higher-Order Functions
Objectives
• Considering Types of Data Manipulation
• Performing Slicing and Dicing
• Mapping Your Data
• Filtering Data
• Organizing Data
Considering Types of Data Manipulation
• The goal of data manipulation is to see something in the data that you
haven’t seen before
• In this meaning of the data doesn’t change; only the presentation of the data
changes.
• The method used determines the kind of transformation that occurs, and you must
perform certain kinds of transformations to make data useful
• Applying an incorrect transformation or the correct transformation in the wrong way
will result in useless output even when the data itself is correct
Types of Data Manipulation
• You can separate this kind of transformation into a number of methods that include
(but aren’t necessarily limited to) tasks such as the following:
Cleaning:
•when there is missing information
•some information is correct but outdated.
Verification: data is clean doesn’t mean that the data is correct.
• For example, a birthday may be in the right form until you determine that the person in
question is more than 200 years old number
•But after checking, you find that your organization never produced a part with that
number.
Types of Data Manipulation
Data typing:
•A significant problem with data is that the type may be incorrect or it may appear in the
wrong form
•For example, one dataset may use integers for a particular column (feature), while another
uses floating-point values for the same column
Form:
•Datasets come with many form issues.
•For example, one dataset may use a single column for people’s names, while another might
use three columns (first, middle, and last), and another might use five columns (prefix, first,
middle, last, and suffix)
Types of Data Manipulation
Range:
•Some data is categorical or uses specific ranges to denote certain conditions
•For example, probabilities range from 0 to 1. In some cases, there isn’t an agreed-upon range
Baseline:
•Without a reference value or a baseline, determining what the dB value truly means is
impossible. For audio, the dB is referenced to 1 volt (dBV)
•Now, imagine the chaos that would result if some people used 1 volt for a reference and
others used 2 volts. dBV would become meaningless as a unit of measure
•The point of this section is that the method used determines the kind of transformation that
occurs, and you must perform certain kinds of transformations to make data useful.
Performing Slicing and Dicing
• Keeping datasets controlled
• Focusing on specific data
• Slicing and dicing with Haskell
• Slicing and dicing with Python
Performing Slicing and Dicing
• Slicing and dicing are two ways to control the size of a dataset
• Slicing occurs when you use a subset of the dataset in a single axis
• Dicing occurs when you perform slicing in multiple directions
• When working with two-dimensional data, you select certain rows and certain
columns from those rows
• We must use slicing and dicing to break the data down into training and testing
units for computer technologies such as machine learning
• Training set helps an algorithm perform the correct processing in the correct way
through examplestesting set then verifies that the training went as planned
• Slicing and dicing techniques help us improve the focus of a particular analysis
Slicing and dicing with Haskell
• Slicing can be a single-step process if you have the correct code. To begin, the
following code begins with a one-dimensional list, let myList = [1, 2, 3, 4, 5]
Slicing and dicing with Haskell
• The slice created by the last statement begins by dropping the first two elements
using drop 2 myList, leaving [3,4,5]
• The $ operator connects this output to the next function call, take 1, which
produces an output of [3]
• Syntax to create a slice function: slice xs x y = take y $ drop x xs
• To test the dice function, begin with a slightly more robust list, let myList3 = [[1,2,3],
[4,5,6],[7,8,9], [10,11,12],[13,14,15]]
• now dealing with the inner values rather than the lists contained with a list, it rely
on recursion to perform the task
• The following code shows a simplified, but complete, dicing sequence
Slicing and dicing with Haskell
Dicing in Haskell
• To use forM, you must import Control.Monad
• The slice function is the same as before, but you must define it within the scope
created after the import
• The dice function uses forM to examine every element within the input list and
then slice it as required
• Here it is slicing the list within the list
• The next items of code first slice myList3 into rows, and then into columns
• The output is as you would expect: [[5],[8],[11]]
Slicing and dicing with Python
• Slicing and dicing is considerably easier in Python than in Haskell
• Slicing a two-dimensional list is every bit as easy as working with a onedimensional
list
• Here’s the code and output for the two-dimensional part of the example:
Slicing and dicing with Python
• Python perform the task using indexes instead
• Dicing does require using a special function, but the function is concise in this case
and doesn’t require multiple steps
Mapping Your Data
• Understanding the purpose of mapping
• Performing mapping tasks with Haskell
• Performing mapping tasks with Python
Understanding the purpose of mapping
• The main idea behind mapping is to apply a function to all members of a list or
similar structure
• Using mapping can help you adjust the range of the values or prepare the values for
particular kinds of analysis
Mapping tasks with Haskell
• Haskell is one of the few computer languages whose map function isn’t necessarily
what you want
• For example, the map associated with Data.Map.Strict, Data.Map.Lazy, and
Data.IntMap works with the creation and management of dictionaries, not the
application of a consistent function to all members of a list
• composition operator (., or dot) to combine complex functions
• Haskell actually applies the second function first
• Consequently, map (square.double) items produces an output of [0,4,16,36,64]
because Haskell doubles the numbers first, and then squares them
• The apply operator ($) is also important to mapping
Mapping tasks with Haskell
• we can create a condition for which we apply an argument to a list of functions
• You place the argument first in the list, followed by the function list (map ($4)
[double, square])
• List with one element for each function, which is [8,16] in this case
Performing mapping tasks with Haskell
Performing mapping tasks with Python
• Note that you must convert the map object to a list object before printing it

• Python requires a lambda function to get the job done


Performing mapping tasks with Python
• Using multiple paradigms in Python makes mapping tasks easier
Filtering Data
• Understanding the purpose of filtering
• Using Haskell to filter data
• Using Python to filter data
Purpose of filtering
• Data filtering is an essential tool in removing outliers from datasets, as well as
selecting specific data based on one or more criteria for analysis
• Slicing and dicing, mapping, and filtering are applied together to shape data in a
manner that doesn’t change the inherent relationships among data elements
Using Haskell to filter data
• Haskell relies on a filter function to remove unwanted elements from lists and other
dataset structures
• The filter function accepts two inputs: a description of what you want removed and
the list of elements to filter
The filter descriptions come in three forms:
• Special keywords, such as odd and even
• Simple logical comparisons, such as >
• Lambda functions, such as \x -> mod x 3 == 0
• carefully consider the use of Haskell operators when performing any task
Using Haskell to filter data

• rem and mod might not seem much different. Using rem 5 3 produces the same output as
mod 5 3 (an output of 2)
• difference arises when working with a negative number. In this situation, mod 3 (-5)
produces an output of -2, while rem 3 (-5) produces an output of 3
Using Python to filter data
• all the filtering in Python requires the use of lambda functions

• The lambda function you create must evaluate to True or False


• Python lacks some of the Haskell special filtering features
Organizing Data
• Considering the types of organization
• Sorting data with Haskell
• Sorting data with Python
Types of organization
• Organization — the forming of any object based on a particular pattern—is an
essential part of working with data for humans
• The following list provides some ideas on organization
Sorting:
The idea of sorting simply means placing the values in an order from greatest to
least (or vice versa) according to whatever criteria the sorter deems necessary
Grouping:
Clustering data such that the data with the highest degree of commonality is
together is another kind of sorting. For example, you might group data by
value range, with each range forming a particular group
Considering the types of organization
Categorizing:
Analyzing the data and placing data that has the same properties together
is another method of organization
Shuffling:
Data shuffling often enhances the output of algorithms and creates
conditions that enable you to see unexpected patterns
Sorting data with Haskell
• Haskell provides a wide variety of sorting mechanisms
• a list that’s a little more complex than others used in this chapter: original = [(1,
"Hello"), (4, "Yellow"), (5, "Goodbye"), (2, "Yes"), (3, "No")]
• Use the following code to perform a basic sort:

• The output is based on the first member of each tuple: [(1,"Hello"),(2,"Yes"),


(3,"No"),(4,"Yellow"),(5,"Goodbye")]
• To perform a reverse sort, the following call is used:
• include the space shown between reverse, sort, and the composition operator (.)
Sorting data with Haskell
• The problem with using this approach is that Haskell must go through the list twice:
once to sort it and once to reverse it
• An alternative is to use the sortBy function, as shown here:

• The sortBy function lets you use any comparison function needed to obtain the
desired result
• For example, If not interested in sorting by the first member of the tuple but
instead prefer to sort by the second member
• In this case, you must use the snd function from Data.Tuple (which loads with
Prelude) with the comparing function from Data.Ord
Sorting data with Haskell

• the correct operator is essential to make sorts work


• The results are as you would expect: [(5,"Goodbye"),(1,"Hello"),(3,"No"),
(4,"Yellow"),(2,"Yes")]
• to sort by the length of the words in the second member of the tuple
make the following call:
• The call applies comparing to the result of the composition of snd, followed by
length (essentially, the length of the second tuple member). The output reflects the
change in comparison: [(3,"No"),(2,"Yes"),(1,"Hello"),(4,"Yellow"), (5,"Goodbye")]
Sorting data with Haskell
• a
Sorting data with Python
• use the same list

• original = [(1, "Hello"), (4, "Yellow"), (5, "Goodbye"), (2, "Yes"), (3, "No")],
• The output is sorted by the first member of the tuple: [(1, 'Hello'), (2, 'Yes'), (3,
'No'), (4, 'Yellow'), (5, 'Goodbye')]
• Reversing a list requires the use of the reverse keyword

• Both Haskell and Python make use of lambda functions to perform special sorts
Sorting data with Python
• a
Dealing with Types
Objective
• Developing Basic Types
• Composing Types
• Parameterizing Types
• Dealing with Missing Data
• Creating and Using Type Classes
Developing Basic Types
• Understanding the functional perception of type
• Considering the type signature
• Creating types
• Using AND
• Using OR
• Defining enumerations
• Considering type constructors and data constructors
Developing Basic Types
• Functional languages provide a number of methods for defining type
• Understanding the functional perception of type in Haskell
• When you type :t True and press Enter, you see True :: Bool as output because True is an
expression that produces a Bool output
• To see this perception of type, you use the Python type function. When you type type(1),
you see <class 'int'> as output
• If you create a variable by typing myInt = 1 and pressing Enter, then use the type(myInt)
function, you still see as output.
Considering the type signature: Haskell
• The type signature in Haskell
• the expression findNext (on the left side of the double colon) expects an Int and an
[Int] (list) as input, and provides an Int as output
• A type signature encompasses everything needed to fully describe an expression
and helps relieve potential ambiguity concerning the use of the expression
• Haskell will raise an error if ambiguity exists in the use of an expression and you
don’t provide the required type signature.
Considering the type signature :Python
• Python can also use type signatures, but the philosophy behind Python is different
from that of many other languages
• Consider this function with the type signature:

• For example, doAdd(1, 2) produces an output of 3


• The call doAdd("Hello", " Goodbye") produces an output of 'Hello Goodbye‘
• When you type type((doAdd("Hello", " Goodbye"))) and press Enter, you obtain
the correct, but not expected, output of <class 'str'>
Creating types in Haskell
• Haskell takes an entirely different approach to the process that is naturally in line
with functional programming principles
• Using AND
• Haskell has this concept of adding types together to create a new kind of type
• One of the operations you can perform on these types is AND, which equates to
this type and this type as a single new type

• The left side is the type constructor, create a type constructor simply by providing a
name, which is CompNum
• The right side is the data constructor, it includes an identifier, Comp, followed by
two Int values
Creating types in Haskell
• To create and test this type, you would use the following code:

• The output, as you might expect, is x :: CompNum


Creating types in Haskell
• declaring that a data type does something is enough to create the implementation, as shown
here:

• The deriving keyword is important to remember because it makes your life much simpler. The
new data type now works as expected
• Use the deriving keyword to add features to the data type
Using OR in Haskell
• Haskell data types can create a Sum data type — a type that contains multiple
constructors that essentially define multiple associated types
• To create such a type, you separate each data constructor using a bar (|), which is
essentially an OR operator

• When working with a real number, the imaginary part is always 0


• Likewise, when working with an imaginary number, the real part is always 0
Consequently, the Real and Img definitions require only one Int as input
Using OR in Haskell

• Use the deriving keyword to add features to the data type


Defining enumerations
• The ability to enumerate values is essential as a part of categorizing
• The following code demonstrates how to create an enumeration in Haskell:
• Notice that you provide only a label for the individual constructors that are then
separated by an OR operator
• As with previous examples, we use deriving to allow the display of the particular
variable’s content
Defining enumerations

• Enumerations are made of data constructors without inputs


Defining enumerations
• Enumerations also appear using alternative text. Fortunately, Haskell addresses this
need as well
• This updated code presents the colors in a new way:

• the output of this example:


Type constructors and Data constructors
• Many data sources rely on records to package data for easy use. A record has
individual elements that you use together to describe something
• create record types in Haskell

• The Name type includes a data constructor for Employee that contains fields
named first and last of type String and middle of type Char
Type constructors and Data constructors

• Haskell supports record types using special data constructor syntax


• here construction is parameterized, input comes from the type constructor. The
difference is we can now create the record using a Char or a String for the middle name
Composing Types
• Understanding monoids
• Considering the use of Nothing, Maybe, and Just
• Understanding semigroups
Monoids
• This section begins with a Haskell list, which is a monoid
• To prove that it’s a monoid, a list has to follow three laws:
Closure: The result of an operation must always be a part of the set comprising
the group that defines the monoid
Associativity: The order in which operations on three or more objects occur
shouldn’t matter, the order of the individual elements can matter
Identity: There is always an operation that does nothing
Monoids
• Lists automatically address the first law
• working with a list of numbers will result in a numeric output, even if that output is
another list
• begin by creating the following three lists:

• the example uses concatenation (++) to create a single list from the three lists
Monoids
• The associativity law demands that the order in which an operation occurs
shouldn’t matter, but that the order of the individual elements can matter. The
following two lines test both of these criteria:

• The output of the first comparison is True because the order of the concatenation
doesn’t matter
• The output of the second comparison is False because the order of the individual
elements does matter.
Monoids
• The third law, the identity law, requires the use of an empty list, which is equivalent
to the 0 in the set of all numbers that is often used to explain identity.
Consequently, both of these statements are true:

• When performing tasks using some Haskell, you need to use import Data.Monoid
• strings also work just fine as monoids
• as monoids. Note the demonstration of identity using an empty string. In fact, many
Haskell collection types work as monoids with a variety of operators, including
Sequence, Map, Set, IntMap, and IntSet
Monoids

• Strings can act as monoids, too


• After you import Data.Monoid, you also have access to the <> operator to perform
append operations. For example, the following line of Haskell code tests the
associative law:
Monoids
• Haskell provides the Dual function, which reverses the output of an append
operation. The following statement is true because the right expression uses the
Dual function:

• To make the statement work, you must also call getDual to convert the Dual object
to a standard list
Monoids
• Python collections can also act as monoids.

The use of Nothing, Maybe, and Just
• Haskell doesn’t actually have a universal sort of null value. It does have Nothing,
but to use Nothing, the underlying type must support it
• Nothing is actually something, so it’s not actually null
• Nothing is a special kind of value that tells you that the data is missing, without
actually assigning null to the variable
• Normally we don’t assign Nothing to a variable directly. Rather, create a function or
other expression that makes the assignment
• The following example shows a simple function that simply adds two numbers.
However, the numbers must be positive integers greater than 0:
The use of Nothing, Maybe, and Just

• Notice that the type signature has Maybe Int as the output. This means that the
output could be an Int or Nothing
• need to load some support for it:
• To test this how Maybe works, you can try various versions of the function call:
The use of Nothing, Maybe, and Just

• Haskell enables you to process data in unique ways with little code
Understanding semigroups
• Semigroups are like monoids except that they have no identity requirement.
Semigroups actually represent a final level of abstraction
• An example of an object that must use a semigroup is a bounding box. A bounding
box can’t be empty; it must take up some space or it doesn’t exist and therefore the
accompanying object has no purpose
• Another example of when to use a semigroup is Data.List.NonEmpty
• which is a list that must always have at least one entry
• The point is that semigroups have a definite place in creating robust code
Parameterizing Types
• Parameterized types work best when the type acts as a sort of box that could hold
any sort of value
• example for parameterizing types is to create a custom tuple that accepts three
inputs and provides the means to access each member using a special function
• It would be sort of an extension of the fst and snd functions provided by the default
tuple
• this example starts with a real tuple, but of a special kind, Triple
• the example uses a similar, but different, naming strategy of fstT, sndT, and thdT
• Finally, cvtToTuple enables you to change a Triple back into a tuple with three
elements
Parameterizing Types

The outputs demonstrate that the type


works as expected:
• A
Dealing with Missing Data
• Handling nulls
• Performing data replacement
• Considering statistical measures
Dealing with Missing Data
• datasets often contain a lot of missing data
• wondering just how to address the issue so that your analysis is correct
• your application doesn’t crash
• no one from the outside can corrupt your setup using something like a virus
Handling nulls : Haskell
• Different languages use different terms for the absence of a value
• Python uses the term None and Haskell uses the term Nothing
• working with Haskell, you must provide a check for Nothing values, as described in
the “Considering the use of Maybe and Just”
• The goal is to ensure that the checks in place now that a good reason for unchecked
null values no longer exist
• The point is that Haskell doesn’t have an independent type that you can call upon
as Nothing
• the Nothing type is associated with each data type that requires it, which makes
locating and handling null values easier
Handling nulls :Python
• Python does include an individual null type called None, and you can assign it to a
variable
• Because None is an object, you can check for it using is
• because of the nature of None, it tends to cause fewer crashes and leave fewer
doors open to nefarious individuals
• example of using None:

• The output of this example is x is missing,


Performing data replacement
• Creating types (using the techniques found in earlier sections in the chapter) that
automatically verify their own data is a good start
• a dataset may contain unusable data entries or some entries that don’t contain
data at all
• you must perform verification of such issues as missing data and data that appears
out of range
• In most cases, you have the following three options:
• Ignore the issue
• Correct the entry
• Delete the entry and associated elements
Considering statistical measures
• A statistical measure is one that relies on math to create some sort of overall or
average entry to use in place of
• you may be able to rely on statistical measures to fix at least some problems in your
dataset a missing or incorrect entry
• Statistical measures generally see use for only numeric data
• Some statistical corrections for missing or inaccurate data see more use than others
do
Considering statistical measures
• List of commonly used statistical measures down to these:
• Average (or mean): A calculation that involves adding all the values in a column
together and dividing by the number of items in that column.
• Median: The middle value of a series of numbers. This value is not necessarily
an average but is simply a middle value.
• Most common (mode): The number that appears most often in a series, even if
the value is at either end of the scale.
Creating and Using Type Classes
• Haskell has plenty of type classes
• The most common type classes include Eq, Ord, Show, Read, Enum, Bounded, Num,
Integral, and Floating
• the best way to view a type class is as a kind of interface in which you describe
what to do but not how to do it
• The following example shows how to use a type class named Equal:
Creating and Using Type Classes
• In this case, Equal defines the ## operator
• Equal accepts two values of any type, but of the same types (as defined by a) and
outputs a Bool
• MyNum, a type, defines I as accepting a single Int value. It derives from the
common type class, Show, and then implements an instance of Equal
• Equal simply checks the equality of two variables of type MyNum
• the following code test the result
Summary
• Basics of recursion using the two target languages
• Gaining the ability to shape data in certain ways
• Refine its appearance, change its type and otherwise condition it to meet your
needs is the essential goal
• How to organize data to better see the patterns it contains
• Dealing with Types
References
• http://learnyouahaskell.com/input-and-output
• https://hackage.haskell.org/package/base-4.2.0.1/ docs/Control-Monad.html
• http://hackage.haskell.org/package/containers-0.5.11.0/docs/DataSet.html
• https://stackoverflow.com/questions/7556573/why-is-there-no-builtin-set-data-typ
e-in-haskell
• http://learnyouahaskell.com/ starting-out#im-a-list-comprehension
• http://hackage.haskell.org/ package/collections-api-1.0.0.0/docs/Data-
Collections.html and Python at https://docs.python.org/3/library/collections.html
• https://en.wikipedia.org/wiki/Data_mapping
• https://www.mathsisfun.com/numbers/complex-numbers.html
References
• https:// haskell-containers.readthedocs.io/en/latest/map.html and http://hackage.
haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict.html
• https://stackoverflow.com/questions/5891140/ difference-between-mod-and-rem-
in-Haskell
• http:// www.vision3d.com/sghidden.html
• https://fractalfoundation.org/resources/what-is-chaos-theory/
• https://www.w3schools.com/js/ js_strict.asp
• http:// mypy-lang.org/
• http://wiki.c2.com/?DuckTyping and https://en.wikipedia.org/wiki/ Duck_typing
• https://docs.python.org/3/ tutorial/classes.html and
https://www.learnpython.org/en/Classes_and_ Objects

You might also like