if condition based on smarty day of the week and hour of the 24H day in prestashop TPL - task-parallel-library

Good Afternoon,
I'm trying to code an in-page informative in my prestashop template where the product page of each item, based on availability, provides information regarding possible delivery day.
The instrument should show specific rules based on our of the day (24H) and day of the week (1 per Monday, 2 per Tuesday...).
As per now, thanks to an original comment on prestashop forum itself, I have managed to have a working only-on-day-of-the-week based code that actually works, as follows:
{if $product->quantity >= 1}
{assign var="Delivery_day" value=$smarty.now|date_format:"%u"}
{l s='If you are ordering before 11:30 a.m., delivery to Italy will be between'}
{if $Delivery_day == 7}
{"+2 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+3 days"|strtotime|date_format:"d-m-Y"}
{/if}
{if $Delivery_day == 6}
{"+3 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+4 days"|strtotime|date_format:"d-m-Y"}
{/if}
{if $Delivery_day > 0 && $Delivery_day < 6}
{"tomorrow"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+2 days"|strtotime|date_format:"d-m-Y"}
{/if}
{l s='. If later, please get in touch so we can inform you if still able to ship today. For deliveries outside Italy, please count 72H for EU and up to 1 Week for Extra EU'}
{/if}
The update I have coded is the following:
{if $product->quantity >= 1}
{assign var="Delivery_day" value=$smarty.now|date_format:"%u"}
{assign var="Delivery_hour" value=$smarty.now|date_format:"%k"}
{l s='Order now and receive you order in'}
<!-- Domenica -->
{if $Delivery_day == 7}
{"+2 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+3 days"|strtotime|date_format:"d-m-Y"}
{/if}
<!-- Sabato-->
{if $Delivery_day == 6}
{"+3 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+4 days"|strtotime|date_format:"d-m-Y"}
{/if}
<!-- Prima di Mezzo Giorno-->
{if $Delivery_hour > 0 && $Delivery_hour < 12 && $Delivery_hour = 0}
<!-- Lun-Giov-->
{if $Delivery_day > 0 && $Delivery_day < 5}
{"tomorrow"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+2 days"|strtotime|date_format:"d-m-Y"}
{/if}
<!-- Venerdì-->
{if $Delivery_day == 5}
{"+3 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+4 days"|strtotime|date_format:"d-m-Y"}
{/if}
{/if}
<!-- Dopo di Mezzo Giorno-->
{if $Delivery_hour >= 12 && $Delivery_hour <= 23 }
<!-- Lun-Giov-->
{if $Delivery_day > 0 && $Delivery_day < 5}
{"+2 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+3 days"|strtotime|date_format:"d-m-Y"}
{/if}
<!-- Venerdì-->
{if $Delivery_day == 5}
{"+4 days"|strtotime|date_format:"d-m-Y"} {l s='and'} {"+5 days"|strtotime|date_format:"d-m-Y"}
{/if}
{/if}
{l s='. If later, please get in touch so we can inform you if still able to ship today. For deliveries outside Italy, please count 72H for EU and up to 1 Week for Extra EU'}
{/if}
But, unfortunately, my attempt was unsuccessful and I was wondering if there was any chance to understand which conflict I may have created.
Thanks for any reply.
Have a good day!
Francesco

Related

Determine if a given year is a leap year

UPDATE The problem I was trying to solve required a bit more than the Date implementation, as it required a method to take into account both the post-1752 Gregorian and the pre-1752 Julian calendars' differing definitions of a leap year.
The following is my solution, which passed all my RSpecs and is a considerable improvement on the nested conditional I started with:
def leap_year?(year)
gregorian_year = true if year >= 1752
julian_year = true if year < 1752
gregorian_test = true if year % 4 == 0 && year % 100 != 0 || year % 400 == 0
julian_test = true if year % 4 == 0
case
when gregorian_year && gregorian_test
true
when julian_year && julian_test
true
else
false
end
end
ORIGINAL QUESTION
I wrote a simple, ugly nested conditional to achieve the following:
To achieve the following:
Return "true" if the year meets the following conditions:
Is divisible by four
AND is not a century year (e.g.) 1900
UNLESS it is divisible by 400 (e.g. 400, 800, 2000)
I wrote an ugly nested conditional:
if year % 4 == 0
puts "Divisible by four"
if year % 100 == 0
puts "Century year"
if year % 400 == 0
puts "Quad-century year, leap year"
true
else
"Not a Quad-century year, not a leap year"
false
end
else
puts "Not a century year, leap year"
true
end
else
puts "Not divisible by four: not a leap year."
false
end
I tried to achieve the same with a case conditional, but it fails to detect the number 2016 as leap year:
case year
when (year % 4 == 0 && year % 100 != 0)
true
when year % 400
true
when year % 4 != 0
false
end
Two questions:
What am I doing wrong in my case conditional?
Is there a better way to achieve this?
If you would like to determine if a given year is a leap year, that has already been implemented for you in the Date class as Date#leap?:
Date.leap?(2000)
#=> true
# Or, alternatively:
Date.gregorian_leap?(1900)
#=> false
Date.julian_leap?(1900)
#=> true
More info in the Ruby documentation: Date#leap?
If you would like to build it yourself regardless, this should work:
def leap_year?(year)
return false unless year % 4 == 0
return true unless year % 100 == 0
year % 400 == 0
end
leap_year?(2016)
#=> true
Remove the year from case year if your when arguments are all boolean:
case
when (year % 4 == 0 && year % 100 != 0)
true
when year % 400 == 0
true
else
false
end
You can check it works :
def is_leap?(year)
case
when (year % 4 == 0 && year % 100 != 0)
true
when year % 400 == 0
true
else
false
end
end
require 'date'
p (0..2050).all?{|y| Date.leap?(y) == is_leap?(y)}
# true
This variant might be a bit more readable :
def is_leap?(year)
case
when year % 400 == 0
true
when year % 100 == 0
false
when year % 4 == 0
true
else
false
end
end
Finally, you could just write a single expression without any if or case :
year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)

how to print same randomint after if/elif?

I want to get randint to be printed the same as in the if/elif statements each time it executes without a new integer returning. Also is there another way instead of having to write so much code after the while statement or is it fine?
from random import *
def randomchance():
return randint(1, 100)
def randomknife():
return randint(1, 8)
skins = ['blue', 'purple', 'pink', 'red']
knives = ['karambit', 'flip', 'bowie', 'butterfly', 'm9 bayonet', 'bayonet', 'daggers', 'falchion']
print 'Welcome to CS GO case lottery'
for skin in skins:
print "Available", skin,
for knife in knives:
print "Available", knife,
print '(blue = common, purple = uncommon, pink = rare, red = epic)'
keys = 10
while keys >0:
resp=raw_input("Enter 'yes' to open a case: ")
if (resp == str('yes') or resp == str('Yes')):
print 'Opening case...'
if (randomchance() >= 35):
print 'You\'ve won a', skins[0]
elif (randomchance() >= 20):
print 'You\'ve won a', skins[1]
elif (randomchance() >= 10):
print 'You\'ve won a', skins[2]
elif (randomchance() >= 5):
print 'You\'ve won a', skins[3]
elif (randomchance() >= 1):
if randomknife == 1:
print 'You\'ve won a', knifes[0]
elif randomknife() == 2:
print 'You\'ve won a', knifes[1]
elif randomknife() == 3:
print 'You\'ve won a', knifes[2]
elif randomknife() == 4:
print 'You\'ve won a', knifes[3]
elif randomknife() == 5:
print 'You\'ve won a', knifes[4]
elif randomknife() == 6:
print 'You\'ve won a', knifes[5]
elif randomknife() == 7:
print 'You\'ve won a', knifes[6]
elif randomknife() == 8:
print 'You\'ve won a', knifes[7]
keys -= 1
elif(resp == str('no') or resp==str('No')):
resp1=raw_input('Would you like to exit? Enter no for exit: ')
if resp1 == 'no' or "No":
exit()
else:
print "Yes or No. Answers only"
else:
print 'You\'ve run out of keys!'
#Konstantin has the right answer for how to choose the random number just once before testing all your conditions.
As to your second question (how to use less code to test all the conditions), take a look at my rewrite/cleanup below. In particular, I used random.choice to pick a knife, and I used a list of thresholds (35, 20, etc.) to pick skins.
I also fixed up a couple bugs, like your if resp1 == 'no' or "No": which should be if resp1 == 'no' or resp1 == "No": (but I used resp1.lower() instead).
And I couldn't stand 'Would you like to exit? Enter no for exit: ', so I made "yes" exit instead. :-)
import random
skins = ['blue', 'purple', 'pink', 'red']
knives = ['karambit', 'flip', 'bowie', 'butterfly', 'm9 bayonet', 'bayonet', 'daggers', 'falchion']
print 'Welcome to CS GO case lottery'
print "Available skins: %s" % ', '.join(skins)
print "Available knives: %s" % ', '.join(knives)
print '(blue = common, purple = uncommon, pink = rare, red = epic)'
for _ in range(10):
resp = raw_input("Enter 'yes' to open a case: ")
while resp.lower() != 'yes':
if resp.lower() == 'no':
if raw_input('Would you like to exit? ').lower() == 'yes':
exit()
else:
print "Yes or no answers only."
resp = raw_input("Enter 'yes' to open a case: ")
print 'Opening case...'
chance = random.randint(1, 100)
for i, n in enumerate([35, 20, 10, 5]):
if chance >= n:
print "You've won a %s skin." % skins[i]
break
if chance < 5:
print "You've won a %s knife." % random.choice(knives)
print "You've run out of keys!"
Try to save to a variable before if/else statement:
number = randomchance();
if (number >= 35): print 'you select a ', number
This is how I would do it:
knives = ['karambit', 'flip', 'bowie', 'butterfly', 'm9 bayonet', 'bayonet', 'daggers', 'falchion']
skins = ['blue'] * 35 + ['purple'] * 20 + ['pink'] * 10 + ['red'] * 5 + [0]
skin = random.choice(skins)
print "You won a " + skin + " skin" if skin else "You won a " + random.choice(knives) + " knife"

Project Euler #6 in Ruby (What's the difference?)

I solved #6 for Project Euler using two different methods, but the second one just happened to be coincidental. I don't really understand why I don't have to return the square of new_sum like I did for my first method. Does anyone know what's the major difference between the two?
def square_difference(num)
new_sum = 0
sum = 0
while num >= 1
sum += num**2 && new_sum += num
num -= 1
end
return new_sum**2 - sum
end
AND
def square_difference(num)
new_sum = 0
sum = 0
while num >= 1
new_sum += num && sum += num**2
num -= 1
end
return new_sum - sum
end
The precedence of && is higher than that of +=. So these expressions:
sum += num**2 && new_sum += num
new_sum += num && sum += num**2
don't work as you expected. The first one just happen to provide the seemingly "correct" result.
Divide them into separate lines and you'll see the difference. Or, at least use and instead of &&. and has a lower precedence than that of +=.
Both formulas have the same subtle bug. I stepped through it a couple of times to understand what was going on.
From the second one:
[30] pry(main)> square_difference(4)
new_sum: 16, sum: 16, num: 3
new_sum: 41, sum: 25, num: 2
new_sum: 70, sum: 29, num: 1
new_sum: 100, sum: 30, num: 0
=> 70
We can see that new_sum does not seem to be behaving as intended.
What is actually happening is that new_sum += num && sum += num**2 is being evaluated to new_sum += (num && sum += num **2), which in turn evaluates to new_sum += (sum += num **2)
This is a result of the && operator, which has higher precedence (as Yu Hao pointed out) and returns the first value which determines whether the AND condition is satisfied.
[31] pry(main)> 2 && 2
=> 2
[32] pry(main)> 2 && 4
=> 4
[33] pry(main)> 4 && 2
=> 2
[34] pry(main)> nil && 2
=> nil
[35] pry(main)> 2 && nil
=> nil

Simple rock, paper, scissors game

I wrote a "Rock, paper, scissors" game:
puts "Hello, this is a rock, papers, scissors game. Let's play."
puts "Player 1, plase enter your choice: \n"
puts "r for rock. \np for paper. \ns for scissors."
p1 = gets.chomp.downcase
puts "Player 2, please enter your choice: \n"
puts "r for rock. \np for paper. \ns for scissors."
p2 = gets.chomp.downcase
if p1 == 'r' && p2 == 's'
puts "Player 1 wins."
elsif p1 == 'r' && p2 == 'p'
puts "Player 2 wins."
elsif p1 == 'r' && p2 == 'r'
puts "Tie."
elsif p1 == 'p' && p2 == 'r'
puts "Player 1 wins."
elsif p1 == 'p' && p2 == 's'
puts "Player 2 wins."
elsif p1 == 'p' && p2 == 'p'
puts "Tie."
elsif p1 == 's' && p2 == 'r'
puts "Player 2 wins."
elsif p1 == 's' && p2 == 'p'
puts "Player 1 wins."
elsif p1 == 's' && p2 == 's'
puts "Tie."
end
It works, however, that's a lot of elsifs, and I know that this is possible with case...when statements, the thing is that I can't figure out how.
I was trying to use a return statement depending on the input: "return 0 for rock, 1 for paper and 2 for scissors", and then use a conditional to say something like "hey, if player one returns 1 and player 2 also returns 1, then puts 'tie'", and the same for the other possible results.
I was trying to associate a number to the result: return - 1 when player one wins, return 0 for a tie, and return 2 for player two wins.
I did it like this, but it's kind of the same, and I feel that it's so bad:
case p1
when p1 == 'r' && p2 == 'r'
result = 0
when p1 == 'r' && p2 == 'p'
result = 1
when p1 == 'r' && p2 == 's'
result = -1
when p1 == 'p' && p2 == 'r'
result = -1
when p1 == 'p' && p2 == 'p'
result = 0
when p1 == 'p' && p2 == 's'
result = 1
when p1 == 's' && p2 == 'r'
result = 1
when p1 == 's' && p2 == 'p'
result = -1
when p1 == 's' && p2 == 's'
result = 0
end
if result == -1
puts "P1 wins"
elsif result == 0
puts "Tie"
elsif result == 1
puts "P2 wins"
end
I would appreciate any kind of help.
An array can be used as a ring, with each item having
a weaker item to its right, and a stronger one to its left.
weapons = ['paper', 'rock', 'scissors']
select weapons by your favorite means
w1 = weapons[rand(weapons.length)]
w2 = weapons[rand(weapons.length)]
rotate array till w1 is at the center
while weapons[1] != w1
weapons.rotate! 1
end
now the result is indicated by the index of w2 in weapons array, conveniently.
verbs = ['is beat by', 'ties', 'beats']
puts "#{w1} #{verbs[weapons.index(w2)]} #{w2}"
Example output from a few runs:
paper beats rock
paper ties paper
rock beats scissors
scissors beats paper
rock is beat by paper
You could get creative and add a hash of verb-arrays, one for each weapon, using w1 as the key so that it would output (for example) paper covers rock, etc.
You can try something like this :
if (p1 == p2)
puts "Tie"
elsif (p1 == 'r' && p2 == 'p') ||
(p1 == 'p' && p2 == 's') ||
(p1 == 's' && p2 == 'r')
puts "P2 wins"
else
puts "P1 wins"
end
You could also do the ruby equivalent of saying
If p1 = 'r' then
goto R
endif
If p1 = 'p' then
goto S
endif
etc.
then at your goto locations later
R:
if p2 = 'r' then
puts "tie"
etc.
however the idea of p1 = p2 then ... is a good one.
Here's another way:
WINNERS = {s: :p, p: :r, r: :s}
# => {:s=>:p, :p=>:r, :r=>:s}
def win_lose_or_tie?(me, you)
return "I win! :-)" if WINNERS[me] == you
return "you win! :-(" if WINNERS[you] == me
"it's a tie :-|"
end
keys = WINNERS.keys
keys.product(keys).each { |me, you|
puts "If I play #{me} and you play #{you}, then #{win_lose_or_tie?(me, you)}" }
# If I play s and you play s, then it's a tie :-|
# If I play s and you play p, then I win! :-)
# If I play s and you play r, then you win! :-(
# If I play p and you play s, then you win! :-(
# If I play p and you play p, then it's a tie :-|
# If I play p and you play r, then I win! :-)
# If I play r and you play s, then I win! :-)
# If I play r and you play p, then you win! :-(
# If I play r and you play r, then it's a tie :-|
I'd use a case/when statement like:
result = case [p1, p2]
when %w[r r], %w[p p], %w[s s]
0
when %w[r p], %w[p s], %w[s r]
1
when %w[r s], %w[p r], %w[s p]
-1
end
puts case result
when 0
"Tie"
when -1
"P1 wins"
when 1
"P2 wins"
end
But, after writing that this makes more sense:
puts case [p1, p2]
when %w[r r], %w[p p], %w[s s]
'Tie'
when %w[r p], %w[p s], %w[s r]
'P1 wins'
when %w[r s], %w[p r], %w[s p]
'P2 wins'
end
Here's a test:
[
%w[r r], %w[p p], %w[s s],
%w[r p], %w[p s], %w[s r],
%w[r s], %w[p r], %w[s p]
].each do |p1, p2|
puts case [p1, p2]
when %w[r r], %w[p p], %w[s s]
'Tie'
when %w[r p], %w[p s], %w[s r]
'P1 wins'
when %w[r s], %w[p r], %w[s p]
'P2 wins'
end
end
# >> Tie
# >> Tie
# >> Tie
# >> P1 wins
# >> P1 wins
# >> P1 wins
# >> P2 wins
# >> P2 wins
# >> P2 wins

Ruby with Rspec - How is this test passing?

This test passes validations, but how?
#Rspec
it "handles a case with an answer > 1 distance to the left" do
nearest_larger([8,2,4,3], 2).should == 0
end
#Function
def nearest_larger(arr, idx)
diff = 1
loop do
left = idx - diff
right = idx + diff
if (left >= 0) && (arr[left] > arr[idx])
return left
elsif (right < arr.length) && (arr[right] > arr[idx])
return right
elsif (left > 0) && (right >= arr.length)
return nil
end
diff += 1
end
end
I'm working through some ruby examples and I can't understand how this test passes validation. Where is 0 being returned from?
When idx is 2 and diff is 2 (that is, on your second loop), left is 2 - 2 = 0, and arr[0] == 8, which is greater than arr[2] == 4. The function then returns left, which is zero.

Resources