dbwebb-se / webtec

Course repo for web technologies - webtec.
Other
11 stars 8 forks source link

Tips och trix till kmom04 och fotokalendern #16

Open mosbth opened 2 years ago

mosbth commented 2 years ago

Jag började rätta i kmom04 och tog ett par bilder på de första rättningarna och deras fotokalendrar. https://imgur.com/a/8vMRVh3

I Discord har det förekommit ett par tips om hur man kan börja tänka när man jobbar med kalendern, här är ett av de tipsen.

# find a monday to start with
start = find first day in month (or better, find the first monday in the month, or last monday in the previous month

# find a sunday to end with
stop = find last day in month, or even better, find the first sunday in the next month, if the current month does not stop on a sunday

while ( not reached the final sunday + 1) {
    prepare to print details for one week, one row in the month calender

    for (weekday 1 up to 7) {
        print details of each weekday in one row of the month calender
    }
}

Att jobba med en array och foreach kan nog också vara en trevlig lösning. Då hade jag nog preppat arrayen med data först, och sedan loopat igenom den och klurat ut ett fint sätt att "byta rad i html-koden" efter varje söndag.

mosbth commented 2 years ago

Innan jag själv hade börjat koda så hade jag plockat fram ett par grundvärden, ungefär som ovan så förväntar jag mig att jag behöver leta reda på första måndagen och sista söndagen på något sätt. Koden som löser det kan se rätt olik ut, men man bör på något sätt komma fram till något liknande som jag visar i bilden här, innan man sätter igång med loopandet och utskriften av kalendern. Screenshot 2022-09-22 183017

Det kan nu vara en tanke att utgå från den första timestampen och loopa fram + 1 day i taget och "byta rad" varje söndag.

Om man börjar med någon enkel konstruktion så kanske saker faller på plats allt eftersom?

mosbth commented 2 years ago

Att skissa sin problemlösning med pseudokod kan vara ett bra alternativ att snabbt få ned en grov plan på en lösning. Sedan kan man ta kodbitarna steg för steg.

Här är en variant av pseudokod som är en skiss på en loopkonstruktion för fotokalendern. Det kan finnas flera andra varianter av giltiga lösningar, så försök att problemlösa på egen hand.

firstDay = find first day in month, use it to find the date of the first Monday in the calendar
lastDay = find the last day in the month and use it to find the date of the last Sunday in the calendar

<table><tr><th>...</tr>
currentDay = firstDay
while (currentDay not passed the lastDay) {
  <tr>
  Get weekNum from currentDay
  <td>weekNum

  for (i between 1 to 7) {
    Get all details for the currentDay, save in variables
    <td>Print details on this day
    currentDay + 1 day
  }  

  </tr>
} 
</table>
mosbth commented 2 years ago

Enklaste möjliga loop med for (hårdkoda antalet veckor)

Jag klurade lite på hur man gör enklaste möjliga utskriften i loopen. Det handlar en del om problemlösning och veta vad man kan göra med sina datum. Här är pseudokod för en variant som troligen är enkelt att förstå. Lösningen utgår från att om man skriver ut 6 veckor så löser det alltid alla månader. Kanske är det en fullösning, men funkar det så löser det problemet och det är inget bekymmer om det kommer med en extra vecka.

Lösningen bygger på att man har kommit så här långt i sin kod och nu skall skriva ut vecka för vecka och det första man skriver ut är veckonumret.

image

$currentTimestamp = the timestamp of the first day
$numWeeks = 6; 
for ($week = 0; $week < $numWeeks; $week++) {
    // Start the table row
    <tr>

    // Get the current week number
    $currentWeek = Use the current timestamp to get the week number
   <td>$currentWeek

    for ($i = 0; $i < 7; $i++) {
        // Loop from monday to sunday, 7 days in one week
        $currentDate = Get the current date from the current timestamp
        <td>$currentDate

        // Move timestamp one day forward
        $currentDate = Create a date 'Y-m-d' from the current timestamp
        $currentTimestamp = Use $currentDate . " + 1 day" to move the timestamp one day forward
    }

    // Close the table row
    </tr>
}

Kanske är detta det enklaste sättet att lösa fotokalendern, att helt enkelt hårdkoda in att man skriver ut 6 veckor. På det viset slipper man iallafall att försöka klura ut hur man loopar fram till sista dagen och hur det villkoret skulle kunna se ut.

mosbth commented 2 years ago

Om jag kodar enligt for-loopen ovan så blir mitt enda bekymmer att jag får en extra vecka. Men det gör inget. För min del blir resultatet så här när jag lyckats med loopen ovan.

image

Kanske kan jag lösa sista veckan med någon "fix" så jag hoppar ur loopen om det blir en vecka för mycket, men det kan man ta som överkurs.

mosbth commented 2 years ago

Snyggare loop-lösning med do-while

Jag fortsatte klura lite på hur man gör en snyggare lösning med while och där är ju trixet vilket villkor man skall ha i loopen. Det är faktiskt inte uppenbart, iallafall om man är ny på programmering.

Är man ny så kan man nog köra på for-loopen ovan.

Men, om vi skall försöka hitta en snyggare lösning så kan man fundera vidare på vilket villkor man kan ha som löser att man skriver ut rätt antal veckor. Jag gissar att flera av er löser det på något klurigt sätt.

För min egen del så valde jag att använda en do-while loop. Den är ungefär likadan som en while loop, men villkoret ligger i slutet och skillnaden är att man alltid går ett varv i loopen, innan man testar villkoret. I mitt fall gjorde det att jag kunde köra loopen ända fram till $lastDate som i mitt fall var formatterat enligt 2023-01-01 i mitt exemepl med december månad.

Här är en grov pseudokod för en do-while lösning.

// Loop from first day to last day and print each day in a <td>
$currentTimestamp = Timestamp of first day
$currentDate = null;
do {
    // Start the table row 
    // Get the current week number

    for ($i = 0; $i < 7; $i++) {
        // Loop from monday to sunday, 7 days in one week
        // Move one day forward
        $currentDate = 'Y-m-d' according to $currentTimestamp
        $currentTimestamp = $currentday + 1 day
    }

    // Close the table row

} while ($currentDate != $lastDate);

Föredelen med denna lösningen, jämfört med hårdkoda 6 veckor, är att min fotokalender innehåller exakt de veckorna jag vill. Utmaningen är att klura ut villkoret för hur länge man skall loopa i while-loopen, eller som jag gjore, en do-while-loop.

Så här ser min kalender ut nu.

image

mosbth commented 1 year ago

En sak som är lite svår att läsa ut från manualen är hur man kan göra datumberäkningar med funktionen strtotime() och strängar utifrån en timestamp. Kika på följande exempel som användes i en kmom03 zoom.

$firstDayInWeek  = date('Y-m-d', strtotime("Monday this week", $timestamp));
$lastDayInWeek  = date('Y-m-d', strtotime("Sunday this week", $timestamp));
$firstDayInMonth = date('Y-m-d', strtotime("first day of this month", $timestamp));
$lastDayInMonth = date('Y-m-d', strtotime("last day of this month", $timestamp));
$previousMonth = date('Y-m-d', strtotime("first day of previous month", $timestamp));
$nextMonth = date('Y-m-d', strtotime("first day of next month", $timestamp));
mosbth commented 1 month ago

Ibland behöver man leka runt för att hitta rätt startdatum, då kan man skriva små enkla testprogram som tar fram de värden man behöver. Här är ett sådant testprogram.

image

https://github.com/dbwebb-se/webtec/blob/main/example/sample/date.php