Feeds

#! code: Drupal 9: Using The Caching API To Store Data

Planet Drupal - Sun, 2022-04-24 14:19

The cache system in Drupal has a number of different components with time, contexts and tags being used to determine the cache.

Whilst all of these mechanisms are really useful you can also inject data directly into the cache system. This is beneficial if you have an expensive function that takes a long time to complete. The result of the function can be stored in the Drupal cache system just like other cache data.

For example, let's say you are pulling data from a slow API. If the data doesn't change much it might be better to add a cache to the request so that instead of going to the slow API the fast cache systems are used instead.

To get an instance of the cache system you can use the \Drupal::cache() method, which will return an instance of a CacheBackendInterface type object. By default, this will assume that you want to use the 'default' cache bin, which is essentially the cache_default table (assuming you are using the database for your cache storage).

Once you have a cache object, there are a couple of important methods you can use.

Cache Methods

The first method to talk about is the set() method, which is used to write some cache to the cache system. This takes a few parameters and is called like this.

\Drupal::cache()->set($cacheId, $data, Cache::PERMANENT, $cacheTags);

Let's go through the parameters a little.

Read more.

Categories: FLOSS Project Planets

The Python Coding Blog: Have your Apollo 11 moment: A Python Lunar Landing game using the turtle module

Planet Python - Sun, 2022-04-24 13:53

How difficult can it be to land on the moon? I have no idea. All I know is that it’s not that easy landing the lunar module in this Python turtle game:

But, how about writing the game? I’ve taken a ‘first-principles’ approach to write this lunar landing game and used Python’s turtle module instead of other game-writing libraries.

Let me take you all the way from launch to landing.

The Python Lunar Landing Game

Look at the video of the game again. The lunar module starts in a spot in the top-left corner of the game screen. It is also spinning with a random angular velocity at the beginning of the game.

The aim of the game is to land the lunar module safely on the landing pad by controlling its descent.

Controlling the Lunar Module

You can turn on either of the two thrusters or both at once. If only one thruster is turned on, the module’s rotational velocity increases. This affects how fast the lunar module is spinning and in which direction. The longer the thruster is on, the faster it will spin.

If the module is spinning clockwise, let’s say, and the anticlockwise (counterclockwise) thruster is turned on and kept on, the lunar module’s spinning will slow down until it stops rotating completely for a brief period. Then, it will start spinning anticlockwise.

If both thrusters are turned on at the same time, the lunar module will accelerate in the direction opposite to where the thrusters are facing. If the module is spinning and both thrusters are turned on, the direction of acceleration will keep changing as the module spins. This makes the module hard to control when it’s spinning rapidly!

Landing the Lunar Module

The lunar module must land on the landing pad while facing upwards. There is some tolerance level that is acceptable on both location of landing and orientation of the lunar module when it reaches the landing pad.

However, if the lunar module hits the landing pad outside of these tolerances, the landing is unsuccessful. The landing is considered a failed landing also if the lunar module goes below the bottom edge of the game screen.

Setting Up the Scene

You’ll use Python’s turtle module to create the graphics in this game. If you’ve used this module before, you’re already familiar with the key classes you’ll use and the methods to draw and move things around.

However, it’s not a problem if you’ve never used the turtle module. I’ll introduce everything that’s needed from this module as and when required in this article.

Creating the Game Window

You can start by creating the window you’ll need for the game and setting its size and background colour:

import turtle # Set up the game window window = turtle.Screen() window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() turtle.done()

The first step is to create an object representing the screen in which the game will run. You name it window. When you call window.setup(0.6, 0.6), you set the size of the window to 60% of your display’s width and height. You can also use integers as arguments in setup() to choose the pixel size directly instead of choosing the fraction of your display’s width and height.

You’ll need to use the actual width and height of the window often throughout the code, so you assign the values returned by window_width() and window_height() to width and height.

The remaining methods set the window’s title bar and the background colour. Finally, turtle.done() keeps the program from exiting and keeps the window open. This is the mainloop of the game when using turtle.

Creating the Stars and the Moon’s Surface

The other key object available in the turtle module is the Turtle object. This is the drawing pen which you’ll be able to move around the screen to draw things. You can create two “turtles” to create the stars and the moon:

import random import turtle # Set up the game window window = turtle.Screen() window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) turtle.done()

You use several Turtle methods:

  • hideturtle() hides the arrow representing the Turtle object on the screen.
  • penup() ensures that as you move the turtle around the screen, no lines are drawn.
  • color() sets the turtle’s colour and that of the graphics it produces.
  • dot() draws a dot with any given size.
  • setposition() places the turtle at a given set of coordinates.
  • setx() and sety() set only one of the coordinates, either x or y.

You’ve now set up the background for this Python lunar landing game:

However, you’ll have noticed that it takes a long time for the turtles to move around, drawing all the stars and the moon. The turtle module draws each small step the turtles make. This takes time. This issue will also cause lag during the gameplay as every movement will be slowed down due to the program drawing every step of every movement.

You can turn this default behaviour off by calling the window.tracer(0), which does not draw any of the intermediate steps. The screen is refreshed each time you call window.update():

import random import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) window.update() turtle.done()

That completes the background of the lunar landing game. Now, for the fun part!

Creating the Lunar Module

Next, you need to draw the lunar module. However, the spaceship is not stationary in this Python lunar landing game. It spins and it moves around as the player tries to land it:

import random import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) def draw_lunar_module(): lunar_module.pendown() lunar_module.pensize(5) # Landing gear lunar_module.color(landing_gear_colour) lunar_module.forward(branch_size) lunar_module.left(90) lunar_module.forward(branch_size / 2) lunar_module.forward(-branch_size) lunar_module.forward(branch_size / 2) lunar_module.right(90) lunar_module.forward(-branch_size) lunar_module.pensize(1) # Pods around the edge of the module lunar_module.color(disc_colour) for _ in range(n_of_discs - 1): lunar_module.right(360 / n_of_discs) lunar_module.forward(branch_size) lunar_module.dot(branch_size / 2) lunar_module.forward(-branch_size) # Centre part of the lunar module lunar_module.color(centre_colour) lunar_module.dot(branch_size) lunar_module.penup() # Will remove this later draw_lunar_module() window.update() turtle.done()

You add parameters to define the size and colours of the lunar module and create a new Turtle object lunar_module. The position of this turtle is in the top-left region of the window.

Then, you define draw_lunar_module(), which does what the function name says! You can read through the steps in the function to follow the lunar_module turtle as it draws the landing gear, the outer pods and the central part of the lunar module. The variable branch_size determines the distance between the centre of the lunar module and the centre of one of the outer discs. You’ll use this value to scale several aspects of the drawing.

You add a temporary call to draw_lunar_module() so you can look at what the lunar module looks like:

There is one problem that you can’t see yet but will soon become evident. Try and add a second call to draw_lunar_module() immediately after the one already in the code:

As the lunar_module turtle moves around to draw the spaceship, it ends up in the same place it starts, which is at the centre of the spaceship but facing in a different orientation. Therefore, when you draw the lunar module a second time, it’s facing the wrong direction.

You can work out the maths you need to make sure the turtle ends its drawing of the lunar module facing the same way as when it started. However, there’s an easier solution:

import random import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) def draw_lunar_module(): # "save" the starting position and orientation position = lunar_module.position() heading = lunar_module.heading() lunar_module.pendown() lunar_module.pensize(5) # Landing gear lunar_module.color(landing_gear_colour) lunar_module.forward(branch_size) lunar_module.left(90) lunar_module.forward(branch_size / 2) lunar_module.forward(-branch_size) lunar_module.forward(branch_size / 2) lunar_module.right(90) lunar_module.forward(-branch_size) lunar_module.pensize(1) # Pods around the edge of the module lunar_module.color(disc_colour) for _ in range(n_of_discs - 1): lunar_module.right(360 / n_of_discs) lunar_module.forward(branch_size) lunar_module.dot(branch_size / 2) lunar_module.forward(-branch_size) # Centre part of the lunar module lunar_module.color(centre_colour) lunar_module.dot(branch_size) lunar_module.penup() # reset the turtle to initial position and orientation lunar_module.setposition(position) lunar_module.setheading(heading) # Will remove this later print(lunar_module.heading()) print(lunar_module.position()) draw_lunar_module() draw_lunar_module() print(lunar_module.heading()) print(lunar_module.position()) window.update() turtle.done()

You start the definition of draw_lunar_module() by storing the position and heading of the turtle before it starts drawing. Then,you finish the function definition by resetting the turtle’s position and orientation. You don’t really need to reset the position as the turtle is already in the correct location. However, you may need to do this if you go for a different spaceship design!

In the last few lines of code, you print out the lunar module’s orientation and position before and after you call draw_lunar_module() twice to confirm that these remain the same after successive calls to the function.

Now, you can remove the lines in the # Will remove this later section now.

Adding Thrusters to Turn the Lunar Module

There are two key things you’ll need to do to add thrusters that can turn the lunar module. There’s the “artistic” side of showing the burning fuel coming out of the thrusters and the “functional” side that turns the lunar module. Let’s start with the latter.

You can start by creating an instance variable bound to lunar_module called rotation which determines the rotational speed of the lunar module. For the time being, you can set this to 0.

You create two more instance variables which are also bound to lunar_module. These instance variables determine whether the clockwise and anticlockwise thrusters are on or off. Initially, you set these to False, which means the thrusters are turned off. Then, you define two functions which can turn these thrusters on.

This is a good time to create the main game loop. All the steps needed in every frame of the animation will occur in the while loop.

Although you can set a required number of frames per second to make sure your game runs at a specific frame rate, I’m choosing a simpler version in this project in which we just let the while loop run at whichever speed it will run without controlling its exact timing. However, you can add a short delay to each while loop to slow it down if it’s running too fast. The sleep() function from the time module is useful for this:

import random import time import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Lunar module movement parameters rotation_step = 0.2 # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) lunar_module.rotation = 0 lunar_module.clockwise_thruster = False lunar_module.anticlockwise_thruster = False def draw_lunar_module(): lunar_module.clear() # "save" the starting position and orientation position = lunar_module.position() heading = lunar_module.heading() lunar_module.pendown() lunar_module.pensize(5) # Landing gear lunar_module.color(landing_gear_colour) lunar_module.forward(branch_size) lunar_module.left(90) lunar_module.forward(branch_size / 2) lunar_module.forward(-branch_size) lunar_module.forward(branch_size / 2) lunar_module.right(90) lunar_module.forward(-branch_size) lunar_module.pensize(1) # Pods around the edge of the module lunar_module.color(disc_colour) for _ in range(n_of_discs - 1): lunar_module.right(360 / n_of_discs) lunar_module.forward(branch_size) lunar_module.dot(branch_size / 2) lunar_module.forward(-branch_size) # Centre part of the lunar module lunar_module.color(centre_colour) lunar_module.dot(branch_size) lunar_module.penup() # reset the turtle to initial position and orientation lunar_module.setposition(position) lunar_module.setheading(heading) def turn_on_clockwise_thruster(): lunar_module.clockwise_thruster = True def turn_on_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = True window.onkeypress(turn_on_clockwise_thruster, "Right") window.onkeypress(turn_on_anticlockwise_thruster, "Left") window.listen() while True: # Change rotational speed of lunar module if lunar_module.clockwise_thruster: lunar_module.rotation -= rotation_step if lunar_module.anticlockwise_thruster: lunar_module.rotation += rotation_step # Rotate lunar module lunar_module.left(lunar_module.rotation) # Refresh image of lunar module draw_lunar_module() time.sleep(0.05) window.update() turtle.done()

You add a call to lunar_module.clear() at the beginning of draw_lunar_module() so that each time you redraw the spaceship, the previous drawing is cleared from the screen.

You bind the functions turn_on_clockwise_thruster() and turn_on_anticlockwise_thruster() to the right and left arrow keys using window.onkeypress() and window.listen(). The latter method ensures that the program is “listening” out for keypresses.

This works. However, there’s a problem:

The rotational speed of the lunar module keeps increasing once you hit the arrow key. That’s because you can toggle the thruster on, but you can’t turn it off.

You can amend this by adding a couple more functions to turn the thrusters off. I’m only showing a section of the code below. The rest of the code is unchanged:

# ... def turn_on_clockwise_thruster(): lunar_module.clockwise_thruster = True def turn_on_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = True def turn_off_clockwise_thruster(): lunar_module.clockwise_thruster = False def turn_off_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = False window.onkeypress(turn_on_clockwise_thruster, "Right") window.onkeypress(turn_on_anticlockwise_thruster, "Left") window.onkeyrelease(turn_off_clockwise_thruster, "Right") window.onkeyrelease(turn_off_anticlockwise_thruster, "Left") window.listen() # ...

Releasing the arrow keys now turns the thrusters off. Therefore, you have more control over how the lunar module spins:

You can control the animation’s speed by changing the argument in time.sleep() if you need.

Drawing the Burning Fuel

You can now change the rotational speed of the lunar module by using the arrow keys. Next, you can focus on the “artistic” element of turning the thrusters on and off. You can create another Turtle object and a function to draw the burning fuel:

import random import time import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Lunar module movement parameters rotation_step = 0.2 # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) lunar_module.rotation = 0 lunar_module.clockwise_thruster = False lunar_module.anticlockwise_thruster = False def draw_lunar_module(): lunar_module.clear() # "save" the starting position and orientation position = lunar_module.position() heading = lunar_module.heading() lunar_module.pendown() lunar_module.pensize(5) # Landing gear lunar_module.color(landing_gear_colour) lunar_module.forward(branch_size) lunar_module.left(90) lunar_module.forward(branch_size / 2) lunar_module.forward(-branch_size) lunar_module.forward(branch_size / 2) lunar_module.right(90) lunar_module.forward(-branch_size) lunar_module.pensize(1) # Pods around the edge of the module lunar_module.color(disc_colour) for _ in range(n_of_discs - 1): lunar_module.right(360 / n_of_discs) lunar_module.forward(branch_size) lunar_module.dot(branch_size / 2) lunar_module.forward(-branch_size) # Centre part of the lunar module lunar_module.color(centre_colour) lunar_module.dot(branch_size) lunar_module.penup() # reset the turtle to initial position and orientation lunar_module.setposition(position) lunar_module.setheading(heading) # Create burning fuel burning_fuel = turtle.Turtle() burning_fuel.penup() burning_fuel.hideturtle() def draw_burning_fuel(thruster): # Place turtle in the correct location # depending on which thruster is on if thruster == "clockwise": direction = 1 elif thruster == "anticlockwise": direction = -1 burning_fuel.penup() burning_fuel.setposition(lunar_module.position()) burning_fuel.setheading(lunar_module.heading()) burning_fuel.right(direction * 360 / n_of_discs) burning_fuel.forward(branch_size) burning_fuel.left(direction * 360 / n_of_discs) # Draw burning fuel burning_fuel.pendown() burning_fuel.pensize(8) burning_fuel.color("yellow") burning_fuel.forward(branch_size) burning_fuel.backward(branch_size) burning_fuel.left(5) burning_fuel.color("red") burning_fuel.pensize(5) for _ in range(2): burning_fuel.forward(branch_size) burning_fuel.backward(branch_size) burning_fuel.right(10) def turn_on_clockwise_thruster(): lunar_module.clockwise_thruster = True def turn_on_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = True def turn_off_clockwise_thruster(): lunar_module.clockwise_thruster = False def turn_off_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = False window.onkeypress(turn_on_clockwise_thruster, "Right") window.onkeypress(turn_on_anticlockwise_thruster, "Left") window.onkeyrelease(turn_off_clockwise_thruster, "Right") window.onkeyrelease(turn_off_anticlockwise_thruster, "Left") window.listen() while True: burning_fuel.clear() # Change rotational speed of lunar module if lunar_module.clockwise_thruster: draw_burning_fuel("clockwise") lunar_module.rotation -= rotation_step if lunar_module.anticlockwise_thruster: draw_burning_fuel("anticlockwise") lunar_module.rotation += rotation_step # Rotate lunar module lunar_module.left(lunar_module.rotation) # Refresh image of lunar module draw_lunar_module() time.sleep(0.05) window.update() turtle.done()

In the draw_burning_fuel() function definition, you’re moving the turtle to the centre of one of the outer discs. The lunar_module turtle’s resting position is at the centre of the spaceship, facing downwards towards the landing gear. You use the direction variable, which is either 1 or -1, to send the turtle to the correct disc.

The drawing of the burning fuel is simply three thick lines: a yellow one in the middle and two red ones on either side of the middle yellow line!

You can now set the initial rotation to a random value since you need the initial parameters to be random to make the game more challenging:

# ... # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) lunar_module.rotation = random.randint(-9, 9) lunar_module.clockwise_thruster = False lunar_module.anticlockwise_thruster = False # ...

Each time you run the program, the lunar module will start off spinning with a random rotational velocity. You can practise controlling the rotation of the lunar module using the thrusters before moving on!

Moving the Lunar Module

You can rotate the lunar module by turning either thruster on and off. However, rotational movement is only one of the ways the lunar module can move in this Python lunar landing game. Now, you need to be able to translate the lunar module, too.

There are two factors that will make the lunar module move from its starting location: gravity and thrust. When both thrusters are turned on at the same time, the lunar module will be pushed forward in the direction it’s facing. Gravity, on the other hand, will act on the lunar module all the time.

You can add two instance variables bound to lunar_module called travel_speed and travel_direction. These instance variables determine the lunar module’s speed and direction of travel at any time in the animation. Note that the orientation of the turtle used to draw the spaceship is not the same as the direction of travel of the spaceship:

# ... # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) lunar_module.rotation = random.randint(-9, 9) lunar_module.clockwise_thruster = False lunar_module.anticlockwise_thruster = False lunar_module.travel_speed = random.randint(1, 3) lunar_module.travel_direction = random.randint(-45, 0) # ...

You set both of the new instance variables you created to random values so that the lunar module’s starting position is different each time you run the game. Next, you need to move the lunar module using these values. Therefore, you can add a section in the while loop that works out how much the spaceship should move in the x- and y-directions and move it:

import math import random import time import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Lunar module movement parameters rotation_step = 0.2 # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) lunar_module.rotation = random.randint(-9, 9) lunar_module.clockwise_thruster = False lunar_module.anticlockwise_thruster = False lunar_module.travel_speed = random.randint(1, 3) lunar_module.travel_direction = random.randint(-45, 0) def draw_lunar_module(): lunar_module.clear() # "save" the starting position and orientation position = lunar_module.position() heading = lunar_module.heading() lunar_module.pendown() lunar_module.pensize(5) # Landing gear lunar_module.color(landing_gear_colour) lunar_module.forward(branch_size) lunar_module.left(90) lunar_module.forward(branch_size / 2) lunar_module.forward(-branch_size) lunar_module.forward(branch_size / 2) lunar_module.right(90) lunar_module.forward(-branch_size) lunar_module.pensize(1) # Pods around the edge of the module lunar_module.color(disc_colour) for _ in range(n_of_discs - 1): lunar_module.right(360 / n_of_discs) lunar_module.forward(branch_size) lunar_module.dot(branch_size / 2) lunar_module.forward(-branch_size) # Centre part of the lunar module lunar_module.color(centre_colour) lunar_module.dot(branch_size) lunar_module.penup() # reset the turtle to initial position and orientation lunar_module.setposition(position) lunar_module.setheading(heading) # Create burning fuel burning_fuel = turtle.Turtle() burning_fuel.penup() burning_fuel.hideturtle() def draw_burning_fuel(thruster): # Place turtle in the correct location # depending on which thruster is on if thruster == "clockwise": direction = 1 elif thruster == "anticlockwise": direction = -1 burning_fuel.penup() burning_fuel.setposition(lunar_module.position()) burning_fuel.setheading(lunar_module.heading()) burning_fuel.right(direction * 360 / n_of_discs) burning_fuel.forward(branch_size) burning_fuel.left(direction * 360 / n_of_discs) # Draw burning fuel burning_fuel.pendown() burning_fuel.pensize(8) burning_fuel.color("yellow") burning_fuel.forward(branch_size) burning_fuel.backward(branch_size) burning_fuel.left(5) burning_fuel.color("red") burning_fuel.pensize(5) for _ in range(2): burning_fuel.forward(branch_size) burning_fuel.backward(branch_size) burning_fuel.right(10) def turn_on_clockwise_thruster(): lunar_module.clockwise_thruster = True def turn_on_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = True def turn_off_clockwise_thruster(): lunar_module.clockwise_thruster = False def turn_off_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = False window.onkeypress(turn_on_clockwise_thruster, "Right") window.onkeypress(turn_on_anticlockwise_thruster, "Left") window.onkeyrelease(turn_off_clockwise_thruster, "Right") window.onkeyrelease(turn_off_anticlockwise_thruster, "Left") window.listen() while True: burning_fuel.clear() # Change rotational speed of lunar module if lunar_module.clockwise_thruster: draw_burning_fuel("clockwise") lunar_module.rotation -= rotation_step if lunar_module.anticlockwise_thruster: draw_burning_fuel("anticlockwise") lunar_module.rotation += rotation_step # Rotate lunar module lunar_module.left(lunar_module.rotation) # Translate lunar module x = lunar_module.travel_speed * math.cos( math.radians(lunar_module.travel_direction) ) y = lunar_module.travel_speed * math.sin( math.radians(lunar_module.travel_direction) ) lunar_module.setx(lunar_module.xcor() + x) lunar_module.sety(lunar_module.ycor() + y) # Refresh image of lunar module draw_lunar_module() time.sleep(0.05) window.update() turtle.done()

You calculate the x- and y-components of the lunar module’s speed using trigonometry. You import the math module, too. Then, you can shift the position of the lunar_module turtle accordingly.

When you run this code, the lunar module will start travelling at the speed and direction determined by the random values chosen at the beginning. You can change the rotational speed of the lunar module using the thrusters:

However, you still cannot change the lunar module’s speed and direction of travel.

Some Maths

Let’s review the maths that you’ll need to work out the change in the lunar module’s speed and direction when a force acts on it. Consider the lunar module that’s travelling in the direction shown by the green arrow below:

If the thrusters are turned on, they will create a force pointing in the direction shown by the red arrow in the diagram above. This direction represents the top of the lunar module.

You can break this force vector into two components, which are shown as blue arrows in the diagram:

  • the tangential component of the force created by the thrusters is the component that acts in the same direction as the spaceship’s current direction of travel. This is the blue arrow that’s pointing in the same direction as the green arrow.
  • the normal component of the force is the component that acts perpendicularly to the spaceship’s current direction of travel. This is shown as the blue arrow that’s 90º to the green arrow.

You can calculate the thruster force’s tangential and normal components by multiplying the magnitude of the force by the cosine and sine of the angle between the direction of the force and the direction of travel.

Turning On Both Thrusters

You can start by creating speed_step, which determines the step size by which you increase the speed each time you apply a “unit” of force. You also define apply_force(), which works out the change in direction and speed needed for each “unit” of thruster force applied. The function is called once in each iteration of the while loop when both thrusters are turned on:

# ... # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Lunar module movement parameters rotation_step = 0.2 speed_step = 0.1 # ... window.onkeypress(turn_on_clockwise_thruster, "Right") window.onkeypress(turn_on_anticlockwise_thruster, "Left") window.onkeyrelease(turn_off_clockwise_thruster, "Right") window.onkeyrelease(turn_off_anticlockwise_thruster, "Left") window.listen() # Applying forces to translate the lunar module def apply_force(): # Initial components of lunar module velocity tangential = lunar_module.travel_speed normal = 0 force_direction = lunar_module.heading() + 180 angle = math.radians( force_direction - lunar_module.travel_direction ) # New components of lunar module velocity tangential += speed_step * math.cos(angle) normal += speed_step * math.sin(angle) direction_change = math.degrees( math.atan2(normal, tangential) ) lunar_module.travel_direction += direction_change lunar_module.travel_speed = math.sqrt( normal ** 2 + tangential ** 2 ) while True: burning_fuel.clear() # Apply thrust if both thrusters are on if ( lunar_module.clockwise_thruster and lunar_module.anticlockwise_thruster ): apply_force() # Change rotational speed of lunar module if lunar_module.clockwise_thruster: draw_burning_fuel("clockwise") lunar_module.rotation -= rotation_step if lunar_module.anticlockwise_thruster: draw_burning_fuel("anticlockwise") lunar_module.rotation += rotation_step # Rotate lunar module lunar_module.left(lunar_module.rotation) # Translate lunar module x = lunar_module.travel_speed * math.cos( math.radians(lunar_module.travel_direction) ) y = lunar_module.travel_speed * math.sin( math.radians(lunar_module.travel_direction) ) lunar_module.setx(lunar_module.xcor() + x) lunar_module.sety(lunar_module.ycor() + y) # Refresh image of lunar module draw_lunar_module() time.sleep(0.05) window.update() turtle.done()

In apply_force(), you start by setting the tangential component of the velocity to the current speed of the lunar module. The normal component is 0 at this point. That’s because the tangential component is along the spaceship’s direction of travel.

Since the turtle drawing the lunar module faces the bottom of the lunar module in its “resting” state, you can set the direction of the force to the opposite direction of this by adding 180º. The turtle module measures angles in degrees. However, when using sines and cosines, you’ll need to convert these to radians.

Next, you can break down the change in speed from one iteration into its tangential and normal components and add them to the starting tangential and normal components of the lunar module’s velocity.

Now that you have the new components, you can work out the new speed and direction of the spaceship. You also add an if statement in the while loop to call apply_force() whenever both thrusters are turned on.

You can now fully steer the lunar module by:

  • turning thrusters on one at a time to change the lunar module’s rotation, or
  • turning both thrusters on at the same time to change the lunar module’s velocity.

The last thing that you’ll need to make the spaceship’s movement more realistic is to add the effect of gravity on the lunar module.

Adding the Effects of Gravity

In this game, we can assume a constant value for the moon’s gravitational pull on the spaceship. You create a variable called gravity to define this value. You can fine-tune this and other initial values to change the game’s difficulty level if you wish.

The force due to gravity is similar to the force applied when both thrusters are turned on. The only differences are the magnitude of the force and the direction. Gravity always pulls the lunar module vertically downwards.

This means that you don’t need to write a new function to take gravity into account. You can re-use apply_force() and make some modifications:

# ... # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Lunar module movement parameters rotation_step = 0.2 speed_step = 0.1 gravity = 0.03 # ... # Applying forces to translate the lunar module def apply_force(mode): # Initial components of lunar module velocity tangential = lunar_module.travel_speed normal = 0 if mode == "gravity": force_direction = -90 step = gravity elif mode == "thrusters": force_direction = lunar_module.heading() + 180 step = speed_step angle = math.radians( force_direction - lunar_module.travel_direction ) # New components of lunar module velocity tangential += step * math.cos(angle) normal += step * math.sin(angle) direction_change = math.degrees( math.atan2(normal, tangential) ) lunar_module.travel_direction += direction_change lunar_module.travel_speed = math.sqrt( normal ** 2 + tangential ** 2 ) while True: burning_fuel.clear() # Apply thrust if both thrusters are on if ( lunar_module.clockwise_thruster and lunar_module.anticlockwise_thruster ): apply_force("thrusters") # Change rotational speed of lunar module if lunar_module.clockwise_thruster: draw_burning_fuel("clockwise") lunar_module.rotation -= rotation_step if lunar_module.anticlockwise_thruster: draw_burning_fuel("anticlockwise") lunar_module.rotation += rotation_step # Rotate lunar module lunar_module.left(lunar_module.rotation) # Apply effect of gravity apply_force("gravity") # Translate lunar module x = lunar_module.travel_speed * math.cos( math.radians(lunar_module.travel_direction) ) y = lunar_module.travel_speed * math.sin( math.radians(lunar_module.travel_direction) ) lunar_module.setx(lunar_module.xcor() + x) lunar_module.sety(lunar_module.ycor() + y) # Refresh image of lunar module draw_lunar_module() time.sleep(0.05) window.update() turtle.done()

You refactor apply_force() by adding a required argument. This argument will be either "gravity" or "thrusters", depending on which function mode you need to use. Note that you’ll need to update the call to apply_force(), which you already have in your code, to include the "thrusters" argument.

You also refactor the function to use the new local variable step as the change in speed you need to apply to the lunar module. When using gravity-mode, this value is equal to the gravity value, and the direction is -90º, which is vertically downwards. When using thrusters-mode for this function, the step and direction values are the same as they were before this last set of changes.

You also need to call apply_force("gravity") in each iteration of the while loop since gravity will always act on the lunar module.

The spaceship will start falling and accelerating towards the lunar surface when you run the program now. You’ll need to control its spinning and use the thrusters to push the lunar module back up:

You’ve now completed the part of this Python lunar landing program which controls the movement of the lunar module. Once you’ve practised your piloting skills, you’re ready to work on landing the spaceship!

Landing the Lunar Module

It’s time to land your lunar module in this Python lunar landing game. You’ll first need to create the landing pad on the moon’s surface. You also need to define acceptable tolerances for successfully landing the lunar module. Next, you’ll need a function that checks whether there has been a successful landing or not:

import math import random import time import turtle # Set up the game window window = turtle.Screen() window.tracer(0) window.setup(0.6, 0.6) window.title("The Python Lunar Landing Game") window.bgcolor("black") width = window.window_width() height = window.window_height() # Game parameters n_of_stars = 100 # Lunar module design parameters branch_size = width / 16 n_of_discs = 5 disc_colour = "light gray" centre_colour = "gold" landing_gear_colour = "red" # Lunar module movement parameters rotation_step = 0.2 speed_step = 0.1 # Landing parameters landing_pad_position = 0, -height / 2.1 module_landing_position = ( landing_pad_position[0], landing_pad_position[1] + branch_size, ) landing_pos_tolerance_x = 20 landing_pos_tolerance_y = 5 landing_orientation = 270 # vertically downwards landing_orientation_tolerance = 15 gravity = 0.03 # Create stars and moon stars = turtle.Turtle() stars.hideturtle() stars.penup() stars.color("white") for _ in range(n_of_stars): # Use floor division // to ensure ints in randint() x_pos = random.randint(-width // 2, width // 2) y_pos = random.randint(-height // 2, height // 2) stars.setposition(x_pos, y_pos) stars.dot(random.randint(2, 6)) moon = turtle.Turtle() moon.penup() moon.color("slate gray") moon.sety(-height * 2.8) moon.dot(height * 5) # Create landing pad landing_pad = turtle.Turtle() landing_pad.hideturtle() landing_pad.penup() landing_pad.setposition(landing_pad_position) landing_pad.pendown() landing_pad.pensize(10) landing_pad.forward(branch_size / 2) landing_pad.forward(-branch_size) landing_pad.forward(branch_size / 2) # Create the lunar module lunar_module = turtle.Turtle() lunar_module.penup() lunar_module.hideturtle() lunar_module.setposition(-width / 3, height / 3) lunar_module.rotation = random.randint(-9, 9) lunar_module.clockwise_thruster = False lunar_module.anticlockwise_thruster = False lunar_module.travel_speed = random.randint(1, 3) lunar_module.travel_direction = random.randint(-45, 0) def draw_lunar_module(): lunar_module.clear() # "save" the starting position and orientation position = lunar_module.position() heading = lunar_module.heading() lunar_module.pendown() lunar_module.pensize(5) # Landing gear lunar_module.color(landing_gear_colour) lunar_module.forward(branch_size) lunar_module.left(90) lunar_module.forward(branch_size / 2) lunar_module.forward(-branch_size) lunar_module.forward(branch_size / 2) lunar_module.right(90) lunar_module.forward(-branch_size) lunar_module.pensize(1) # Pods around the edge of the module lunar_module.color(disc_colour) for _ in range(n_of_discs - 1): lunar_module.right(360 / n_of_discs) lunar_module.forward(branch_size) lunar_module.dot(branch_size / 2) lunar_module.forward(-branch_size) # Centre part of the lunar module lunar_module.color(centre_colour) lunar_module.dot(branch_size) lunar_module.penup() # reset the turtle to initial position and orientation lunar_module.setposition(position) lunar_module.setheading(heading) # Create burning fuel burning_fuel = turtle.Turtle() burning_fuel.penup() burning_fuel.hideturtle() def draw_burning_fuel(thruster): # Place turtle in the correct location # depending on which thruster is on if thruster == "clockwise": direction = 1 elif thruster == "anticlockwise": direction = -1 burning_fuel.penup() burning_fuel.setposition(lunar_module.position()) burning_fuel.setheading(lunar_module.heading()) burning_fuel.right(direction * 360 / n_of_discs) burning_fuel.forward(branch_size) burning_fuel.left(direction * 360 / n_of_discs) # Draw burning fuel burning_fuel.pendown() burning_fuel.pensize(8) burning_fuel.color("yellow") burning_fuel.forward(branch_size) burning_fuel.backward(branch_size) burning_fuel.left(5) burning_fuel.color("red") burning_fuel.pensize(5) for _ in range(2): burning_fuel.forward(branch_size) burning_fuel.backward(branch_size) burning_fuel.right(10) def turn_on_clockwise_thruster(): lunar_module.clockwise_thruster = True def turn_on_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = True def turn_off_clockwise_thruster(): lunar_module.clockwise_thruster = False def turn_off_anticlockwise_thruster(): lunar_module.anticlockwise_thruster = False window.onkeypress(turn_on_clockwise_thruster, "Right") window.onkeypress(turn_on_anticlockwise_thruster, "Left") window.onkeyrelease(turn_off_clockwise_thruster, "Right") window.onkeyrelease(turn_off_anticlockwise_thruster, "Left") window.listen() # Applying forces to translate the lunar module def apply_force(mode): # Initial components of lunar module velocity tangential = lunar_module.travel_speed normal = 0 if mode == "gravity": force_direction = -90 step = gravity elif mode == "thrusters": force_direction = lunar_module.heading() + 180 step = speed_step angle = math.radians( force_direction - lunar_module.travel_direction ) # New components of lunar module velocity tangential += step * math.cos(angle) normal += step * math.sin(angle) direction_change = math.degrees( math.atan2(normal, tangential) ) lunar_module.travel_direction += direction_change lunar_module.travel_speed = math.sqrt( normal ** 2 + tangential ** 2 ) # Check for successful landing def check_landing(): if ( abs(lunar_module.xcor() - module_landing_position[0]) < landing_pos_tolerance_x and abs(lunar_module.ycor() - module_landing_position[1]) < landing_pos_tolerance_y ): if ( abs(lunar_module.heading() - landing_orientation) < landing_orientation_tolerance ): lunar_module.setposition(module_landing_position) lunar_module.setheading(landing_orientation) draw_lunar_module() burning_fuel.clear() return True else: burning_fuel.clear() return False # Crash on landing pad - wrong angle if lunar_module.ycor() < -height / 2: burning_fuel.clear() return False # Crash below moon surface return None # No successful or unsuccessful landing yet while True: burning_fuel.clear() # Apply thrust if both thrusters are on if ( lunar_module.clockwise_thruster and lunar_module.anticlockwise_thruster ): apply_force("thrusters") # Change rotational speed of lunar module if lunar_module.clockwise_thruster: draw_burning_fuel("clockwise") lunar_module.rotation -= rotation_step if lunar_module.anticlockwise_thruster: draw_burning_fuel("anticlockwise") lunar_module.rotation += rotation_step # Rotate lunar module lunar_module.left(lunar_module.rotation) # Apply effect of gravity apply_force("gravity") # Translate lunar module x = lunar_module.travel_speed * math.cos( math.radians(lunar_module.travel_direction) ) y = lunar_module.travel_speed * math.sin( math.radians(lunar_module.travel_direction) ) lunar_module.setx(lunar_module.xcor() + x) lunar_module.sety(lunar_module.ycor() + y) # Refresh image of lunar module draw_lunar_module() # Check for successful or unsuccessful landing successful_landing = check_landing() if successful_landing is not None: if successful_landing: window.title("Well Done! You've landed successfully") else: window.bgcolor("red") window.title("The lunar module crashed") break time.sleep(0.05) window.update() turtle.done()

The module’s landing position is shifted vertically upwards from the landing pad by a distance equal to branch_size since this position refers to the centre of the lunar module.

The check_landing() function first checks whether the lunar module’s (x, y) position is within the tolerance range. If it is, then there are two possible outcomes:

  • The lunar module’s orientation is within the tolerance range. The position and orientation of the lunar module are set to the correct landing values so that the spaceship “snaps” in place. The function returns True.
  • The lunar module’s orientation is outside the tolerance range. This means the spaceship has crashed on the landing pad. The function returns False.

The function also returns False if the lunar module falls below the lower edge of the window. This case corresponds to the lunar module crashing on the moon’s surface.

If neither of these conditions is met, the function returns None, which means that the lunar module is still in flight.

Your final step is to check for each of these scenarios in the while loop and end the game with a success or failure warning.

Here’s the output of the final version of this Python lunar landing game:

Final Words

You’ve completed the Python lunar landing game. By using the turtle module, you’ve been able to build the game from first principles, controlling how the Turtle objects move and how they interact with each other.

However, there’s more you can add if you want to upgrade the game. For example, you can ensure that the lunar module doesn’t land with a speed that’s too high, or you can set a limited amount of fuel.

Have a go at adding more features to this game!

Further Reading Get the latest blog updates

No spam promise. You’ll get an email when a new blog post is published

The post Have your Apollo 11 moment: A Python Lunar Landing game using the turtle module appeared first on The Python Coding Book.

Categories: FLOSS Project Planets

ItsMyCode: How to get column names in Pandas Dataframe

Planet Python - Sun, 2022-04-24 09:24

Pandas DataFrame is Two-dimensional, size-mutable, potentially heterogeneous tabular data. Pandas DataFrame consists of rows and columns to store the data. Each column will have its own header name that can be used to identify the columns.

This tutorial will explore different methods available to get column names in Pandas Dataframe with examples.

Get Column names in Pandas DataFrame

Let us consider a simple dataframe that we will be using throughout the tutorial.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) print(df)

Output

Software_Names Rating Total_Qty_In_Stock Unit_Price Total_Sales 0 Windows Defender 4.2 10 23.55 3 1 AVG Antivirus 3.7 4 NaN 1 2 Mcafee Antivirus 4.0 8 32.78 7 3 Kaspersky Security 4.5 3 33.00 5 4 Norton Antivirus 3.0 5 NaN 11 5 Bit Defender 4.7 20 45.00 14 Pandas Get column names using column attribute

The easiest way to get the column names in Pandas Dataframe is using the Columns attribute. The df.columns attribute returns all the column labels of the dataframe.

Syntax

df.columns

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) # print all the columns in the dataframe print(df.columns)

Output

Index(['Software_Names', 'Rating', 'Total_Qty_In_Stock', 'Unit_Price', 'Total_Sales'], dtype='object') Get a list from Pandas DataFrame column headers

If you are using Python 3.5 and above or the latest Pandas version 1.4 or above, you could use df.columns.values that return all the columns as NumPy array or list.

Syntax 

df.columns.values

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) column_list = df.columns.values # print all the columns in the dataframe print(column_list)

Output

['Software_Names' 'Rating' 'Total_Qty_In_Stock' 'Unit_Price' 'Total_Sales']

If you are using an older version of Python and Pandas, you need to convert the NumPy array into a list using the tolist() method.

Syntax

df.columns.values.tolist()

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) column_list = df.columns.values.tolist() # print all the columns in the dataframe print(column_list)

Output

['Software_Names' 'Rating' 'Total_Qty_In_Stock' 'Unit_Price' 'Total_Sales']

Another way to get the list of column headers from Pandas Dataframe is using the list() method.

We can pass the Dataframe object to the list() method, and it returns all the column headers as a list.

Syntax

columns_list = list(df)  # import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) column_list = list(df) # pandas print column names print(column_list)

Output

['Software_Names' 'Rating' 'Total_Qty_In_Stock' 'Unit_Price' 'Total_Sales'] Get Pandas Column names with datatype

We may need to fetch the column name with its type in specific situations. In that case, we can use the dtypes attribute. This returns a Series with the data type of each column in the dataframe.

Syntax

df.dtypes

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) # pandas print column names with datatype print(df.dtypes)

Output

Software_Names object Rating float64 Total_Qty_In_Stock int64 Unit_Price float64 Total_Sales int64 dtype: object Get the list of columns from Pandas Dataframe based on specific Datatype

Here let us check how to get a list from dataframe column headers based on the data type of the column.

For instance, if we need to fetch all the columns names of datatype int64. We can use select_dtypes() method available in the dataframe. The select_dtypes() method returns a subset of the DataFrame’s columns based on the column dtypes.

Syntax

DataFrame.select_dtypes(include=Noneexclude=None)

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) # pandas print column names based on datatype print(df.select_dtypes('int64').columns.values)

Output

['Total_Qty_In_Stock' 'Total_Sales'] Get Pandas Dataframe Columns names sorted

The sorted() method accepts the dataframe and returns a list of column names or headers sorted alphabetically.

Syntax 

sorted(df)

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) # pandas print column names sorted alphabetically print(sorted(df))

Output

['Rating', 'Software_Names', 'Total_Qty_In_Stock', 'Total_Sales', 'Unit_Price'] Pandas Get Column Names With NaN

We can also get all the column headers with NaN. In Pandas, the missing values are denoted using the NaN.

We can use isna() and isnull() methods in Pandas to get all the columns with missing data.

The isna() method returns a boolean same-sized object indicating if the values are NA. NA values, such as None or numpy.NaN, gets mapped to True values. Everything else gets mapped to False values.

Syntax

df.isna().any()

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) # pandas print column names which are NaN print(df.isna().any())

Output

Software_Names False Rating False Total_Qty_In_Stock False Unit_Price True Total_Sales False dtype: bool

Syntax

df.isnull().any()

This isnull() function takes a scalar or array-like object and indicates whether values are missing (NaN in numeric arrays, None or NaN in object arrays, NaT in datetimelike).

Let us check how it works with an example.

# import pandas library import numpy as np import pandas as pd # create pandas DataFrame df = pd.DataFrame({'Software_Names': ['Windows Defender', 'AVG Antivirus', 'Mcafee Antivirus', 'Kaspersky Security', 'Norton Antivirus', 'Bit Defender'], 'Rating': [4.2, 3.7, 4, 4.5, 3, 4.7], 'Total_Qty_In_Stock': [10, 4, 8, 3, 5, 20], 'Unit_Price': [23.55, np.nan, 32.78, 33.0, np.nan, 45], 'Total_Sales': [3, 1, 7, 5, 11, 14] }) # pandas print column names which are NaN print(df.isnull().any())

Output

Software_Names False Rating False Total_Qty_In_Stock False Unit_Price True Total_Sales False dtype: bool Conclusion

Pandas Datafrmae consists of rows and columns to store data. Each columns will have its own header name to identify the column.

We have used multiple ways to get the column names in Pandas Dataframe using attributes and methods such as df.columns, df.columns.values, df.columns.values.tolist(), list(df) etc.

Categories: FLOSS Project Planets

Lucas Cimon: fpdf2.5.2 : SVG support and borb

Planet Python - Sun, 2022-04-24 06:53

fpdf2 is a simple & fast PDF creation library for Python that I have been maintaining since mid-2020.

In this article, I'm going to present some of the new features that landed since my last post on the subject. Hence, this will cover versions 2.5.0, 2.5.1 & 2 …


Permalink
Categories: FLOSS Project Planets

Docksal: Docksal 1.17.0 Release

Planet Drupal - Sat, 2022-04-23 19:00

And a very special release it is!

A little pre-DrupalCon gift just dropped — Docksal v1.17.0. This release now supports Apple M1 and Linux ARM64 architectures. That is just the tip of this iceberg of a release (albeit a very big tip for those that have been waiting).

Software Version UpdatesDocker Dependencies

The Docker suite now uses new versions:

  • Docker v20.10.12
  • Docker Compose v2.1.0.
  • Docker Desktop for Mac/Win users are able to update to the latest Docker Desktop v4.4.2+ version manually (tested officially with build 73305).

VirtualBox version (to v6.1.32), which adds official support for macOS Monterey 12.3.

Image Library and StacksAlmost all services in the Docksal catalog have been updated to use fresh multi-arch (amd64/arm64) images.

docksal/cli has been updated v3.2. When v3.0 was released in July 2021, it was the first to have arm64 support. However, users had to manually set the CLI_IMAGE to use this version. v3.1 released in Feb 2022 dropped PHP 7.3 after it was EOL in Dec 2021. v3.2.0 through v3.2.2 has seen more updates to included tools. From v3.1 on, terminus 3.x is included with PHP 8 support.

PHP 8.1 is now the default version in the default stack and in fin run cli

The Acquia, Pantheon, and Platform.sh stacks default to PHP 7.4 to match their configuration. However, even using those stacks, you can still override the image version that you use.

MariaDB 10.4 is now the default db service. It functions as a limited drop-replacement for MySQL 5.7, which does not have an ARM64 Docker image.

Notable Features and ChangesCloudflare Tunnel

Cloudflare Tunnel was added as fin share-v2 command.

It’s an alternative sharing method to ngrok (fin share command).

Cloudflare Tunnel creates a tunnel from the public internet to a port on your local machine. You can share the URL with anyone to give them access to your local development environment.

Gitpod Integration

Gitpod can provide fully initialized, perfectly set-up remote development environment that helps people set up the tools they need to develop. The recent integration allows you to use the same Docksal tools that you’ve used locally, but now in the cloud.

Switch to the new base domain

We are deprecating the use of .docksal base domain along with docksal-dns internal DNS resolver. Follow the instructions to switch to the new public base domain: .docksal.site.

Drupal 8 EOL

Since Drupal 8 is EOL, it is no longer offered as an option in fin project create. Drupal 7 (which is supported until Nov 2023) and Drupal 9 are still offered as options. The old Drupal 8 boilerplates have been archived, but are still accessible on GitHub.

Documentation Updates

It is always a goal to improve the documentation you need to take full advantage of Docksal. Several contributors helped make these updates to docs.docksal.io:

  • Expanded docs around project auto start/stop features
  • Added instructions for installing an addon globally
  • Added documentation on composer memory issues
  • Reorganized and updated help sections in fin + misc updates in fin help
  • Added disk space issue to common issues
  • Updated MailHog docs
  • Added Github Actions build badge in README.md
  • Added section on common issues for Apple MDM (Mobile Device Management) troubleshooting
  • Updated docs around disabling built-in DNS resolver (docksal-dns)
  • Added Cloudflare Tunnel (fin share-v2) docs
  • Added example on how to override solr service image
  • Added sponsor documentation

For a complete list of changes, fixes, and updates, see the release v1.17.0 notes on GitHub.

Thanks to all of our contributors, sponsors, and all of our users!!

Ever thought about how much time (and $) Docksal saves you and your team every month? Consider becoming a GitHub Sponsor ❤ to Docksal️.
Any contribution is welcome! https://docs.docksal.io/sponsor/

Yours,
Team Docksal

Docksal 1.17.0 Release was originally published in Docksal Maintainers Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.

Categories: FLOSS Project Planets

ItsMyCode: Convert DateTime to Unix timestamp in Python

Planet Python - Sat, 2022-04-23 12:34

This tutorial will look at how to convert DateTime to Unix timestamp in Python and String Date to timestamp with examples.

What is Unix Timestamp?

Unix was initially developed between 1960 – and 1970. The start time of the Unix was set to January 1, 1970, GMT (Midnight Greenwich Mean Time). The ISO format is represented as ISO 8601: 1970-01-01T00:00:00Z

In Computing, “Epoch Time” refers to the starting point used to calculate the number of seconds elapsed.

The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT) and not counting the leap seconds. 

How to convert DateTime to Unix Timestamp in Python?

It is common to store the DateTime as a Timestamp in the Database, and most Databases have a timestamp data type. It has a lot of benefits as it’s easier to track the created and modified records in the Database. It also occupies lesser space in DB when compared to DateTime datatype.

Now that we know the history of the Unix timestamp and how it is calculated, let us look at how to convert the DateTime object to Unix Timestamp in Python.

Example 1 – How to get the Current timestamp in Python using datetime module?

Using the Python’s datetime module we first get the current date and time using datetime.now() method, and we can pass the current datetime to datetime.timestamp() method to obtain the Unix timestamp.

from datetime import datetime # current date and time currentDateTime = datetime.now() print("Current Date Time is ", currentDateTime) # convert datetime to timestamp timestamp = datetime.timestamp(currentDateTime) print("Current Unix Timestamp is ", timestamp)

Output

Current Date Time is 2022-04-23 21:39:43.821740 Current Unix Timestamp is 1650730183.82174 Example 2 – How to convert string date to timestamp in Python

We leverage the strptime() method to convert the string to a datetime object. We cannot create the datetime object from any string, meaning a string needs to be in a specific format to convert it into a datetime object.

We first convert it into a given string into a date object using the strptime() and then convert it into the time tuple.

Using the time module’s mktime() method, we can pass the time tuple to convert it into the Unix timestamp.

import time import datetime # date in string format dt="23/04/2022" # convert into the time tuple time_tuple=datetime.datetime.strptime(dt, "%d/%m/%Y").timetuple() print("Time tuple format ",time_tuple) # using mktime() convert to timestamp print("The timestamp is ",time.mktime(time_tuple))

Output

Time tuple format time.struct_time(tm_year=2022, tm_mon=4, tm_mday=23, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=113, tm_isdst=-1) The timestamp is 1650652200.0 Conclusion

There are multiple ways to convert Datetime to Unix timestamp in Python. The two best approaches are using the mktime() method in the time module if the date is passed as a string object. If we have to get the current timestamp, we can leverage the datetime.timestamp() method.

Categories: FLOSS Project Planets

Nikola: Nikola v8.2.1 is out!

Planet Python - Sat, 2022-04-23 11:23

On behalf of the Nikola team, I am pleased to announce the immediate availability of Nikola v8.2.1. This is a minor release with a couple new features, as well as fixes for compatibility with the latest version of doit.

What is Nikola?

Nikola is a static site and blog generator, written in Python. It can use Mako and Jinja2 templates, and input in many popular markup formats, such as reStructuredText and Markdown — and can even turn Jupyter Notebooks into blog posts! It also supports image galleries, and is multilingual. Nikola is flexible, and page builds are extremely fast, courtesy of doit (which is rebuilding only what has been changed).

Find out more at the website: https://getnikola.com/

Downloads

Install using pip install Nikola.

Changes Features
  • Add emphasize_lines directive to code blocks (Issue #3607)

  • Gallery index pages support the status flag (Issue #3598)

  • Add start_at option to youtube directive (Issue #3603)

Bugfixes
  • Add data files to dependency file (Issue #3608)

  • Compatibility with doit 0.36.0 (Issue #3612)

Note: nikola doit_auto is not available if using doit>=0.36.0. You can still use nikola auto.

Categories: FLOSS Project Planets

Bálint Réczey: Firefox on Ubuntu 22.04 from .deb (not from snap)

Planet Debian - Sat, 2022-04-23 10:38

It is now widely known that Ubuntu 22.04 LTS (Jammy Jellyfish) ships Firefox as a snap, but some people (like me) may prefer installing it from .deb packages to retain control over upgrades or to keep extensions working.

Luckily there is still a PPA serving firefox (and thunderbird) debs at https://launchpad.net/~mozillateam/+archive/ubuntu/ppa maintained by the Mozilla Team. (Thank you!)

You can block the Ubuntu archive’s version that just pulls in the snap by pinning it:

$ cat /etc/apt/preferences.d/firefox-no-snap Package: firefox* Pin: release o=Ubuntu* Pin-Priority: -1

Now you can remove the transitional package and the Firefox snap itself:

sudo apt purge firefox sudo snap remove firefox sudo add-apt-repository ppa:mozillateam/ppa sudo apt update sudo apt install firefox

Since the package comes from a PPA unattended-upgrades will not upgrade it automatically, unless you enable this origin:

echo 'Unattended-Upgrade::Allowed-Origins:: "LP-PPA-mozillateam:${distro_codename}";' | sudo tee /etc/apt/apt.conf.d/51unattended-upgrades-firefox

Happy browsing!

Update: I have found a few other, similar guides at https://fostips.com/ubuntu-21-10-two-firefox-remove-snap and https://ubuntuhandbook.org/index.php/2022/04/install-firefox-deb-ubuntu-22-04 and I’ve updated the pinning configuration based on them.

Categories: FLOSS Project Planets

parallel @ Savannah: GNU Parallel 20220422 ('Буча') released

GNU Planet! - Sat, 2022-04-23 07:19

GNU Parallel 20220422 ('Буча') has been released. It is available for download at: lbry://@GnuParallel:4

Quote of the month:

  Immensely useful which I am forever grateful that it exists.
    -- AlexDragusin@ycombinator

New in this release:

  • sash is no longer supported as shell.
  • --retries 0 is an alias for --retries 2147483647.
  • --shell-completion returns shell completion code.
  • --ssh-login-file reloads every second.
  • --parset is replaced with --_parset because it is only used internally.
  • sem --pipe passes STDIN (standard input) to the command.
  • Bug fixes and man page updates.

Get the book: GNU Parallel 2018 http://www.lulu.com/shop/ole-tange/gnu-parallel-2018/paperback/product-23558902.html

GNU Parallel - For people who live life in the parallel lane.

If you like GNU Parallel record a video testimonial: Say who you are, what you use GNU Parallel for, how it helps you, and what you like most about it. Include a command that uses GNU Parallel if you feel like it.

About GNU Parallel

GNU Parallel is a shell tool for executing jobs in parallel using one or more computers. A job can be a single command or a small script that has to be run for each of the lines in the input. The typical input is a list of files, a list of hosts, a list of users, a list of URLs, or a list of tables. A job can also be a command that reads from a pipe. GNU Parallel can then split the input and pipe it into commands in parallel.

If you use xargs and tee today you will find GNU Parallel very easy to use as GNU Parallel is written to have the same options as xargs. If you write loops in shell, you will find GNU Parallel may be able to replace most of the loops and make them run faster by running several jobs in parallel. GNU Parallel can even replace nested loops.

GNU Parallel makes sure output from the commands is the same output as you would get had you run the commands sequentially. This makes it possible to use output from GNU Parallel as input for other programs.

For example you can run this to convert all jpeg files into png and gif files and have a progress bar:

  parallel --bar convert {1} {1.}.{2} ::: *.jpg ::: png gif

Or you can generate big, medium, and small thumbnails of all jpeg files in sub dirs:

  find . -name '*.jpg' |
    parallel convert -geometry {2} {1} {1//}/thumb{2}_{1/} :::: - ::: 50 100 200

You can find more about GNU Parallel at: http://www.gnu.org/s/parallel/

You can install GNU Parallel in just 10 seconds with:

    $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
       fetch -o - http://pi.dk/3 ) > install.sh
    $ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
    12345678 883c667e 01eed62f 975ad28b 6d50e22a
    $ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
    cc21b4c9 43fd03e9 3ae1ae49 e28573c0
    $ sha512sum install.sh | grep ec113b49a54e705f86d51e784ebced224fdff3f52
    79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
    fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
    $ bash install.sh

Watch the intro video on http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial (man parallel_tutorial). Your command line will love you for it.

When using programs that use GNU Parallel to process data for publication please cite:

O. Tange (2018): GNU Parallel 2018, March 2018, https://doi.org/10.5281/zenodo.1146014.

If you like GNU Parallel:

  • Give a demo at your local user group/team/colleagues
  • Post the intro videos on Reddit/Diaspora*/forums/blogs/ Identi.ca/Google+/Twitter/Facebook/Linkedin/mailing lists
  • Get the merchandise https://gnuparallel.threadless.com/designs/gnu-parallel
  • Request or write a review for your favourite blog or magazine
  • Request or build a package for your favourite distribution (if it is not already there)
  • Invite me for your next conference

If you use programs that use GNU Parallel for research:

  • Please cite GNU Parallel in you publications (use --citation)

If GNU Parallel saves you money:

About GNU SQL

GNU sql aims to give a simple, unified interface for accessing databases through all the different databases' command line clients. So far the focus has been on giving a common way to specify login information (protocol, username, password, hostname, and port number), size (database and table size), and running queries.

The database is addressed using a DBURL. If commands are left out you will get that database's interactive shell.

When using GNU SQL for a publication please cite:

O. Tange (2011): GNU SQL - A Command Line Tool for Accessing Different Databases Using DBURLs, ;login: The USENIX Magazine, April 2011:29-32.

About GNU Niceload

GNU niceload slows down a program when the computer load average (or other system activity) is above a certain limit. When the limit is reached the program will be suspended for some time. If the limit is a soft limit the program will be allowed to run for short amounts of time before being suspended again. If the limit is a hard limit the program will only be allowed to run when the system is below the limit.GNU Parallel 20220422 ('Буча') has been released. It is available for download at: lbry://@GnuParallel:4

Quote of the month:

  Immensely useful which I am forever grateful that it exists.
    -- AlexDragusin@ycombinator

 

New in this release:

  • sash is no longer supported as shell.
  • --retries 0 is an alias for --retries 2147483647.
  • --shell-completion returns shell completion code.
  • --ssh-login-file reloads every second.
  • --parset is replaced with --_parset because it is only used internally.
  • sem --pipe passes STDIN (standard input) to the command.
  • Bug fixes and man page updates.

Get the book: GNU Parallel 2018 http://www.lulu.com/shop/ole-tange/gnu-parallel-2018/paperback/product-23558902.html

GNU Parallel - For people who live life in the parallel lane.

If you like GNU Parallel record a video testimonial: Say who you are, what you use GNU Parallel for, how it helps you, and what you like most about it. Include a command that uses GNU Parallel if you feel like it.

About GNU Parallel

GNU Parallel is a shell tool for executing jobs in parallel using one or more computers. A job can be a single command or a small script that has to be run for each of the lines in the input. The typical input is a list of files, a list of hosts, a list of users, a list of URLs, or a list of tables. A job can also be a command that reads from a pipe. GNU Parallel can then split the input and pipe it into commands in parallel.

If you use xargs and tee today you will find GNU Parallel very easy to use as GNU Parallel is written to have the same options as xargs. If you write loops in shell, you will find GNU Parallel may be able to replace most of the loops and make them run faster by running several jobs in parallel. GNU Parallel can even replace nested loops.

GNU Parallel makes sure output from the commands is the same output as you would get had you run the commands sequentially. This makes it possible to use output from GNU Parallel as input for other programs.

For example you can run this to convert all jpeg files into png and gif files and have a progress bar:

  parallel --bar convert {1} {1.}.{2} ::: *.jpg ::: png gif

Or you can generate big, medium, and small thumbnails of all jpeg files in sub dirs:

  find . -name '*.jpg' |
    parallel convert -geometry {2} {1} {1//}/thumb{2}_{1/} :::: - ::: 50 100 200

You can find more about GNU Parallel at: http://www.gnu.org/s/parallel/

You can install GNU Parallel in just 10 seconds with:

    $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
       fetch -o - http://pi.dk/3 ) > install.sh
    $ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
    12345678 883c667e 01eed62f 975ad28b 6d50e22a
    $ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
    cc21b4c9 43fd03e9 3ae1ae49 e28573c0
    $ sha512sum install.sh | grep ec113b49a54e705f86d51e784ebced224fdff3f52
    79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
    fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
    $ bash install.sh

Watch the intro video on http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial (man parallel_tutorial). Your command line will love you for it.

When using programs that use GNU Parallel to process data for publication please cite:

O. Tange (2018): GNU Parallel 2018, March 2018, https://doi.org/10.5281/zenodo.1146014.

If you like GNU Parallel:

  • Give a demo at your local user group/team/colleagues
  • Post the intro videos on Reddit/Diaspora*/forums/blogs/ Identi.ca/Google+/Twitter/Facebook/Linkedin/mailing lists
  • Get the merchandise https://gnuparallel.threadless.com/designs/gnu-parallel
  • Request or write a review for your favourite blog or magazine
  • Request or build a package for your favourite distribution (if it is not already there)
  • Invite me for your next conference

If you use programs that use GNU Parallel for research:

  • Please cite GNU Parallel in you publications (use --citation)

If GNU Parallel saves you money:

About GNU SQL

GNU sql aims to give a simple, unified interface for accessing databases through all the different databases' command line clients. So far the focus has been on giving a common way to specify login information (protocol, username, password, hostname, and port number), size (database and table size), and running queries.

The database is addressed using a DBURL. If commands are left out you will get that database's interactive shell.

When using GNU SQL for a publication please cite:

O. Tange (2011): GNU SQL - A Command Line Tool for Accessing Different Databases Using DBURLs, ;login: The USENIX Magazine, April 2011:29-32.

About GNU Niceload

GNU niceload slows down a program when the computer load average (or other system activity) is above a certain limit. When the limit is reached the program will be suspended for some time. If the limit is a soft limit the program will be allowed to run for short amounts of time before being suspended again. If the limit is a hard limit the program will only be allowed to run when the system is below the limit.

Categories: FLOSS Project Planets

Russell Coker: Got Covid

Planet Debian - Sat, 2022-04-23 05:52

I’ve currently got Covid, I believe I caught it on the 11th of April (my first flight since the pandemic started) with a runny nose on the 13th and a positive RAT on the evening of the 14th. I got an official PCR test on the 16th with a positive result returned on the 17th. I think I didn’t infect anyone else (yay)! Now I seem mostly OK but still have a lack of energy, sometimes I suddenly feel tired after 20 minutes of computer work.

The progression of the disease was very different to previous cold/flu diseases that I have had. What I expect is to start with a cough or runny nose, escalate with more of that, have a day or two of utter misery with congestion, joint pain, headache, etc, then have it suddenly decrease overnight. For Covid I had a runny nose for a couple of days which went away then I got congestion in my throat with serious coughing such that I became unable to speak. Then the coughing went away and I had a really bad headache for a day with almost no other symptoms. Then the headache went away and I was coughing a bit the next day. The symptoms seemed to be moving around my body.

I got a new job and they wanted me to fly to the head office to meet the team, I apparently got it on the plane a day before starting work. I’ve discussed this with a manager and stated my plan to drive instead of fly in future. It’s only a 7 hour drive and it’s not worth risking the disease to save 3-4 hours travel time, or even the 5 hours travel I’d have saved if the airports were working normally (apparently a lot of airport staff are off sick so there’s delays). Given the flight delays and the fact that I was advised to arrive extra early at the airport I ended up taking almost 7 hours for the entire trip!

7 hours driving is a bit of effort, but sitting in an airport waiting for a delayed flight while surrounded by diseased people isn’t fun either.

Related posts:

  1. another visual migraine This morning while travelling to work by tram I had...
  2. more security foolishness Dutch police arrested 12 people for acting suspiciously on a...
  3. more on vision I had a few comments on my last so I...
Categories: FLOSS Project Planets

KDE Frameworks Barcode Scanner

Planet KDE - Sat, 2022-04-23 04:30

KDE Framework’s Prison library for displaying one-dimensional barcodes and two-dimensional matrix codes will also provide a component to scan those codes from a camera feed in its upcoming 5.94 release.

Features

There are a few copies of code for scanning barcodes from a Qt Multimedia video feed using ZXing in apps like Kaidan or Qrca, as well in projects outside of KDE’s repositories. That’s usually a good indicator that this functionality belongs into a shared component or library.

For 5.94 KDE Frameworks now provides this, taking the best bits of the existing implementations and expanding on them:

  • Barcode detection happens in a separate thread to not impact displaying the video feed or application UI.
  • By using newer ZXing API we can avoid expensive color conversions for many video formats, in the best case detection is now done without a single video frame copy.
  • For planar or semi-planar video formats (that is formats which have a luminance channel that isn’t interleaved with color channels), barcode detection is performed solely on the luminance data, avoiding not only the color conversion but also effectively reducing the amount of data to process by half.
  • Forward-compatibility with Qt6, which changed the API of Qt Multimedia significantly.

Overall this is fast enough for running barcode detection on every frame of a live video feed, on a phone.

This is available both from a C++ and a QML API which can consume a Qt Multimedia video stream and outputs the detected barcodes, including their textual or binary content, the barcode format and the barcode position in the source video frame.

App Integration

There is no UI included, applications have full control on how to integrate and display this. This isn’t difficult at all though, and just takes three elements to get started:

import QtQuick 2.15 import QtMultimedia 5.15 import org.kde.prison.scanner 1.0 as Prison ApplicationWindow { Camera { id: camera } VideoOutput { id: viewFinder anchors.fill: parent source: camera filters: [scanner] } Prison.VideoScanner { id: scanner onResultChanged: console.log(result.text) } }

Slightly more comprehensive QML examples for both Qt5 and Qt6 are included in the Prison source code, demonstrating more ways to use the scan results for example.

There’s also two merge requests for use in applications already:

Integrated barcode scanner in KDE Itinerary. Contribute

There are more applications that would benefit from direct barcode scanning integration, such as Vakzination or Keysmith. Another place might the Wi-Fi setup UI of Plasma Mobile, Qrca even already has the necessary Wi-Fi QR code parsing code which might come in handy here.

Categories: FLOSS Project Planets

Andrej Shadura: To England by train (part 2)

Planet Debian - Sat, 2022-04-23 02:45

My attempt to travel to the UK by train last year didn’t go quite as well as I expected. As I mentioned in that blog post, the NightJet to Brussels was cancelled, forcing me to fly instead. This disappointed me so much that I actually unpublished the blog post minutes after it was originally put online. The timing was nearly perfect: I type make publish and I get an email from ÖBB saying they don’t know if my train is going to run. Of course it didn’t, as Deutsche Bahn workers went ahead with their strike. The blog post sat in the drafts for more than half a year until yesterday, when I finally updated and published it.

The reason I have finally published it is that I’m going to the UK by train once again. Now, unless railways decide to hold a strike again, fully by train both ways. Very expensive, especially compared to the price of Ryanair flights to my destination. Unfortunately, even though Eurostar added more daily services, they’re still not cheap, especially on a shorter notice. This seems to apply to the ÖBB’s NightJet even more: I tried many routes between Vienna and London, and the cheapest still seemed to be the connection through Brussels.

While researching the prices of the tickets, it seems all booking systems decided to stop co-operating. The Trainline refused to let me look up any trains at all, even with all tracking and advertisement allowed, SNCF kepts showing me overly generic errors (Sorry, an error has occurred.), while the GWR booking system kept crashing with a 500 Internal Server Error for about two hours.

Trainline, GWR and SNCF kept crashing

Eventually, having spent a lot of time and money, I’ve booked my trains to, within and back from England. This time, Cambridge is among the destinations.

The complete route Date Station Arrival Departure Train 26.4 Bratislava hl.st. 18:37 REX 2529 Wien Hbf 19:44 20:13 NJ 40490 27.4 Bruxelles-Midi 9:54 15:56 EST 9145 London St Pancras 17:01 17:43 ThamesLink Cambridge 18:43

I’m not sure about it yet, but I may end up taking an earlier train from Bratislava just to ensure there’s enough time for the change in Vienna; similarly, I’m not sure how much time I will be spending at St Pancras, so I may take one of the later trains.

P.S. The maps in this and other posts were created using uMap; the map data come from OpenStreetMap. The train route visualisation was generated with help of signal.eu.org.

Categories: FLOSS Project Planets

Pages