Permalänk
Medlem

Räkna ut ålder JAVA

Hej.... är ny inom programmering och ska nu börja jobba med mina slutuppgifter i programmerings kursen.
Jag vet att ni inte gör våra läxor men jag behöver verkligen lite tips och råd.

Min logg ser ut som följande:
Jag ber användaren om dess personnr, med hjälp av en switch sats får jag reda på om personen är en kvinna eller man...(här är jag nu)
sedan vill jag ta ut födelseåret ur personnr och beräkna åldern på personen och spara ner resultatet i "rätt" variabel beroende på om det är en kvinna eller man...
därefter vill jag få ut ett medelvärde på summan i variablerna som hela tiden uppdateras och printas ut allt eftersom fler användare matar in sina uppgifter...

Gör jag det onödigt svårt för mig genom att försöka ta ut åldern utifrån personnr om man jämför med om jag bara skulle be användarna att mata in sin ålder och sitt kön direkt?
Det blir ju bättre för mig i scenario 2 men bättre för usern i scenario 1....

Koden ser just nu ut såhär:

package buppgift; import javax.swing.*; public class alt2 { public static void main (String[] arg) { String s = JOptionPane.showInputDialog("Personnumer (ååmmdd-nnnn)?"); switch(s.charAt(9)) { case '0': case '2': case '4': case '6': case '8': int kvinna = + 1; JOptionPane.showMessageDialog(null, "Kvinna " + kvinna); break; case '1': case '3': case '5': case '7': case '9': int man = + 1; JOptionPane.showMessageDialog(null, "Man " + man); break; default: JOptionPane.showMessageDialog(null, "Felaktigt personnummer"); } } }

Letar just nu efter hur jag ska kunna räkna ut åldern utefter personnr men hittar inga vettiga ledtrådar i hur jag ska bära mig åt... jag antar väll att jag ska använda mig av en a.trim och sedan göra någon slags beräkning.
Fasiken det känns som jag kanske tagit mig vatten över huvudet!

[Code]-taggar /screamin-daemon, moderator
Permalänk
Medlem

@Pensum: Om du vill använda personnummer så går det egentligen att göra det så avancerat som du vill. Man kan beräkna en ungefärlig ålder med 2019 - årtalet i personnummret, men det kan ju bli fel på ett år beroende på när personen är född på året.

En gyllene regel när det gäller programmering och datum är dock att inte utföra datumberäkningar själv om man kan undvika det, det är mycket krångligare än man kan tro. Istället bör man använda programmeringsspråkets inbyggda datum-funktioner, eller något bibliotek om språket inte har det inbyggt. Se t.ex. denna genomgång för hur man hantera datum i Java.

Sen kan du fundera på om du kanske ska ta personnummret på formatet ÅÅÅÅMMDD-NNNN istället, så att du får hela årtalet och inte bara de två sista siffrorna.

Och sist men viktigast av allt, se till att din lösning uppfyller kraven för uppgiften. Om uppgiften inte säger att du ska hålla på med personnummer så kanske det är onödigt att krångla till det.

Tillägg: Just det, det obligatoriska tipset eftersom forumet fortfarande saknar knappar för att infoga kod: använd
[code]
Kod här
[/code]
när du skriver in kod, så bevaras formateringen.

Permalänk
99:e percentilen

Ett par tankar:

Plocka ut näst sista siffran

String s = JOptionPane.showInputDialog("Personnumer (ååmmdd-nnnn)?"); switch(s.charAt(9)) { ... }

Här kan flera frågor uppstå i en läsares hjärna:

  • Vadå 9? Varför dyker den siffran upp helt plötsligt? Varför just 9? Tänk särskilt på om koden läses av någon som inte har järnkoll på svenska personnummer. (Nu menar jag inte att det är ett realistiskt scenario för själva uppgiften i sig, men syftet är ju att du ska lära dig principer för programmering.)

  • Vad händer om användaren inte följer ditt format? Vad är "4604300014".charAt(9)? Vad drar ditt program för slutsats om den personen? Vad är "5".charAt(9)?

Om du inte hittar något bättre sätt att beskriva "näst sista siffran" än "siffran på plats 9" kan det åtminstone vara rättfärdigat med en kommentar som beskriver varför det står 9 mitt i koden.

Näst sista siffrans semantik

Raden

case '0': case '2': case '4': case '6': case '8':

och dess komplementrad tål att funderas på. De är ganska våta och möjliggör misstag som till exempel att du råkar glömma en av siffrorna eller att du råkar skriva

case '0': case '2': case '4': case '6': case '6':

och därmed introducerar en riktigt elak bugg.

Uttrycker de raderna verkligen vad du egentligen menar? Om jag skulle beskriva semantiken hos den näst sista siffran i ett personnummer skulle jag inte säga "Om den är en nolla, tvåa, fyra, sexa eller åtta tillhör personnumret en kvinna; om den är en etta, trea, femma, sjua eller nia tillhör det en man", utan hellre "Om den är jämn tillhör personnumret en kvinna; om den är udda tillhör det en man".

Modellering av kön

Kan du berätta lite om vad tanken med variablerna kvinna och man är? Försök sätta ord på det så gott du kan; det hjälper ofta väldigt mycket för att förstå själv. Vi är din gummianka.

Numeriska literaler

Det är inte så idiomatiskt att skriva + 1 för heltalet 1. När man läser

int kvinna = + 1;

kan man inte undgå att tänka att du kanske menar något annat, för det vanliga sättet att skriva den raden på är

int kvinna = 1;

Misstänker personligen att detta kanske hänger ihop med föregående punkt, så vi inväntar dina tankar om variablerna i fråga.

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk
Medlem

1. Reflektera över vad Alling skrev; mycket matnyttigt i den posten.

2. Om du lätt vill kunna "räkna" på datum så finns java.time. Klasserna som är intressanta här är LocalTime och Period. Mer info finns på https://docs.oracle.com/javase/8/docs/api/java/time/package-s...

Du kan inleda med att skapa två datumobjekt, ett för födelsedatumet och ett för dagens datum enligt följande:

LocalDate date_of_birth = LocalDate.of(year, month, day);
LocalDate today = LocalDate.now();

För att få reda på hur lång tid som gått mellan två datum skapar du sedan ett objekt av klassen Period:

Period time_diff = Period.between(date_of_birth, today);

Från denna period kan du sedan ta reda på hur många år som skiljer dessa två datum åt med följande kod:

int age = time_diff.getYears();

Detta tar hänsyn till om födelsedagen inträffat eller ej, så skillnaden, i antal hela år, mellan idag (2019-05-01) och 2000-04-01 är 19 år, medan skillnaden mellan idag (2019-05-01) och 2000-06-01 är 18 år.

Överkurs
----------
Man kan även "bygga ihop" stegen ovan till följande:

int age = Period.between(LocalDate.of(year, month, day), LocalDate.now()).getYears();

Man skall dock vara försiktig med sådant, då det ofta gör koden mer svårläst. Mer komplicerade "byggen" än raden ovan skulle iaf jag välja att skriva stegvis istället.

Permalänk
Medlem

Lite sen till festen, men det kanske kan vara intressant för framtida läsare.
Som Alling berörde kan du titta på om siffran är jämn eller udda.

Detta kan du göra med följande algoritm
https://en.m.wikipedia.org/wiki/Modulo_operation

Kanske blir lite överkurs att lära dig matematiken bakom, men det är en väldigt användbar beräkning som är lätt att implementera.

Visa signatur

Stationär: Core i9 13900k | Asus X790 ROG Strix Gaming-F | 32GB DDR5 | GeForce RTX 5090 | Lian Li PC-O11 dynamic evo
Laptop: Macbook Pro 16" | Apple M1 Max

Permalänk
Medlem

Man kan kolla udda & jämna divisioner genom t.ex.

if(x % 2 == 1) // ej ett jämnt resultat. 1 i rest.

if(x % 2 != 1) // resultatet är jämnt. 0 i rest.

Visa signatur

[IT-Dept]
Ryzen 5700x - 32 - 1070

Permalänk
Hedersmedlem
Skrivet av AllMessedUp:

Man kan kolla udda & jämna divisioner genom t.ex.

if(x % 2 == 1) // ej ett jämnt resultat. 1 i rest.

if(x % 2 != 1) // resultatet är jämnt. 0 i rest.

Vill man ha lite prestanda-tänk(modulus är en relativt tung och iterativ operator) så finns det ett väldigt enkelt sätt att kolla jämna tal.

if((x & 1) == 0) { // Jämnt tal } else { // Udda tal }