Vinnaren i pepparkakshustävlingen!
2016-02-16, 16:06
  #1
Medlem
KruxaNs avatar
Jag läser på högskolan och halva kursen som vi läser för tillfället inriktar sig på Perl. Som handlar om total noll logik i mitt tycke. Vi hade C++ tidigare men det var enkelt att förstå, eftersom det handlar om logiskt tänkande. Men detsamma fungerar inte Perl på samma sätt. Vi har fått "basic scripts" att lösa och det har jag grejat. Men sedan. Så är det ett stort steg mellan dessa och själva huvuduppgiften. Som jag inte alls förstår hur jag ska gå tillväga för att lösa. Inte ens hur jag ska börja.

Instruktionerna lyder: Evaluate number of logins per user and return a list of users and their number of successful logins. It should be possible to order the list of users by their number of logins.

Som sagt, det står absolut noll uppfattning i skallen på mig. Jag ber er inte att lösa min uppgift men att hjälpa mig på vägen.
Citera
2016-02-16, 16:13
  #2
Medlem
BigBusinesss avatar
Fick du ingen mer info?

Var finns informationen om inloggningar? I en fil, ska du hitta på själv, eller har du gjort någon sorts lista av inloggningar ibtidigare uppgift?
Citera
2016-02-16, 16:18
  #3
Medlem
KruxaNs avatar
Vi har använt oss av en lista i form av en CSV-fil med användare utifrån de tidigare grundläggande frågorna.
Citera
2016-02-16, 16:22
  #4
Medlem
BigBusinesss avatar
Iterera listan med inloggningar, för varje lyckad inloggning räknar du upp en hash (nyckel användare, värde antal lyckade inloggningar).

Sen kommer det svåra, sortera på värde. Hittar rätt många exempel vid googling, men förstår dem ärligt talat inte då det var länge sen jag jobbade intensivt med Perl.

Edit:

Blev nyfiken. Här kommer en bra ledtråd från mitt egna experiment:

Kod:
$exampleHash{'ett'} ++;
$exampleHash{'två'} ++;
$exampleHash{'två'} ++;
$exampleHash{'tre'} ++;
$exampleHash{'tre'} ++;
$exampleHash{'tre'} ++;
 
@
keysSortedByValue sort $exampleHash{$a} <=> $exampleHash{$b} } keys %exampleHash;
foreach 
my $sortedKey (@keysSortedByValue) {
        print 
$sortedKey." ".$exampleHash{$sortedKey}."\n";

__________________
Senast redigerad av BigBusiness 2016-02-16 kl. 16:39.
Citera
2016-02-17, 10:30
  #5
Medlem
Låter som konstig uppgift att ge er helt ut utan vägledning.

Men om det är en CSV-fil, får ni använda moduler som tex Text::CSV, isf är det otroligt lätt(*). Nu gav du inget exempel på hur CSV-filen ser ut men jag säger att den ska se ut så här:

Kod:
kungen,10,2016-02-17
tarp,7,2016-02-16
silvia,1,2015-12-24
refat,2,2005-03-12

Inloggningsnamn, antal inloggningar, senaste inloggningen.

Parsa datan:

Kod:
use strict;
use 
warnings;
use 
Text::CSV;

my $filename "/fil/som/innehåller/csv-datan"
my $c Text::CSV->new();
open(my $fh"<"$filename) or die $!;
my @data = ();
while( (
my $arr $c->getline($fh)) ) {
    
push @data, {
        
name => $arr->[0],
        
num => $arr->[1],
        
lastTime => $arr->[2],
    };
}
close($fh); 

Koden öppnar $filename och läser in datan till en array @data. Varje element i arrayen är ett hash med olika nycklar (array of hashes). Man skulle kunnat spara det som en array of array men tycker det är lättare senare med namngivna nycklar istället för [0], [1] etc.

Sen för att sortera och skriva ut det på antal inloggningar (fallande).

Kod:
foreach my $item sort {$b->{'num'} <=> $a->{'num'} || $a cmp $b} @data ) {
     
printf("%s: %d\n"$item->{'name'}, $item->{'num'});


En liten förklaring kanske. sort-syntaxen ser kanske lite mysko ut vid första ögonkastet. "$a" och "$b" är speciella variabler inne i en "sort {} @array". De är helt enkelt de två element som den just nu försöker sortera ur @array. "$a" är det första och "$b" det andra, "<=>" är numerisk jämförelse.

Så den första delen "$b->{'num'} <=> $a->{'num'}" betyder helt enkelt att den jämför "num"-elementen i data med varandra och stoppar det högre först (då $b är före $a).

"||" är vad den ska göra om den hittar två lika värden. Då går den vidare och kör "$a cmp $b", "cmp" här är alfabetisk sortering. Så den sorterar alfabetiskt stigande (då $a är före $b).


(*): Om ni inte får köra med Text::CSV, fråga varför. Modulerna till Perl är otroligt bra och det finns otroligt många, att inte köra de när de finns är bara dumheter. När man ska lära sig ett språk så är ju syntaxen nästan banal i jämförelse med att lära sig moduler och liknande.

men om de verkligen inte får så kan du göra en simpel regexpsökning som inte kommer ta allt men det mesta.

Kod:
while( defined(my $line = <$fh>) ) {
    if( 
$line =~ /^([^,]+),([^,]+),(.+)$/xms ) {
        
push @data, {
            
name => $arr->[0],
            
num => $arr->[1],
            
lastTime => $arr->[2],
        };
    }

Citera
2016-02-17, 17:45
  #6
Medlem
KruxaNs avatar
Jag är riktigt tacksam för era detaljerade svar men jag pratade idag med några klasskamrater och dom nämnde att de använde ingen fil i deras kod. Utan scriptet ska kunna läsa inloggningarna utan en fil.

De nämnde även att kommandot last har alla inloggningar i sig.
__________________
Senast redigerad av KruxaN 2016-02-17 kl. 17:59.
Citera
2016-02-18, 10:01
  #7
Medlem
qx{}:a lite med last då och regexpa fram det.

Fortfarande en mysko uppgift men men.
Citera
2016-02-18, 14:32
  #8
Medlem
KruxaNs avatar
Jag är ledsen. Men allt är total förvirring i mitt huvud. Jag vet nämligen inte ens vart jag ska börja med att använda qx och last.
Citera
2016-02-29, 13:28
  #9
Medlem
Förlåt för lite sent svar, varit ute o rest. Men något liknande för att lista hur många gånger användarna har loggat in.

Kod:
use strict;
use 
warnings;

my %login = ();
foreach 
my $line qx { /usr/bin/last } ) {
    if( 
$line =~ /^(\w+)\s{2,}/xms ) {
        
$login{$1}++;
    }
}

foreach 
my $key sort {$login{$b} <=> $login{$a} || $a cmp $bkeys %login ) {
     
printf("%s: %d\n"$key$login{$key});

Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback