Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
lfa:2022:lab01-programming-intro [2022/10/05 10:14]
mihai.udubasa created
lfa:2022:lab01-programming-intro [2022/10/14 13:13] (current)
mihai.udubasa add solutions
Line 1: Line 1:
-====== 1. Introduction ​to Python ​======+====== Programming introduction ====== 
 + 
 +===== 1. Scala introduction ===== 
 + 
 +**Exercise 1.1.** Write a function ​ ''​startStop''​ which retrieves the elements of a list from within bounds. Use patterns in your implementation. Define an object ''​Main''​ as shown below. 
 +Any code within the object can be directly executed. (Hint: use a simply-recursive function)/​ 
 + 
 +<code scala> 
 +object Main extends App { 
 +def startStop[A] (l: List[A] ,start: Int, stop: Int): List[A] = ??? 
 + 
 +println(startStop(List(1,​2,​3,​4,​5,​6),​1,​4)) 
 + // = List(2,3,4)  
 +
 +</​code>​  
 + 
 +**Exercise 1.2.** Write a function which determines the number of occurrences of each character in a string. (Hint: use a tail-recursive function) 
 +<code scala> 
 +def countChars (s:String): Map[Char,​Int] = { 
 +    def aux(l: List[Char], acc: Map[Char,​Int]):​ Map[Char,​Int] = ??? 
 +    ??? 
 +  } 
 +</​code>​ 
 + 
 +**Exercise 1.3** Write a function which takes a list of records first name, last name, CNP (encoded as tuples), and returns a list of the last names and ages of all females which are younger than the average of the entire list. E.g. ''​List( (“Mary”,​ “2030694123456”),​ (“Anne”,​“2121092123456”),​ (“Matei”,​ “5121202123456”),​ (“Maggie”,​ “2121078123456”) )''​ yields ''​List( (“Mary”,​28),​ (“Anne”,​30) )''​. Maggie was born in '78, whereas Mary, Anne and Matei were born in '94, '92 and 2002, respectively. (Hint: use combinations of **map** with **filter**) 
 + 
 +<code scala> 
 +val example = List(("​Mary", ​ "​2030694123456"​),​ ("​Anne", ​ "​2121092123456"​),​ ("​Matei",​ "​5121202123456"​),​ ("​Maggie",​ "​2121078123456"​)) 
 + 
 +def youngerThanAverage(l:​ List[(String,​String)]):​ List[(String,​Int)] = { 
 +    def getAge(s:​String):​Int = ???  
 +    // female gender = True 
 +    def getGender(s:​String):​Boolean = ??? 
 +    ??? 
 +  } 
 +</​code>​ 
 + 
 +**Exercise 1.4**  
 +A labelled graph is encoded as a String text where **each line** is an edge ''<​from>​ <​label>​ <to>''​ 
 +Example: 
 +<​code>​ 
 +0 r 1 
 +0 r 2 
 +0 g 1 
 +1 g 2  
 +1 b 3 
 +1 r 4 
 +4 g 1 
 +3 b 2 
 +2 r 2 
 +2 g 3 
 +</​code>​ 
 + 
 +  * Suppose we encode streets as labelled graphs, where each label '​r',​ '​g'​ or '​b'​ denotes a street color. These colors can be any alphabetical character, not necessarily just rgb.  
 +  * Given a **start node** and a **sequence of colors**, find all the destination nodes that can be accessed by traversing streets in that particular color. 
 +    * Example: Starting from 0, on the sequence ''​rrg'',​ the destination node are ''​1''​ (0 red to 1 red to 4 green to 1) and ''​3''​ (0 red to 2, red to 2, red to 3) 
 +  * Hint: use **foldLeft** as well as **for expressions**. 
 + 
 +<code scala> 
 +val example ​"""​0 r 1 
 +                  |0 r 2 
 +                  |0 g 1 
 +                  |1 g 2 
 +                  |1 b 3 
 +                  |1 r 4 
 +                  |4 g 1 
 +                  |3 b 2 
 +                  |2 r 2 
 +                  |2 g 3"""​.stripMargin 
 +            
 +type Streets = Map[(Int,​Char),​Set[Int]] 
 +def readStreets(s:​ String): Streets = ??? 
 + 
 +def findDestination(start:​ Int, colors: String, streets: Streets): Set[Int] = ??? 
 +</​code>​ 
 + 
 + 
 + 
 +===== 2. Python introduction ​=====
  
 Python3 is a multi-paradigm language, that combines the **imperative** style with the **functional** style. It also supports Object-Oriented programming,​ albeit in a limited way.  Python3 is a multi-paradigm language, that combines the **imperative** style with the **functional** style. It also supports Object-Oriented programming,​ albeit in a limited way. 
Line 12: Line 90:
 ==== List traversal ==== ==== List traversal ====
  
-**Exercise ​1.1.** Write a function ''​f(l)''​ which determines the maximum of a list ''​l''​ of integers.+**Exercise ​2.1.** Write a function ''​f(l)''​ which determines the maximum of a list ''​l''​ of integers.
  
 <hidden The pythonic way> ​ <hidden The pythonic way> ​
Line 23: Line 101:
 </​hidden>​ </​hidden>​
  
-**Exercise ​1.2.** Modify the previous function to ''​f(l,​start,​stop)''​ and determine the maximum between positions ''​start''​ and ''​stop''​.+**Exercise ​2.2.** Modify the previous function to ''​f(l,​start,​stop)''​ and determine the maximum between positions ''​start''​ and ''​stop''​.
  
 <hidden The pythonic way> ​ <hidden The pythonic way> ​
Line 35: Line 113:
 ==== Slicing lists ==== ==== Slicing lists ====
  
-**Exercise ​1.3.** Find the **longest** sequence of positive integers from a list. E.g. for the list ''​[1,​3,​-1,​2,​0,​1,​5,​4,​-2,​4,​5,​-3,​0,​1,​2]''​ the answer is ''​[2,​0,​1,​5,​4]''​.+**Exercise ​2.3.** Find the **longest** sequence of positive integers from a list. E.g. for the list ''​[1,​3,​-1,​2,​0,​1,​5,​4,​-2,​4,​5,​-3,​0,​1,​2]''​ the answer is ''​[2,​0,​1,​5,​4]''​.
  
 <hidden The pythonic way> ​ <hidden The pythonic way> ​
Line 53: Line 131:
 </​hidden>​ </​hidden>​
  
-**Exercise ​1.4.** Write a pythonic function to check if a list is palindrome.+**Exercise ​2.4.** Write a pythonic function to check if a list is palindrome.
  
 ===== Other datatypes ===== ===== Other datatypes =====
Line 69: Line 147:
 </​code>  ​ </​code>  ​
  
-**Exercise ​1.5.** Write a function which determines (and returns) the **longest** sequence of consecutive integers from a list.+**Exercise ​2.5.** Write a function which determines (and returns) the **longest** sequence of consecutive integers from a list.
  
 ==== Dictionaries ==== ==== Dictionaries ====
Line 290: Line 368:
 <​code>​ <​code>​
 5 5
-+r 1 
-2  +0 r 2 
-+0 g 
-+2  
-+
-2+
 +
 +2 
 +2 r 2 
 +2 g 3
 </​code>​ </​code>​
  
-  * Suppose we encode streets as labelled graphs, where each label 'X' or 'O' denotes ​if a street ​is closed or open.  +  * Suppose we encode streets as labelled graphs, where each label 'r', 'g' or 'b' denotes a street ​color. These colors can be any alphabetical character, not necessarily just rgb.  
-  * Compute the set of accessible nodes from given **source**, via open streets.+  * Given a **start node** and a **sequence of colors**, find all the destination nodes that can be accessed by traversing ​streets ​in that particular color. 
 +    * Example: Starting from 0, on the sequence ''​rrg'',​ the destination node are ''​1''​ (0 red to 1 red to 4 green to 1) and ''​3''​ (0 red to 2, red to 2, red to 3)
   * (Hint1: google //Python read lines// to see how to read from a file; also, google ''​split''​ in Python)   * (Hint1: google //Python read lines// to see how to read from a file; also, google ''​split''​ in Python)
   * (Hint2: you will need a dictionary to store, for each node and label l, the list of its l-successors)   * (Hint2: you will need a dictionary to store, for each node and label l, the list of its l-successors)
  
  
-===== Haskell practice ===== 
  
-Solve the same exerciseonly build your own input as a stringinstead ​of a file.+===== Python typing annotations ===== 
 + 
 +Newer versions of python support type annotations and pre-runtime type checking (supported by some code editors). 
 +The typing module allows programmers to provide hints regarding ​the types of different objectsthe signature (parameters and return value types) of functions and methods, and create generic classes. 
 + 
 +To create such hints the syntax is as follows: 
 + 
 +  * for variables: ''<​var_name>:​ <​type>​ [= expr]'':​ 
 +<code python>​ 
 +x: int 
 +y: int = 5 
 +z: str = 'hello world'​ 
 +t: MyCustomType 
 +</​code>​ 
 +  * for functions/​methods:​ ''​def <​func_name>​([<​param>:​ <​type>,​ ...]) -> <​return_type>'':​ 
 +<code python>​ 
 +def hello() -> str: 
 +    ... 
 +def get_item_at(index:​ int) -> Any: 
 +    ... 
 +class MyCustomType():​ 
 +    def method(self,​ param1: Any, param2: int) -> str 
 +        ... 
 +</​code>​ 
 +  * for generic classes: extend either a generic class (such as list[_], set[_] or tuple[_]) or extend the Generic class (introduced by the typing module): 
 +<code python>​ 
 +from typing import TypeVar, Generic 
 + 
 +StateType = TypeVar("​StateType"​) # !!! important: type variables must be declared and initialised before they are used 
 +class DFA(Generic[StateType]):​ 
 +    def next_state(self,​ from_state: StateType, token: str) -> StateType:​ 
 +        ... 
 +    ... 
 +     
 +dfa: DFA[int] = DFA[int](...) 
 +     
 +A = TypeVar("​A"​) 
 +B = TypeVar("​B"​) 
 +     
 +class TupleLinkedList(Generic[A,​B]):​ 
 +    value: tuple[A,​B] 
 +    next: '​TupleLinkedList[A,​B]'​ | None # !!! important: in most python versions, if you need to use the 
 +                                        #                type of the class within its own definition, you 
 +                                        #                need to quote its name (this delays the evaluation 
 +                                        #                of the hint until after the class is fully defined) 
 +    ... 
 +     
 +class IntList(list[int]):​ 
 +    ... 
 +</​code>​  
 + 
 +Useful type hints: 
 +  * ''​int,​ str, bool, float etc.''​ : the basic datatypes (charaters are hinted ​as strings, as python does not make the distinction) 
 +  * ''​list[type],​ set[type], frozenset[type],​ dict[key_type,​ val_type]'':​ basic data collections (items introduced in ''​set''​s and ''​frozenset''​s and the keys of dictionaries need to be hashable: see the [[lfa:​dictionaries|appendix for python hashing]]) 
 +  * ''​Any'': ​type is compatible with any other type (if no type hint is specifiedthis is what type checkers usually default to) 
 +  * ''​Callable[ [<​param_types>​...],​ <​return_type>​]'':​ this defines a function with a given signature 
 +  * ''<​type1>​ | <​type2>'':​ the ''​|''​ operator allows us to indicate that a given object can be one of two(or more) types 
 +  * ''​None'':​ represents the lack of a value (or an explicit None value); useful to mark functions which have no return value, or that a value may be purposefully missing (in combination with the ''​|''​ operator), and a None check may be necessary 
 +full documentation of the python typing module: [[https://​docs.python.org/​3/​library/​typing.html]] 
 + 
 + 
 + 
 +===== Solutions ===== 
 +<note important>​ 
 +[[https://​github.com/​NethDR/​LFA-LAB1-solutions|click here for spoilers/​solutions]] 
 +</​note>​