Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tips och trix till kmom04 och fotokalendern #16

Open
mosbth opened this issue Sep 22, 2022 · 7 comments
Open

Tips och trix till kmom04 och fotokalendern #16

mosbth opened this issue Sep 22, 2022 · 7 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@mosbth
Copy link
Member

mosbth commented Sep 22, 2022

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 mosbth added the documentation Improvements or additions to documentation label Sep 22, 2022
@mosbth mosbth self-assigned this Sep 22, 2022
@mosbth
Copy link
Member Author

mosbth commented Sep 22, 2022

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.

  • Starta med en tabell header med månad, år och namnen på veckodagarna.
  • Loopa från första dagen till den sista (på något sätt)
    • Börja med en ny tabellrad <tr>
    • Kanske skriver man ut veckans nummer i första tabell-cellen, <td><?= $weekNum ?></td>
    • Sen kommer en dag per tabell-cell,från måndag till söndag.
    • Använd css-klasser om det är något speciellt med dagen som skall formatteras.
    • När det blir söndag får man byta rad med någon konstruktion likt </tr>
  • Stäng tabellen

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

@mosbth
Copy link
Member Author

mosbth commented Sep 26, 2022

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
Copy link
Member Author

mosbth commented Sep 29, 2022

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
Copy link
Member Author

mosbth commented Sep 29, 2022

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
Copy link
Member Author

mosbth commented Sep 29, 2022

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
Copy link
Member Author

mosbth commented Sep 26, 2023

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
Copy link
Member Author

mosbth commented Oct 15, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant