# 2022-2023 Deeltoets 1 ## Opgaven De opgaven kun je vinden op: [https://bitbucket.org/HR_ELEKTRO/ems10/wiki/Toetsen/2022-2023_Deeltoets_1.pdf](https://bitbucket.org/HR_ELEKTRO/ems10/wiki/Toetsen/2022-2023_Deeltoets_1.pdf) ## Uitwerkingen ### Toetsvraag 1a ```python import math def bereken_shannoncapaciteit(B, S, N): C = B*math.log(1+S/N)/math.log(2) return int(C) ``` De lokale variabele `C` is niet echt nodig: ```python import math def bereken_shannoncapaciteit(B, S, N): return int(B*math.log(1+S/N)/math.log(2)) ``` ### Toetsvraag 1b Een stap-voor-stap oplossing: ```python bandbreedte = float(input('Geef de bandbreedte in Hz: ')) vermogen_signaal = float(input('Geef het gemiddeld vermogen van het signaal in W: ')) vermogen_ruis = float(input('Geef het gemiddeld vermogen van de ruis in W: ')) C = bereken_shannoncapaciteit(bandbreedte, vermogen_signaal, vermogen_ruis) print('De shannoncapaciteit is:', C , 'bit/s') ``` Een compacte oplossing: ```python print('De shannoncapaciteit is:', bereken_shannoncapaciteit(float(input('Geef de bandbreedte in Hz: ')), float(input('Geef het gemiddeld vermogen van het signaal in W: ')), float(input('Geef het gemiddeld vermogen van de ruis in W: '))) , 'bit/s') ``` ### Toetsvraag 1c Met een `for`-loop: ```python def shannoncapaciteit_met_bandbreedte(bb): for sn in range(100, 1000, 100): print('bandbreedte:', bb, 'Hz, S/N:', sn, 'shannoncapaciteit:', bereken_shannoncapaciteit(bb, sn, 1)) ``` Met een `while`-loop: ```python def shannoncapaciteit_met_bandbreedte(bb): sn = 100 while sn < 1000: print('bandbreedte:', bb, 'Hz, S/N:', sn, 'shannoncapaciteit:', bereken_shannoncapaciteit(bb, sn, 1)) sn = sn + 100 ``` ### Toetsvraag 2 Een te eenvoudige, **niet correcte**, oplossing: ```python def verwijder_eh_en_ehm(lijst): lijst.remove('eh') lijst.remove('ehm') ``` In het bovenstaande programma wordt gebruik gemaakt van de `remove` method van `list`. Dit wordt uitgelegd in paragraaf 10.6 van het [boek](https://greenteapress.com/thinkpython2/thinkpython2.pdf#page=116). Helaas werkt dit niet correct omdat dit alleen de eerste 'eh' en 'ehm' verwijdert. Een voor de hand liggende oplossing voor dit probleem die helaas **niet correct** is: ```python def verwijder_eh_en_ehm(lijst): for woord in lijst: if woord == 'eh' or woord == 'ehm': lijst.remove(woord) return lijst ``` Deze oplossing faalt als er twee opeenvolgende woorden 'eh' en/of 'ehm' zijn. De `for`-loop slaat na de `remove` een woord over. De volgende testcode: ```python zin = 'eh eh ik heb hier ehm eh geen actieve eh herinneringen aan' woordenlijst = zin.split() ondertiteling = verwijder_eh_en_ehm(woordenlijst) print(' '.join(ondertiteling)) ``` Geeft de **onjuiste** uitvoer: ``` ik heb hier eh geen actieve eh herinneringen aan ``` Dit probleem kan op verschillende manieren opgelost worden. In plaats van elementen te verwijderen uit de lijst, kan een nieuwe lijst worden gemaakt met alleen de gewenste elementen: ```python def verwijder_eh_en_ehm(lijst): nieuwelijst = [] for woord in lijst: if woord != 'eh' and woord != 'ehm': nieuwelijst.append(woord) return nieuwelijst ``` De voorwaarde van het `if`-statement kan ook anders geformuleerd worden: ```python def verwijder_eh_en_ehm(lijst): nieuwelijst = [] for woord in lijst: if woord not in ['eh', 'ehm']: nieuwelijst.append(woord) return nieuwelijst ``` Er kan ook gebruik worden gemaakt van twee `while`-loops: ```python def verwijder_eh_en_ehm(lijst): while 'eh' in lijst: lijst.remove('eh') while 'ehm' in lijst: lijst.remove('ehm') return lijst ``` Je kunt dit **niet** vereenvoudigen tot: ```python def verwijder_eh_en_ehm(lijst): while 'eh' in lijst or 'ehm' in lijst: lijst.remove('eh') lijst.remove('ehm') return lijst ``` Omdat `remove` een **error** geeft als het te verwijderen element niet aanwezig is Het probleem kun je oplossen door extra `if`-statements toe te voegen: ```python def verwijder_eh_en_ehm(lijst): while 'eh' in lijst or 'ehm' in lijst: if 'eh' in lijst: lijst.remove('eh') if 'ehm'in lijst: lijst.remove('ehm') return lijst ``` Je kunt ook een `while True`-loop gebruiken en die verlaten met een `return`-statement als er geen 'eh' en 'ehm' meer in de lijst zit: ```python def verwijder_eh_en_ehm(lijst): while True: if 'eh' in lijst: lijst.remove('eh') elif 'ehm'in lijst: lijst.remove('ehm') else: return lijst ``` In plaats van `while`-loops kun je ook `for`-loops gebruiken: ```python def verwijder_eh_en_ehm(lijst): for _ in range(lijst.count('eh')): lijst.remove('eh') for _ in range(lijst.count('ehm')): lijst.remove('ehm') return lijst ``` Een recursieve oplossing: ```python def verwijder_eh_en_ehm(lijst): if 'eh' in lijst: lijst.remove('eh') return verwijder_eh_en_ehm(lijst) if 'ehm' in lijst: lijst.remove('ehm') return verwijder_eh_en_ehm(lijst) return lijst ``` Een compacte oplossing: ```python def verwijder_eh_en_ehm(lijst): return [woord for woord in lijst if woord != 'eh' and woord != 'ehm'] ``` In het bovenstaande programma wordt gebruik gemaakt van *list comprehension*. Dit is niet behandeld in de les, maar wordt uitgelegd in paragraaf 19.2 van het [boek](https://greenteapress.com/thinkpython2/thinkpython2.pdf#page=206). Testcode: ```python zin = 'eh ik heb hier ehm geen actieve eh herinneringen aan' woordenlijst = zin.split() ondertiteling = verwijder_eh_en_ehm(woordenlijst) print(' '.join(ondertiteling)) ```