Dynamic conditional statement in DAX - powerbi

Is there a way in which I can write a dynamic conditional statement. For example, I want to see that my data can be grouped by 50 or 100 by just tipping the value 50 or 100.
table = generate(1,9000000, 0.01)
Here there is an example, when I want to group the data by 50
= Table.AddColumn(one_pm_test_lm_5_sek_xyl_1_Table, "XLenght bin", each if
[XLength] >= 500 then "500 and above"
else if [XLength] >= 450 then "450 - 500"
else if [XLength] >= 400 then "400 - 450"
else if [XLength] >= 350 then "350 - 400"
else if [XLength] >= 300 then "300 - 350"
else if [XLength] >= 250 then "250 - 300"
else if [XLength] >= 200 then "200 - 250"
else if [XLength] >= 150 then "150 - 200"
else if [XLength] >= 100 then "100 - 150"
else if [XLength] >= 50 then "50 - 100"
else "50 or below")
I try to create a dynamic function or something like that which makes posible that I group the data for example in 50. Until now, I make it manually. I would like to know if there is another way to do it in order to enter the values manually.
XLength Group = SWITCH(TRUE(),
[XLength] < 50, "<50",
[XLength] <= 100, "50-100",
[XLength] <= 150, "100-150",
[XLength] <= 200, "150-200",
[XLength] <= 250, "200-250",
[XLength] <= 300, "250-300",
[XLength] <= 350, "300-350",
[XLength] <= 400, "350-400",
[XLength] <= 450, "400-450",
[XLength] <= 500, "450-500",
[XLength] > 500, "500+")

Related

Switch true for min and max range in power bi desktop

I am trying to specify each dimension range (length, width and height) of values specify criteria based on the length, width and height.
In data table I have 3 columns are length, width,height based on the 3 columns I would like to generate status columns which is based on the below mentioned condition range.
Conditions Range
Length, width and height is start from 1 to 300 then A1.
Length, width and height is start from 301 to 650 then A2.
Length, width and height is start from 651 to 900 then A3.
Length, width and height is start from 901 to 1200 then A4
Length, width and height is start from 1201 above then XXX
Data
LENGTH
WIDTH
HEIGHT
DESIRED RESULT RANGE
NA
NA
NA
NA
20000
5000
230
XX
400
300
140
A1
BLANKS
600
400
285
A2
600
400
285
A2
400
300
150
A1
280
230
170
A1
320
320
320
A1
320
320
320
A1
600
400
140
A1
400
300
140
A1
400
300
140
A1
370
320
340
A1
320
240
250
A1
300
200
90
A1
400
290
140
A1
600
400
285
A1
Table and result look like
Any suggestions please
Well, you may try the following dax measure, as it will assign all row to each category, and assign to Other if does not match any of the criteria, do take note due to your data contain NA, therefore all the value is in Text for that need to convert to number during calculation:
Result = IF(Sheet1[LENGTH] = "NA" || Sheet1[WIDTH] = "NA" || Sheet1[HEIGHT] ="NA", "NA",
IF(VALUE(Sheet1[LENGTH])>0 && VALUE(Sheet1[LENGTH]) <=300 && VALUE(Sheet1[WIDTH]) >0 && VALUE(Sheet1[WIDTH]) <=300 && VALUE(Sheet1[HEIGHT]) >0 && VALUE(Sheet1 [HEIGHT]) <=300, "A1",
IF(VALUE(Sheet1[LENGTH])>300 && VALUE(Sheet1[LENGTH]) <=650 && VALUE(Sheet1[WIDTH]) >300 && VALUE(Sheet1[WIDTH]) <=650 && VALUE(Sheet1[HEIGHT]) >300 && VALUE (Sheet1[HEIGHT]) <=650, "A2",
IF(VALUE(Sheet1[LENGTH])>650 && VALUE(Sheet1[LENGTH]) <=900 && VALUE(Sheet1[WIDTH]) >650 && VALUE(Sheet1[WIDTH]) <=900 && VALUE(Sheet1[HEIGHT]) >650 && VALUE (Sheet1[HEIGHT]) <=900, "A3",
IF(VALUE(Sheet1[LENGTH])>900 && VALUE(Sheet1[LENGTH]) <=1200 && VALUE(Sheet1[WIDTH]) >900 && VALUE(Sheet1[WIDTH]) <=1200 && VALUE(Sheet1[HEIGHT]) >900 && VALUE(Sheet1[HEIGHT]) <=1200, "A4",
IF(VALUE(Sheet1[LENGTH])>1200 && VALUE(Sheet1[WIDTH]) >1200 && VALUE(Sheet1[HEIGHT]) >1200 , "XXX",
"Others"))))))
Result:

Math: How to optimize this if so it looks cleaner and faster?

This solution looks ugly. I've tried to simplify using a vector and cycling a vector but would it be faster? I tried making up a formula to retrieve these numbers but I'm terrible at math!
if (SkillValue > 115 && SkillValue <= 135)
{
return 100 / 2;
}
else if (SkillValue > 135 && SkillValue <= 160)
{
return 100 / 3;
}
else if (SkillValue > 160 && SkillValue <= 190)
{
return 100 / 4;
}
else if (SkillValue > 190 && SkillValue <= 215)
{
return 100 / 5;
}
else if (SkillValue > 215 && SkillValue <= 295)
{
return 100 / 6;
}
else if (SkillValue > 295 && SkillValue <= 315)
{
return 100 / 9;
}
else if (SkillValue > 315 && SkillValue <= 355)
{
return 100 / 10;
}
else if (SkillValue > 355 && SkillValue <= 425)
{
return 100 / 11;
}
else if (SkillValue > 425 && SkillValue < 450)
{
return 100 / 12;
}
return 100;
}
There doesn't appear to be any pattern to the bounds for each if condition, or at least any pattern that would let you write this as a closed form check.
However, you are currently checking all the if conditions, which is O(n) where n is the number of conditions. You can do this in O(log(n)) by using std::lower_bound on a range to find the value of the denominator, like this:
std::array bounds { 115, 135, 160, 190, ... };
std::array dens {1, 2, 3, 4, ... , 1}; // extra 1 at the end to account for the
// case that none of the bounds match
auto it = std::lower_bound(std::begin(bounds), std::end(bounds), SkillValue);
return 100 / dens[std::distance(std::begin(bounds), it)];
Right off the bat, you are repeating logic in each conditional that can be refactored out of the previous conditionals by switching to the following form:
if (SkillValue <= 115) {
return 100/1;
} else if (SkillValue <= 135) {// the 'else' explicitly means that it is already NOT <= 115, aka IS > 115, so no need to repeat with a '&&'
return 100/2;
} else if (SkillValue <= 160) {
return 100/3;
} else if (SkillValue <= 190) {
return 100/4;
}//... and so on
It's hard to find an equation to compute your result because your ranges are not equal in size, and the divisor jumps at 295.
To make a more compact version, here's a way:
#include <algorithm>
#include <iterator>
// 296 repeats to compensate for the jump in your divisor
constexpr int ranges[] = {0, 115, 136, 161, 191, 216, 296, 296, 296, 316, 356, 426, 456};
int compute(int SkillValue) {
if (SkillValue <= 115 or SkillValue >= 450) {
return 100;
}
auto elt = std::upper_bound(std::begin(ranges), std::end(ranges), SkillValue);
return 100 / (elt == std::end(ranges) ? 1 : elt - std::begin(ranges));
}
This computes the same output as your original function, but I can't actually say I like it any better.
Using a map, it's a little easier to read:
#include <map>
const std::map<int,int> ranges {
{115, 1},
{135, 2},
{160, 3},
{190, 4},
{215, 5},
{295, 6},
{315, 9},
{355, 10},
{425, 11},
{450, 12}
};
int compute(int SkillValue) {
if (SkillValue <= 115 or SkillValue >= 450) return 100;
auto elt = ranges.upper_bound(SkillValue-1);
return 100 / (elt == std::end(ranges) ? 1 : elt->second);
}

Python Pandas: Create Groups by Range using map

I have a large data set where I am looking to create groups based upon cumulative sum percent of the total. I have gotten this to work by using the map function see below code. Is there a better way to do this say if I wanted to make my groups even more granular? So for example now am looking at 5% increments...what if want to look at 1 % increments. Wondering if there is another way where I don't have to explicitly enter them into my "codethem" function.
def codethem(dl):
if dl < .05 : return '5'
elif .05 < dl <= .1: return '10'
elif .1 < dl <= .15: return '15'
elif .15 < dl <= .2: return '20'
elif .2 < dl <= .25: return '25'
elif .25 < dl <= .3: return '30'
elif .3 < dl <= .35: return '35'
elif .35 < dl <= .4: return '40'
elif .4 < dl <= .45: return '45'
elif .45 < dl <= .5: return '50'
elif .5 < dl <= .55: return '55'
elif .55 < dl <= .6: return '60'
elif .6 < dl <= .65: return '65'
elif .65 < dl <= .7: return '70'
elif .7 < dl <= .75: return '75'
elif .75 < dl <= .8: return '80'
elif .8 < dl <= .85: return '85'
elif .85 < dl <= .9: return '90'
elif .9 < dl <= .95: return '95'
elif .95 < dl <= 1: return '100'
else: return 'None'
my_df['code'] = my_df['sales_csum_aspercent'].map(code them)
Thank you!
there is a special method for that - pd.cut()
Demo:
create random DF:
In [393]: df = pd.DataFrame({'a': np.random.rand(10)})
In [394]: df
Out[394]:
a
0 0.860256
1 0.399267
2 0.209185
3 0.773647
4 0.294845
5 0.883161
6 0.985758
7 0.559730
8 0.723033
9 0.126226
we should specify bins when calling pd.cut():
In [404]: np.linspace(0, 1, 11)
Out[404]: array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
In [395]: pd.cut(df.a, bins=np.linspace(0, 1, 11))
Out[395]:
0 (0.8, 0.9]
1 (0.3, 0.4]
2 (0.2, 0.3]
3 (0.7, 0.8]
4 (0.2, 0.3]
5 (0.8, 0.9]
6 (0.9, 1]
7 (0.5, 0.6]
8 (0.7, 0.8]
9 (0.1, 0.2]
Name: a, dtype: category
Categories (10, object): [(0, 0.1] < (0.1, 0.2] < (0.2, 0.3] < (0.3, 0.4] ... (0.6, 0.7] < (0.7, 0.8] < (0.8, 0.9] < (0.9, 1]]
if we want to have a custom labels, we should explicitly specify them:
In [401]: bins = np.linspace(0,1, 11)
NOTE: bin labels must be one fewer than the number of bin edges
In [402]: labels = (bins[1:]*100).astype(int)
In [412]: labels
Out[412]: array([ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
In [403]: pd.cut(df.a, bins=bins, labels=labels)
Out[403]:
0 90
1 40
2 30
3 80
4 30
5 90
6 100
7 60
8 80
9 20
Name: a, dtype: category
Categories (10, int64): [10 < 20 < 30 < 40 ... 70 < 80 < 90 < 100]
Lets do it with the 5% step
In [419]: bins = np.linspace(0, 1, 21)
In [420]: bins
Out[420]: array([ 0. , 0.05, 0.1 , 0.15, 0.2 , 0.25, 0.3 , 0.35, 0.4 , 0.45, 0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.8
5, 0.9 , 0.95, 1. ])
In [421]: labels = (bins[1:]*100).astype(int)
In [422]: labels
Out[422]: array([ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100])
In [423]: pd.cut(df.a, bins=bins, labels=labels)
Out[423]:
0 90
1 40
2 25
3 80
4 30
5 90
6 100
7 60
8 75
9 15
Name: a, dtype: category
Categories (20, int64): [5 < 10 < 15 < 20 ... 85 < 90 < 95 < 100]

Doctirine 2 Case Statement

I use Doctirine 2 and zf2. How can i convert this sql query to dql. (Doctirine Query Language)
My product entity is here "Application\Entity\Product" I 've tried it but it doesn't work..
Thanks for your help.
SELECT price_range, count(*) AS num
FROM
(SELECT CASE WHEN price >= 0 AND price <= 10 THEN '0-10'
WHEN price >= 10 AND price <= 20 THEN '10-20'
WHEN price >= 20 AND price <= 30 THEN '30-40'
WHEN price >= 30 AND price <= 40 THEN '30-40'
WHEN price >= 40 AND price <= 50 THEN '40-50'
WHEN price >= 50 AND price <= 60 THEN '50-60'
WHEN price >= 60 AND price <= 70 THEN '60-70'
WHEN price >= 70 AND price <= 80 THEN '70-80'
WHEN price >= 80 AND price <= 90 THEN '90-100'
WHEN price >= 100 AND price <= 110 THEN '100-110'
ELSE 'over 1000'
END as price_range
FROM product
WHERE 1
) AS price_summaries
GROUP BY price_range
Well, unfortunately you can't. Doctrine doesn't support CASE. And looking at your problem, I'm also unable to find an adequate other solution with DQL.
You can however use a native query. Native queries are embedded raw SQL queries, basically an extension of PDO.
Native queries are of course generally discouraged, as they have two disadvantages:
You must do the hydration into Doctrine entities yourself, using ResultSetMapping (if you want the result of the query to contain ready-made entities instead of plain arrays/objects).
Native queries undermine the whole point of using a DBAL: you loose portability. (But, to be honest, most projects don't just switch their RDBMS, so it's a rather theoretical concern).
But if you need to have the above query executed, use a native query in this single case.
Doctirine support case statement.
This works
SELECT CASE WHEN (p.price >= 0 AND p.price <= 10) THEN '0-10'
WHEN (p.price >= 10 AND p.price <= 20) THEN '10-20'
WHEN (p.price >= 20 AND p.price <= 30) THEN '30-40'
WHEN (p.price >= 30 AND p.price <= 40) THEN '30-40'
WHEN (p.price >= 40 AND p.price <= 50) THEN '40-50'
WHEN (p.price >= 50 AND p.price <= 60) THEN '50-60'
WHEN (p.price >= 60 AND p.price <= 70) THEN '60-70'
WHEN (p.price >= 70 AND p.price <= 80) THEN '70-80'
WHEN (p.price >= 80 AND p.price <= 90) THEN '90-100'
WHEN (p.price >= 100 AND p.price <= 110) THEN '100-110'
ELSE 'over 1000'
END as price_range
FROM \Application\Entity\Product p
But this doesn't work, i think i should try native query
SELECT price_range, count(*) AS num
FROM
(SELECT CASE WHEN (p.price >= 0 AND p.price <= 10) THEN '0-10'
WHEN (p.price >= 10 AND p.price <= 20) THEN '10-20'
WHEN (p.price >= 20 AND p.price <= 30) THEN '30-40'
WHEN (p.price >= 30 AND p.price <= 40) THEN '30-40'
WHEN (p.price >= 40 AND p.price <= 50) THEN '40-50'
WHEN (p.price >= 50 AND p.price <= 60) THEN '50-60'
WHEN (p.price >= 60 AND p.price <= 70) THEN '60-70'
WHEN (p.price >= 70 AND p.price <= 80) THEN '70-80'
WHEN (p.price >= 80 AND p.price <= 90) THEN '90-100'
WHEN (p.price >= 100 AND p.price <= 110) THEN '100-110'
ELSE 'over 1000'
END as price_range
FROM \Application\Entity\Product p
) AS price_summaries
GROUP BY price_range

Pygame 2,7 Collision To 3,3

I have recently made a game in python 2.7.6 with pygame and I am now converting all of the syntax and code to work with python 3.3.3. But I am having an issue with collision. Before I converted the collisions worked flawlessly, but in 3.3.3 all the collisions completely messed up. Here is my current code for the player, zombie and boss collisions:
def player_move(self):
# Line start
self.point = self.player.rect.x + 30, self.player.rect.y + 30
# add gravity
self.player.do_jump()
# simulate gravity
self.player.on_ground = False
if not self.player.on_ground and not self.player.jumping:
self.player.velY = 4
if self.player.rect.y >= 680:
self.player.lives -= 1
self.player.rect.x = 320
self.player.rect.y = 320
# Drops
for drop in self.gameDrops:
if pygame.sprite.collide_rect(self.player, drop):
if type(drop) == HealthDrop:
self.player.health += 50
self.gameDrops.remove(drop)
elif type(drop) == SuperHealthDrop:
self.player.health += 1000
self.gameDrops.remove(drop)
elif type(drop) == TriBullets:
self.player.power = POWER_TRIBULLETS
self.gameDrops.remove(drop)
elif type(drop) == ShieldDrop:
self.player.power = POWER_SHIELD
self.gameDrops.remove(drop)
if self.player.score >= self.next_level_score:
self.game_state = STATE_VICTORY
self.player.score = 0
self.zombieskilled = 0
self.alivetime = 0
self.lives = 3
self.health = 200
self.player.rect.x = 320
self.player.rect.y = 320
for zombie in self.zombies:
zombie.rect.x = random.randint(0, 1280)
zombie.rect.y = random.randint(0, 100)
# Health
for m in self.meteors:
if pygame.sprite.collide_rect(self.player, m):
if self.player.power == POWER_SHIELD:
self.player.health -= 25
else:
self.player.health -= 50
for zombie in self.zombies:
if pygame.sprite.collide_rect(self.player, zombie):
if self.player.power == POWER_SHIELD:
self.player.health -= 1
else:
self.player.health -= 5
for boss in self.bosses:
if pygame.sprite.collide_rect(self.player, boss):
if self.player.power == POWER_SHIELD:
self.player.health -= 50
else:
self.player.health -= 50
# check if we die
if self.player.health <= 0:
self.player.power = POWER_NONE
self.player.lives -= 1
self.player.rect.x = 320
self.player.rect.y = 320
self.player.health = 200
if self.player.lives <= 0:
self.player.lives += 3
self.player.score = 0
self.targetscore = 100
self.player.rect.x = 320
self.player.rect.y = 320
self.game_state = STATE_GAMEOVER
for zombie in self.zombies:
zombie.rect.x = random.randint(0, 1280)
zombie.rect.y = random.randint(0, 100)
# move player and check for collision at the same time
self.player.rect.x += self.player.velX
self.check_collision(self.player, self.player.velX, 0)
self.player.rect.y += self.player.velY
self.check_collision(self.player, 0, self.player.velY)
def zombie_move(self, zombie_sprite):
# add gravity
zombie_sprite.do_jump()
percentage = random.randint(0, 100)
# simualte gravity
zombie_sprite.on_ground = False
if not zombie_sprite.on_ground and not zombie_sprite.jumping:
zombie_sprite.velY = 8
if zombie_sprite.jumping:
zombie_sprite.velX = 0
for zombie in self.zombies:
if zombie.rect.y >= 680:
self.zombies.remove(zombie)
dx = zombie_sprite.rect.x - self.player.rect.x
if dx > 20 and not zombie_sprite.jumping:
zombie_sprite.velX = -5
elif dx < 20 and not zombie_sprite.jumping:
zombie_sprite.velX = +5
# Zombie damage
for zombie in self.zombies:
for m in self.meteors:
if pygame.sprite.collide_rect(m, zombie):
zombie.health -= 10
if zombie.health <= 0:
if (percentage >= 0) and (percentage < 40):
self.gameDrops.append(HealthDrop(zombie.rect.x + 10, zombie.rect.y + 30))
elif (percentage >= 0) and (percentage < 5):
self.gameDrops.append(SuperHealthDrop(zombie.rect.x + 20, zombie.rect.y + 30))
elif (percentage >= 1) and (percentage < 20):
self.gameDrops.append(TriBullets(zombie.rect.x + 30, zombie.rect.y + 30, self.player.direction))
elif (percentage >= 1) and (percentage < 50):
self.gameDrops.append(ShieldDrop(zombie.rect.x + 40, zombie.rect.y + 30))
self.zombieskilled += 0
self.player.score += 0
self.meteors.remove(m)
break
for zombie in self.zombies:
for b in self.bullets:
if pygame.sprite.collide_rect(b, zombie):
#The same bullet cannot be used to kill
#multiple zombies and as the bullet was
#no longer in Bullet.List error was raised
zombie.health -= 10
self.bullets.remove(b)
if zombie.health <= 0:
if (percentage >= 0) and (percentage < 40):
self.gameDrops.append(HealthDrop(zombie.rect.x + 10, zombie.rect.y + 30))
elif (percentage >= 0) and (percentage < 5):
self.gameDrops.append(SuperHealthDrop(zombie.rect.x + 20, zombie.rect.y + 30))
elif (percentage >= 1) and (percentage < 20):
self.gameDrops.append(TriBullets(zombie.rect.x + 30, zombie.rect.y + 30, self.player.direction))
elif (percentage >= 1) and (percentage < 50):
self.gameDrops.append(ShieldDrop(zombie.rect.x + 40, zombie.rect.y + 30))
self.zombieskilled += 1
self.player.score += 10
self.total_score += 10
self.zombies.remove(zombie)
break
# move zombie and check for collision
zombie_sprite.rect.x += zombie_sprite.velX
self.check_collision(zombie_sprite, zombie_sprite.velX, 0)
zombie_sprite.rect.y += zombie_sprite.velY
self.check_collision(zombie_sprite, 0, zombie_sprite.velY)
def boss_move(self, boss_sprite):
# add gravity
boss_sprite.do_jump()
percentage = random.randint(0, 100)
# simualte gravity
boss_sprite.on_ground = False
if not boss_sprite.on_ground and not boss_sprite.jumping:
boss_sprite.velY = 8
if boss_sprite.jumping:
boss_sprite.velX = 0
for boss in self.bosses:
if boss.rect.y >= 620:
self.bosses.remove(boss)
dx = boss_sprite.rect.x - self.player.rect.x
if dx > 20 and not boss_sprite.jumping:
boss_sprite.velX = -5
elif dx < 20 and not boss_sprite.jumping:
boss_sprite.velX = +5
# Zombie damage
for boss in self.bosses:
for m in self.meteors:
if pygame.sprite.collide_rect(m, boss):
boss.health -= 0
if boss.health <= 0:
if (percentage >= 0) and (percentage < 40):
self.gameDrops.append(HealthDrop(boss.rect.x + 10, boss.rect.y + 30))
elif (percentage >= 0) and (percentage < 5):
self.gameDrops.append(SuperHealthDrop(boss.rect.x + 20, boss.rect.y + 30))
elif (percentage >= 1) and (percentage < 20):
self.gameDrops.append(TriBullets(boss.rect.x + 30, boss.rect.y + 30, self.player.direction))
elif (percentage >= 1) and (percentage < 50):
self.gameDrops.append(ShieldDrop(boss.rect.x + 40, boss.rect.y + 30))
self.zombieskilled += 0
self.player.score += 0
self.meteors.remove(m)
break
for boss in self.bosses:
for b in self.bullets:
if pygame.sprite.collide_rect(b, boss):
#The same bullet cannot be used to kill
#multiple bosses and as the bullet was
#no longer in Bullet.List error was raised
boss.health -= 5
self.bullets.remove(b)
if boss.health <= 0:
if (percentage >= 0) and (percentage < 50):
self.gameDrops.append(SuperHealthDrop(boss.rect.x + 90, boss.rect.y + 90))
elif (percentage >= 0) and (percentage < 50):
self.gameDrops.append(TriBullets(boss.rect.x + 90, boss.rect.y + 90, self.player.direction))
self.zombieskilled += 1
self.player.score += 50
self.total_score += 50
self.bosses.remove(boss)
break
# move boss and check for collision
boss_sprite.rect.x += boss_sprite.velX
self.check_collision(boss_sprite, boss_sprite.velX, 0)
boss_sprite.rect.y += boss_sprite.velY
self.check_collision(boss_sprite, 0, boss_sprite.velY)
def check_collision(self, sprite, x_vel, y_vel):
# for every tile in Background.levelStructure, check for collision
for block in self.moon.get_surrounding_blocks(sprite):
if block is not None:
if pygame.sprite.collide_rect(sprite, block):
# we've collided! now we must move the collided sprite a step back
if x_vel < 0:
sprite.rect.x = block.rect.x + block.rect.w
if type(sprite) is Zombie:
# the sprite is a zombie, let's make it jump
if not sprite.jumping:
sprite.jumping = True
sprite.on_ground = False
else:
sprite.jumping = False
sprite.on_ground = True
if x_vel > 0:
sprite.rect.x = block.rect.x - sprite.rect.w
if type(sprite) is Zombie:
# the sprite is a zombie, let's make it jump
if not sprite.jumping:
sprite.jumping = True
sprite.on_ground = False
else:
sprite.jumping = False
sprite.on_ground = True
if y_vel < 0:
sprite.rect.y = block.rect.y + block.rect.h
if y_vel > 0 and not sprite.on_ground:
sprite.on_ground = True
sprite.rect.y = block.rect.y - sprite.rect.h
That is all of the code from the player, zombie and boss for them you collide and there functions so they know to collide. I have called the collision function too as you can see in the code for all three. I am really annoyed at this because I am not sure whether it is to do with syntax or what. Any help will be appreciated. Thank you.
I have finally found the fix! In my levelstructure file to randomly generate the terrain and position. In my generation class I had a get_surrounding_blocks as you can see in def check_collision. In that surrounding_blocks I had:
def get_surrounding_blocks(self, sprite):
# calculate the grid position of the sprite
sprite_x = sprite.rect.x / 64
sprite_y = sprite.rect.y / 64
And in python 2.7.6 one division sign (/) will give you an integer but in python 3.3.3 you must do // to get an integer otherwise you may get a float with just one /.