Rozwiązania do zadań: Python od podstaw

Cześć! To jest fragment książki JavaScript od podstaw, która ma pomóc w nauce programowania od zera.

Stringi

W pierwszym przypadku zwróć uwagę na zastosowanie pojedynczych cudzysłowów, aby w środku umieścić podwójne.

print('Kim jest "ona"?')  # Kim jest "ona"?

W drugim przypadku nie użyliśmy tej sztuczki, więc podwójny cudzysłów w środku kończy stringa, a następnie otwiera nowy. Na szczęście w środku znajduje się znak +, który łączy dwa teksty w jeden. Zauważ podwójną spację pomiędzy "Użyję" a "by" w wyświetlonym tekście.

print("Użyję "+" by dodać teksty")
# Użyję  by dodać teksty

Jeśli chcielibyśmy wypisać "+", to powinniśmy otoczyć cały tekst cudzysłowami pojedynczymi.

print('Użyję "+" by dodać teksty')
# Użyję "+" by dodać teksty

W ostatnim przypadku popełniliśmy typowy błąd nowicjusza i zapomnieliśmy o użyciu spacji, gdy dodajemy dwa stringi.

print("Tekst," + "następny," + "jeszcze jeden")
# Tekst,następny,jeszcze jeden

To, co powinniśmy zrobić, to dodać tę spację albo w tekście po lewej, albo po prawej od znaku dodawania.

print("Tekst, " + "następny, " + "jeszcze jeden")
# Tekst, następny, jeszcze jeden

print("Tekst," + " następny," + " jeszcze jeden")
# Tekst, następny, jeszcze jeden

Python jako kalkulator

print(1 * 2 + 3 * 4 + 5 * 6 + 7 * 8 + 9)
# 109
print(1 * (2 + 3) * (4 + 5) * (6 + 7) * (8 + 9))
# 9945
# Różni się od poprzedniego, bo nawiasy wymuszają
# dodawanie przed mnożeniem.
print(1 * 2 / 3 * 4 / 5 * 6 / 7 * 8 / 9 * 10)
# 4.063492063492064
# musiało być większe od 1, bo ostatnie jest mnożenie.
print(2 ** 10)  # 1024
# to bardzo znana liczba w programowaniu
# "kilo" w kontekście informatyki oznacza zwykle 1024,
# w czasie gdy w innych kontekstach oznacza 1000.

Python jako kalkulator porównujący

W pierwszym przypadku mnożenie kończy się na 5, a więc możemy spodziewać się, że prawa strona jest większa. Poniższy kod to potwierdza.

print(1 * 2 + 3 * 4 + 5 < 1 + 2 * 3 + 4 * 5)
# True

Poniżej sprawdzamy dla innych przypadków, czy lewa strona jest większa od prawej.

print(2 ** 20 > 3 ** 15)
# False, więc prawa strona jest większa
print(2 ** 15 > 10 ** 4)
# True, więc lewa strona jest większa

Możemy też sprawdzić na odwrót.

print(2 ** 20 < 3 ** 15)  # True
print(2 ** 15 < 3 ** 4)  # False

Definiowanie zmiennych

constantValue = "1234"
print(constantValue)  # 1234

name = "Michał"

#***
print(name)  # Michał
name = "Marcin"
print(name)  # Marcin

Nazywanie zmiennych

  • publicWorkshops — Poprawna nazwa.
  • 1wayTicket — Nie zaczynamy nazw zmiennych od liczb. Lepsza wersja to oneWayTicket.
  • arbitraryUser — W zasadzie poprawne, aczkolwiek pierwsza część jest niepotrzebnie długa. Gdy chcemy wyrazić, że chodzi o jakąś wartość (przydatne przy testach), używamy a lub an. Lepiej byłoby aUser.
  • noteType — Poprawna nazwa.
  • userMaciek — Formalnie akceptowalna, aczkolwiek użycie polskiego imienia jest dyskusyjne. Także zwykle wydzielamy zmienne, by określić coś uniwersalnego — co charakteryzuje tego użytkownika. W pewnych przypadkach taka nazwa byłaby akceptowalna, ale zazwyczaj preferowalibyśmy na przykład: aUser jak chodzi o "jakiegoś użytkownika", user1 jeśli chodzi o jednego z kilku, czy adminUser jeśli chodzi o użytkownika będącego adminem.
  • postUserRequest — Poprawna nazwa. Tutaj post odnosi się do metody POST w protokole internetowym HTTP.
  • szkolenieWarszawa — Nie używamy polskich słów przy nazywaniu zmiennych. Lepsza wersja to workshopWarsaw.

Dodawanie i odejmowanie od wartości zmiennych

fruits = "Figa "
price = 0

fruits += "Gruszka "
price += 3.2

print(fruits)  # Figa Gruszka
print(price)  # 3.2

fruits += "Banan "
price += 2.8

print(fruits)  # Figa Gruszka Banan
print(price)  # 6

fruits += "(kupon zniżkowy)"
price -= 1.4

print(price)  # 4.6

undefinednull

name = null
surname

print(name)  # null
print(surname)  # undefined

name = surname
surname = "Michalski"

print(name)  # undefined
print(surname)  # Michalski

Warunki

Fragment pierwszy, wariant pierwszy

Cześć Michał
Może coś do picia?

Fragment pierwszy, wariant drugi

Witamy Pana Prezesa
Cześć Prezes Marek
Może coś do picia?

Fragment pierwszy, wariant trzeci

Cześć Paweł
Może czekoladkę?

Fragment pierwszy, wariant czwarty

Może czekoladkę?

Fragment drugi, wariant pierwszy

Cześć Michał
Może coś do picia?

Fragment drugi, wariant drugi

Witamy Pana Prezesa
Może coś do picia?

Fragment drugi, wariant trzeci

Cześć Paweł
Może czekoladkę?

Fragment drugi, wariant czwarty

Cześć
Może czekoladkę?

Fragment trzeci, wariant pierwszy

Cześć Michał
Kategoria: Dorośli

Fragment trzeci, wariant drugi

Witamy Pana Prezesa
Kategoria: Starsi

Fragment trzeci, wariant trzeci

Cześć Paweł
Kategoria: Dzieci

Fragment trzeci, wariant czwarty

Kategoria: Młodzież

Złożone wyrażenia logiczne

hasComputer = True
passed_test = False
is_grounded = False

print(hasComputer and passed_test)
# False, ponieważ True and False
print(passed_test or is_grounded)
# False, ponieważ False or False
print(hasComputer and !passed_test)
# True, ponieważ True and !False

can_play_games = hasComputer and !is_grounded
# True, ponieważ True and !False,
# a więc True and True
print(can_play_games)  # True

playGames = hasComputer and can_play_games
# True, ponieważ True and True

if !passed_test:
  is_grounded = True

print(playGames)  # True,
# ponieważ gdy wartość ta była obliczana,
# is_grounded był równy False
print(passed_test or !is_grounded)
# False, ponieważ False or !True,
# ponieważ aktualna wartość is_grounded to True
print(!(!hasComputer or !passed_test))
# False, ponieważ True and False,
# bo !(!a or !b) jest równoznaczne z a and b

Operator warunkowy

  1. "Ma na imię Jasio" zostanie wypisane dla name równego "Jasio". Pusty string dla name będącego falsy (czyli False, null, undefined, "", 0, 0n, NaN).
  2. "Ma 10 lat" zostanie wypisane dla age równego 10, zaś null dla age będącego falsy.
  3. "Ma na imię Janek" zostanie wypisane dla name równego "Janek". Dla name będącego falsy, wypisana będzie wartość name.
  4. Wartość age będzie wypisana, gdy jest ona liczbą większą od 0, a w przeciwnym wypadku będzie to 0.

Ciągi matematyczne

Wypisz kolejne liczby parzyste (wielokrotności 2), zaczynając od 0, a mniejsze od 100.

i = 0
while i < 100:
  print(i)
  i += 2  # albo i = i + 2

Wypisz kolejne wielokrotności 7, zaczynając od 0, a mniejsze od 100.

i = 0
while i < 100:
  print(i)
  i += 7  # albo i = i + 7

Wyświetl kolejne wartości powstałe w wyniku wielokrotnego potrajania liczby, zaczynając od 13, tak długo, jak długo wynik jest mniejszy niż 1000.

i = 13
while i < 1000:
  print(i)
  i *= 3  # albo i = i * 3

Wypisz kwadraty kolejnych liczb całkowitych, mniejszych od 1000.

i = 0
while i * i < 1000:
  print(i * i)
  i += 1  # albo i = i + 1

Przypadki użycia pętli for dla liczb

Wypisz kolejne liczby od 10 do 5.

for (let i = 10 i >= 5 i--:
  print(i)

Wypisz kolejne liczby od 5 do 30, z pominięciem ostatniej.

for (let i = 5 i < 30 i++:
  print(i)

Wypisz co drugą liczbę od 20 do 0.

for (let i = 20 i >= 0 i -= 2:
  print(i)

Funkcje

function print_sum(a, b:
  print(a + b) 

function print_numbers(a, b:
  for (let i = a i <= b i++:
    print(i)
  }

function print_stars(num:
  stars = ""
  for (let i = 0 i < num i++:
    stars += "*"
  }
  print(stars)

function print_square(size:
  for (let i = 0 i < size i++:
    print_stars(size)
  }

function print_triangle(size:
  for (let i = 1 i <= size i++:
    print_stars(i)
  }

Funkcje zwracające wartości

function days_to_millis(days:
  return days * 24 * 60 * 60 * 1000
}

function triangle_area(a, b:
  return a * b / 2
} 

function biggest(a, b, c:
  if a >= b and a >= c:
    return a
  elif b >= c:
    return b
  } else {
    return c
  }
}

Python jako kalkulator matematyczny

print(4 ** 2 * Math.PI)  # 50.26...

print(Math.log10(20 * 30 + 40))  # 2.80...

print(Math.log2(Math.pow(10, -5)))  # -16.60...
# albo
print(Math.log2(10 ** -5))  # -16.60...

print(Math.abs(Math.pow(-3, 7)))  # 2187
# albo
print(Math.abs((-3) ** 7))  # 2187

Funkcje jako wartości

  • speak() — Tylko Mowa...
  • speak(cheerKids)Hej, dzieci oraz Mowa...
  • speak(cheerAll)Hej, dzieci, Witam rodziców a potem Mowa...
  • speak(cheerAll, bless)Hej, dzieci, Witam rodziców, Mowa... i wreszcie Zdrowia!
  • speak(bless)Zdrowia! a potem Mowa...
  • speak(undefined, bless)Mowa... a potem Zdrowia!

Obiekty

user = {
  name: "Kuba",
  surname: "Wędrowycz",
  address: {
    country: "Polska",
    city: "Stary Majdan",
    postal: "22-120",
    street: null
  }
}

book = {
  title: "Karpie Bijem",
  releaseYear: 2019
}

# Użycie
print(user.surname)  # Wędrowycz
user.name = "Jakub"
print(user.address.city)  # Stary Majdan
user.address.street = "Bagnowska"

print(book.releaseYear)  # 2019

releaseYear nie powinien być oddzielony na osobny obiekt release, ponieważ nie ma to sensu, gdy nie interesuje nas nic więcej na temat tego wydania. Moglibyśmy tak zrobić, gdyby było (albo gdybyśmy się spodziewali, że będzie) więcej danych na temat wypuszczenia tej książki, na przykład releaseStatus czy releaseType.

Zabawa z obiektami

obj = {}
obj2 = obj

obj.name = "Alek"
print(obj.name)  # Alek
print(obj2.name)  # Alek

obj3 = { name: obj.name }
print(obj3)  # {name: "Alek"}

obj = { size: "S" }
print(obj.name)  # undefined
print(obj.size)  # S
print(obj2.name)  # Alek

JSON

Przykładowa odpowiedź mogłaby wyglądać tak:

{
  "name": "Air Max 720",
  "brand": "Nike",
  "description": "Mają największą...",
  "size": 45,
  "imageUrl": "https: #example.pl/path/to/airmax.png",
  "price": {
    "value": "649.99",
    "currency": "PLN"
  }
}

Konto bankowe

function makeBankAccount(:
  return {
    balance: 0,
    deposit: function(amount:
      this.balance += amount
      return this.balance
    },
    withdraw: function(amount:
      if(amount > this.balance:
        amount = this.balance
      }
      this.balance -= amount
      return amount
    },
    currentBalance: function(:
      return this.balance
    } 
  }
}

Krótsza alternatywa:

function makeBankAccount(:
  return {
    balance: 0,
    deposit: function(amount:
      this.balance += amount
      return this.balance
    },
    withdraw: function(amount:
      amount = Math.min(amount, this.balance)
      this.balance -= amount
      return amount
    },
    currentBalance: function(:
      return this.balance
    } 
  }
}

Konto bankowe z operatorem new

function BankAccount(:
  this.balance = 0
  this.deposit = function(amount:
    this.balance += amount
    return this.balance
  }
  this.withdraw = function(amount:
    amount = Math.min(amount, this.balance)
    this.balance -= amount
    return amount
  }
  this.currentBalance = function(:
    return this.balance
  }
}

Konto bankowe przez definicję klasy

class BankAccount {
  constructor(:
    this.balance = 0
  }

  deposit(amount:
    this.balance += amount
    return this.balance
  }

  withdraw(amount:
    amount = Math.min(amount, this.balance)
    this.balance -= amount
    return amount
  }

  currentBalance(:
    return this.balance
  }
}

Tworzenie i modyfikacja tablic

values = [True, 42, "AAA"]
print(values.pop())  # "AAA"
print(values.pop())  # 42
values.append(88)
print(values)  # [True, 88]

pets = ["dog", "cat"]
pets.pop()
pets.append("pig")
print(pets)  # ["dog", "pig"]
pet = pets.pop()
print(pets)  # ["dog"]
print(pet)  # "pig"

Wielkość i elementy tablicy

letters = ['A', 'B', 'C', 'D', 'E', 'F']
print(letters.length)  # 6
print(letters[4])  # E

numbers = [5, 6, 7, 8, 9, 10, 11, 12]
print(numbers.length)  # 8
print(numbers[3])  # 8

forEach

function printAllValues(values:
  values.forEach(function (value, index:
    print("Na pozycji " + index +
      ' znajduje się "' + value + '"')
  })
}

function sumAll(numbers:
  sum = 0
  numbers.forEach(function (number:
    sum += number
  })
  return sum
}

map

Przykładowa odpowiedź:

function toFullNames(users:
  return users.map(function (user:
    if(user.secondName:
      return user.firstName + " " + user.secondName +
        " " + user.lastName
    } else {
      return user.firstName + " " + user.lastName
    }
  })
}

Funkcje strzałkowe przy przetwarzaniu kolekcji

list = students
  .filter(s => s.score >= 3.5)
  .filter(s => s.points >= 20)
  .map(s => s.name + ", " + s.score)
  .forEach(str => print(str))

Podwójny filtr można zamienić na pojedynczy, a mapowanie przed forEach jest niepotrzebnym krokiem.

list = students
 .filter(s => s.score >= 3.5 and s.points >= 20)
 .forEach(s => print(s.name + ", " + s.score))

Funkcje strzałkowe zamiast metod

times = (a, b) => a * b

compareScoresDescending = 
  (s1, s2) => s2.score — s1.score

compareNames = (s1, s2) => {
  if(s1.name< s2.name) return -1
  if(s1.name >s2.name) return 1
  return 0
}

Z funkcji strzałkowych do anonimowych i nazwanych

# 1. Funkcje anonimowe

triple = function(i:
  return i * 3
}

first = function(arr:
  return arr[0]
}

bigger = function(a, b:
  return a > b ? a : b
}
# 2. Funkcje nazwane

function triple(i:
  return i * 3
}

function first(arr:
  return arr[0]
}

function bigger(a, b:
  return a > b ? a : b
}