Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
Oystein Kristoffer Tveit | 744d91aa49 | |
Oystein Kristoffer Tveit | 1bd7fa4e0e | |
Oystein Kristoffer Tveit | 23adf99347 | |
Oystein Kristoffer Tveit | d630115cce | |
Oystein Kristoffer Tveit | 4335edea97 | |
Oystein Kristoffer Tveit | 1c10a0fd83 | |
Oystein Kristoffer Tveit | e1125351f7 | |
Oystein Kristoffer Tveit | 1c6bb26ee3 | |
Oystein Kristoffer Tveit | 15fed3634d | |
Oystein Kristoffer Tveit | a2ea83fcbb | |
Oystein Kristoffer Tveit | 0c07bfaf9d | |
Oystein Kristoffer Tveit | 72478e8199 | |
Oystein Kristoffer Tveit | d9c5d7d400 |
|
@ -1,3 +1,4 @@
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
.vim
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
# The default ``config.py``
|
|
||||||
# flake8: noqa
|
|
||||||
|
|
||||||
|
|
||||||
def set_prefs(prefs):
|
|
||||||
"""This function is called before opening the project"""
|
|
||||||
|
|
||||||
# Specify which files and folders to ignore in the project.
|
|
||||||
# Changes to ignored resources are not added to the history and
|
|
||||||
# VCSs. Also they are not returned in `Project.get_files()`.
|
|
||||||
# Note that ``?`` and ``*`` match all characters but slashes.
|
|
||||||
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
|
|
||||||
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
|
|
||||||
# '.svn': matches 'pkg/.svn' and all of its children
|
|
||||||
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
|
|
||||||
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
|
|
||||||
prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
|
|
||||||
'.hg', '.svn', '_svn', '.git', '.tox']
|
|
||||||
|
|
||||||
# Specifies which files should be considered python files. It is
|
|
||||||
# useful when you have scripts inside your project. Only files
|
|
||||||
# ending with ``.py`` are considered to be python files by
|
|
||||||
# default.
|
|
||||||
# prefs['python_files'] = ['*.py']
|
|
||||||
|
|
||||||
# Custom source folders: By default rope searches the project
|
|
||||||
# for finding source folders (folders that should be searched
|
|
||||||
# for finding modules). You can add paths to that list. Note
|
|
||||||
# that rope guesses project source folders correctly most of the
|
|
||||||
# time; use this if you have any problems.
|
|
||||||
# The folders should be relative to project root and use '/' for
|
|
||||||
# separating folders regardless of the platform rope is running on.
|
|
||||||
# 'src/my_source_folder' for instance.
|
|
||||||
# prefs.add('source_folders', 'src')
|
|
||||||
|
|
||||||
# You can extend python path for looking up modules
|
|
||||||
# prefs.add('python_path', '~/python/')
|
|
||||||
|
|
||||||
# Should rope save object information or not.
|
|
||||||
prefs['save_objectdb'] = True
|
|
||||||
prefs['compress_objectdb'] = False
|
|
||||||
|
|
||||||
# If `True`, rope analyzes each module when it is being saved.
|
|
||||||
prefs['automatic_soa'] = True
|
|
||||||
# The depth of calls to follow in static object analysis
|
|
||||||
prefs['soa_followed_calls'] = 0
|
|
||||||
|
|
||||||
# If `False` when running modules or unit tests "dynamic object
|
|
||||||
# analysis" is turned off. This makes them much faster.
|
|
||||||
prefs['perform_doa'] = True
|
|
||||||
|
|
||||||
# Rope can check the validity of its object DB when running.
|
|
||||||
prefs['validate_objectdb'] = True
|
|
||||||
|
|
||||||
# How many undos to hold?
|
|
||||||
prefs['max_history_items'] = 32
|
|
||||||
|
|
||||||
# Shows whether to save history across sessions.
|
|
||||||
prefs['save_history'] = True
|
|
||||||
prefs['compress_history'] = False
|
|
||||||
|
|
||||||
# Set the number spaces used for indenting. According to
|
|
||||||
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
|
|
||||||
# unit-tests use 4 spaces it is more reliable, too.
|
|
||||||
prefs['indent_size'] = 4
|
|
||||||
|
|
||||||
# Builtin and c-extension modules that are allowed to be imported
|
|
||||||
# and inspected by rope.
|
|
||||||
prefs['extension_modules'] = []
|
|
||||||
|
|
||||||
# Add all standard c-extensions to extension_modules list.
|
|
||||||
prefs['import_dynload_stdmods'] = True
|
|
||||||
|
|
||||||
# If `True` modules with syntax errors are considered to be empty.
|
|
||||||
# The default value is `False`; When `False` syntax errors raise
|
|
||||||
# `rope.base.exceptions.ModuleSyntaxError` exception.
|
|
||||||
prefs['ignore_syntax_errors'] = False
|
|
||||||
|
|
||||||
# If `True`, rope ignores unresolvable imports. Otherwise, they
|
|
||||||
# appear in the importing namespace.
|
|
||||||
prefs['ignore_bad_imports'] = False
|
|
||||||
|
|
||||||
# If `True`, rope will insert new module imports as
|
|
||||||
# `from <package> import <module>` by default.
|
|
||||||
prefs['prefer_module_from_imports'] = False
|
|
||||||
|
|
||||||
# If `True`, rope will transform a comma list of imports into
|
|
||||||
# multiple separate import statements when organizing
|
|
||||||
# imports.
|
|
||||||
prefs['split_imports'] = False
|
|
||||||
|
|
||||||
# If `True`, rope will remove all top-level import statements and
|
|
||||||
# reinsert them at the top of the module when making changes.
|
|
||||||
prefs['pull_imports_to_top'] = True
|
|
||||||
|
|
||||||
# If `True`, rope will sort imports alphabetically by module name instead
|
|
||||||
# of alphabetically by import statement, with from imports after normal
|
|
||||||
# imports.
|
|
||||||
prefs['sort_imports_alphabetically'] = False
|
|
||||||
|
|
||||||
# Location of implementation of
|
|
||||||
# rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
|
|
||||||
# case, you don't have to change this value, unless you're an rope expert.
|
|
||||||
# Change this value to inject you own implementations of interfaces
|
|
||||||
# listed in module rope.base.oi.type_hinting.providers.interfaces
|
|
||||||
# For example, you can add you own providers for Django Models, or disable
|
|
||||||
# the search type-hinting in a class hierarchy, etc.
|
|
||||||
prefs['type_hinting_factory'] = (
|
|
||||||
'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
|
|
||||||
|
|
||||||
|
|
||||||
def project_opened(project):
|
|
||||||
"""This function is called after opening the project"""
|
|
||||||
# Do whatever you like here!
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
def inputTypeCheck(message, type, errorMessage):
|
||||||
|
while True:
|
||||||
|
inputValue = input(message)
|
||||||
|
try:
|
||||||
|
return type(inputValue)
|
||||||
|
except ValueError:
|
||||||
|
print(errorMessage)
|
|
@ -0,0 +1,31 @@
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
class recipe:
|
||||||
|
def __init__(self, ingredients, standardPortions):
|
||||||
|
self.ingredients = ingredients
|
||||||
|
self.standardPortions = standardPortions
|
||||||
|
|
||||||
|
def getIngredients(self, portions):
|
||||||
|
ratio = portions / self.standardPortions
|
||||||
|
for ingredient in self.ingredients:
|
||||||
|
print(f'{ingredient}: {self.ingredients[ingredient]*ratio}')
|
||||||
|
|
||||||
|
cookies = recipe(
|
||||||
|
ingredients={
|
||||||
|
'sukker(g)': 400,
|
||||||
|
'smør(g)': 320,
|
||||||
|
'sjokolade(g)': 500,
|
||||||
|
'egg': 2,
|
||||||
|
'hvetemel(g)': 460
|
||||||
|
},
|
||||||
|
standardPortions=48,
|
||||||
|
)
|
||||||
|
|
||||||
|
cookieNumber = inputTypeCheck(
|
||||||
|
message = 'Hvor mange cookies ønsker du å bake? ',
|
||||||
|
type = float,
|
||||||
|
errorMessage = 'Beklager, det du skrev inn er ikke et tall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
print('Antall cookies:', cookieNumber)
|
||||||
|
cookies.getIngredients(cookieNumber)
|
|
@ -0,0 +1,79 @@
|
||||||
|
from typing import List, Dict, Union
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
COLUMN_PADDING = 10
|
||||||
|
|
||||||
|
class recipe:
|
||||||
|
def __init__(self, ingredients, standardPortions):
|
||||||
|
self.ingredients = ingredients
|
||||||
|
self.standardPortions = standardPortions
|
||||||
|
|
||||||
|
def toMap(self, portions):
|
||||||
|
ratio = portions / self.standardPortions
|
||||||
|
result = {'Antall cookies': portions}
|
||||||
|
for ingredient in self.ingredients:
|
||||||
|
result[ingredient] = self.ingredients[ingredient]*ratio
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
cookies = recipe(
|
||||||
|
ingredients={
|
||||||
|
'sukker(g)': 400,
|
||||||
|
'smør(g)': 320,
|
||||||
|
'sjokolade(g)': 500,
|
||||||
|
'egg': 2,
|
||||||
|
'hvetemel(g)': 460
|
||||||
|
},
|
||||||
|
standardPortions=48,
|
||||||
|
)
|
||||||
|
|
||||||
|
columnsToPrint = ['Antall cookies', 'sukker(g)', 'sjokolade(g)']
|
||||||
|
questionList = [
|
||||||
|
'Hvor mange cookies vil du lage? ',
|
||||||
|
'Hvor mange cookies vil du lage nå? ',
|
||||||
|
'Hvor mange cookies vil du lage til slutt? '
|
||||||
|
]
|
||||||
|
|
||||||
|
ask = lambda question: inputTypeCheck(
|
||||||
|
message=question,
|
||||||
|
type=float,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et tall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
cookieAmounts = list(map(ask, questionList))
|
||||||
|
cookieObjects = list(map(lambda cNum: cookies.toMap(cNum), cookieAmounts))
|
||||||
|
|
||||||
|
def createColumns(columnsToPrint) -> Dict[str, List[Union[str, int]]]:
|
||||||
|
rawColumnData = {}
|
||||||
|
for column in columnsToPrint:
|
||||||
|
rawColumnData[column] = [column]
|
||||||
|
recipeRows = list(map(lambda cookie: cookie[column], cookieObjects))
|
||||||
|
rawColumnData[column].extend(recipeRows)
|
||||||
|
return rawColumnData
|
||||||
|
|
||||||
|
rawColumns = createColumns(columnsToPrint)
|
||||||
|
|
||||||
|
def getColumnLength(column, padding) -> int:
|
||||||
|
lengths = list(map(lambda element: len(str(element)), column))
|
||||||
|
return max(lengths) + padding
|
||||||
|
|
||||||
|
def formatRows(column) -> List[str]:
|
||||||
|
columnLength = getColumnLength(column, COLUMN_PADDING)
|
||||||
|
formattedColumn = []
|
||||||
|
for entry in column:
|
||||||
|
formattedColumn.append(str(entry).ljust(columnLength))
|
||||||
|
return formattedColumn
|
||||||
|
|
||||||
|
def formatColumns(unFormattedColumns, columnsToPrint) -> Dict[str, List[str]]:
|
||||||
|
formattedColumns = {}
|
||||||
|
for column in columnsToPrint:
|
||||||
|
formattedColumns[column] = formatRows(unFormattedColumns[column])
|
||||||
|
return formattedColumns
|
||||||
|
|
||||||
|
formattedColumns = formatColumns(rawColumns, columnsToPrint)
|
||||||
|
|
||||||
|
for row in range(0, len(formattedColumns['Antall cookies'])):
|
||||||
|
thisRow=[]
|
||||||
|
for column in formattedColumns:
|
||||||
|
thisRow.append(formattedColumns[column][row])
|
||||||
|
print(''.join(thisRow))
|
|
@ -0,0 +1,7 @@
|
||||||
|
def inputTypeCheck(message, type, errorMessage):
|
||||||
|
while True:
|
||||||
|
inputValue = input(message)
|
||||||
|
try:
|
||||||
|
return type(inputValue)
|
||||||
|
except ValueError:
|
||||||
|
print(errorMessage)
|
|
@ -0,0 +1,28 @@
|
||||||
|
import math
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
# Bump the decimal point up by numberOfDecimal points,
|
||||||
|
# add 0.5 to make floor go from 0-1 to 0.5-1.5,
|
||||||
|
# then add back the decimal points.
|
||||||
|
def myRoundFunction(number, numberOfDecimals):
|
||||||
|
decimalFactor = 10 ** numberOfDecimals
|
||||||
|
return math.floor(number * decimalFactor + 0.5) / decimalFactor
|
||||||
|
|
||||||
|
def removeEmptyDecimals(number):
|
||||||
|
hasEmptyDecimals = (number == int(number))
|
||||||
|
return int(number) if hasEmptyDecimals else number
|
||||||
|
|
||||||
|
number = inputTypeCheck(
|
||||||
|
message='Gi inn et desimaltall: ',
|
||||||
|
type=float,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et nummer. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
numberOfDecimals = inputTypeCheck(
|
||||||
|
message='Antall desimaler i avrunding: ',
|
||||||
|
type=int,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et heltall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
roundedNumber = removeEmptyDecimals(myRoundFunction(number,numberOfDecimals))
|
||||||
|
print(f'Avrundet til {numberOfDecimals} desimal: {roundedNumber}')
|
|
@ -0,0 +1,58 @@
|
||||||
|
import math
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
def removeEmptyDecimals(number):
|
||||||
|
hasEmptyDecimals = (number == int(number))
|
||||||
|
return int(number) if hasEmptyDecimals else number
|
||||||
|
|
||||||
|
def myRoundFunction(integerPart,decimalPart,amountOfDecimals):
|
||||||
|
decimalOffset = len(str(integerPart))
|
||||||
|
roundOffset = decimalOffset + amountOfDecimals
|
||||||
|
numberString = f'{integerPart}{decimalPart}'
|
||||||
|
|
||||||
|
lastDigit = int(numberString[roundOffset-1])
|
||||||
|
firstEvalDigit = int(numberString[roundOffset])
|
||||||
|
|
||||||
|
addPointAtOffset = lambda num,off: float(str(num)[:off] + '.' + str(num)[off:])
|
||||||
|
|
||||||
|
if (firstEvalDigit < 5):
|
||||||
|
return addPointAtOffset(numberString[:roundOffset], decimalOffset)
|
||||||
|
|
||||||
|
elif (firstEvalDigit == 5):
|
||||||
|
try:
|
||||||
|
hasDigitsBehind5 = (int(numberString[roundOffset+1:]) > 0)
|
||||||
|
except ValueError:
|
||||||
|
hasDigitsBehind5 = False
|
||||||
|
|
||||||
|
# This is the special case where round() rounds 2.5 down to 2.
|
||||||
|
# It is only valid when there's no digits behind the eval digit
|
||||||
|
# and when the base digit is even.
|
||||||
|
specialCase = ((not hasDigitsBehind5) and (lastDigit % 2 == 0))
|
||||||
|
roundedNumber = int(numberString[:roundOffset]) + 1 - specialCase
|
||||||
|
|
||||||
|
return addPointAtOffset(roundedNumber, decimalOffset)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return addPointAtOffset(int(numberString[:roundOffset]) + 1, decimalOffset)
|
||||||
|
|
||||||
|
integerPart = inputTypeCheck(
|
||||||
|
message='Oppgi heltallsdelen av tallet (det foran punktum): ',
|
||||||
|
type=int,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et heltall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
decimalPart = inputTypeCheck(
|
||||||
|
message='Oppgi desimaldelen av tallet (det bak punktum): ',
|
||||||
|
type=int,
|
||||||
|
errorMessage='Beklager, dette er ikke et tall, eller inneholder et desimalpunkt. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
amountOfDecimals = inputTypeCheck(
|
||||||
|
message='Oppgi ønsket antall desimaler i avrunding: ',
|
||||||
|
type=int,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et heltall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
roundedNumber = removeEmptyDecimals(myRoundFunction(integerPart, decimalPart, amountOfDecimals))
|
||||||
|
|
||||||
|
print(f'{integerPart}.{decimalPart} avrundet til {amountOfDecimals} desimaler blir {roundedNumber}')
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Known bug:
|
||||||
|
# The program will not accept a name consisting of a single name and a single surname
|
||||||
|
# when the surname only consists of the capital letters IVXLCDM and it will wrongly accept
|
||||||
|
# a surname consisting of those letters as Roman numerals. In order to fix, some more
|
||||||
|
# complex regex logic is needed.
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
capitalize = lambda name: name.capitalize()
|
||||||
|
|
||||||
|
PREPOSITION_LIST = ['von', 'van', 'de', 'di']
|
||||||
|
PREPOSITION_LIST.extend(list(map(capitalize, PREPOSITION_LIST)))
|
||||||
|
SUFFIX_PATTERN = '[sj]r\.?'
|
||||||
|
ROMAN_NUMERAL_PATTERN = '[IVXLCDM]+\.?'
|
||||||
|
|
||||||
|
hasSuffix = lambda word: re.match(SUFFIX_PATTERN, word, re.IGNORECASE) is not None
|
||||||
|
hasRomanNumerals = lambda word: re.match(ROMAN_NUMERAL_PATTERN, word) is not None
|
||||||
|
|
||||||
|
def getName():
|
||||||
|
while True:
|
||||||
|
name = input('Jeg heter: ')
|
||||||
|
if (' ' in name):
|
||||||
|
names = name.split(' ')
|
||||||
|
if not (len(names) == 2 and (hasSuffix(names[-1]) or hasRomanNumerals(names[-1]))):
|
||||||
|
return names
|
||||||
|
print('Putt et mellomrom mellom fornavn og etternavn')
|
||||||
|
|
||||||
|
names = list(map(capitalize, getName()))
|
||||||
|
firstNames = names[:-1]
|
||||||
|
lastNames=[names[-1]]
|
||||||
|
|
||||||
|
moveLastFirstNameToLastNames = lambda: lastNames.insert(0, firstNames.pop())
|
||||||
|
|
||||||
|
|
||||||
|
if hasSuffix or hasRomanNumerals:
|
||||||
|
moveLastFirstNameToLastNames()
|
||||||
|
|
||||||
|
hasPreposition = firstNames[-1] in PREPOSITION_LIST and len(firstNames) != 1
|
||||||
|
|
||||||
|
if hasPreposition:
|
||||||
|
moveLastFirstNameToLastNames()
|
||||||
|
|
||||||
|
lastNamesString = ' '.join(lastNames)
|
||||||
|
firstNamesString = ' '.join(firstNames)
|
||||||
|
|
||||||
|
print(f'The name is {lastNamesString}, {firstNamesString} {lastNamesString}')
|
|
@ -1,2 +0,0 @@
|
||||||
main :: IO ()
|
|
||||||
main = putStrLn "Hello world"
|
|
|
@ -1,10 +0,0 @@
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
putStrLn $ show $ 1 + 2 * (3+4) + 4/2 - 1
|
|
||||||
|
|
||||||
let minutter = 355 :: Int
|
|
||||||
|
|
||||||
let timer = minutter `div` 60
|
|
||||||
let minutterIgjen = minutter `mod` 60
|
|
||||||
|
|
||||||
putStrLn $ show $ show minutter ++ " minutter blir " ++ show timer ++ " timer og " ++ show minutterIgjen ++ " minutter"
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
def inputTypeCheck(message, type, errorMessage):
|
||||||
|
while True:
|
||||||
|
inputValue = input(message)
|
||||||
|
try:
|
||||||
|
return type(inputValue)
|
||||||
|
except ValueError:
|
||||||
|
print(errorMessage)
|
|
@ -0,0 +1,18 @@
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
AVOGADROS_CONSTANT = 6.022e23
|
||||||
|
|
||||||
|
substance = input('Si et stoff du er i besittelse av: ')
|
||||||
|
weight = inputTypeCheck(
|
||||||
|
message='Hva er molvekt i gram for vann? ',
|
||||||
|
type=float,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et tall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
amount = inputTypeCheck(
|
||||||
|
message='Hvor mange gram vann har du? ',
|
||||||
|
type=float,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et tall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
numberOfMolecules = (amount * AVOGADROS_CONSTANT / weight)
|
||||||
|
print(f'Du har {format(numberOfMolecules, ".1e")} molekyler {substance.lower()}')
|
|
@ -0,0 +1,13 @@
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
AMOUNT_OF_POSSIBLE_MELODIES = 8.25e19
|
||||||
|
|
||||||
|
melodiesHeard = inputTypeCheck(
|
||||||
|
message = 'Antall ulike 10-toners melodilinjer du har hørt? ',
|
||||||
|
type = int,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et heltall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
percentMelodiesHeard = melodiesHeard / AMOUNT_OF_POSSIBLE_MELODIES * 100
|
||||||
|
|
||||||
|
print(f'Du har hørt {percentMelodiesHeard} prosent av melodier som er mulig.')
|
|
@ -1,14 +0,0 @@
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
input <- promptLine "Skriv inn h: "
|
|
||||||
let h = read input :: Double
|
|
||||||
putStrLn $ show $ tetraederVolum h
|
|
||||||
|
|
||||||
promptLine :: String -> IO String
|
|
||||||
promptLine prompt = do
|
|
||||||
putStr prompt
|
|
||||||
getLine
|
|
||||||
|
|
||||||
tetraederVolum :: Double -> Double
|
|
||||||
tetraederVolum h = sqrt 2 * a / 12
|
|
||||||
where a = 3 / sqrt 6 * h
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Exercise 1
|
||||||
|
|
||||||
|
## About `common.py`
|
||||||
|
I've copied the function inputTypeCheck() into a common.py for each directory. Normally, I would've made it a module, but to avoid system specific bugs, I've decided not edit global environment variables like PYTHONPATH or edit the sys.path. This means, at least as far as I know, that I can't use relative imports.
|
|
@ -0,0 +1,7 @@
|
||||||
|
def inputTypeCheck(message, type, errorMessage):
|
||||||
|
while True:
|
||||||
|
inputValue = input(message)
|
||||||
|
try:
|
||||||
|
return type(inputValue)
|
||||||
|
except ValueError:
|
||||||
|
print(errorMessage)
|
|
@ -0,0 +1,25 @@
|
||||||
|
from math import sqrt
|
||||||
|
from common import inputTypeCheck
|
||||||
|
|
||||||
|
class Tetraeder:
|
||||||
|
def __init__(self, length):
|
||||||
|
self.length = length
|
||||||
|
self.a = 3/sqrt(6) * length
|
||||||
|
|
||||||
|
getArea = lambda self: sqrt(3) * (self.a**2)
|
||||||
|
getVolume = lambda self: sqrt(2) * (self.a**3) / 12
|
||||||
|
|
||||||
|
figure1 = Tetraeder(3)
|
||||||
|
print(f'Et tetraeder med høyde {figure1.length} har areal {figure1.getArea()}')
|
||||||
|
print(f'Et tetraeder med høyde {figure1.length} har volum {figure1.getVolume()}')
|
||||||
|
print()
|
||||||
|
|
||||||
|
figure2 = Tetraeder(
|
||||||
|
inputTypeCheck(
|
||||||
|
message='Skriv inn en høyde: ',
|
||||||
|
type=float,
|
||||||
|
errorMessage='Beklager, det du skrev inn er ikke et tall. Prøv igjen\n'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f'Et tetraeder med høyde {figure2.length} har volum {figure2.getVolume()} og areal {figure2.getArea()}')
|
|
@ -0,0 +1,17 @@
|
||||||
|
from math import floor
|
||||||
|
|
||||||
|
recursive_sum = lambda n: 1 if n == 1 else n + recursive_sum(n - 1)
|
||||||
|
|
||||||
|
merge_sum = lambda lst: lst[0] if len(lst) == 1 else merge_sum(lst[0:floor(len(
|
||||||
|
lst) / 2)]) + merge_sum(lst[floor(len(lst) / 2):len(lst)])
|
||||||
|
|
||||||
|
|
||||||
|
def find_smallest_element(lst):
|
||||||
|
if len(lst) == 1: return lst[0]
|
||||||
|
smallest_element = find_smallest_element(lst[1:])
|
||||||
|
return lst[0] if lst[0] < smallest_element else smallest_element
|
||||||
|
|
||||||
|
|
||||||
|
def binary_search(numbers, element):
|
||||||
|
|
||||||
|
return -float('inf')
|
|
@ -0,0 +1,7 @@
|
||||||
|
from math import sin
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
x_verdier = [x/10 for x in range(301)]
|
||||||
|
y_verdier = [sin(x) for x in x_verdier]
|
||||||
|
plt.plot(x_verdier, y_verdier, c='r')
|
||||||
|
plt.show()
|
|
@ -0,0 +1,309 @@
|
||||||
|
from typing import Callable, Iterable, Union
|
||||||
|
from os import system
|
||||||
|
from shutil import get_terminal_size as getTerminalSize
|
||||||
|
|
||||||
|
from piece import Piece
|
||||||
|
|
||||||
|
|
||||||
|
def centerText(text):
|
||||||
|
terminalWidth = getTerminalSize((60, 0))[0] # Column size 60 as fallback
|
||||||
|
return "\n".join(line.center(terminalWidth) for line in text.split('\n'))
|
||||||
|
|
||||||
|
|
||||||
|
def centerBlockText(text):
|
||||||
|
terminalWidth = getTerminalSize((60, 0))[0] # Column size 60 as fallback
|
||||||
|
textArray = text.split('\n')
|
||||||
|
offset = int((terminalWidth - len(textArray[0])) / 2)
|
||||||
|
return "\n".join(offset * ' ' + line for line in textArray)
|
||||||
|
|
||||||
|
|
||||||
|
def determineMove(key, x, y, maxmin) -> tuple:
|
||||||
|
if key in ['s', 'j'] and y != maxmin[1]: return (0, 1)
|
||||||
|
elif key in ['w', 'k'] and y != maxmin[0]: return (0, -1)
|
||||||
|
elif key in ['d', 'l'] and x != maxmin[1]: return (1, 0)
|
||||||
|
elif key in ['a', 'h'] and x != maxmin[0]: return (-1, 0)
|
||||||
|
else: return False
|
||||||
|
|
||||||
|
|
||||||
|
class Board:
|
||||||
|
|
||||||
|
def __init__(self, boardState=None):
|
||||||
|
"""Create a standard board if nothing else is defined in boardState"""
|
||||||
|
self.boardArray = [
|
||||||
|
[Piece(type, 'black') for type in ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']],
|
||||||
|
[Piece('p', 'black') for _ in range(8)],
|
||||||
|
*[[None for _ in range(8)] for _ in range(4)],
|
||||||
|
[Piece('p', 'white') for _ in range(8)],
|
||||||
|
[Piece(type, 'white') for type in ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']],
|
||||||
|
] if boardState == None else boardState
|
||||||
|
|
||||||
|
def draw(self, config={}) -> str:
|
||||||
|
"""Returns a string representing the board
|
||||||
|
|
||||||
|
config options:
|
||||||
|
highlightedContent: [(x,y)] - Pieces to color
|
||||||
|
highlightEscapeCodes: (str, str) - Terminal escape codes to color highlightedContent with
|
||||||
|
highlightedBoxes: [(x,y)] - Boxes to make bold
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Fill default values in config dict
|
||||||
|
def fillConfigDefaultValue(key, defaultValue):
|
||||||
|
if key not in config:
|
||||||
|
config[key] = defaultValue
|
||||||
|
|
||||||
|
fillConfigDefaultValue('highlightedContent', [])
|
||||||
|
fillConfigDefaultValue('highlightedBoxes', [])
|
||||||
|
fillConfigDefaultValue('highlightEscapeCodes', ('\033[32;5;7m', '\033[0m'))
|
||||||
|
|
||||||
|
# Draw general outline with ┼ as all corners
|
||||||
|
stringArray = [list('┼' + '───┼' * 8)] + [[None] for _ in range(8 * 2)]
|
||||||
|
for y, row in enumerate(self.boardArray):
|
||||||
|
for x, _ in enumerate(row):
|
||||||
|
stringArray[2 * y + 1][4 * x] = '│'
|
||||||
|
stringArray[2 * y + 2][4 * x] = '┼'
|
||||||
|
|
||||||
|
symbol = str(self.boardArray[y][x]) if self.boardArray[y][x] != None else ' '
|
||||||
|
stringArray[2 * y + 1] += list(' {} │'.format(symbol))
|
||||||
|
stringArray[2 * y + 2] += list('───┼')
|
||||||
|
|
||||||
|
# Overwrite corners
|
||||||
|
stringArray[0][0] = '╭'
|
||||||
|
stringArray[0][-1] = '╮'
|
||||||
|
stringArray[-1][0] = '╰'
|
||||||
|
stringArray[-1][-1] = '╯'
|
||||||
|
|
||||||
|
# Overwrite T-junctions
|
||||||
|
for i in range(int(len(stringArray[0]) / 4) - 1): # Loop row
|
||||||
|
stringArray[0][i * 4 + 4] = '┬'
|
||||||
|
stringArray[-1][i * 4 + 4] = '┴'
|
||||||
|
for i in range(int(len(stringArray) / 2) - 1): # Loop column
|
||||||
|
stringArray[i * 2 + 2][0] = '├'
|
||||||
|
stringArray[i * 2 + 2][-1] = '┤'
|
||||||
|
|
||||||
|
def highlightContent(x, y, modifiers=config['highlightEscapeCodes']):
|
||||||
|
"""highlight inner part of a box with xterm-256colors modifiers"""
|
||||||
|
stringArray[y * 2 + 1][x * 4 + 1] = \
|
||||||
|
modifiers[0] + stringArray[y * 2 + 1][x * 4 + 1]
|
||||||
|
stringArray[y * 2 + 1][x * 4 + 3] += modifiers[1]
|
||||||
|
|
||||||
|
def highlightBox(x, y):
|
||||||
|
"""Make box around a position bold"""
|
||||||
|
|
||||||
|
boldBoxChars = {
|
||||||
|
'─': '═',
|
||||||
|
'│': '║',
|
||||||
|
'┼': '╬',
|
||||||
|
'╰': '╚',
|
||||||
|
'╯': '╝',
|
||||||
|
'╭': '╔',
|
||||||
|
'╮': '╗',
|
||||||
|
'├': '╠',
|
||||||
|
'┴': '╩',
|
||||||
|
'┤': '╣',
|
||||||
|
'┬': '╦',
|
||||||
|
}
|
||||||
|
|
||||||
|
pointsToChange = \
|
||||||
|
[(x * 4 + 0, y * 2 + i) for i in range(3)] + \
|
||||||
|
[(x * 4 + 4, y * 2 + i) for i in range(3)] + \
|
||||||
|
[(x * 4 + i, y * 2 + 0) for i in range(1,4)] + \
|
||||||
|
[(x * 4 + i, y * 2 + 2) for i in range(1,4)]
|
||||||
|
|
||||||
|
# This has to doublecheck that the character exists, because if neighbour
|
||||||
|
# boxes are to be highlighed, it will try to overwrite already bold borders
|
||||||
|
for x, y in pointsToChange:
|
||||||
|
symbolExists = stringArray[y][x] in boldBoxChars
|
||||||
|
stringArray[y][x] = boldBoxChars[stringArray[y][x]] if symbolExists else stringArray[y][x]
|
||||||
|
|
||||||
|
# Color white pieces
|
||||||
|
for piece in self.getPositionsWhere(lambda piece: piece.color == 'white'):
|
||||||
|
highlightContent(*piece, ('\033[7m', '\033[0m'))
|
||||||
|
|
||||||
|
for box in config['highlightedBoxes']:
|
||||||
|
highlightBox(*box)
|
||||||
|
|
||||||
|
for piece in config['highlightedContent']:
|
||||||
|
highlightContent(*piece)
|
||||||
|
|
||||||
|
return '\n'.join([''.join(line) for line in stringArray])
|
||||||
|
|
||||||
|
def selectPiece(self, player, x=0, y=0, centering=True) -> tuple:
|
||||||
|
"""Lets the user select a piece"""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
system('clear')
|
||||||
|
playerString = '\n' + player.name + '\n'
|
||||||
|
checkString = f"\033[41m{'CHECK' if self.checkCheck(player.color) else ''}\033[0m" + '\n'
|
||||||
|
|
||||||
|
hoveringPiece = self.getPieceAt(x, y)
|
||||||
|
pieceIsOwnColor = hoveringPiece != None and hoveringPiece.color == player.color
|
||||||
|
|
||||||
|
menuString = self.draw({
|
||||||
|
'highlightedBoxes': [(x, y)],
|
||||||
|
'highlightedContent': Piece.possibleMoves(x, y, self) if pieceIsOwnColor else []
|
||||||
|
}) + '\n'
|
||||||
|
inputString = f" W E\nA S D <- Enter : "
|
||||||
|
|
||||||
|
if centering:
|
||||||
|
playerString = centerText(playerString)
|
||||||
|
checkString = centerText(checkString)
|
||||||
|
menuString = centerBlockText(menuString)
|
||||||
|
inputString = centerBlockText(inputString)
|
||||||
|
|
||||||
|
print(playerString)
|
||||||
|
print(checkString)
|
||||||
|
print(menuString)
|
||||||
|
|
||||||
|
try:
|
||||||
|
key = input(inputString)[0]
|
||||||
|
except IndexError: # Input was empty
|
||||||
|
key = ''
|
||||||
|
|
||||||
|
try:
|
||||||
|
if move := determineMove(key, x, y, (0, 7)):
|
||||||
|
x += move[0]
|
||||||
|
y += move[1]
|
||||||
|
elif key == 'e' \
|
||||||
|
and hoveringPiece.color == player.color \
|
||||||
|
and Piece.possibleMoves(x, y, self) != []:
|
||||||
|
return (x, y)
|
||||||
|
except AttributeError: # Chosen tile contains no piece
|
||||||
|
pass
|
||||||
|
|
||||||
|
def selectMove(self, player, x, y, legalMoves, centering=True) -> Union[tuple, bool]:
|
||||||
|
"""Lets the user select a move to make from a graphic board"""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
system('clear')
|
||||||
|
playerString = '\n' + player.name + '\n'
|
||||||
|
checkString = f"\033[41m{'CHECK' if self.checkCheck(player.color) else ''}\033[0m" + '\n'
|
||||||
|
menuString = self.draw({
|
||||||
|
'highlightedBoxes': [(x, y)],
|
||||||
|
'highlightedContent': legalMoves
|
||||||
|
}) + '\n'
|
||||||
|
inputString = f"Q W E\nA S D <- Enter : "
|
||||||
|
|
||||||
|
if centering:
|
||||||
|
playerString = centerText(playerString)
|
||||||
|
checkString = centerText(checkString) #TODO: Doesn't center because of escape chars
|
||||||
|
menuString = centerBlockText(menuString)
|
||||||
|
inputString = centerBlockText(inputString)
|
||||||
|
|
||||||
|
print(playerString)
|
||||||
|
print(checkString)
|
||||||
|
print(menuString)
|
||||||
|
|
||||||
|
try:
|
||||||
|
key = input(inputString)[0]
|
||||||
|
except IndexError: # Input was empty
|
||||||
|
key = ''
|
||||||
|
|
||||||
|
if move := determineMove(key, x, y, (0, 7)):
|
||||||
|
x += move[0]
|
||||||
|
y += move[1]
|
||||||
|
elif key == 'q':
|
||||||
|
return False
|
||||||
|
elif key == 'e' and (x, y) in legalMoves:
|
||||||
|
return (x, y)
|
||||||
|
|
||||||
|
def getPieceAt(self, x, y) -> Union[Piece, None]:
|
||||||
|
"""Gets a piece at a certain position"""
|
||||||
|
try:
|
||||||
|
return self.boardArray[y][x]
|
||||||
|
except IndexError: # Outside board
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getPositionsWhere(self, condition: Callable[[Piece], bool]) -> Iterable[tuple]:
|
||||||
|
"""Returns a list of xy pairs of the pieces where a condition is met """
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for y, row in enumerate(self.boardArray):
|
||||||
|
for x, piece in enumerate(row):
|
||||||
|
try:
|
||||||
|
if condition(piece):
|
||||||
|
result.append((x, y))
|
||||||
|
except AttributeError: # Position is None
|
||||||
|
pass
|
||||||
|
return result
|
||||||
|
|
||||||
|
def checkCheck(self, color, simulation=False) -> bool:
|
||||||
|
"""Check whether a team is caught in check. The color is the color of the team to check"""
|
||||||
|
king = self.getPositionsWhere(lambda piece: piece.type == 'k' and piece.color == color)[0]
|
||||||
|
piecesToCheck = self.getPositionsWhere(lambda piece: piece.color != color)
|
||||||
|
# Resend simulation status into possibleMoves in order to avoid indefinite recursion
|
||||||
|
return any(
|
||||||
|
king in Piece.possibleMoves(*piece, self, simulation=simulation) for piece in piecesToCheck)
|
||||||
|
|
||||||
|
def getPositionsToProtectKing(self, color) -> Iterable[tuple]:
|
||||||
|
"""Get a list of the positions to protect in order to protect the king when in check. The color is the color of the team who's in check"""
|
||||||
|
king = self.getPositionsWhere(lambda piece: piece.type == 'k' and piece.color == color)[0]
|
||||||
|
piecesToCheck = self.getPositionsWhere(lambda piece: piece.color != color)
|
||||||
|
|
||||||
|
# Get all pieces that threaten the king
|
||||||
|
piecesToCheck = [piece for piece in piecesToCheck if king in Piece.possibleMoves(*piece, self)]
|
||||||
|
|
||||||
|
# Add only self if piece is pawn, knight or king
|
||||||
|
result = []
|
||||||
|
for piece in piecesToCheck:
|
||||||
|
result.append([piece])
|
||||||
|
if self.getPieceAt(*piece).type not in ['p', 'n', 'k']:
|
||||||
|
|
||||||
|
def getDirection(fromPosition, toPosition) -> tuple:
|
||||||
|
"""Get the direction as a tuple from the threatening piece to the king"""
|
||||||
|
x = -1 if toPosition[0] > fromPosition[0] else \
|
||||||
|
0 if toPosition[0] == fromPosition[0] else 1
|
||||||
|
y = -1 if toPosition[1] > fromPosition[1] else \
|
||||||
|
0 if toPosition[1] == fromPosition[1] else 1
|
||||||
|
return (x, y)
|
||||||
|
|
||||||
|
def getPositionsUntilKing(x, y, direction) -> Iterable[tuple]:
|
||||||
|
"""Return a list of every position until the king"""
|
||||||
|
result = []
|
||||||
|
x += direction[0]
|
||||||
|
y += direction[1]
|
||||||
|
while self.getPieceAt(x, y) == None:
|
||||||
|
result.append((x, y))
|
||||||
|
x += direction[0]
|
||||||
|
y += direction[1]
|
||||||
|
return result
|
||||||
|
|
||||||
|
direction = getDirection(piece, king)
|
||||||
|
result[-1] += getPositionsUntilKing(*king, direction)
|
||||||
|
|
||||||
|
def getCommonValues(lst: Iterable[Iterable[tuple]]):
|
||||||
|
"""Combine lists so that only tuples in all the lists of threatening pieces are valid"""
|
||||||
|
result = set(lst[0])
|
||||||
|
for sublst in lst[1:]:
|
||||||
|
result.intersection_update(sublst)
|
||||||
|
return result
|
||||||
|
|
||||||
|
return getCommonValues(result)
|
||||||
|
|
||||||
|
def playerHasLegalMoves(self, color) -> bool:
|
||||||
|
""" returns whether or not a player has any legal moves left"""
|
||||||
|
enemyPieces = self.getPositionsWhere(lambda piece: piece.color == color)
|
||||||
|
if self.checkCheck(color):
|
||||||
|
getLegalMoves = lambda piece: Piece.possibleMoves(
|
||||||
|
*piece, self, legalMoves=self.getPositionsToProtectKing(color))
|
||||||
|
else:
|
||||||
|
getLegalMoves = lambda piece: Piece.possibleMoves(*piece, self)
|
||||||
|
|
||||||
|
return any(getLegalMoves(piece) != [] for piece in enemyPieces)
|
||||||
|
|
||||||
|
def checkStaleMate(self, color) -> bool:
|
||||||
|
"""Check whether a team is caught in stalemate. The color is the color of the team to check"""
|
||||||
|
return (not self.checkCheck(color)) and not self.playerHasLegalMoves(color)
|
||||||
|
|
||||||
|
def checkCheckMate(self, color) -> bool:
|
||||||
|
"""Check whether a team is caught in checkmate. The color is the color of the team to check"""
|
||||||
|
return self.checkCheck(color) and not self.playerHasLegalMoves(color)
|
||||||
|
|
||||||
|
def movePiece(self, position, toPosition, piecesToRemove=[]):
|
||||||
|
""" Move a piece from position to toPosition. In case of extra pieces to be removes, add them to the list piecesToRemove"""
|
||||||
|
x, y = position
|
||||||
|
toX, toY = toPosition
|
||||||
|
self.boardArray[toY][toX] = self.boardArray[y][x]
|
||||||
|
self.boardArray[y][x] = None
|
||||||
|
|
||||||
|
for x, y in piecesToRemove:
|
||||||
|
self.boardArray[y][x] = None
|
|
@ -0,0 +1,96 @@
|
||||||
|
#!/bin/python3
|
||||||
|
|
||||||
|
from os import system
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from board import Board
|
||||||
|
from piece import Piece
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Player:
|
||||||
|
name: str
|
||||||
|
color: str
|
||||||
|
|
||||||
|
|
||||||
|
class Chess:
|
||||||
|
|
||||||
|
def __init__(self, players):
|
||||||
|
self.players = players
|
||||||
|
self.board = Board()
|
||||||
|
|
||||||
|
def win(self, player):
|
||||||
|
if player.color == 'white':
|
||||||
|
print('''
|
||||||
|
░█░█░█░█░▀█▀░▀█▀░█▀▀░░░█░█░▀█▀░█▀█
|
||||||
|
░█▄█░█▀█░░█░░░█░░█▀▀░░░█▄█░░█░░█░█
|
||||||
|
░▀░▀░▀░▀░▀▀▀░░▀░░▀▀▀░░░▀░▀░▀▀▀░▀░▀
|
||||||
|
''')
|
||||||
|
else:
|
||||||
|
print('''
|
||||||
|
░█▀▄░█░░░█▀█░█▀▀░█░█░░░█░█░▀█▀░█▀█
|
||||||
|
░█▀▄░█░░░█▀█░█░░░█▀▄░░░█▄█░░█░░█░█
|
||||||
|
░▀▀░░▀▀▀░▀░▀░▀▀▀░▀░▀░░░▀░▀░▀▀▀░▀░▀
|
||||||
|
''')
|
||||||
|
input('Press any button to exit...')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def tie(self):
|
||||||
|
print('''
|
||||||
|
░█▀▀░▀█▀░█▀█░█░░░█▀▀░█▄█░█▀█░▀█▀░█▀▀
|
||||||
|
░▀▀█░░█░░█▀█░█░░░█▀▀░█░█░█▀█░░█░░█▀▀
|
||||||
|
░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀
|
||||||
|
''')
|
||||||
|
input('Press any button to exit...')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def promoteIfPossible(self, player, position):
|
||||||
|
promoteY = 0 if player.color == 'white' else 7
|
||||||
|
if (piece := self.board.getPieceAt(*position)).type == 'p' and position[1] == promoteY:
|
||||||
|
while True:
|
||||||
|
answer = input('What would you like your pawn to become? (q,b,r or n) ')
|
||||||
|
if answer in 'qbrn' and len(answer) == 1:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print('\nCouldn\'t parse input. Try again')
|
||||||
|
|
||||||
|
piece.type = answer
|
||||||
|
|
||||||
|
|
||||||
|
def makeMove(self, player):
|
||||||
|
# Get the first piece belonging to the player
|
||||||
|
currentPlayersPiece = lambda piece: piece.color == player.color
|
||||||
|
chosenTile = self.board.getPositionsWhere(currentPlayersPiece)[0]
|
||||||
|
while True:
|
||||||
|
piece = self.board.selectPiece(player, *chosenTile)
|
||||||
|
chosenTile = piece
|
||||||
|
possibleMoves = Piece.possibleMoves(*piece, self.board)
|
||||||
|
if move := self.board.selectMove(player, *piece, possibleMoves):
|
||||||
|
break
|
||||||
|
self.board.movePiece(piece, move)
|
||||||
|
self.promoteIfPossible(player, move)
|
||||||
|
|
||||||
|
def turn(self, playerNum):
|
||||||
|
system('clear')
|
||||||
|
self.makeMove(players[playerNum])
|
||||||
|
# 1 - 1 = 0 and 1 - 0 = 1
|
||||||
|
if self.board.checkCheckMate(players[1 - playerNum].color):
|
||||||
|
self.win(players[playerNum])
|
||||||
|
elif self.board.checkStaleMate(players[1 - playerNum].color):
|
||||||
|
self.tie()
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while True:
|
||||||
|
self.turn(0)
|
||||||
|
self.turn(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
players = (
|
||||||
|
Player('Spiller 1', 'white'),
|
||||||
|
Player('Spiller 2', 'black'),
|
||||||
|
)
|
||||||
|
|
||||||
|
game = Chess(('Spiller 1', 'Spiller 2'))
|
||||||
|
game.loop()
|
|
@ -0,0 +1,140 @@
|
||||||
|
from typing import Iterable, Callable
|
||||||
|
from itertools import product
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
|
class Piece:
|
||||||
|
|
||||||
|
def __init__(self, type, color):
|
||||||
|
self.type = type
|
||||||
|
self.color = color
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.type.upper() if self.color == 'white' else self.type
|
||||||
|
|
||||||
|
# Unused code. I'm missing the font for my terminal, but go ahead and use piece.symbol instead of str(symbol) in board.draw if you'd like
|
||||||
|
@property
|
||||||
|
def symbol(self):
|
||||||
|
symbols = [{
|
||||||
|
'p': '♙',
|
||||||
|
'r': '♖',
|
||||||
|
'n': '♘',
|
||||||
|
'b': '♗',
|
||||||
|
'q': '♕',
|
||||||
|
'k': '♔',
|
||||||
|
}, {
|
||||||
|
'p': '♟︎',
|
||||||
|
'r': '♜',
|
||||||
|
'n': '♞',
|
||||||
|
'b': '♝',
|
||||||
|
'q': '♛',
|
||||||
|
'k': '♚',
|
||||||
|
}]
|
||||||
|
return symbols[0 if self.color == 'white' else 1][self.type]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def possibleMoves(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
board,
|
||||||
|
legalMoves=None,
|
||||||
|
simulation=False,
|
||||||
|
) -> Callable[[int, int], Iterable[tuple]]:
|
||||||
|
"""
|
||||||
|
Calculate all possible moves for a piece at (x, y) given a board in a certain state.
|
||||||
|
|
||||||
|
If there is restrictions for where the piece can go, the legal moves can be set to these.
|
||||||
|
If the function is part of a simulation, simulation needs to be set to True so that it doesn't keep on recursing simulation indefinetely.
|
||||||
|
"""
|
||||||
|
|
||||||
|
piece = board.getPieceAt(x, y)
|
||||||
|
moves = []
|
||||||
|
|
||||||
|
pieceIsEnemyColor = lambda pieceToCheck: pieceToCheck != None and pieceToCheck.color != piece.color
|
||||||
|
pieceIsEmpty = lambda pieceToCheck: pieceToCheck == None
|
||||||
|
pieceIsEmptyOrEnemyColor = lambda pieceToCheck: pieceToCheck == None or pieceToCheck.color != piece.color
|
||||||
|
positionInsideBounds = lambda x, y: x in range(8) and y in range(8)
|
||||||
|
|
||||||
|
def addMoveIfTrue(xOffset, yOffset, condition: Callable[[Piece], bool]) -> bool:
|
||||||
|
"""Tests a condition against a position away from self. Adds move if condition returns true. Returns condition result"""
|
||||||
|
if condition(board.getPieceAt(x + xOffset, y + yOffset)):
|
||||||
|
moves.append((x + xOffset, y + yOffset))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def assertNotCheck(newX, newY) -> bool:
|
||||||
|
"""Simulate a move and return whether or not the move will result in check"""
|
||||||
|
testBoard = deepcopy(board)
|
||||||
|
testBoard.movePiece((x, y), (newX, newY))
|
||||||
|
return not testBoard.checkCheck(piece.color, simulation=True)
|
||||||
|
|
||||||
|
def addWhileInsideBoard(direction: tuple):
|
||||||
|
"""Adds moves in direction until it either hits a piece or the edge"""
|
||||||
|
localX, localY = x, y
|
||||||
|
while positionInsideBounds(localX, localY):
|
||||||
|
localX += direction[0]
|
||||||
|
localY += direction[1]
|
||||||
|
currentPiece = board.getPieceAt(localX, localY)
|
||||||
|
if pieceIsEmpty(currentPiece):
|
||||||
|
moves.append((localX, localY))
|
||||||
|
else:
|
||||||
|
if pieceIsEnemyColor(currentPiece):
|
||||||
|
moves.append((localX, localY))
|
||||||
|
return
|
||||||
|
|
||||||
|
if piece.type == 'p':
|
||||||
|
localY = 1 if piece.color == 'black' else -1
|
||||||
|
startPosition = 1 if piece.color == 'black' else 6
|
||||||
|
pieceAtStartPosition = lambda pieceToCheck: pieceToCheck == None and y == startPosition
|
||||||
|
|
||||||
|
addMoveIfTrue(1, localY, pieceIsEnemyColor)
|
||||||
|
addMoveIfTrue(-1, localY, pieceIsEnemyColor)
|
||||||
|
if addMoveIfTrue(0, localY, pieceIsEmpty):
|
||||||
|
addMoveIfTrue(0, localY * 2, pieceAtStartPosition)
|
||||||
|
|
||||||
|
elif piece.type == 'n':
|
||||||
|
positions = [
|
||||||
|
(-2, -1),
|
||||||
|
(-2, 1),
|
||||||
|
(-1, -2),
|
||||||
|
(-1, 2),
|
||||||
|
(1, -2),
|
||||||
|
(1, 2),
|
||||||
|
(2, -1),
|
||||||
|
(2, 1),
|
||||||
|
]
|
||||||
|
for position in positions:
|
||||||
|
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
|
||||||
|
|
||||||
|
elif piece.type == 'k':
|
||||||
|
positions = list(product([-1, 0, 1], repeat=2))
|
||||||
|
positions.remove((0, 0))
|
||||||
|
for position in positions:
|
||||||
|
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
|
||||||
|
|
||||||
|
elif piece.type == 'r':
|
||||||
|
for direction in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
|
||||||
|
addWhileInsideBoard(direction)
|
||||||
|
|
||||||
|
elif piece.type == 'b':
|
||||||
|
for direction in product([-1, 1], repeat=2):
|
||||||
|
addWhileInsideBoard(direction)
|
||||||
|
|
||||||
|
elif piece.type == 'q':
|
||||||
|
directions = list(product([-1, 0, 1], repeat=2))
|
||||||
|
directions.remove((0, 0))
|
||||||
|
for direction in directions:
|
||||||
|
addWhileInsideBoard(direction)
|
||||||
|
|
||||||
|
# Remove moves that will lead the piece out of the board
|
||||||
|
moves = [move for move in moves if positionInsideBounds(*move)]
|
||||||
|
|
||||||
|
# Remove moves that is not included in the legal moves (moves to block check)
|
||||||
|
if legalMoves != None and piece.type != 'k':
|
||||||
|
moves = [move for move in moves if move in legalMoves]
|
||||||
|
|
||||||
|
# Remove moves that will put the king in check
|
||||||
|
if not simulation:
|
||||||
|
moves = [position for position in moves if assertNotCheck(*position)]
|
||||||
|
|
||||||
|
return moves
|
|
@ -0,0 +1,18 @@
|
||||||
|
print("Dette er et program for å teste din sjenerøsitet.")
|
||||||
|
har_epler = int(input("Hvor mange epler har du? "))
|
||||||
|
if har_epler == 0:
|
||||||
|
print("Æsj, det sier du bare for å slippe å gi noe!")
|
||||||
|
else:
|
||||||
|
gir_epler = int(input("Hvor mange kan du gi til meg? "))
|
||||||
|
if gir_epler < har_epler / 2:
|
||||||
|
print("Du beholder det meste for deg selv...")
|
||||||
|
else:
|
||||||
|
print("Takk, det var snilt!")
|
||||||
|
print("Du har nå", har_epler - gir_epler, "epler igjen.")
|
||||||
|
|
||||||
|
# Logg:
|
||||||
|
# Reindent everything to 2 spaces
|
||||||
|
# line 3: changed = to == for boolean expression
|
||||||
|
# line 5: added a colon after else
|
||||||
|
# line 8: indent print statement
|
||||||
|
# line 9: unindent else
|
|
@ -0,0 +1,14 @@
|
||||||
|
def remainingApplesString(applesLeft):
|
||||||
|
return "Du har nå " + str(applesLeft) + (" epler" if applesLeft != 1 else " eple") +" igjen."
|
||||||
|
|
||||||
|
print("Dette er et program for å teste din sjenerøsitet.")
|
||||||
|
har_epler = int(input("Hvor mange epler har du? "))
|
||||||
|
if har_epler == 0:
|
||||||
|
print("Æsj, det sier du bare for å slippe å gi noe!")
|
||||||
|
else:
|
||||||
|
gir_epler = int(input("Hvor mange kan du gi til meg? "))
|
||||||
|
if gir_epler < har_epler / 2:
|
||||||
|
print("Du beholder det meste for deg selv...")
|
||||||
|
else:
|
||||||
|
print("Takk, det var snilt!")
|
||||||
|
print(remainingApplesString(har_epler - gir_epler))
|
|
@ -0,0 +1,17 @@
|
||||||
|
def remainingApplesString(applesLeft):
|
||||||
|
applesOwed = applesLeft < 0
|
||||||
|
actualApplesLeft = 0 if applesOwed else applesLeft
|
||||||
|
remainingApplesString = "Du har nå " + str(actualApplesLeft) + (" epler" if applesLeft != 1 else " eple") +" igjen."
|
||||||
|
return remainingApplesString + f' Gi meg de {abs(applesLeft)} du skylder meg neste gang vi møtes.' * applesOwed
|
||||||
|
|
||||||
|
print("Dette er et program for å teste din sjenerøsitet.")
|
||||||
|
har_epler = int(input("Hvor mange epler har du? "))
|
||||||
|
if har_epler == 0:
|
||||||
|
print("Æsj, det sier du bare for å slippe å gi noe!")
|
||||||
|
else:
|
||||||
|
gir_epler = int(input("Hvor mange kan du gi til meg? "))
|
||||||
|
if gir_epler < har_epler / 2:
|
||||||
|
print("Du beholder det meste for deg selv...")
|
||||||
|
else:
|
||||||
|
print("Takk, det var snilt!")
|
||||||
|
print(remainingApplesString(har_epler - gir_epler))
|
|
@ -0,0 +1,23 @@
|
||||||
|
def getValues() -> (int, int, int):
|
||||||
|
while True:
|
||||||
|
values = input('Gi inn en andregradsliknings a, b og c separert med mellomrom:\n\t')
|
||||||
|
try:
|
||||||
|
splitValues = values.split(' ')
|
||||||
|
assert len(splitValues) == 3
|
||||||
|
return map(int, splitValues)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
print('Sørg for at alle tallene er heltall.\n')
|
||||||
|
except AssertionError:
|
||||||
|
print('Det skal bare være 3 tall.\n')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
a, b, c = getValues()
|
||||||
|
d = b**2 - 4 * a * c
|
||||||
|
|
||||||
|
if d > 0:
|
||||||
|
print('Ligninga har to reelle løsninger')
|
||||||
|
elif d == 0:
|
||||||
|
print('Ligninga har en reell løsning')
|
||||||
|
else:
|
||||||
|
print('Ligninga har to imaginære løsninger')
|
|
@ -0,0 +1,23 @@
|
||||||
|
from math import sqrt
|
||||||
|
|
||||||
|
from task11a import getValues
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
a, b, c = getValues()
|
||||||
|
d = b**2 - 4 * a * c
|
||||||
|
|
||||||
|
expression = f'{a}x^2 + {b}x + {c}'
|
||||||
|
if d > 0:
|
||||||
|
roots = (
|
||||||
|
(-b + sqrt(d)) / (2 * a),
|
||||||
|
(-b - sqrt(d)) / (2 * a)
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f'Andregradsligningen {expression} har de to reelle løsningene {roots[0]} og {roots[1]}'
|
||||||
|
)
|
||||||
|
elif d == 0:
|
||||||
|
root = (-b + sqrt(d)) / (2 * a)
|
||||||
|
print(f'Andregradsligningen {expression} har en reell dobbelrot {root}')
|
||||||
|
else:
|
||||||
|
print(f'Andregradsligningen {expression} har to imaginære løsninger')
|
|
@ -0,0 +1,14 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def evalPrice(daysToTrip):
|
||||||
|
return 'Du kan få minipris: 199,-' if (
|
||||||
|
daysToTrip >= 14) else 'For sent for minipris; fullpris 440,-'
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
daysToTrip = inputTypeCheck('Dager til du skal reise? ', int)
|
||||||
|
print(evalPrice(daysToTrip))
|
|
@ -0,0 +1,20 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.boolInput import boolInput
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def miniPriceBranch():
|
||||||
|
choseMiniPrice = boolInput('Minipris 199,- kan ikke refunderes/endres\nØnskes dette (J/N)? ')
|
||||||
|
print('Takk for pengene, god reise!' if choseMiniPrice else 'Da tilbyr vi fullpris: 440,-')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
daysToTrip = inputTypeCheck('Dager til du skal reise? ', int)
|
||||||
|
|
||||||
|
if daysToTrip >= 14:
|
||||||
|
miniPriceBranch()
|
||||||
|
else:
|
||||||
|
print('For sent for minipris; fullpris 440,-')
|
|
@ -0,0 +1,40 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.boolInput import boolInput
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def miniPriceBranch():
|
||||||
|
choseMiniPrice = boolInput(
|
||||||
|
'Minipris 199,- kan ikke refunderes/endres\nØnskes dette (J/N)? ')
|
||||||
|
if choseMiniPrice:
|
||||||
|
print('Takk for pengene, god reise!')
|
||||||
|
else:
|
||||||
|
normalBranch()
|
||||||
|
|
||||||
|
|
||||||
|
def evalDiscountPercent():
|
||||||
|
age = inputTypeCheck('Skriv inn din alder: ', int)
|
||||||
|
if age < 16:
|
||||||
|
return 50
|
||||||
|
elif age >= 60:
|
||||||
|
return 25
|
||||||
|
|
||||||
|
hasSpecialSocialStatus = boolInput('Er du student eller militær (J/N)?')
|
||||||
|
return 25 if hasSpecialSocialStatus else 0
|
||||||
|
|
||||||
|
|
||||||
|
def normalBranch():
|
||||||
|
discountPercent = evalDiscountPercent()
|
||||||
|
print(f'Prisen på biletten blir: {440 - 440 * discountPercent/100}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
daysToTrip = inputTypeCheck('Dager til du skal reise? ', int)
|
||||||
|
|
||||||
|
if daysToTrip >= 14:
|
||||||
|
miniPriceBranch()
|
||||||
|
else:
|
||||||
|
normalBranch()
|
|
@ -0,0 +1,34 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
INFO = f"""INFO
|
||||||
|
Dette programmet besvarer om din utleie av egen bolig er skattepliktig.
|
||||||
|
Først trenger vi å vite hvor stor del av boligen du har leid ut.
|
||||||
|
Angi dette i prosent, 100 betyr hele boligen, 50 betyr halve,
|
||||||
|
20 en mindre del av boligen som f.eks. en hybel. """
|
||||||
|
|
||||||
|
HLINE = '----------------------------------------------------------------------'
|
||||||
|
|
||||||
|
def mainBranch():
|
||||||
|
print('DATAINNHENTING:')
|
||||||
|
|
||||||
|
percentRented = inputTypeCheck('Oppgi hvor mye av boligen som ble utleid: ', float)
|
||||||
|
rentIncome = inputTypeCheck('Skriv inn hva du har hatt i leieinntekt: ', float)
|
||||||
|
|
||||||
|
hasTax = percentRented > 50 and rentIncome >= 20000
|
||||||
|
hasTaxString = 'Inntekten er skattepliktig' if hasTax else 'Inntekten er ikke skattepliktig'
|
||||||
|
|
||||||
|
print(HLINE)
|
||||||
|
print('SKATTEBEREGNING')
|
||||||
|
print (hasTaxString)
|
||||||
|
if hasTax:
|
||||||
|
print(f'Skattepliktig beløp er {rentIncome}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(INFO)
|
||||||
|
print(HLINE)
|
||||||
|
mainBranch()
|
|
@ -0,0 +1,76 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.choiceInput import choiceInput
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
INFO = """INFO
|
||||||
|
Dette programmet besvarer om din utleie en annen type bolig,
|
||||||
|
her sekundær- eller fritidsbolig, er skattepliktig.
|
||||||
|
Først trenger vi å vite om du leier ut en sekundær- eller en fritidsbolig."""
|
||||||
|
|
||||||
|
HLINE = '---------------------------------------------------------------------'
|
||||||
|
|
||||||
|
FRITIDSBOLIG_INFO = """INFO
|
||||||
|
Du har valgt fritidsbolig.
|
||||||
|
Nå trenger vi først å vite om fritidsboligen(e) primært brukes til utleie eller fritid.
|
||||||
|
Deretter trenger vi å vite hvor mange fritidsbolig(er) du leier ut.
|
||||||
|
Til slutt trenger vi å vite hvor store utleieinntekter du har pr. fritidsbolig."""
|
||||||
|
|
||||||
|
SECONDARYHOUSE_INFO = """INFO
|
||||||
|
Du har valgt sekundærbolig.
|
||||||
|
Nå trenger vi først å vite hvor mange sekundærbolig(er) du leier ut.
|
||||||
|
Deretter trenger vi å vite hvor store utleieinntekter du har pr. sekundærbolig."""
|
||||||
|
|
||||||
|
|
||||||
|
def fritidsboligBranch():
|
||||||
|
print(FRITIDSBOLIG_INFO)
|
||||||
|
print(HLINE)
|
||||||
|
print('DATAINNHENTING:')
|
||||||
|
housePurposeIsRenting = choiceInput(
|
||||||
|
prompt='Skriv inn formålet med fritidsboligen(e): ',
|
||||||
|
choices=['utleie', 'fritid']
|
||||||
|
) == 'utleie'
|
||||||
|
houseAmount = inputTypeCheck('Skriv inn antallet fritidsboliger du leier ut: ', int)
|
||||||
|
rentPerHouse = inputTypeCheck('Skriv inn utleieinntekten pr. fritidsbolig: ', int)
|
||||||
|
print()
|
||||||
|
print(HLINE)
|
||||||
|
print('SKATTEBEREGNING')
|
||||||
|
|
||||||
|
hasTax = housePurposeIsRenting or rentPerHouse > 10000
|
||||||
|
if hasTax:
|
||||||
|
print('Inntekten er skattepliktig')
|
||||||
|
if not housePurposeIsRenting:
|
||||||
|
print(f'Overskytende beløp pr. fritidsbolig er {rentPerHouse - 10000}')
|
||||||
|
|
||||||
|
housePurposeDeduction = 0 if housePurposeIsRenting else 10000
|
||||||
|
taxedRentPerHouse = (rentPerHouse - housePurposeDeduction) * 85/100
|
||||||
|
|
||||||
|
print(f'Skattepliktig inntekt pr. fritidsbolig er {taxedRentPerHouse}')
|
||||||
|
print(f'Totalt skattepliktig beløp er {houseAmount * taxedRentPerHouse}')
|
||||||
|
else:
|
||||||
|
print('Inntekten er ikke skattepliktig')
|
||||||
|
|
||||||
|
def secondaryHouseBranch():
|
||||||
|
print(SECONDARYHOUSE_INFO)
|
||||||
|
print(HLINE)
|
||||||
|
print('DATAINNHENTING:')
|
||||||
|
houseAmount = inputTypeCheck('Skriv inn antallet sekundærboliger du leier ut: ', int)
|
||||||
|
rentPerHouse = inputTypeCheck('Skriv inn utleieinntekten pr. sekundærbolig: ', int)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(INFO)
|
||||||
|
print(HLINE)
|
||||||
|
print('DATAINNHENTING:')
|
||||||
|
houseType = choiceInput(
|
||||||
|
prompt='Skriv inn type annen bolig (sekundærbolig/fritidsbolig) du har leid ut: ',
|
||||||
|
choices=['fritidsbolig','sekundærbolig']
|
||||||
|
)
|
||||||
|
print()
|
||||||
|
|
||||||
|
if houseType == 'fritidsbolig':
|
||||||
|
fritidsboligBranch()
|
||||||
|
else:
|
||||||
|
secondaryHouseBranch()
|
|
@ -0,0 +1,22 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.choiceInput import choiceInput
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
from task9a import mainBranch
|
||||||
|
from task9b import fritidsboligBranch, secondaryHouseBranch
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
choices = ['egen bolig', 'sekundærbolig', 'fritidsbolig']
|
||||||
|
|
||||||
|
choice = choiceInput(
|
||||||
|
prompt=f'Skriv inn hustype for skatteutregning ({", ".join(choices)}): ',
|
||||||
|
choices=choices)
|
||||||
|
|
||||||
|
if choice == 'egen bolig':
|
||||||
|
mainBranch()
|
||||||
|
elif choice == 'sekundærbolig':
|
||||||
|
secondaryHouseBranch()
|
||||||
|
else:
|
||||||
|
fritidsboligBranch()
|
|
@ -0,0 +1,34 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def numberPyramid(length):
|
||||||
|
for i in range(length):
|
||||||
|
row = ''
|
||||||
|
for k in range(i + 1):
|
||||||
|
row += f'{k+1} '
|
||||||
|
print(row)
|
||||||
|
|
||||||
|
|
||||||
|
def numberPyramidGenerator():
|
||||||
|
currentList = ['1']
|
||||||
|
while True:
|
||||||
|
yield ' '.join(currentList)
|
||||||
|
currentList.append(str(int(currentList[-1]) + 1))
|
||||||
|
|
||||||
|
|
||||||
|
def solutionWithForLoops(n):
|
||||||
|
return numberPyramid(n)
|
||||||
|
|
||||||
|
|
||||||
|
def solutionWithGenerator(n):
|
||||||
|
myGenerator = numberPyramidGenerator()
|
||||||
|
for i in range(n):
|
||||||
|
print(next(myGenerator))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
n = inputTypeCheck('n: ', int)
|
||||||
|
print(solutionWithForLoops(n))
|
|
@ -0,0 +1,20 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def numberPyramid(length):
|
||||||
|
for i in range(length):
|
||||||
|
print('X', ' ' * i + 'X')
|
||||||
|
|
||||||
|
|
||||||
|
def numberPyramidDoubleLoop(length):
|
||||||
|
for i in range(length):
|
||||||
|
space = ''.join([' ' for _ in range(i)])
|
||||||
|
print('X', space + 'X')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
n = inputTypeCheck('n: ', int)
|
||||||
|
numberPyramidDoubleLoop(n)
|
|
@ -0,0 +1,50 @@
|
||||||
|
from math import sqrt
|
||||||
|
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# O(√n)
|
||||||
|
def isPrime(n):
|
||||||
|
if n < 2: return False
|
||||||
|
if n == 2 or n == 3 or n == 5: return True
|
||||||
|
limit = int(sqrt(n))
|
||||||
|
numberToCheck = 5
|
||||||
|
while numberToCheck <= limit:
|
||||||
|
if n % numberToCheck == 0: return False
|
||||||
|
numberToCheck += 2 # Skip all even numbers
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# Would be O(log₂(n)), but isPrime(n) is used,
|
||||||
|
# thus it's O(√n)
|
||||||
|
def findAllFactors(n):
|
||||||
|
factors = []
|
||||||
|
while not isPrime(n):
|
||||||
|
for i in range(2, int(n)):
|
||||||
|
if n % i == 0:
|
||||||
|
factors.append(i)
|
||||||
|
n = n / i
|
||||||
|
break
|
||||||
|
factors.append(int(n))
|
||||||
|
return factors
|
||||||
|
|
||||||
|
|
||||||
|
def factorize(n):
|
||||||
|
factors = []
|
||||||
|
if isPrime(n):
|
||||||
|
factors.append(n)
|
||||||
|
else:
|
||||||
|
factors = findAllFactors(n)
|
||||||
|
return factors
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
n = inputTypeCheck('Skriv inn et positivt heltall: ', int)
|
||||||
|
factors = factorize(n)
|
||||||
|
if len(factors) == 1:
|
||||||
|
print(f'{n} er et primtall')
|
||||||
|
else:
|
||||||
|
print(f'{n} = {" * ".join([str(tall) for tall in factorize(n)])}')
|
|
@ -0,0 +1,63 @@
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
|
||||||
|
class multiplicationGame:
|
||||||
|
def __init__(self, min, max, tries):
|
||||||
|
self.min = min
|
||||||
|
self.max = max
|
||||||
|
self.tries = tries
|
||||||
|
self.updateProblem()
|
||||||
|
|
||||||
|
def generateNewMultiplicationProblem(self) -> (int, int):
|
||||||
|
number = lambda: randint(self.min, self.max)
|
||||||
|
self.currentProblem = (number(), number())
|
||||||
|
|
||||||
|
def updateProblem(self):
|
||||||
|
self.generateNewMultiplicationProblem()
|
||||||
|
self.currentTries = self.tries
|
||||||
|
|
||||||
|
def userWantsNewQuestion(self) -> bool:
|
||||||
|
while True:
|
||||||
|
answer = input(
|
||||||
|
'Er det ønskelig med flere spørsmål? Skriv 1 for ja og 0 for nei: ')
|
||||||
|
if answer in ['1', '0']:
|
||||||
|
return bool(int(answer))
|
||||||
|
else:
|
||||||
|
print('Skriv 1 for ja og 0 for nei')
|
||||||
|
|
||||||
|
def checkIfUserWantsNewQuestion(self):
|
||||||
|
if not self.userWantsNewQuestion():
|
||||||
|
exit(0)
|
||||||
|
print()
|
||||||
|
|
||||||
|
def wrongAnswer(self):
|
||||||
|
self.currentTries -= 1
|
||||||
|
if self.currentTries == 0:
|
||||||
|
print(
|
||||||
|
'Dessverre klarte du ikke dette regnestykket, men vent så får du et nytt et:)'
|
||||||
|
)
|
||||||
|
self.checkIfUserWantsNewQuestion()
|
||||||
|
self.updateProblem()
|
||||||
|
else:
|
||||||
|
print(f'Dessverre ikke riktig. Du har {self.currentTries} forsøk igjen.')
|
||||||
|
|
||||||
|
def correctAnswer(self):
|
||||||
|
print('Gratulerer, det er helt riktig!')
|
||||||
|
self.checkIfUserWantsNewQuestion()
|
||||||
|
self.updateProblem()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
answer = int(input(f'Hva blir {self.currentProblem[0]} * {self.currentProblem[1]}? '))
|
||||||
|
if answer == self.currentProblem[0] * self.currentProblem[1]:
|
||||||
|
self.correctAnswer()
|
||||||
|
else:
|
||||||
|
self.wrongAnswer()
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while True:
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game = multiplicationGame(min=0, max=10, tries=3)
|
||||||
|
game.loop()
|
|
@ -0,0 +1,22 @@
|
||||||
|
from task11d import multiplicationGame
|
||||||
|
|
||||||
|
class newMultiplicationGame(multiplicationGame):
|
||||||
|
def __init__(self, roundsBetweenDifficultyUpdate, *args, **kwargs):
|
||||||
|
self.roundsBetweenDifficultyUpdate = roundsBetweenDifficultyUpdate
|
||||||
|
self.roundsPlayed = 0
|
||||||
|
return super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def updateDifficulty(self):
|
||||||
|
self.max = self.max + 5
|
||||||
|
print('Oppgavene har nå blitt litt vanskeligere.\n')
|
||||||
|
|
||||||
|
def updateProblem(self):
|
||||||
|
super().updateProblem()
|
||||||
|
self.roundsPlayed += 1
|
||||||
|
if self.roundsPlayed % self.roundsBetweenDifficultyUpdate == 0:
|
||||||
|
self.updateDifficulty()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game = newMultiplicationGame(roundsBetweenDifficultyUpdate=5, min=0, max=10, tries=3)
|
||||||
|
game.loop()
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def alternateSum(n):
|
||||||
|
positiveNumbers = [
|
||||||
|
num**2 for num in [i for i in range(1, n + 1) if i % 2 != 0]
|
||||||
|
]
|
||||||
|
negativeNumbers = [
|
||||||
|
-num**2 for num in [i for i in range(1, n + 1) if i % 2 == 0]
|
||||||
|
]
|
||||||
|
return sum(positiveNumbers + negativeNumbers)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
n = inputTypeCheck('n: ', int)
|
||||||
|
print(alternateSum(n))
|
|
@ -0,0 +1,34 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def AlternateNumberGenerator():
|
||||||
|
isEven = lambda n: n % 2 == 0
|
||||||
|
n = 1
|
||||||
|
counter = 2
|
||||||
|
while True:
|
||||||
|
yield n
|
||||||
|
n = n + (-counter**2 if isEven(counter) else counter**2)
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
|
||||||
|
def alternateSumStopAt(k):
|
||||||
|
numGen = AlternateNumberGenerator()
|
||||||
|
previousN = None
|
||||||
|
n = next(numGen)
|
||||||
|
iterations = 0
|
||||||
|
while n < k:
|
||||||
|
previousN = n
|
||||||
|
n = next(numGen)
|
||||||
|
iterations += 1
|
||||||
|
|
||||||
|
print(
|
||||||
|
f'Summen av tallene før summen blir større enn k er {previousN}. Antall iterasjoner: {iterations}'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
k = inputTypeCheck('k: ', int)
|
||||||
|
alternateSumStopAt(k)
|
|
@ -0,0 +1,57 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class game():
|
||||||
|
def __init__(self):
|
||||||
|
self.secret_word = input('Skriv inn det hemmelige ordet: ')
|
||||||
|
self.lives = int(input('Hvor mange forsøk får brukeren? '))
|
||||||
|
self.lettersLeft = list(self.secret_word)
|
||||||
|
os.system('clear')
|
||||||
|
|
||||||
|
def getWord(self):
|
||||||
|
return ''.join([('*' if (ch in self.lettersLeft) else ch)
|
||||||
|
for ch in list(self.secret_word)])
|
||||||
|
|
||||||
|
def removeLetterFromLettersLeft(self, letter):
|
||||||
|
self.lettersLeft = list(
|
||||||
|
filter(lambda leftLetter: leftLetter != letter, self.lettersLeft))
|
||||||
|
|
||||||
|
def gameOver(self):
|
||||||
|
print('Du har ingen liv igjen.')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def gameWon(self):
|
||||||
|
print(f'Gratulerer. Ordet var {self.secret_word}')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def wrongLetter(self, letter):
|
||||||
|
print(f'Bokstaven {letter} er ikke i ordet.')
|
||||||
|
self.lives -= 1
|
||||||
|
if self.lives == 0:
|
||||||
|
self.gameOver()
|
||||||
|
print(f'Du har {self.lives} liv igjen, prøv på nytt.')
|
||||||
|
|
||||||
|
def rightLetter(self, letter):
|
||||||
|
print('Stemmer, bokstaven er i ordet')
|
||||||
|
self.removeLetterFromLettersLeft(letter)
|
||||||
|
if self.lettersLeft == []:
|
||||||
|
self.gameWon()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
print(self.getWord())
|
||||||
|
letter = input('Gjett på én bokstav i ordet: ')
|
||||||
|
if letter in self.lettersLeft:
|
||||||
|
self.rightLetter(letter)
|
||||||
|
else:
|
||||||
|
self.wrongLetter(letter)
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while True:
|
||||||
|
os.system('clear')
|
||||||
|
self.update()
|
||||||
|
input("Trykk enter for å fortsette...")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
myGame = game()
|
||||||
|
myGame.loop()
|
|
@ -0,0 +1,25 @@
|
||||||
|
try:
|
||||||
|
from common.inputChecking.typeCheck import inputTypeCheck
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Sjekk README.md for hvilke flagg python trenger')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def fibonacciIterative(n):
|
||||||
|
k1 = 0
|
||||||
|
k2 = 1
|
||||||
|
for i in range(n - 1):
|
||||||
|
previousK2 = k2
|
||||||
|
k2 = k1 + k2
|
||||||
|
k1 = previousK2
|
||||||
|
return k1
|
||||||
|
|
||||||
|
|
||||||
|
fibonacciSum = lambda n: sum([fibonacciIterative(i) for i in range(1, n + 1)])
|
||||||
|
fibonacciList = lambda n: [fibonacciIterative(i) for i in range(1, n + 1)]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
n = inputTypeCheck('n: ', int)
|
||||||
|
|
||||||
|
print(f'a) Fibonacci({n})', fibonacciIterative(n))
|
||||||
|
print(f'b) Sum av Fibonacci(1..{n})', fibonacciSum(n))
|
||||||
|
print(f'c) Sum av Fibonacci(1..{n})', fibonacciList(n))
|
|
@ -0,0 +1,21 @@
|
||||||
|
month = input('Skriv inn en måned: ').lower()
|
||||||
|
if month == 'februar':
|
||||||
|
year = input('Skriv inn et år: ')
|
||||||
|
isLeapyear = int(year) % 4 == 0
|
||||||
|
print(29 if isLeapyear else 28)
|
||||||
|
else:
|
||||||
|
months = {
|
||||||
|
"januar": 31,
|
||||||
|
# "februar": 30,
|
||||||
|
"mars": 31,
|
||||||
|
"april": 30,
|
||||||
|
"mai": 31,
|
||||||
|
"juni": 30,
|
||||||
|
"july": 31, # Hmmm
|
||||||
|
"august": 31,
|
||||||
|
"september": 30,
|
||||||
|
"oktober": 31,
|
||||||
|
"november": 30,
|
||||||
|
"desember": 31
|
||||||
|
}
|
||||||
|
print(months[month])
|
|
@ -0,0 +1,32 @@
|
||||||
|
months = {
|
||||||
|
"januar": 31,
|
||||||
|
# "februar": 30,
|
||||||
|
"mars": 31,
|
||||||
|
"april": 30,
|
||||||
|
"mai": 31,
|
||||||
|
"juni": 30,
|
||||||
|
"july": 31, # Hmmm
|
||||||
|
"august": 31,
|
||||||
|
"september": 30,
|
||||||
|
"oktober": 31,
|
||||||
|
"november": 30,
|
||||||
|
"desember": 31
|
||||||
|
}
|
||||||
|
|
||||||
|
def myMonth():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
month = input('Skriv inn en måned: ').lower()
|
||||||
|
if month == 'februar':
|
||||||
|
year = int(input('Skriv inn et år: '))
|
||||||
|
assert ((year >= 0) and ( year <= 2020))
|
||||||
|
isLeapyear = year % 4 == 0
|
||||||
|
days = 29 if isLeapyear else 28
|
||||||
|
else:
|
||||||
|
assert month in months
|
||||||
|
days = month[month]
|
||||||
|
return f'Det er {days} dager i denne måneden'
|
||||||
|
except:
|
||||||
|
print('Ugyldig input! Prøv på nytt!')
|
||||||
|
|
||||||
|
print(myMonth)
|
|
@ -0,0 +1,4 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
def correct_word(string):
|
||||||
|
return bool(re.match('^\w+$', string))
|
|
@ -0,0 +1,8 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
def count_letters(string):
|
||||||
|
try:
|
||||||
|
assert bool(re.match('^\w+$', string))
|
||||||
|
return len(string)
|
||||||
|
except AssertionError:
|
||||||
|
return -1
|
|
@ -0,0 +1,5 @@
|
||||||
|
def spam_with_questions(question) -> str:
|
||||||
|
while True:
|
||||||
|
answer = input(question).lower()
|
||||||
|
if answer == 'stopp':
|
||||||
|
break
|
|
@ -0,0 +1,12 @@
|
||||||
|
def energy_efficient_spamming(q1, q2):
|
||||||
|
try:
|
||||||
|
assert len(q1)>len(q2)
|
||||||
|
answer = input(q1)
|
||||||
|
while True:
|
||||||
|
if answer == 'stopp':
|
||||||
|
break
|
||||||
|
answer = input(q2)
|
||||||
|
except AssertionError:
|
||||||
|
return
|
||||||
|
|
||||||
|
energy_efficient_spamming('jadu', 'nei')
|
|
@ -0,0 +1,3 @@
|
||||||
|
def triangle(h):
|
||||||
|
for n in range(1,h+1):
|
||||||
|
print('* '*n)
|
|
@ -0,0 +1,3 @@
|
||||||
|
def triangle(h):
|
||||||
|
for n in reversed(range(1,h+1)):
|
||||||
|
print('* '*n)
|
|
@ -0,0 +1,4 @@
|
||||||
|
def isosceles_triangle(h):
|
||||||
|
for i in range(1, h+1):
|
||||||
|
spaces = h-i
|
||||||
|
print(spaces*' ' + i*'* ')
|
|
@ -0,0 +1,13 @@
|
||||||
|
def cubeInput():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
l,w,h = (float(input('Lengde: ')), float(input('Bredde: ')), float(input('Høyde: ')))
|
||||||
|
assert w != l and l != h and w != h
|
||||||
|
return (l,w,h)
|
||||||
|
except AssertionError:
|
||||||
|
print('Morten er ikke fornøyd, prøv igjen')
|
||||||
|
except ValueError:
|
||||||
|
print('Det er ikke et tall, prøv igjen')
|
||||||
|
|
||||||
|
d = min(cubeInput())
|
||||||
|
print(f'Den største kuben vil ha et volum på {d**3}')
|
|
@ -0,0 +1,4 @@
|
||||||
|
x = 3
|
||||||
|
while x:
|
||||||
|
print('#'*x)
|
||||||
|
x-=1
|
|
@ -0,0 +1 @@
|
||||||
|
print(f'Det minste talled du skrev inn var { min([int(input("Skriv et tall: ")) for _ in range(5)]) }.')
|
|
@ -0,0 +1,3 @@
|
||||||
|
def print_table(n):
|
||||||
|
for a in range(1, n+1):
|
||||||
|
print(' '.join([str(a*b) for b in range(1, n+1)]))
|
|
@ -0,0 +1,15 @@
|
||||||
|
def f(tol):
|
||||||
|
g = lambda k: 1 + 1/k**2
|
||||||
|
iterationCount = 2
|
||||||
|
result = 2
|
||||||
|
|
||||||
|
while True:
|
||||||
|
prevResult = result
|
||||||
|
result *= g(iterationCount)
|
||||||
|
if result - prevResult < tol:
|
||||||
|
return (result, iterationCount)
|
||||||
|
iterationCount += 1
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
result, iterationCount = f(0.01)
|
||||||
|
print(f'Produktet ble {"{:.2f}".format(result)} etter {iterationCount} iterasjoner.')
|
|
@ -0,0 +1,14 @@
|
||||||
|
def f(tol, count=0):
|
||||||
|
g = lambda x: 1 + 1/x**2
|
||||||
|
product = g(count+1)
|
||||||
|
|
||||||
|
# Base case
|
||||||
|
if product < 1 + tol:
|
||||||
|
return (product, count)
|
||||||
|
|
||||||
|
newProd, newCount = f(tol, count + 1)
|
||||||
|
return (product * newProd, newCount) # Nest in the last count value without modification
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
result, recursionCount = f(0.01)
|
||||||
|
print(f'Rekursjonsdybden er {recursionCount}\nProduktet ble {"{:.2f}".format(result)}')
|
|
@ -0,0 +1,9 @@
|
||||||
|
from local import is_leap_year
|
||||||
|
|
||||||
|
def weekday_newyear(year):
|
||||||
|
daySum = sum([366 if is_leap_year(year) else 365 for year in range(year)])
|
||||||
|
return (daySum - 2) % 7
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
days = ['man', 'tir', 'ons', 'tor', 'fre', 'lor', 'son']
|
||||||
|
_ = [ print(f'{year} {days[weekday_newyear(year)]}') for year in range(1900, 1920) ]
|
|
@ -0,0 +1,2 @@
|
||||||
|
def is_workday(day):
|
||||||
|
return day < 5
|
|
@ -0,0 +1,15 @@
|
||||||
|
from itertools import islice, cycle
|
||||||
|
|
||||||
|
from local import is_leap_year
|
||||||
|
from a import weekday_newyear
|
||||||
|
from b import is_workday
|
||||||
|
|
||||||
|
def workdays_in_year(year):
|
||||||
|
firstDay = weekday_newyear(year)
|
||||||
|
cycler = islice( cycle(range(7)), firstDay, None)
|
||||||
|
days = [next(cycler) for day in range((366 if is_leap_year(year) else 365))]
|
||||||
|
workdays = [day for day in days if day < 5]
|
||||||
|
return len(workdays)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
_ = [print(f'{year} har {workdays_in_year(year)} arbeidsdager') for year in range(1900, 1920)]
|
|
@ -0,0 +1,8 @@
|
||||||
|
def is_leap_year ( year ):
|
||||||
|
if year % 400 == 0:
|
||||||
|
return True
|
||||||
|
elif year % 100 == 0:
|
||||||
|
return False
|
||||||
|
elif year % 4 == 0:
|
||||||
|
return True
|
||||||
|
return False
|
|
@ -0,0 +1,260 @@
|
||||||
|
from common.inputChecking.boolInput import boolInput
|
||||||
|
|
||||||
|
from os import get_terminal_size, system
|
||||||
|
from math import ceil
|
||||||
|
import random
|
||||||
|
|
||||||
|
class Card:
|
||||||
|
def __init__(self, cardId, color):
|
||||||
|
"""
|
||||||
|
cardId goes from 1 to 1 where 1 is A and 13 is K
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.id = cardId
|
||||||
|
self.color = color
|
||||||
|
|
||||||
|
cardNums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
|
||||||
|
cardSyms = {
|
||||||
|
'spade': '♠',
|
||||||
|
'heart': '♥',
|
||||||
|
'diamond': '♦',
|
||||||
|
'club': '♣'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.num = cardNums[cardId-1]
|
||||||
|
self.sym = cardSyms[color]
|
||||||
|
|
||||||
|
WIDTH = 11
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"""┌─────────┐
|
||||||
|
│{self.num}{' ' if self.id != 10 else ''} │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ {self.sym} │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ {' ' if self.id != 10 else ''}{self.num}│
|
||||||
|
└─────────┘"""
|
||||||
|
|
||||||
|
def value(self, aceValue):
|
||||||
|
cardValues = {
|
||||||
|
'A': aceValue,
|
||||||
|
'2': 2,
|
||||||
|
'3': 3,
|
||||||
|
'4': 4,
|
||||||
|
'5': 5,
|
||||||
|
'6': 6,
|
||||||
|
'7': 7,
|
||||||
|
'8': 8,
|
||||||
|
'9': 9,
|
||||||
|
'10': 10,
|
||||||
|
'J': 10,
|
||||||
|
'Q': 10,
|
||||||
|
'K': 10
|
||||||
|
}
|
||||||
|
return cardValues[self.num]
|
||||||
|
|
||||||
|
class CardHandler:
|
||||||
|
def __init__(self, cards, printSep=5, aceValue = 1):
|
||||||
|
self.cards = cards
|
||||||
|
self.printSeparator = printSep
|
||||||
|
self.aceValue = aceValue
|
||||||
|
|
||||||
|
def addCard(self, card):
|
||||||
|
self.cards.append(card)
|
||||||
|
|
||||||
|
def generateNewCard(self):
|
||||||
|
cardTypes = range(1,14)
|
||||||
|
cardColors = ['spade', 'heart', 'diamond', 'club']
|
||||||
|
self.addCard(Card(random.choice(cardTypes), random.choice(cardColors)))
|
||||||
|
|
||||||
|
def _concatenateCards(self, cards):
|
||||||
|
"""
|
||||||
|
Concatenate several card objects into an list of sublists
|
||||||
|
where each sublist contains the strings for the cards to be
|
||||||
|
printed for a specific horizontal line.
|
||||||
|
"""
|
||||||
|
|
||||||
|
cardStringLists = [(str(card)).split('\n') for card in cards]
|
||||||
|
cardHeight = len(cardStringLists[0])
|
||||||
|
linesToPrint = [[] for line in range(cardHeight)]
|
||||||
|
|
||||||
|
for cardStringList in cardStringLists:
|
||||||
|
[linesToPrint[line].append(cardStringList[line]) for line in range(cardHeight)]
|
||||||
|
return linesToPrint
|
||||||
|
|
||||||
|
|
||||||
|
def printCards(self, cardsPerLine):
|
||||||
|
"""
|
||||||
|
Print <cardsPerLine> cards per line, horizontally aligned
|
||||||
|
"""
|
||||||
|
|
||||||
|
splitCards =[[] for _ in range(ceil(len(self.cards)/cardsPerLine))]
|
||||||
|
|
||||||
|
for i, card in enumerate(self.cards):
|
||||||
|
splitCards[i // cardsPerLine].append(card)
|
||||||
|
|
||||||
|
SplitCardStrings = [self._concatenateCards(cardList) for cardList in splitCards]
|
||||||
|
printCardList = lambda cardList: print('\n'.join([ (' ' * self.printSeparator).join(line) for line in cardList ]))
|
||||||
|
[ printCardList(SplitCardString) for SplitCardString in SplitCardStrings ]
|
||||||
|
|
||||||
|
|
||||||
|
def safePrintCards(self):
|
||||||
|
"""
|
||||||
|
Print the amount of cards that there is room for depending on the terminal width
|
||||||
|
"""
|
||||||
|
cardWidth = Card.WIDTH
|
||||||
|
extendedCardWidth = (cardWidth + self.printSeparator)
|
||||||
|
terminalWidth = get_terminal_size().columns
|
||||||
|
|
||||||
|
isRoomForExtraCard = terminalWidth % extendedCardWidth >= cardWidth
|
||||||
|
cardsPerLine = terminalWidth // extendedCardWidth + (1 if isRoomForExtraCard else 0)
|
||||||
|
|
||||||
|
self.printCards(cardsPerLine)
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cardSum(self):
|
||||||
|
|
||||||
|
return sum([card.value(aceValue=self.aceValue) for card in self.cards])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def containsAce(self):
|
||||||
|
return any([True for card in self.cards if card.id == 1])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def containsBlackJack(self):
|
||||||
|
return any([True for card in self.cards if card.num == 'A']) \
|
||||||
|
and any([True for card in self.cards if card.value(self.aceValue) == 10])
|
||||||
|
|
||||||
|
|
||||||
|
def emptyCard():
|
||||||
|
result = Card(1,'spade')
|
||||||
|
result.num = '?'
|
||||||
|
result.sym = '?'
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class Blackjack:
|
||||||
|
def __init__(self):
|
||||||
|
self.handler = CardHandler([])
|
||||||
|
self.emptyHandler = CardHandler([emptyCard(), emptyCard()])
|
||||||
|
self.dealerHandler = CardHandler([])
|
||||||
|
self.gameResults = [0,0]
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def generateNewCards(self):
|
||||||
|
self.dealerHandler.cards = []
|
||||||
|
self.handler.cards = []
|
||||||
|
for _ in range(2):
|
||||||
|
self.dealerHandler.generateNewCard()
|
||||||
|
self.handler.generateNewCard()
|
||||||
|
self.emptyHandler.cards[0] = self.dealerHandler.cards[0]
|
||||||
|
|
||||||
|
def determineAceValue(self):
|
||||||
|
if self.handler.cardSum < 11 and self.handler.containsAce: # 11 + 1 = 12, 11 + 11 = 22
|
||||||
|
self.handler.aceValue = self.dealerHandler.aceValue = 11
|
||||||
|
else:
|
||||||
|
self.handler.aceValue = self.dealerHandler.aceValue = 1
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.generateNewCards()
|
||||||
|
self.determineAceValue()
|
||||||
|
|
||||||
|
def youWin(self):
|
||||||
|
self.gameResults[0] += 1
|
||||||
|
print("""
|
||||||
|
__ __
|
||||||
|
/\ \ /\ \ __
|
||||||
|
\ `\`\\\\/'/ ___ __ __ __ __ __/\_\ ___
|
||||||
|
`\ `\ /' / __`\/\ \/\ \ /\ \/\ \/\ \/\ \ /' _ `\
|
||||||
|
`\ \ \/\ \L\ \ \ \_\ \\ \\ \ \_/ \_/ \ \ \/\ \/\ \
|
||||||
|
\ \_\ \____/\ \____/ \ \___x___/'\ \_\ \_\ \_\\
|
||||||
|
\/_/\/___/ \/___/ \/__//__/ \/_/\/_/\/_/
|
||||||
|
""")
|
||||||
|
|
||||||
|
def youLose(self):
|
||||||
|
self.gameResults[1] += 1
|
||||||
|
print("""
|
||||||
|
__ __ ___
|
||||||
|
/\ \ /\ \ /\_ \
|
||||||
|
\ `\`\\\\/'/ ___ __ __ \//\ \ ___ ____ __
|
||||||
|
`\ `\ /' / __`\/\ \/\ \ \ \ \ / __`\ /',__\ /'__`\
|
||||||
|
`\ \ \/\ \L\ \ \ \_\ \ \_\ \_/\ \L\ \/\__, `\/\ __/
|
||||||
|
\ \_\ \____/\ \____/ /\____\ \____/\/\____/\ \____\\
|
||||||
|
\/_/\/___/ \/___/ \/____/\/___/ \/___/ \/____/
|
||||||
|
""")
|
||||||
|
|
||||||
|
def gameOver(self, gameWon):
|
||||||
|
system('clear')
|
||||||
|
|
||||||
|
print('\nDEALERS CARDS\n')
|
||||||
|
self.dealerHandler.safePrintCards()
|
||||||
|
print('\nYOUR CARDS\n')
|
||||||
|
self.handler.safePrintCards()
|
||||||
|
print()
|
||||||
|
print('Ace value is', self.handler.aceValue)
|
||||||
|
|
||||||
|
if gameWon:
|
||||||
|
self.youWin()
|
||||||
|
else:
|
||||||
|
self.youLose()
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(f'Wins: {self.gameResults[0]} Losses: {self.gameResults[1]}')
|
||||||
|
if boolInput(
|
||||||
|
'Do you want to play again? [y/n]: ',
|
||||||
|
yesNoLetters=['y','n'],
|
||||||
|
error=''
|
||||||
|
):
|
||||||
|
self.reset()
|
||||||
|
else:
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def checkIfLost(self):
|
||||||
|
|
||||||
|
winningConditions = [
|
||||||
|
self.handler.containsBlackJack and not self.dealerHandler.containsBlackJack,
|
||||||
|
self.dealerHandler.cardSum > 21
|
||||||
|
]
|
||||||
|
|
||||||
|
losingConditions = [
|
||||||
|
self.handler.cardSum > 21
|
||||||
|
]
|
||||||
|
|
||||||
|
if any(losingConditions):
|
||||||
|
self.gameOver(gameWon=False)
|
||||||
|
return True
|
||||||
|
elif any(winningConditions):
|
||||||
|
self.gameOver(gameWon=True)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
system('clear')
|
||||||
|
|
||||||
|
print('\nDEALERS CARDS\n')
|
||||||
|
self.emptyHandler.safePrintCards()
|
||||||
|
print('\nYOUR CARDS\n')
|
||||||
|
self.handler.safePrintCards()
|
||||||
|
print()
|
||||||
|
print('Ace value is', self.handler.aceValue)
|
||||||
|
print()
|
||||||
|
|
||||||
|
if not self.checkIfLost():
|
||||||
|
if not boolInput('Continue? [y/n]: ', yesNoLetters=('y','n')):
|
||||||
|
gameWon = self.dealerHandler.cardSum < self.handler.cardSum
|
||||||
|
self.gameOver(gameWon=gameWon)
|
||||||
|
return
|
||||||
|
self.handler.generateNewCard()
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while True:
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game = Blackjack()
|
||||||
|
game.loop()
|
|
@ -0,0 +1,131 @@
|
||||||
|
from common.inputChecking.typeCheck import validateInput as validateTypeInput
|
||||||
|
from common.inputChecking.boolInput import validateInput as validateBoolInput
|
||||||
|
|
||||||
|
from json import dumps as serialize
|
||||||
|
from json import loads as unserialize
|
||||||
|
from os.path import isfile
|
||||||
|
|
||||||
|
class ExitError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def boolInput(question, yesNoLetters=('j','n'), exitKeyword='hade'):
|
||||||
|
yesLetters = [yesNoLetters[0], yesNoLetters[0].capitalize()]
|
||||||
|
while True:
|
||||||
|
answer = input(question)
|
||||||
|
if answer == exitKeyword:
|
||||||
|
raise ExitError
|
||||||
|
if validateBoolInput(answer, yesNoLetters):
|
||||||
|
return answer in yesLetters
|
||||||
|
|
||||||
|
def inputTypeCheck(question, type, exitKeyword='hade'):
|
||||||
|
while True:
|
||||||
|
userInput = input(question)
|
||||||
|
if userInput == exitKeyword:
|
||||||
|
raise ExitError
|
||||||
|
if validateTypeInput(userInput, type):
|
||||||
|
return userInput
|
||||||
|
|
||||||
|
class DataSchema:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
genderIsMale = None,
|
||||||
|
age = None,
|
||||||
|
hasMultipleSubjects = None,
|
||||||
|
hasITGK = None,
|
||||||
|
avgStudyTime = None
|
||||||
|
):
|
||||||
|
self.genderIsMale = genderIsMale
|
||||||
|
self.age = age
|
||||||
|
self.hasMultipleSubjects = hasMultipleSubjects
|
||||||
|
self.hasITGK = hasITGK
|
||||||
|
self.avgStudyTime = avgStudyTime
|
||||||
|
|
||||||
|
|
||||||
|
class Survey:
|
||||||
|
def __init__(self, savePath='./results.json', resultsPath=''):
|
||||||
|
self.savePath = savePath
|
||||||
|
if resultsPath != '':
|
||||||
|
self.resultsPath = resultsPath
|
||||||
|
self.loadResults()
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
def loadResults(self):
|
||||||
|
try:
|
||||||
|
file = open(self.resultsPath, 'r')
|
||||||
|
dicts = unserialize(file.read())
|
||||||
|
self.results = [DataSchema(**dict) for dict in dicts]
|
||||||
|
except FileNotFoundError:
|
||||||
|
print('Fant ikke undersøkelsesdata ved', self.resultsPath)
|
||||||
|
except Exception as e:
|
||||||
|
print('Noe gikk galt under lasting av undersøkelsesdata')
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
def printStats(self):
|
||||||
|
print('Resultat av undersøkelse!')
|
||||||
|
men = women = multipleChoice = itgk = studyHours = 0
|
||||||
|
for result in self.results:
|
||||||
|
if result.genderIsMale:
|
||||||
|
men += 1
|
||||||
|
else:
|
||||||
|
women += 1
|
||||||
|
multipleChoice += 1 if result.hasMultipleSubjects else 0
|
||||||
|
itgk += 1 if result.hasITGK else 0
|
||||||
|
studyHours += int(result.avgStudyTime)
|
||||||
|
print("Antall kvinner:", women)
|
||||||
|
print("Antall menn:", men)
|
||||||
|
print("Antall personer som tar fag:", multipleChoice)
|
||||||
|
print("Antall personer som tar ITGK:", itgk)
|
||||||
|
print("Antall timer i snitt brukt på lekser:", studyHours/len(self.results))
|
||||||
|
|
||||||
|
def saveResults(self):
|
||||||
|
serializedResults = serialize([result.__dict__ for result in self.results])
|
||||||
|
|
||||||
|
# Check whether file exists
|
||||||
|
try:
|
||||||
|
assert not isfile(self.savePath)
|
||||||
|
except:
|
||||||
|
if not boolInput(f'Det eksisterer allerede en fil ved {self.savePath}\nVil du overskrive filen? [j/n]: '):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Try to write data to file.
|
||||||
|
try:
|
||||||
|
file = open(self.savePath, "w")
|
||||||
|
file.write(serializedResults)
|
||||||
|
file.close()
|
||||||
|
except:
|
||||||
|
if boolInput('Noe gikk galt under lagring av data. Vil du prøve igjen? [j/n]: '):
|
||||||
|
self.saveResults()
|
||||||
|
|
||||||
|
def end(self):
|
||||||
|
if len(self.results) > 0:
|
||||||
|
self.printStats()
|
||||||
|
self.saveResults()
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
schema = DataSchema()
|
||||||
|
|
||||||
|
print('Velkommen til spørreundersøkelsen!\n')
|
||||||
|
|
||||||
|
try:
|
||||||
|
schema.genderIsMale = boolInput('Hvilket kjønn er du? [f/m]: ', yesNoLetters=('m','f'))
|
||||||
|
schema.age = inputTypeCheck('Hvor gammel er du?: ', int)
|
||||||
|
schema.hasMultipleSubjects = boolInput('Tar du et eller flere fag? [j/n]: ')
|
||||||
|
|
||||||
|
hasITGKQuestion = 'Tar du ITGK? [j/n]: ' if int(schema.age) < 22 else 'Tar du virkelig ITGK? [j/n]: '
|
||||||
|
schema.hasITGK = boolInput(hasITGKQuestion)
|
||||||
|
schema.avgStudyTime = inputTypeCheck('Hvor mange timer bruker du daglig (i snitt) på lekser?: ', float)
|
||||||
|
self.results.append(schema)
|
||||||
|
except ExitError:
|
||||||
|
self.end()
|
||||||
|
print()
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while True:
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
survey = Survey(resultsPath='./results.json')
|
||||||
|
survey.loop()
|
|
@ -0,0 +1,32 @@
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
def random_matrise(x, y):
|
||||||
|
return [[randint(0, 9) for _ in range(x)] for _ in range(y)]
|
||||||
|
|
||||||
|
def print_matrise(matrix, title):
|
||||||
|
print(f'{title}=[')
|
||||||
|
for row in matrix:
|
||||||
|
print('\t', row)
|
||||||
|
print(']')
|
||||||
|
|
||||||
|
def matrise_addisjon(A, B):
|
||||||
|
try:
|
||||||
|
assert len(A) == len(B) and len(A[0]) == len(B[0])
|
||||||
|
newMatrix = [[A[x][y] + B[x][y] for y in range(len(A[0]))] for x in range(len(A))]
|
||||||
|
return newMatrix
|
||||||
|
except:
|
||||||
|
print('Matrisene er ikke av samme dimensjon')
|
||||||
|
|
||||||
|
def main():
|
||||||
|
A = random_matrise(4,3)
|
||||||
|
print_matrise(A, 'A')
|
||||||
|
B = random_matrise(3,4)
|
||||||
|
print_matrise(B, 'B')
|
||||||
|
C = random_matrise(3,4)
|
||||||
|
print_matrise(C, 'C')
|
||||||
|
D = matrise_addisjon(A,B)
|
||||||
|
E = matrise_addisjon(B,C)
|
||||||
|
print_matrise(E, 'B+C' )
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -0,0 +1,11 @@
|
||||||
|
def separate(numbers, threshold):
|
||||||
|
return(
|
||||||
|
[num for num in numbers if num < threshold],
|
||||||
|
[num for num in numbers if num >= threshold],
|
||||||
|
)
|
||||||
|
|
||||||
|
def multiplication_table(n):
|
||||||
|
return [[(x+1)*(y+1) for x in range(n)] for y in range(n)]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(multiplication_table(4))
|
|
@ -0,0 +1,60 @@
|
||||||
|
from random import sample
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
def guessInput(amount):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
answer = input(f'Gjett {amount} tall\n').split(' ')
|
||||||
|
assert len(answer) == amount
|
||||||
|
return [int(num) for num in answer]
|
||||||
|
except:
|
||||||
|
print(f'Er du sikker på at du har skrevet inn {amount} tall? Prøv igjen.')
|
||||||
|
|
||||||
|
drawNumber = lambda numList, amount: sample(numList, amount)
|
||||||
|
compList = lambda list1, list2: len([1 for elem in list1 if elem in list2])
|
||||||
|
|
||||||
|
def Winnings(rightNums, rightExtraNums):
|
||||||
|
isBiggerThan = lambda rn, ren: rightNums >= rn and rightExtraNums >= ren
|
||||||
|
if isBiggerThan(7,0): return 2749455
|
||||||
|
elif isBiggerThan(6,1): return 102110
|
||||||
|
elif isBiggerThan(6,0): return 3385
|
||||||
|
elif isBiggerThan(5,0): return 95
|
||||||
|
elif isBiggerThan(4,1): return 45
|
||||||
|
else: return 0
|
||||||
|
|
||||||
|
numbers = list(range(1,35))
|
||||||
|
calculateRightNumbers = lambda list: compList(list, drawNumber(numbers, len(list)))
|
||||||
|
combinedRightNumbers = lambda list1, list2: Winnings(calculateRightNumbers(list1), calculateRightNumbers(list2))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
myGuess = guessInput(7)
|
||||||
|
print('Nå skal du gjette ekstra-tall')
|
||||||
|
myExtraGuess = guessInput(3)
|
||||||
|
|
||||||
|
print('Du vant {} kroner'.format(combinedRightNumbers(myGuess, myExtraGuess) - 5))
|
||||||
|
|
||||||
|
# g)
|
||||||
|
|
||||||
|
def calculateMillionSum(threadNum):
|
||||||
|
timesPerTread = int(1000000/threadNum)
|
||||||
|
results = []
|
||||||
|
|
||||||
|
def threadTarget():
|
||||||
|
partialSum = sum([combinedRightNumbers(sample(numbers, 7), sample(numbers, 3)) - 5 for _ in range(timesPerTread)])
|
||||||
|
results.append(partialSum)
|
||||||
|
|
||||||
|
threads = [threading.Thread(target=threadTarget) for _ in range(threadNum)]
|
||||||
|
|
||||||
|
for thread in threads:
|
||||||
|
thread.start()
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
|
||||||
|
return sum(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# main()
|
||||||
|
result = calculateMillionSum(64)
|
||||||
|
print(result)
|
|
@ -0,0 +1,18 @@
|
||||||
|
def tooth(g):
|
||||||
|
result = []
|
||||||
|
coins = [20, 10, 5, 1]
|
||||||
|
|
||||||
|
def findCoinAmount(gramsLeft, coinIndex):
|
||||||
|
result.append(gramsLeft//coins[coinIndex])
|
||||||
|
if coinIndex != len(coins) - 1:
|
||||||
|
findCoinAmount(gramsLeft%coins[coinIndex], coinIndex+1)
|
||||||
|
|
||||||
|
findCoinAmount(g, 0)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
teeth = [95,103,71,99,114,64,95,53,97,114,109,11,2,21,45,2,26,81,54,14,118,108,117,27,115,43,70,58,107]
|
||||||
|
prettyPrint = lambda tooth: print(f'20: {tooth[0]}, 10: {tooth[1]}, 5: {tooth[2]}, 1: {tooth[3]}')
|
||||||
|
for grams in teeth:
|
||||||
|
prettyPrint(tooth(grams))
|
|
@ -0,0 +1,17 @@
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
def areOrthagonal(list1,list2):
|
||||||
|
vec1 = np.array(list1)
|
||||||
|
vec2 = np.array(list2)
|
||||||
|
return np.dot(vec1,vec2) == 0
|
||||||
|
|
||||||
|
def createColumnArray():
|
||||||
|
return np.arange(1,16).reshape(3,5).transpose()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(areOrthagonal([0,1],[1,0]))
|
||||||
|
print(areOrthagonal([1,0],[1,0]))
|
||||||
|
print()
|
||||||
|
print(createColumnArray())
|
|
@ -0,0 +1,34 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
def find_substring_indexes(str1, str2):
|
||||||
|
matches = re.compile(f'(?=({str1}))', re.IGNORECASE).finditer(str2)
|
||||||
|
return [match.span()[0] for match in matches]
|
||||||
|
|
||||||
|
def sub_string_matches(str1, str2, str3):
|
||||||
|
matchIndexes = find_substring_indexes(str1, str2)
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
newString = str2
|
||||||
|
for i in range(len(matchIndexes)):
|
||||||
|
|
||||||
|
realIndex = matchIndexes[i] + offset
|
||||||
|
|
||||||
|
try:
|
||||||
|
if len(str3) - len(str1) - (matchIndexes[i+1] - matchIndexes[i]) > 0:
|
||||||
|
reverseOffset = len(str3) - len(str1) - (matchIndexes[i+1] - matchIndexes[i])
|
||||||
|
else:
|
||||||
|
reverseOffset = 0
|
||||||
|
except IndexError:
|
||||||
|
reverseOffset = 0
|
||||||
|
pass
|
||||||
|
|
||||||
|
newString = newString[:realIndex] + str3 + newString[realIndex + len(str1) - reverseOffset:]
|
||||||
|
|
||||||
|
offset += len(str3) - len(str1) + reverseOffset
|
||||||
|
return newString
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(find_substring_indexes('iS', "Is this the real life? Is this just fantasy?"))
|
||||||
|
print(find_substring_indexes(str1 = "oo", str2 = "Never let you go let me go. Never let me go ooo"))
|
||||||
|
print(sub_string_matches(str1 = "iS", str2 = "Is this the real life? Is this just fantasy?", str3 = "cool"))
|
||||||
|
print(sub_string_matches(str1 = "oo", str2 = "Never let you goooo let me goo. Never let me goo oooo", str3 = "cool"))
|
|
@ -0,0 +1,74 @@
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
class Piece:
|
||||||
|
def __init__(self, char):
|
||||||
|
self.type = char.lower()
|
||||||
|
self.isWhite = char.isupper()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.type.upper() if self.isWhite else self.type
|
||||||
|
|
||||||
|
class Board:
|
||||||
|
def __init__(self, boardString, size=5):
|
||||||
|
pieces = [Piece(char) if char!='.' else None for char in boardString]
|
||||||
|
self.rows = [pieces[i:i+size] for i in range(0, len(pieces), size)]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ''.join([''.join([str(piece) if piece!=None else '.' for piece in row])for row in self.rows])
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
for row in self.rows:
|
||||||
|
for piece in row:
|
||||||
|
print(piece if piece!=None else '.', end='')
|
||||||
|
print()
|
||||||
|
|
||||||
|
def getPiece(self, x, y) -> Union[Piece, None]:
|
||||||
|
x -= 1
|
||||||
|
y = len(self.rows) - y
|
||||||
|
return self.rows[y][x]
|
||||||
|
|
||||||
|
def getLegalMoves(self, x, y):
|
||||||
|
try:
|
||||||
|
piece = self.getPiece(x, y)
|
||||||
|
assert piece.type == 'p'
|
||||||
|
|
||||||
|
frontDirection = 1 if piece.isWhite else -1
|
||||||
|
|
||||||
|
def checkIfStartPosition(x,y):
|
||||||
|
if piece.isWhite and y == 2 and self.getPiece(x,y+2) == None:
|
||||||
|
return [(x,y+2)]
|
||||||
|
elif (not piece.isWhite) and y == 4 and self.getPiece(x,y-2) == None:
|
||||||
|
return [(x,y-2)]
|
||||||
|
return []
|
||||||
|
|
||||||
|
def checkInFrontOf(x, y, frontDirection):
|
||||||
|
if not self.getPiece(x, y+frontDirection):
|
||||||
|
return [(x, y+frontDirection)]
|
||||||
|
return []
|
||||||
|
|
||||||
|
def checkDiagonalOf(x, y, frontDirection):
|
||||||
|
moves = []
|
||||||
|
for xToCheck in [-1, 1]:
|
||||||
|
pieceToCheck = self.getPiece(x+xToCheck, y+frontDirection)
|
||||||
|
if pieceToCheck != None and pieceToCheck.isWhite != piece.isWhite:
|
||||||
|
moves.append((x+xToCheck, y+frontDirection))
|
||||||
|
return moves
|
||||||
|
|
||||||
|
moves = checkInFrontOf(x,y,frontDirection)
|
||||||
|
if moves != []:
|
||||||
|
moves += checkIfStartPosition(x,y)
|
||||||
|
moves += checkDiagonalOf(x,y,frontDirection)
|
||||||
|
return moves
|
||||||
|
|
||||||
|
except AssertionError:
|
||||||
|
print('Piece rules not implemented yet')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
board = Board('rkn.r.p.....P..PP.PPB.K..')
|
||||||
|
board.print()
|
||||||
|
print()
|
||||||
|
print(board.getPiece(5, 2))
|
||||||
|
print(board.getPiece(2, 1))
|
||||||
|
print()
|
||||||
|
print(board.getLegalMoves(4, 2))
|
||||||
|
print(board.getLegalMoves(2, 4))
|
|
@ -0,0 +1,52 @@
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
def EulerCromer( tmax, x0, y0, v0, u0, m, tau):
|
||||||
|
# tmax er tiden jorden bruker rundt solen
|
||||||
|
# x0 og y0 er startbetingelser for jordens posisjon
|
||||||
|
# v0 og u0 er starbetingelser for farten til jorden
|
||||||
|
# m er massen til jorden og tau er steglengden.
|
||||||
|
|
||||||
|
N = int(round(tmax/tau)) #np.zeros(N) lager en liste bestående av bare 0ere av lengde N
|
||||||
|
x = np.zeros(N)
|
||||||
|
y = np.zeros(N)
|
||||||
|
u = np.zeros(N)
|
||||||
|
v = np.zeros(N)
|
||||||
|
radiuser = np.zeros(N)
|
||||||
|
|
||||||
|
# startbetingelser
|
||||||
|
u[0] = u0
|
||||||
|
v[0] = v0
|
||||||
|
x[0] = x0
|
||||||
|
y[0] = y0
|
||||||
|
radiuser[0] = np.sqrt((x[0]) ** 2 + (y[0]) ** 2)
|
||||||
|
|
||||||
|
for n in range(1, N):
|
||||||
|
u[n] = u[n - 1] - 4 * np.pi ** 2 * x[n - 1] * tau / (radiuser[n - 1] ** 3)
|
||||||
|
v[n] = v[n - 1] - 4 * np.pi ** 2 * y[n - 1] * tau / (radiuser[n - 1] ** 3)
|
||||||
|
x[n] = x[n - 1] + u[n] * tau
|
||||||
|
y[n] = y[n - 1] + v[n] * tau
|
||||||
|
radiuser[n] = np.sqrt((x[n]) ** 2 + (y[n]) ** 2)
|
||||||
|
|
||||||
|
|
||||||
|
return x, y # posisjons- og farts-lister
|
||||||
|
|
||||||
|
# startbetingelser:
|
||||||
|
x0 = 1 # Tenk deg at solen er i origo og at jorden starter i posisjon(1,0)
|
||||||
|
y0 = 0
|
||||||
|
u0 = 0 # startfarten i x-retning er 0
|
||||||
|
v0 = 2*3.1415623 # startfarten i y-retning er 2*pi
|
||||||
|
m = 1 / 333480 # dette er massen til Jorden i forhold til massen til Solen
|
||||||
|
tmax = 1 # Omløpstiden rundt Solen er 1(år)
|
||||||
|
tau = 0.01 # denne skrittlengden er såpass liten at plottet blir fint nok
|
||||||
|
|
||||||
|
x1, y1 = EulerCromer(tmax, x0, y0, v0, u0, m, tau)
|
||||||
|
|
||||||
|
# Plotter banen til planeten rundt sola
|
||||||
|
plt.figure()
|
||||||
|
plt.plot(x1, y1)
|
||||||
|
circle = plt.Circle((0, 0), radius=0.06, fc='yellow')
|
||||||
|
plt.gca().add_patch(circle)
|
||||||
|
plt.xlabel(r'x [AU]')
|
||||||
|
plt.ylabel(r'y [AU]')
|
||||||
|
plt.show()
|
|
@ -0,0 +1,28 @@
|
||||||
|
from re import search
|
||||||
|
|
||||||
|
def check_equal(str1, str2):
|
||||||
|
for char in range(len(str1)):
|
||||||
|
if str1[char] != str2[char]: return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def reversed_word(word):
|
||||||
|
return ''.join([word[len(word) - 1 - i] for i in range(len(word))])
|
||||||
|
|
||||||
|
def check_palindrome(string):
|
||||||
|
return string == reversed_word(string)
|
||||||
|
|
||||||
|
def contains_string(str1, str2):
|
||||||
|
match = search(pattern=str2, string=str1)
|
||||||
|
return match.span()[0] if match != None else -1
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(check_equal('hei', 'hello'))
|
||||||
|
print(check_equal('hello', 'hello'))
|
||||||
|
print()
|
||||||
|
print(reversed_word('star desserts'))
|
||||||
|
print()
|
||||||
|
print(check_palindrome('agnes i senga'))
|
||||||
|
print(check_palindrome('hello'))
|
||||||
|
print()
|
||||||
|
print(contains_string('pepperkake', 'per'))
|
||||||
|
print(contains_string('pepperkake', 'ola'))
|
|
@ -0,0 +1,51 @@
|
||||||
|
from random import randrange
|
||||||
|
|
||||||
|
songs = [("You hear the door slam. And realize there's nowhere left to", "run"),
|
||||||
|
("Oh, I wanna dance with somebody. I wanna feel the", "heat"),
|
||||||
|
("There's a fire starting in my heart. Reaching a fever", "pitch"),
|
||||||
|
("Hey, I just met you and this is crazy. But here's my", "number"),
|
||||||
|
("'Cause baby, you're a firework. Come on, show 'em what you're", "worth")]
|
||||||
|
|
||||||
|
# Om jeg tar inn songs som parameter vil ikke pop_random_songs kunne fjerne noe fra lista.
|
||||||
|
# Her velger jeg aktivt å ikke ta et argument inn med tanke på oppgave B
|
||||||
|
def pop_random_songs():
|
||||||
|
songIndex = randrange(len(songs))
|
||||||
|
song = songs[songIndex]
|
||||||
|
del songs[songIndex]
|
||||||
|
return song
|
||||||
|
|
||||||
|
def continueGuessing():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
answer = input('Do you want to go again? [y/n] ')
|
||||||
|
assert answer in ['y', 'Y', 'n', 'N']
|
||||||
|
return answer in ['y', 'Y']
|
||||||
|
except AssertionError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def song_contest():
|
||||||
|
currentSong = pop_random_songs()
|
||||||
|
while True:
|
||||||
|
|
||||||
|
print('The lyrics are:')
|
||||||
|
print(currentSong[0])
|
||||||
|
answer = input('What\'s the next word? ')
|
||||||
|
|
||||||
|
if answer.lower() == currentSong[1].lower():
|
||||||
|
print(f'Correct!')
|
||||||
|
if len(songs) == 0:
|
||||||
|
print('You did it! You remembered all the objects')
|
||||||
|
exit(0)
|
||||||
|
elif continueGuessing():
|
||||||
|
currentSong = pop_random_songs()
|
||||||
|
else:
|
||||||
|
print('Welcome back later :D')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('Wrong guess. Try again.')
|
||||||
|
|
||||||
|
|
||||||
|
song_contest()
|
||||||
|
# for _ in range(5):
|
||||||
|
# print(pop_random_songs())
|
|
@ -0,0 +1,33 @@
|
||||||
|
def smallify_words(objects):
|
||||||
|
return [string.lower() for string in objects]
|
||||||
|
|
||||||
|
def get_5_objects():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
answer = input('Enter five objects separated by \';\': ').split(';')
|
||||||
|
assert len(answer) == 5
|
||||||
|
return answer
|
||||||
|
except AssertionError:
|
||||||
|
print(f'You were supposed to enter five objects, not {len(answer)}. Try again.')
|
||||||
|
|
||||||
|
def play_game():
|
||||||
|
objects = get_5_objects()
|
||||||
|
answer = input('What is your guess? ')
|
||||||
|
while True:
|
||||||
|
if answer == 'quit':
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
if answer in smallify_words(objects):
|
||||||
|
print(f'Congratulations! You remembered {answer}')
|
||||||
|
objects.remove(answer)
|
||||||
|
else:
|
||||||
|
print('Sorry, that was not one of the words')
|
||||||
|
|
||||||
|
if len(objects) == 0:
|
||||||
|
print('You did it! You remembered all the objects')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
answer = input('What is your next guess? ').lower()
|
||||||
|
play_game()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
def derivate(x, function):
|
||||||
|
h = 1e-8
|
||||||
|
return (function(x+h) - function(x)) / h
|
||||||
|
|
||||||
|
print(derivate(3, lambda x: x**2 + 2*x + 13))
|
|
@ -0,0 +1,7 @@
|
||||||
|
def input_strings():
|
||||||
|
return [input('Skriv inn en streng: ') for _ in range(4) ]
|
||||||
|
|
||||||
|
def acronym():
|
||||||
|
return "".join([string[0].upper() for string in input_strings()])
|
||||||
|
|
||||||
|
print(acronym())
|
|
@ -0,0 +1,25 @@
|
||||||
|
def customInput(msg, interval):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
answer = int(input(msg))
|
||||||
|
assert answer in range(*interval)
|
||||||
|
return answer
|
||||||
|
except (AssertionError, ValueError):
|
||||||
|
print('You have to gie a value in the interval [1,10]. Try again')
|
||||||
|
|
||||||
|
def do_user_like(items):
|
||||||
|
print('On a scale of 1 to 10 where 10 is the highest, how much do you like:')
|
||||||
|
return [(item, customInput(f'{item}? ', (1,11))) for item in items]
|
||||||
|
|
||||||
|
|
||||||
|
def get_prioritized_list(lst):
|
||||||
|
return sorted(lst, key=lambda tuple: (tuple[1], tuple[0]), reverse=True)
|
||||||
|
|
||||||
|
def what_user_likes_best(items, num):
|
||||||
|
sortedList = get_prioritized_list(do_user_like(items))
|
||||||
|
print(f'Your top {num} are')
|
||||||
|
for i in range(num):
|
||||||
|
print(f'{i+1}. {sortedList[i][0]}')
|
||||||
|
|
||||||
|
|
||||||
|
x = what_user_likes_best(['dof', 'fas', 'be', 'aa'], 2)
|
|
@ -0,0 +1,153 @@
|
||||||
|
from os import system
|
||||||
|
|
||||||
|
class TicTacToe:
|
||||||
|
def __init__(self, playerSymbols=['0', 'X']):
|
||||||
|
self.board = [0 for _ in range(9)]
|
||||||
|
name1, name2 = self.getUsernames()
|
||||||
|
self.players = [
|
||||||
|
{
|
||||||
|
'name': name1,
|
||||||
|
'sym': playerSymbols[0],
|
||||||
|
'num': 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': name2,
|
||||||
|
'sym': playerSymbols[1],
|
||||||
|
'num': 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def getUsernames(self):
|
||||||
|
return [input(f'Spiller {i+1} sitt navn: ') for i in range(2)]
|
||||||
|
|
||||||
|
|
||||||
|
def toPieceArray(self): return \
|
||||||
|
[ self.players[0]['sym'] if i==self.players[0]['num'] else \
|
||||||
|
self.players[1]['sym'] if i==self.players[1]['num'] else \
|
||||||
|
' ' for i in self.board ]
|
||||||
|
|
||||||
|
|
||||||
|
def pieceExistAt(self, pos):
|
||||||
|
return self.board[pos] == self.players[0]['num'] or self.board[pos] == self.players[1]['num']
|
||||||
|
|
||||||
|
|
||||||
|
def hasWon(self, userId):
|
||||||
|
getPiecesFromIndexes = lambda indexes: [self.board[i] for i in indexes]
|
||||||
|
indexesList = [[0,4,8], [1,4,7], [2,4,6], [3,4,5], [0,3,6], [0,1,2], [2,5,8], [6,7,8]]
|
||||||
|
winningSum = self.players[userId]['num'] * 3
|
||||||
|
return any([sum(getPiecesFromIndexes(indexes)) == winningSum for indexes in indexesList])
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
pieces = self.toPieceArray()
|
||||||
|
return """╭───┬───┬───╮
|
||||||
|
│ {} │ {} │ {} │
|
||||||
|
├───┼───┼───┤
|
||||||
|
│ {} │ {} │ {} │
|
||||||
|
├───┼───┼───┤
|
||||||
|
│ {} │ {} │ {} │
|
||||||
|
╰───┴───┴───╯""".format(*pieces)
|
||||||
|
|
||||||
|
|
||||||
|
def selectedBoardAt(self, x, y) -> str:
|
||||||
|
|
||||||
|
characterMap = {
|
||||||
|
'─': '═',
|
||||||
|
'│': '║',
|
||||||
|
'┼': '╬',
|
||||||
|
'╰': '╚',
|
||||||
|
'╯': '╝',
|
||||||
|
'╭': '╔',
|
||||||
|
'╮': '╗',
|
||||||
|
'├': '╠',
|
||||||
|
'┴': '╩',
|
||||||
|
'┤': '╣',
|
||||||
|
'┬': '╦',
|
||||||
|
}
|
||||||
|
|
||||||
|
pointsToChange = \
|
||||||
|
[(0 + x * 4, i + y * 2) for i in range(3)] + \
|
||||||
|
[(4 + x * 4, i + y * 2) for i in range(3)] + \
|
||||||
|
[(i + x * 4, 0 + y * 2) for i in range(1,4)] + \
|
||||||
|
[(i + x * 4, 2 + y * 2) for i in range(1,4)]
|
||||||
|
|
||||||
|
board = [list(line) for line in str(self).split('\n')]
|
||||||
|
for x,y in pointsToChange:
|
||||||
|
board[y][x] = characterMap[board[y][x]]
|
||||||
|
return '\n'.join([''.join(line) for line in board])
|
||||||
|
|
||||||
|
def drawBoard(self, userId, x=-1, y=-1):
|
||||||
|
system('clear')
|
||||||
|
|
||||||
|
print(f'({self.players[userId]["sym"]}) - {self.players[userId]["name"].upper()}\'S TURN\n')
|
||||||
|
print(self.selectedBoardAt(x,y) if (x,y) != (-1,-1) else str(self))
|
||||||
|
|
||||||
|
|
||||||
|
def selectPiece(self, userId) -> int:
|
||||||
|
x, y = 0, 0
|
||||||
|
while True:
|
||||||
|
self.drawBoard(userId, x,y)
|
||||||
|
|
||||||
|
key = input(f" W E\n A S D <- Enter : ")[0]
|
||||||
|
if key in ['s', 'j'] and y!=2: y+=1
|
||||||
|
elif key in ['w', 'k'] and y!=0: y-=1
|
||||||
|
elif key in ['d', 'l'] and x!=2: x+=1
|
||||||
|
elif key in ['a', 'h'] and x!=0: x-=1
|
||||||
|
elif key == 'e' and not self.pieceExistAt(3*y + x): return 3*y + x
|
||||||
|
|
||||||
|
|
||||||
|
def youWinTheGameItsHalloweenBois(self, userId):
|
||||||
|
print(f"""
|
||||||
|
▓██ ██▓ ▒█████ █ ██ █ █░ ██▓ ███▄ █
|
||||||
|
▒██ ██▒▒██▒ ██▒ ██ ▓██▒ ▓█░ █ ░█░▓██▒ ██ ▀█ █
|
||||||
|
▒██ ██░▒██░ ██▒▓██ ▒██░ ▒█░ █ ░█ ▒██▒▓██ ▀█ ██▒
|
||||||
|
░ ▐██▓░▒██ ██░▓▓█ ░██░ ░█░ █ ░█ ░██░▓██▒ ▐▌██▒
|
||||||
|
░ ██▒▓░░ ████▓▒░▒▒█████▓ ░░██▒██▓ ░██░▒██░ ▓██░
|
||||||
|
██▒▒▒ ░ ▒░▒░▒░ ░▒▓▒ ▒ ▒ ░ ▓░▒ ▒ ░▓ ░ ▒░ ▒ ▒
|
||||||
|
▓██ ░▒░ ░ ▒ ▒░ ░░▒░ ░ ░ ▒ ░ ░ ▒ ░░ ░░ ░ ▒░
|
||||||
|
▒ ▒ ░░ ░ ░ ░ ▒ ░░░ ░ ░ ░ ░ ▒ ░ ░ ░ ░
|
||||||
|
░ ░ ░ ░ ░ ░ ░ ░
|
||||||
|
░ ░ {self.players[userId]['name']}
|
||||||
|
""")
|
||||||
|
|
||||||
|
def spookyTie(self):
|
||||||
|
print("""
|
||||||
|
███▄ █ ▒█████ ▄▄▄▄ ▒█████ ▓█████▄▓██ ██▓ █ █░ ██▓ ███▄ █ ██████
|
||||||
|
██ ▀█ █ ▒██▒ ██▒▓█████▄ ▒██▒ ██▒▒██▀ ██▌▒██ ██▒ ▓█░ █ ░█░▓██▒ ██ ▀█ █ ▒██ ▒
|
||||||
|
▓██ ▀█ ██▒▒██░ ██▒▒██▒ ▄██▒██░ ██▒░██ █▌ ▒██ ██░ ▒█░ █ ░█ ▒██▒▓██ ▀█ ██▒░ ▓██▄
|
||||||
|
▓██▒ ▐▌██▒▒██ ██░▒██░█▀ ▒██ ██░░▓█▄ ▌ ░ ▐██▓░ ░█░ █ ░█ ░██░▓██▒ ▐▌██▒ ▒ ██▒
|
||||||
|
▒██░ ▓██░░ ████▓▒░░▓█ ▀█▓░ ████▓▒░░▒████▓ ░ ██▒▓░ ░░██▒██▓ ░██░▒██░ ▓██░▒██████▒▒
|
||||||
|
░ ▒░ ▒ ▒ ░ ▒░▒░▒░ ░▒▓███▀▒░ ▒░▒░▒░ ▒▒▓ ▒ ██▒▒▒ ░ ▓░▒ ▒ ░▓ ░ ▒░ ▒ ▒ ▒ ▒▓▒ ▒ ░
|
||||||
|
░ ░░ ░ ▒░ ░ ▒ ▒░ ▒░▒ ░ ░ ▒ ▒░ ░ ▒ ▒ ▓██ ░▒░ ▒ ░ ░ ▒ ░░ ░░ ░ ▒░░ ░▒ ░ ░
|
||||||
|
░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ▒ ░░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░
|
||||||
|
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
|
||||||
|
░ ░ ░ ░
|
||||||
|
""")
|
||||||
|
|
||||||
|
def checkGameStatus(self,userId):
|
||||||
|
if self.hasWon(userId):
|
||||||
|
self.drawBoard(userId)
|
||||||
|
# print(self.players[userId]['name'], 'has won!')
|
||||||
|
self.youWinTheGameItsHalloweenBois(userId)
|
||||||
|
exit(0)
|
||||||
|
elif not 0 in self.board:
|
||||||
|
self.drawBoard(userId)
|
||||||
|
self.spookyTie()
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
while True:
|
||||||
|
piece = self.selectPiece(0)
|
||||||
|
self.board[piece] = self.players[0]['num']
|
||||||
|
self.checkGameStatus(0)
|
||||||
|
piece = self.selectPiece(1)
|
||||||
|
self.board[piece] = self.players[1]['num']
|
||||||
|
self.checkGameStatus(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game = TicTacToe()
|
||||||
|
game.loop()
|
||||||
|
print(game)
|
|
@ -0,0 +1,16 @@
|
||||||
|
number_of_lines = lambda filename: len(open(filename, 'r').readlines())
|
||||||
|
|
||||||
|
|
||||||
|
def number_frequency(filename):
|
||||||
|
result = {}
|
||||||
|
for number in open(filename, 'r').read().splitlines():
|
||||||
|
if not number in result: result[number] = 0
|
||||||
|
result[number] += 1
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(number_of_lines('numbers.txt'))
|
||||||
|
frequencies = number_frequency('numbers.txt')
|
||||||
|
for key in frequencies:
|
||||||
|
print(f'{key}: {frequencies[key]}')
|
|
@ -0,0 +1,49 @@
|
||||||
|
from csv import reader
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
|
|
||||||
|
class Subject:
|
||||||
|
def __init__(self, subjectString, criteria):
|
||||||
|
splitString = subjectString.split(" ")
|
||||||
|
self.faculty = splitString[0]
|
||||||
|
self.code = splitString[1]
|
||||||
|
self.name = " ".join(splitString[2:])
|
||||||
|
self.criteria = criteria
|
||||||
|
|
||||||
|
|
||||||
|
def subjectsWithoutLimit(subjectList):
|
||||||
|
return len([subject for subject in subjectList if subject.criteria == 'Alle'])
|
||||||
|
|
||||||
|
|
||||||
|
def averageLimit(subjectList):
|
||||||
|
subjectsWithLimits = [subject for subject in subjectList if subject.criteria != 'Alle']
|
||||||
|
return sum([float(subject.criteria) for subject in subjectsWithLimits]) / len(subjectsWithLimits)
|
||||||
|
|
||||||
|
|
||||||
|
def minLimit(subjectList):
|
||||||
|
subjectsWithLimits = [subject for subject in subjectList if subject.criteria != 'Alle']
|
||||||
|
for subject in subjectsWithLimits:
|
||||||
|
subject.criteria = float(subject.criteria)
|
||||||
|
return min(subjectsWithLimits, key=attrgetter('criteria'))
|
||||||
|
|
||||||
|
|
||||||
|
def getFacultySubjects(subjectList):
|
||||||
|
toDict = lambda subject: {subject.name: subject.criteria}
|
||||||
|
result = {}
|
||||||
|
for subject in subjectList:
|
||||||
|
if not subject.faculty in result: result[subject.faculty] = []
|
||||||
|
result[subject.faculty].append(toDict(subject))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
with open('poenggrenser_2011.csv' ,'r') as file:
|
||||||
|
Subjects = [Subject(*i) for i in reader(file)]
|
||||||
|
|
||||||
|
print('Antall studier hvor alle kom inn:', subjectsWithoutLimit(Subjects))
|
||||||
|
print('Gjennomsnittlig opptaksgrense for NTNU var:', averageLimit(Subjects))
|
||||||
|
|
||||||
|
formatSubject = lambda subject: f'{subject.faculty} {subject.code} {subject.name}'
|
||||||
|
print('Studiet som hadde den laveste opptaksgrensen var:', formatSubject(minLimit(Subjects)))
|
||||||
|
|
||||||
|
print(getFacultySubjects(Subjects))
|
|
@ -0,0 +1,29 @@
|
||||||
|
from re import sub, split
|
||||||
|
|
||||||
|
|
||||||
|
def read_from_file(path):
|
||||||
|
with open(path, 'r') as file:
|
||||||
|
return file.read()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_symbols(string):
|
||||||
|
return sub(r'[^A-Za-z ]', '', string).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def count_words(path):
|
||||||
|
with open(path, 'r') as file:
|
||||||
|
words = split('\s+', remove_symbols(file.read()))
|
||||||
|
if words[0] == '': words = words[1:]
|
||||||
|
if words[-1] == '': words = words[:-1]
|
||||||
|
|
||||||
|
word_counts = {}
|
||||||
|
for word in words:
|
||||||
|
if not word in word_counts: word_counts[word] = 0
|
||||||
|
word_counts[word] += 1
|
||||||
|
return word_counts
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
alice_dict = count_words('alice_in_wonderland.txt')
|
||||||
|
for word, value in alice_dict.items():
|
||||||
|
print(word, value)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,36 @@
|
||||||
|
7
|
||||||
|
4
|
||||||
|
9
|
||||||
|
4
|
||||||
|
1
|
||||||
|
4
|
||||||
|
4
|
||||||
|
3
|
||||||
|
1
|
||||||
|
5
|
||||||
|
3
|
||||||
|
5
|
||||||
|
5
|
||||||
|
7
|
||||||
|
9
|
||||||
|
3
|
||||||
|
2
|
||||||
|
9
|
||||||
|
7
|
||||||
|
3
|
||||||
|
5
|
||||||
|
2
|
||||||
|
5
|
||||||
|
4
|
||||||
|
2
|
||||||
|
6
|
||||||
|
5
|
||||||
|
2
|
||||||
|
3
|
||||||
|
8
|
||||||
|
1
|
||||||
|
4
|
||||||
|
5
|
||||||
|
7
|
||||||
|
9
|
||||||
|
4
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue