Conclusão da semana de trabalho

8

Eu trabalho de nove às cinco. De segunda a sexta. Levo meia hora para o almoço das 12:30 às 13:00.

Escreva-me um programa que, quando executado, calcula a porcentagem da semana de trabalho que completei no momento atual.

Regras

  • Conte apenas o tempo realmente gasto trabalhando. Sou pontual e não trabalho durante o almoço.
  • Sem entrada. Você pode obter informações como hora / data atual, no entanto, é conveniente.
  • A semana de trabalho é considerada completa, de sexta-feira ao fim do dia até meia-noite, entre domingo e segunda-feira.
  • Fuso horário é o fuso horário local.
  • A saída deve ser um número decimal, por exemplo, 66.25498, símbolo de porcentagem opcional.
  • O programa deve ser razoavelmente à prova de futuro. Deve ser capaz de lidar com os anos bissextos.
  • A resolução de saída deve ser um segundo ou melhor. Eu gosto de ver a chaleira ferver.
  • Código de golfe. O menor código vence.
skeevey
fonte
1
Qual é o seu fuso horário? Sistema local? GMT? Ah, e é meia-noite entre sábado e domingo ou domingo e segunda-feira?
Ilmari Karonen
Eu atualizei as regras. Hora local e domingo / segunda-feira à meia-noite.
Skeevey
Você está ganhando salários durante o intervalo para o almoço?
DavidC
Eu não acho que isso faria diferença?
Skeevey 16/08/2012
se você está almoçando, não está trabalhando, portanto, adivinhei em uma semana de trabalho de 37,5 horas
#

Respostas:

4

Q, 111 102

0|100*("i"$(27000000*((.z.d)mod 7)-2)+{0|((17:00:00&x)-09:00:00)-0|00:30:00&x-12:30:00}.z.t)%135000000
tmartin
fonte
5

Python 3, 132

from datetime import*
t=datetime.now().timetuple()
m=max(0,t[3]*2+t[4]/30-18)
print(20*min(5,(t[6]+min(15,m-min(8,max(7,m))+7)/15)))

A resolução é de um minuto ou 2/45 de um por cento. Isso é IMO mais do que suficiente.

Fraxtil
fonte
5

Excel, 132 , 129 , 123 , 119 , 117

cole em A2: A4

=NOW()
=A2-INT(A2)-.375
=(WEEKDAY(A2,3)*7.5+IF(A3<0,0,IF(A3>TIME(8,0,0),7.5,(A3-IF(A3>.1875,TIME(0,30,0),0))*24)))/37.5

formate a célula A4 como% para obter o formato correto

Almoço pago 40 horas por semana:

88 , 81

=NOW()
=A1-INT(A1)-.375
=(WEEKDAY(A1,3)*8+IF(A2<0,0,IF(A2>TIME(8,0,0),8,A2*24)))/40
SeanC
fonte
O primeiro não parece funcionar quando NOW()é depois das 17h.
Gaffi
augh - a * 24 na posição errada .....
SeanC
:-) BTW, bom trabalho me superando na minha abordagem VBA usando fórmulas. Agora estou detalhando ... Sua atualização adicionou um char ( 0) que não é necessário!
Gaffi
minha desculpa é que eu não tenho sido no trabalho após 5:00 por um bom tempo: D
SeanC
2

Perl, 124 caracteres

OK, primeira solução simples para definir o par:

say(($p=((($s,$m,$h,@t)=localtime)[6]+6)%7*20+(($h+=$m/60+$s/3600-9)<0?0:$h<3.5?$h:$h<4?3.5:$h<8?$h-.5:7.5)*8/3)<100?$p:100)

Execute com perl -M5.010para ativar o sayrecurso Perl 5.10+ . A resolução é de um segundo; se a resolução de um minuto for aceitável, a +$s/3600peça poderá ser excluída para um comprimento total de 116 caracteres .

Essa solução é usada localtimepara obter o dia da semana e a hora do dia; portanto, deve funcionar independentemente das alterações do ano, dias bissextos ou qualquer outra peculiaridade do calendário, pelo menos enquanto o ciclo da semana de sete dias não for alterado. As alterações no horário de verão durante a jornada de trabalho o confundiriam um pouco, mas basicamente nunca acontecem de qualquer maneira, presumivelmente precisamente porque isso levaria a muita confusão.

(Para conveniência de teste, observe que localtimeaceita um registro de data e hora do Unix como argumento opcional.)

Ilmari Karonen
fonte
2

Mathematica 169 168 212 214 211 218 210 190 caracteres

Long-winded, pelo código de padrões de golfe.

O seguinte leva em consideração as semanas úteis que cruzam os limites do mês ou ano, bem como os anos bissextos. Considera o tempo trabalhado de acordo com horas e minutos.

Eu não conseguia pensar em uma maneira de evitar soletrar os dias da semana. O Mathematica retorna o dia da semana como uma sequência de 3 caracteres, que deve ser convertida em um número.

h = Plus @@ {#1, #2/60, #3/3600} & @@ Take[DateList[], -3]; 100*Min[37.5, (StringTake[DateString[], 3] /. {"Mon" -> 0, "Tue" -> 1, "Wed" -> 2 , "Thu" -> 3, "Fri" -> 4, _ -> 5})*7.5 + Which[h < 12.5, Max[0, h - 9], h < 13, 4, True, 4 + Min[h - 13, 4]]]/37.5

De-golfe

(* d returns {year, mo, day, h, m, s}   *)
d = DateList[]

(* finished Days: hours worked *)
f = (StringTake[DateString[],  3] /. {"Mon" -> 0, "Tue" -> 1, "Wed" -> 2 , "Thu" -> 3, "Fri" -> 4, _ -> 5})*7.5

(* time of day in hours *)
h = Plus @@ {#1, #2/60} & @@ Take[d, -3]

(* today: hours Worked. It also computes hours for Sat and Sunday but does not use 
them in the final tabulation, which has a maximum of 37.5. *)
t = Which[h < 12.5, Max[0, h - 9], h < 13, 4, _, 4 + Min[h - 13, 4]]

(* hours Worked in week *)
tot = Min[37.5, f + t]

(* % of working week completed *)
100*tot/37.5

semana de trabalho

DavidC
fonte
2

VBA 141

Formatado para executar a partir da janela imediata. Agradecemos a Sean Cheshire por apontar uma melhoria de 10 caracteres!

n=(Now-Int(Now))*24:a=(Weekday(Now,3)*7.5+IIf(n>17,7.5,IIf(n>9,IIf(n<12.5,n,IIf‌​(n>13,n-.5,n))-9,0)))/37.5:MsgBox Format(IIf(a>1,1,a),".0%")
Gaffi
fonte
use n = n * 24, e pode ser reduzido mais. minha luta com ele produziu este: n=(Now-Int(Now))*24:a=(Weekday(Now,3)*7.5+IIf(n>17,7.5,IIf(n>9,IIf(n<12.5,n,IIf(n>13,n-.5,n))-9,0)))/37.5:MsgBox Format(IIf(a>1,1,a),".0%")@ 139
SeanC
@SeanCheshire Excelente ponto! Meu método tinha alguma sintaxe restante de uma versão anterior que usava n, portanto não pôde ser modificada.
Gaffi
1

R, 115 caracteres

---------1---------2---------3---------4---------5---------6---------7---------8---------9---------0---------1---------2
T=as.POSIXlt(Sys.time()-86400);z=T$h+T$mi/60-9;D=function(x,M)min(M,max(0,x));D(((D(z,8)-D(z-3.5,.5))/7.5+T$w)/5,1)

Aqui está uma simulação de uma semana:

week.frac <- function(t) {
   T <- as.POSIXlt(t-86400)
   z <- T$h+T$mi/60-9
   D <- function(x,M)min(M,max(0,x))
   D(((D(z,8)-D(z-3.5,.5))/7.5+T$w)/5,1)
}

time <- seq(from = as.POSIXlt(as.Date("2012-08-20")),
            to   = as.POSIXlt(as.Date("2012-08-27")),
            by   = "min")
week.completion <- sapply(time, week.frac)
plot(time, week.completion, type = "l")

conclusão da semana para a semana atual

modelo
fonte
1

Ruby, 191 116.115 113

A lógica é roubada da solução Fraxtils Python .

t=Time.now
d=t.wday
m=[0,t.hour*2+t.min/3e1-18].max
p d<1?100:20*[5,(d-1+[15,m-[8,[7,m].max].min+7].min/15)].min

Se você quiser testar o código com o teste de unidade, precisará desta solução de 143 caracteres:

class Time  
def r
m=[0,hour*2+min/3e1-18].max
d=wday
d<1?100:20*[5,(d-1+[15,m-[8,[7,m].max].min+7].min/15)].min
end    
end
p Time.now.r

Não é o código mais curto e mais eficiente, mas com um teste de unidade;)

Os 191 caracteres incluem as novas linhas (eu poderia torná-lo uma linha, basta substituir cada nova linha por a ;).

class Time
def r
i=0
d{|t|i+=t.w}
i/1350.0
end
def d
t=dup
yield t-=1 until t.strftime('%w%T')=='109:00:00'
end
def w
h=hour
wday<1||wday>5||h<9||h>16||h==12&&min>29?0:1
end
end
p Time.now.r

E o código de teste:

require 'test/unit'
class MyTest < Test::Unit::TestCase
  def test_mo
    assert_equal( 20, Time.new(2012,8,13,20).r) #monday
  end
  def test_tue
    assert_equal( 40, Time.new(2012,8,14,20).r) #tuesday
  end
  def test_wed_morning
    assert_equal( 40, Time.new(2012,8,15,7).r)
  end
  def test_wed
    assert_equal( 60, Time.new(2012,8,15,20).r)
  end
  def test_thu
    assert_equal( 80, Time.new(2012,8,16,20).r)
  end
  def test_fri
    assert_equal(100, Time.new(2012,8,17,20).r)
  end
  def test_sat
    assert_equal(100, Time.new(2012,8,18,20).r)
  end
  def test_sun
    assert_equal(100, Time.new(2012,8,19,20).r)
  end
  def test_middle
    assert_equal(50, Time.new(2012,8,15,13,15).r)
  end
end
knut
fonte
0

Python 2 130 caracteres

from datetime import*
t=datetime.now().timetuple();
m=min
a=max
n=t[3]+t[4]/60.0
print m(17,a(9,n))-9-(a(0,m(.5,n-12.5)))+7.5*m(t[6],4)

Meh terceira tentativa é molho fraco, mas acho que entendi a lógica.

chucksmash
fonte
1
Isso não funciona. Em uma rápida olhada na saída, não há longos períodos em que a porcentagem permanece a mesma, o que deve acontecer entre as 17h de cada dia e as 9h do dia seguinte, bem como a cada 12:30 -1: 00 PM. Também gera números negativos e números maiores que 100 às vezes.
Fraxtil
Oh, que vergonha para mim. Você está absolutamente correto. Mulligan.
Chucksmash 17/08/2012
@Fraxtil eu acho que já afiou-lo por um fio de cabelo
chucksmash
Parece ter um intervalo de 0 a 37,5. No entanto, ele pausa durante os intervalos apropriados.
Fraxtil
Ah, eu tinha configurado para imprimir o número de horas para depuração. Esqueci de alterá-lo para% para resposta. Eu estou supondo que eu não vou ser capaz de fazer isso em 2 personagens, então eu acho que você me pegou depois de tudo
chucksmash