Sign In
Sign In

Cloud Service Provider
for Developers and Teams

We make it simple to get started in the cloud and scale up as you grow —
whether you have one virtual machine or ten thousand
By signing up you agree to the Terms of Service and Privacy Policy
99.9% Uptime
Our cloud service provides the ultimate in server dependability and stability
Money-back Guarantee
Experience our high-speed cloud services without any risk, assured by our money-back guarantee
Easy to Deploy
Manage your services with ease using our intuitive control panel, where deploying software is a matter of minutes
Reliable and Available
Select from 6 datacenter regions around the world based on latency or deploy across regions for redundancy

Robust cloud services for every demand

See all Products

Cloud Servers

Cutting-edge hardware for cloud solutions: powerful Intel and AMD processors, ultra-fast NVMe disks

Databases

We provide a cloud database ready to store everything you have. The best DBMSs are on deck: MySQL, Redis, Kafka, and more

App Platform

Just link your repo, pick a project to deploy, and Hostman will have it running in the cloud with just a couple of clicks from the dashboard

S3 Storage

A universal object storage compatible with the S3 protocol

Firewall

Multi-layered protection from vulnerability scanning, DDoS, and cyber-attacks

Kubernetes

Automate the management of containerized applications, from deployment and scaling to monitoring and error handling

Managed Backups

Our server and application backup feature allows for both on-demand and scheduled backup and one-click data restoration

Images

Create images for backup free of charge or deploy your own in the Hostman cloud

Hostman's commitment to simplicity
and budget-friendly solutions

1 CPU
2 CPU
4 CPU
8 CPU
Configuration
1 CPU, 1 GB RAM, 25 GB SSD
Hostman
DigitalOcean
Google Cloud
AWS
Vultr
Price
$4
$6
$6.88
$7.59
$5
Tech support
Free
$24/mo
$29/mo + 3% of
monthly charges
$29/mo or 3% of
monthly charges
Free
Backups
from $0.07/GB
20% or 30% higher
base daily/weekly fee
$0.03/GB per mo
$0.05/GB per mo
20% higher base
monthly/hourly fee
Bandwidth
Free
$0.01 per GB
$0.01 per GB
$0.09/GB first
10 TB / mo
$0.01 per GB
Live chat support
Avg. support response time
<15 min
<24 hours
<4 hours
<12 hours
<12 hours
Anup k.
Associate Cloud Engineer
5.0 out of 5

"Hostman Comprehensive Review of Simplicity and Potential"

It been few years that I have been working on Cloud and most of the cloud service...
Mansur H.
Security Researcher
5.0 out of 5

"A perfect fit for everything cloud services!"

Hostman's seemless integration, user-friendly interface and its robust features (backups, etc) makes it much easier...
Adedeji E.
DevOps Engineer
5.0 out of 5

"Superb User Experience"

For me, Hostman is exceptional because of it's flexibility and user-friendliness. The platform's ability to offer dedicated computing resources acr...
Yudhistira H.
Mid-Market(51-1000 emp.)
5.0 out of 5

"Streamlined Cloud Excellence!"

What I like best about Hostman is their exceptional speed of deployment, scalability, and robust security features. Their...
Mohammad Waqas S.
Biotechnologist and programmer
5.0 out of 5

"Seamless and easy to use Hosting Solution for Web Applications"

From the moment I signed up, the process has been seamless and straightforward...
Mohana R.
Senior Software Engineer
5.0 out of 5

"Availing Different DB Engine Services Provided by Hostman is Convenient for my Organization usecases"

Hostman manages the cloud operations...
Faizan A.
5.0 out of 5

"Hostman is a great fit for me"

Hostman is a great fit for me. What do you like best about Hostman? It was very easy to deploy my application and create database, I didn't have
Adam M.
5.0 out of 5

"Perfect website"

This website is extremely user friendly and easy to use. I had no problems so didn't have to contact customer support. Really good website and would recommend to others.
Anup K.
4.0 out of 5

"Simplifying Cloud Deployment with Strengths and Areas for Growth"

What I like best about Hostman is its unwavering commitment to simplicity...
Naila J.
5.0 out of 5

"Streamlined Deployment with Room for Improvement"

Hostman impresses with its user-friendly interface and seamless deployment process, simplifying web application hosting...

Trusted by 500+ companies and developers worldwide

Deploy a cloud server
in just a few clicks

Set up your сloud servers at Hostman swiftly and without any fees, customizing them for your business with a quick selection of region, IP range, and details—ensuring seamless integration and data flow

Code locally, launch worldwide

Our servers, certified with ISO/IEC 27001, are located in Tier 3 data
centers across the US, Europe, and Asia
🇺🇸 San Francisco
🇺🇸 San Jose
🇺🇸 Texas
🇺🇸 New York
🇳🇱 Amsterdam
🇳🇬 Lagos
🇩🇪 Frankfurt
🇵🇱 Gdansk
🇦🇪 Dubai
🇸🇬 Singapore

Latest News

Flask

How to Handle Incoming Request Data in Flask

Websites where you watch videos, read news or chat with friends operate on a client-server architecture. The client (e.g., a browser) sends a request to the server, and based on that request, the server responds—usually by sending an HTML document back. When we look under the hood of how websites work, request handling follows a general logic: Accept the request. Choose a request handler. Execute the handler. Send a response back to the client. A framework is a developer tool used to implement this logic. Flask is a microframework for building websites using Python. The term "micro" means that Flask provides a small, lightweight set of tools that are still sufficient for creating most websites. Flask is great for building APIs or websites hosted on cloud servers. In this article, we'll create a Flask application and explore how to process incoming requests. Getting Started We'll use PyCharm + pipenv on Windows 10. There are plenty of tutorials online for installing this setup on other operating systems, but here’s how to install it on Windows 10. Install Python. Visit the official website www.python.org/downloads, choose the Python version for your OS, and follow the installer instructions. Install pipenv. Pipenv is a package for managing virtual environments in Python. To install it, open the Windows command prompt and run this command: py -m pip install pipenv Install PyCharm. PyCharm is an IDE (Integrated Development Environment) for Python. Download and install it from the official site www.jetbrains.com/pycharm, choosing either the Community or Professional version. Creating a Project In PyCharm, click "File" → "New Project" and specify the following: Project directory Virtual environment settings Path to the Python interpreter Path to pipenv executable After setting everything up, click "Create." Installing Flask After creating the project, open the terminal at the bottom of PyCharm and run: pip install flask If everything is set up correctly, Flask will install. If you encounter an error like "Execution of scripts is disabled," open PowerShell as an administrator and run this command: Set-ExecutionPolicy RemoteSigned Then type [A] to allow the script to run. Working with URLs Once the necessary components are installed, let's start interacting with Flask. First, import Flask: from flask import Flask We’ll write a small Flask application to demonstrate working with URL requests: from flask import Flask app = Flask(__name__) @app.route("/hostman") def hostman(): return "This is the /hostman page" @app.route("/blog") def blog(): return "This is the /blog page" @app.route("/cloud") def cloud(): return "This is the /cloud page" if __name__ == "__main__": app.run() Explanation: First, we import Flask. We then create an instance of the Flask class, app. We use the .route decorator to assign functions to specific URLs. Finally, we run the application using app.run(). Running the Application In the terminal, you will see the local address of your site (127.0.0.1:5000). You might see nothing if you navigate to this address because we still need to define a handler for the root URL (/). However, if you visit: 127.0.0.1:5000/hostman 127.0.0.1:5000/blog 127.0.0.1:5000/cloud You’ll see responses for these routes. Flask automatically logs each request in the console. Handling GET Requests You can pass various parameters to the server via a GET request. For instance, consider this URL: hostman.com/blog?framework=flask&language=python&version=3.10 Here, the parameters are passed as key-value pairs after the question mark (?): framework=flask language=python version=3.10 Let’s write a function, get_example(), to extract these parameters in Flask: from flask import request @app.route("/get_example") def get_example(): framework = request.args.get('framework') language = request.args.get('language') version = request.args.get('version') return f"language = {language}; framework = {framework}; version = {version}" This code: Imports the request class and its methods. Uses the .args.get() method to extract query parameters. Returns the extracted values in the response. If you go to the URL: http://127.0.0.1:5000/get_example?language=python&framework=flask&version=3.10 The application will correctly process the GET request and display the extracted parameters. Handling POST Requests By default, .route() handles only GET requests. Flask can also handle POST requests. Let’s add a simple login form that accepts a username and password: @app.route('/authorization', methods=['GET', 'POST']) def authorization(): if request.method == 'POST': login = request.form.get('Login') password = request.form.get('Password') if login == "admin" and password == "admin": return "Correct" else: return "Incorrect" return ''' <form method="POST"> <div><label>Login: <input type="text" name="Login"></label></div> <div><label>Password: <input type="text" name="Password"></label></div> <input type="submit" value="Enter"> </form>''' Explanation: The decorator handles both GET and POST requests. On a GET request, a form for login and password is displayed. On a POST request (when the form is submitted), the credentials are checked. If correct, it returns "Correct"; otherwise, it is "Incorrect." Visit the URL: 127.0.0.1:5000/authorization If you enter "admin" as both login and password, you will see "Correct." Otherwise, you’ll see "Incorrect." Full Code Example from flask import Flask, request app = Flask(__name__) @app.route("/hostman") def hostman(): return "This is the /hostman page" @app.route("/blog") def blog(): return "This is the /blog page" @app.route("/cloud") def cloud(): return "This is the /cloud page" @app.route("/get_example") def get_example(): framework = request.args.get('framework') language = request.args.get('language') version = request.args.get('version') return f"language = {language}; framework = {framework}; version = {version}" @app.route('/authorization', methods=['GET', 'POST']) def authorization(): if request.method == 'POST': login = request.form.get('Login') password = request.form.get('Password') if login == "admin" and password == "admin": return "Correct" else: return "Incorrect" return ''' <form method="POST"> <div><label>Login: <input type="text" name="Login"></label></div> <div><label>Password: <input type="text" name="Password"></label></div> <input type="submit" value="Enter"> </form>''' if __name__ == "__main__": app.run() Conclusion This article explored how to handle GET and POST requests in Flask. However, it's important to remember that security is critical when handling client data. Always validate and sanitize input to prevent malicious attacks. Prevention is the best way to protect your server from unwanted consequences.
15 October 2024 · 6 min to read
Python

Web Scraping with Python and Beautiful Soup

Beautiful Soup is a Python library that allows you to extract data from web documents. The library provides a simple and intuitive interface for parsing and processing web documents, making it useful for both web scraping and data analysis. In this article, we'll describe how to use Beautiful Soup in Python, explore several essential functions of this library, including applying search filters, using built-in functions, and modifying the DOM tree. But first, let's cover some key terminology. What is the DOM Tree? The DOM (Document Object Model) is a hierarchical structure that represents the content of an HTML document as specific objects called nodes. The DOM tree consists of nodes, each with its own type. For example, elements might be tags like <div>, <p>, or <a>, while text nodes contain textual information displayed on the page. The DOM tree allows access to the document's content, enabling developers to manipulate elements, attributes, and page content using programming languages. For example, DOM lets you modify element content, add new elements, or remove existing ones. Installing Beautiful Soup To install Beautiful Soup for Python 3, open the command line or terminal on your computer and enter the following command: pip install beautifulsoup4 On Windows, you can open the command line by clicking the "Start" button, typing cmd in the search bar, and pressing Enter. On MacOS and Linux, open the terminal from the applications menu or press Ctrl + Alt + T. After that, type the command pip install beautifulsoup4 and press Enter to begin the installation process. If you encounter an error like "pip" is not recognized as an internal or external command… on Windows, it may mean that the path to the pip executable is not set in the PATH variable. To fix this: Open Control Panel. Choose "System and Security" or "System" depending on your Windows version. Click on "Advanced system settings." Select "Environment Variables." Find the PATH variable and click "Edit." Add the path to the Scripts folder where the pip executable is located (usually C:\PythonXX\Scripts, where XX is your Python version). Add it at the end of the line, separated by a semicolon. Be careful not to alter any other paths! After making these changes, click "OK" and close all windows. Now, rerun the pip install beautifulsoup4 command, and it should work. Searching Elements in the DOM find_all() is the standard method in Beautiful Soup used to search for elements on a web page that match certain criteria. find_all() searches for all elements that meet the given parameters and returns them as a list of objects. For example, if you want to find all H2 tags in an HTML document, first specify the path to the document: from bs4 import BeautifulSoup with open("C:/Files/my_wiki_example.html") as fp: soup = BeautifulSoup(fp, 'html.parser') Now, perform the search: for heading in soup.find_all('h2'):    print(heading.text) If there are headings, you will see output like: Chapter 1 Chapter 2 Chapter 3 Chapter 4 If Beautiful Soup doesn’t find anything, it will return an empty string. You can also search using regular expressions. Let’s try to print all headings from the page using: import re for heading in soup.find_all(re.compile('^h[1-6]')): print(heading.name + ' ' + heading.text.strip()) This will return: h1 My First Wiki Doc h2 Chapter 1 h2 Chapter 2 h2 Chapter 3 h2 Chapter 4 As we see, find_all() accepts two arguments: the tag name and a dictionary of attributes. You can use either argument or both together for searching. You can also list tags directly: for heading in soup.find_all(['h1', 'h2', 'h3']): print(heading.name + ' ' + heading.text.strip()) You’ll get: h1 My First Wiki Doc h2 Chapter 1 h2 Chapter 2 h2 Chapter 3 h2 Chapter 4 If you want to count a certain number of elements, you can use: len(soup.find_all(True)) To solve more complex searches, you can write a custom function. Here’s a simple example: def big_lists(tag): return len(tag.contents) > 5 and tag.name == 'ul' len(soup.find_all(big_lists)) This code searches for unordered lists (<ul>) with more than five items and shows that one such list is found. Filtering Elements To filter elements using find_all(), you can search by specific attributes. Let's search by class names and filter the results: import re len(soup.find_all(class_='table')) # Finds tables 18 len(soup.find_all(class_='image')) # Finds images 12 len(soup.find_all(class_='references')) # Finds references 5 len(soup.find_all(class_='redirect')) # Finds redirects 3 If you want to limit the number of results, for instance, to get only the first three tables: soup.find_all(class_='table', limit=3) The output might look like: <span class='table' id='Table1'>Table 1</span> <span class='table' id='Table2'>Table 2</span> <span class='table' id='Table3'>Table 3</span> To filter direct descendants, you can use: len(soup.html.find_all('meta', recursive=False)) The recursive=False stops global searching and limits it to direct child elements. Alternatively, you can use find(). For instance, to find an H2 header: soup.find('h2') Modifying the DOM Beautiful Soup also allows modifying the content of web documents. To change the text of an H1 heading: title = soup.find('h1')title.string = 'New Title' For confirmation, you can check: soup.find('h1')# Output: <h1>New Title</h1> You can also add a new attribute to the first paragraph: paragraph = soup.find('p')paragraph['data-id'] = '12345' To delete a paragraph: paragraph = soup.find('p')paragraph.extract() Use prettify() and print() to check the modified document: print(soup.prettify()) Other useful methods include: append() to add content to an element, insert() to insert content inside an element, clear() to clear an element’s content without removing the tag, decompose() to completely remove an element and its content from the DOM, replace_with() to replace an element with another. These methods allow flexible modifications to web documents. With a bit of practice, you’ll be able to easily find elements in HTML documents and modify their content with no trouble.
15 October 2024 · 5 min to read
JavaScript

How to Use the Date Object in JavaScript

JavaScript provides a built-in Date object that simplifies working with dates and times. This tutorial will guide developers through the essential aspects of the Date object, including its creation, retrieval of date and time information, formatting, manipulation, and handling of time zones. Introduction to JavaScript Date Object The Date object in JavaScript represents datetime values, enabling developers to manage temporal data with ease. It is essential for tasks such as scheduling, time tracking, and logging. The Date object helps: Represent specific date and time values, such as "2022-07-25T14:30:00.000Z". Perform operations like retrieving, formatting, and manipulating dates and times. Simplify date and time calculations across different time zones. Understanding the basics of the Date object will help in managing time-sensitive data efficiently in web applications. Creating a Date Object Creating a Date object in JavaScript is straightforward. Here are the two common ways to achieve it:  Using the current time Using a timestamp Creating a Date Object for the Current Time The simplest way to create a Date object is by instantiating the current date and time: const currentDate = new Date();console.log(currentDate); This creates an object representing the current date and time in the user's local timezone. Creating a Date Object Using a Timestamp You can also create a Date object from a specific timestamp (milliseconds since January 1, 1970): const timestamp = 1643723400000; const dateObject = new Date(timestamp); console.log(dateObject); This is useful for manipulating dates stored in timestamp format. Now that we know how to create a date object, let’s see how to retrieve date and time information. Retrieving JS Date and Time Information The Date object provides methods for extracting various components of a date, such as a year, month, and hour. Key methods include getDate(): Returns the day of the month. getFullYear(): Returns the four-digit year. getMonth(): Returns the month (0-11, where 0 represents January). getHours(): Returns the hour (0-23). getMinutes(): Returns the minutes (0-59). getSeconds(): Returns the seconds (0-59). For example, to retrieve the current date and format it as MM/DD/YYYY HH:MM:ss: function formatDate(dateObject) { const year = dateObject.getFullYear(); const month = dateObject.getMonth() + 1; // Months are zero-indexed const day = dateObject.getDate(); const hours = dateObject.getHours(); const minutes = dateObject.getMinutes(); const seconds = dateObject.getSeconds(); return `${month}/${day}/${year} ${hours}:${minutes}:${seconds}`; } console.log(formatDate(new Date())); Here is the result when executing the function.  There are however interesting methods we can use to format datetime into readable formats.  Formatting Date and Time JavaScript provides methods to format datetime values into human-readable strings. This allows developers to convert a Date object to a string or vice versa. Formatting a Date as a String To output a Date object as a human-readable string, use methods like toDateString() and toTimeString(): const currentDate = new Date(); const dateString = currentDate.toDateString(); console.log(dateString); const timeString = currentDate.toTimeString(); console.log(timeString); Here is the output: Converting Strings to Date Objects Developers can also convert readable strings into Date objects using the Date constructor: const dateFromString = new Date("October 10, 2024");console.log(dateFromString); However, it’s better to use recommended formats.  Recommended Formats To avoid errors when working with date strings, it is advisable to use reliable formats: ISO 8601 Format (Recommended): The safest and most reliable format is the ISO 8601 date format: YYYY-MM-DDTHH:mm:ss.sssZ. If only the date part is provided, it assumes the time as midnight 00:00:00. const date = new Date("2024-10-10T14:48:00Z");console.log(date); RFC2822 Format: Another accepted format is the RFC2822 format commonly used in email headers: Day, DD Mon YYYY HH:mm:ss GMT. const date = new Date("Wed, 10 Oct 2024 14:48:00 GMT");console.log(date); We now know how to format datetime values using the Date object. Let’s see how to manipulate date values for simple scheduling and calculations. Manipulating Date Values Date manipulation is essential for tasks like scheduling and calculating deadlines. JavaScript provides setter methods for modifying specific components of a Date object. Modifying Date Components Developers can modify specific components of a Date object using setter methods. Note that months are zero-indexed: let date = new Date(); date.setFullYear(2025); date.setMonth(5); // Set month to June date.setDate(15); // Set day to 15th date.setHours(10); // Set hour to 10 AM date.setMinutes(30); // Set minutes to 30 date.setSeconds(45); // Set seconds to 45 console.log(date); Adding or Subtracting Days Developers can easily add or subtract days using setDate(): let date = new Date(); date.setDate(date.getDate() + 5); // Add 5 days console.log(date); Date arithmetic can be accomplished using timestamps (milliseconds since January 1, 1970): let now = new Date(); let oneDayInMs = 24 * 60 * 60 * 1000; let tomorrow = new Date(now.getTime() + oneDayInMs); console.log(tomorrow); Comparing Date Objects Date objects can be compared using their timestamps: let date1 = new Date('2024-10-10'); let date2 = new Date('2024-12-25'); console.log(date1 > date2); // false (October 10 is earlier than December 25) console.log(date1 < date2); // true console.log(date1.getTime() === date2.getTime()); // false Now that we now how to manipulate dates values for calculation, let’s see how we can handle dates with time zones. Working with Time Zones The Date object is timezone-agnostic, meaning it doesn't have a built-in concept of time zones. However, JavaScript’s Date object handles dates in local time (system time zone) and UTC. When creating Date objects, it is essential to be aware of time zone conversions, especially when performing operations across different regions. Local Time vs. UTC JavaScript can work with localtime and UTC. Local time allows you to represent the time by the Date object when created without any specific time zone information, reflecting the local time of the environment in which JavaScript is executed. For example, creating a Date object in Paris will reflect the central European time zone. UTC is the time standard not affected by time zones or DayLight Saving Time (DST). Using Coordinated Universal Time (UTC) ensures consistency and avoids ambiguity when working with dates and times across different time zones, simplifying time calculations, logging, and user experience management in applications that serve users in multiple regions. Creating Date Objects in UTC To create a Date object in UTC, use the ISO 8601 format: const utcDate = new Date("2024-10-10T14:30:00Z");console.log(utcDate); Converting Local Time to UTC To retrieve UTC date components, use getUTCDate(), getUTCMonth(), etc.: const localDate = new Date();console.log(localDate.getUTCDate(), localDate.getUTCMonth() + 1, localDate.getUTCFullYear()); Converting UTC to Local Time Similarly, to convert a UTC date to local time, you can use the local equivalent methods: const utcDate = new Date("2024-10-10T14:30:00Z"); // UTC date const localDay = utcDate.getDate(); const localMonth = utcDate.getMonth() + 1; // Months are zero-indexed const localYear = utcDate.getFullYear(); console.log(`Local Date: ${localMonth}/${localDay}/${localYear}`); Being mindful of time zones when working with dates in JavaScript is essential for ensuring accurate datetime representation, especially in applications that require coordination across different regions. Let’s learn more about common Date Object methods. Common Date Object Methods JavaScript provides several static and instance methods that simplify working with dates. Here are some key methods: Date.now(): Returns the current timestamp in milliseconds since January 1, 1970. Date.parse(): Parses a date string and returns the number of milliseconds since the Unix Epoch (January 1, 1970). If the string cannot be parsed, it returns NaN. Date.UTC(): Creates a Date object from UTC values. Date.toString(): Returns a string representation of the Date object in a readable format. valueOf(): Returns the primitive value of the Date object. These methods provide essential functionality for working with dates in JavaScript, enabling developers to efficiently manage and manipulate date values in their applications.  Conclusion The JavaScript Date object is an essential tool for managing datetime in web development. From creating dates to formatting and performing date arithmetic, mastering this object will enable developers to handle time-sensitive data efficiently, regardless of time zone or locale. By using built-in methods and libraries like Moment.js, date-fns, or Day.js, developers can ensure their applications deliver a smooth user experience when working with dates.
15 October 2024 · 8 min to read
Linux

Writing Scripts in Linux Bash

Bash (Bourne-Again SHell) is a command interpreter in UNIX-like operating systems that allows for task automation at the command line level. Bash scripts are files containing a sequence of commands that can be executed by the Bash interpreter. Bash scripts can be used to automate repetitive tasks. For example, if you need to generate and send a report via email every day, you can write a bash script that performs these actions automatically. This saves a lot of time and reduces the likelihood of errors. In this article, we will cover the basic concepts and tools for writing Bash scripts in Linux. Bash Script Syntax Bash scripts can be written in any text editor and must have executable permissions. Let’s consider some of the most popular editors: Nano is a simple text editor that comes with most Linux distributions. It has an intuitive interface and useful features like syntax highlighting. Vim is one of the most popular text editors for Linux, though it may seem complicated for beginners. Vim offers many features to speed up coding, such as syntax highlighting, autocompletion, and macros. Emacs is another popular text editor for Linux. It also has many features that can simplify the coding process. One of its main features is the ability to run the Bash interpreter inside the editor, allowing you to test scripts without exiting the editor. At the beginning of each script, there must be a line called a shebang, which tells the operating system which interpreter to use to execute the script. The shebang should start with a hash symbol (#) followed by an exclamation mark (!), and then the path to the interpreter. To use the Bash interpreter, the shebang will look like this: #!/bin/bash While writing the script, you can also leave comments that start with a hash symbol and continue until the end of the line. Comments will not be executed by the interpreter and are used to describe the functionality of the script. For example: # This is a comment Below, we will write our first script. Suppose we want to create a script in Linux that greets the user and displays the current date and time on the screen. To do this, create a file named greeting.sh in any directory on your computer and add the following code: #!/bin/bash echo "Hello, $USER!" echo "Today is $(date)" The first line indicates that this is a Bash script. The next line, echo "Hello $USER!", outputs a greeting with the current user's name. $USER is a system variable that contains the name of the current user. The third line, echo "Today is $(date)", displays the current date and time. $(date) is used to call the date command, which returns the current date and time in the system's format. When creating a Bash script, it’s important to ensure the file is executable. To do this, you need to change the file permissions. We’ll cover this and how to run the script in the next chapter. Running Scripts To run a script in Linux, it must have executable permissions. To make a file executable, you can use the chmod command (short for "change mode"). This command allows you to change the access permissions of files and directories in Linux. The syntax for the chmod command is as follows: chmod [options] access_rights file where access_rights is a special code that sets the access permissions for a file or directory, and file is the path to the file or directory whose permissions you want to change. To make a file executable, you need to add the execute (x) permission to its access rights. For example, to make the greeting.sh file executable, use the following command: chmod +x greeting.sh This command will add execute permissions for the current user. Now, we can run the Bash script in Linux by invoking it from the terminal: ./greeting.sh The result of running the script is shown below. Command Line Parameters Command line parameters allow you to pass arguments to Linux scripts when they are run. Command line parameters can be accessed in the script as $1, $2, $3, etc., where $1 is the first parameter, $2 is the second parameter, and so on. Let's rewrite the script from the previous chapter to greet the user using a command-line argument: #!/bin/bashecho "Hello $1!" Then run the script, passing the $USER argument: ./greeting.sh $USER The result is shown below. Additionally, you can use special command line parameters: $0 — the name of the script (i.e., the name of the file that was run) $# — the number of passed parameters $* or $@ — a list of all passed parameters (as a single string or array, respectively) $? — the return code of the last executed command For example, to display the number of passed parameters, you can use the following code: #!/bin/bash echo "Hello $1!" echo "Number of passed parameters: $#" The result of running the script is shown below. Variables Variables in Bash are used to store data, such as strings and numbers. They can be explicitly defined by assigning a value or implicitly defined through automatic assignment during certain operations. To create a variable in Bash, you need to assign it a value using an equal sign (=). For example: company="Hostman" Note that there should be no spaces between the variable name, the equal sign, and the value. You can retrieve the value of a variable by specifying its name after the echo command and the $ sign. For example: echo $company It's also possible to assign a variable value through user input using the read command. For example, the following script prompts the user for their name and stores it in a variable: #!/bin/bash echo "What is your name?" read name echo "Hello, $name!" The result of this script is shown below. In Bash, there are several special variables that are automatically defined and filled by the system. For example, the $HOME variable contains the path to the user's home directory, while $PWD contains the path to the current working directory.  Additionally, there are environment variables that are defined by the system and can be used in scripts. For example, $PATH contains a list of directories where Bash looks for executable files. Variables can also be used to pass values between different commands and scripts. For example, to pass a variable’s value from one script to another, use the export command: export variable_name Conditional Operators Conditional operators allow you to execute a specific set of actions depending on whether a condition is true or false. In Bash scripts, conditions are written in brackets and passed to the if command. The syntax of the if operator looks like this: if [ condition ] then commands to execute if the condition is true fi Here, in the square brackets, you specify the condition that needs to be checked. If the condition is true, the commands between then and fi will be executed. For example, let’s write a Linux script, evenodd.sh, that checks whether the number entered by the user is even or odd: #!/bin/bash echo "Enter a number: " read n if (( $n % 2 == 0 )) then echo "The number $n is even" else echo "The number $n is odd" fi In this example, we use the % operator, which calculates the remainder of division by 2. If the remainder is 0, the number is even; otherwise, it’s odd. The result of running the script is shown below. Additionally, there are several comparison operators that can be used in conditional constructions: -eq – equal to; -ne – not equal to; -gt – greater than; -lt – less than; -ge – greater than or equal to; -le – less than or equal to. For example, to check if the variable $a is greater than the variable $b, you can write the following: if [ $a -gt $b ] then echo "$a is greater than $b" fi It is important to remember that you need to use spaces around the comparison operators in conditional constructions. If there are no spaces, Bash will treat this as one large string instead of a comparison operation. In addition to if, Bash scripts also use the case structure. This allows you to check a variable's value against several possible options. We will discuss this in the next chapter. The Case Construction The case construction in Bash scripts allows you to simplify writing conditional operators for comparing variables with multiple possible values. The syntax of the case construction is as follows: case variable in pattern1) command1 ;; pattern2) command2 ;; pattern3) command3 ;; *) default command ;; esac where variable is the variable to check, pattern1, pattern2, pattern3 are the possible values to check, and command1, command2, command3 are the commands to execute depending on the value of the variable. The * symbol at the end of the list of values is used as a default handler if none of the values match the variable. For example, let’s look at a script that checks the day of the week and performs the corresponding action: #!/bin/bash day=$(date +%u) case $day in 1) echo "Today is Monday" ;; 2) echo "Today is Tuesday" ;; 3) echo "Today is Wednesday" ;; 4) echo "Today is Thursday" ;; 5) echo "Today is Friday" ;; 6) echo "Today is Saturday" ;; 7) echo "Today is Sunday" ;; *) echo "Invalid day of the week" ;; esac In this example, we use the day variable, which we define using the date +%u command. In this case, %u is used to obtain the numeric value of the day of the week, from 1 (Monday) to 7 (Sunday). Then we compare this variable with the days of the week using the case construction. If its value matches a certain day of the week, we display the corresponding message. If the value does not match any of the listed days, we display an error message. The result of running the script is shown below.  Loops Loops in Bash are used to perform repetitive actions. There are two types of loops: for and while. The for loop is used to execute commands for each element in a list. The syntax of the for loop is as follows: for variable in list do commands done Here, the variable takes the value of an element from the list, and for each of them, the commands between do and done are executed. Example: #!/bin/bash for i in {1..10}; do echo "Number: $i" done In this example, i takes values from 1 to 10, and for each of them, the echo "Number: $i" command will be executed. The result of running this loop will look like this: The while loop is used to execute commands as long as the condition remains true. The syntax of the while loop is as follows: while [ condition ] do commands done Here, in square brackets, you specify the condition that is checked before each iteration of the loop. The commands between do and done will be executed as long as the condition is true. Example: #!/bin/bash count=1 while [ $count -le 10 ]; do echo "Count: $count" count=$((count+1)) done In this example, count increases by 1 after each iteration of the loop. When the value of count reaches 10, the loop terminates. The result of running this loop will look like this: Functions Functions in Bash are used to group commands into logically related blocks. Functions can be called from a script using their name.  The syntax of a function is as follows: function_name () { commands_and_expressions } The function name must start with a letter or an underscore and can contain only letters, numbers, and underscores. After the function name comes a list of arguments in parentheses. The commands and expressions to be executed when the function is called must be enclosed in curly braces. Here’s an example of a function that outputs the current time and date: #!/bin/bash print_date () { echo "Today's date: $(date)" } print_date # Function call The result of running the script is shown below. Functions can also accept arguments, which are passed as parameters inside the parentheses when calling the function. Here’s an example of a function that takes two arguments and outputs their sum: #!/bin/bash sum_numbers () { result=$(( $1 + $2 )) echo "The sum of $1 and $2 is $result" } sum_numbers 10 20 # Function call In this example, $1 and $2 are variables that contain the values of the first and second arguments, respectively. sum_numbers 10 20 will call the sum_numbers function with the arguments 10 and 20, and output the following result: Functions can also return values using the return keyword. Let’s rewrite the previous example using this new knowledge: #!/bin/bash sum_numbers () { result=$(( $1 + $2 )) return $result } sum_numbers 12 24 # Function call echo "The sum of the numbers is $?" # Output Here, the result is stored in the result variable and returned from the function using the return command. The $? variable contains the return code of the function, which in this case is the result of the sum calculation. The result of running the script is shown below. There is another way to handle the result of a function call without using return. Let’s slightly modify the previous script: #!/bin/bash sum_numbers () { result=$(( $1 + $2 )) echo $result } sum=$(sum_numbers 9 11) echo "The sum of the numbers is $sum" # Output Here, instead of using $? and return, we store the result of the function call in the sum variable and then output its value. The result is shown below. Working with Files and Directories Bash scripts can be used to perform various operations with files and directories in Linux. For example, to check if a file exists, you can use the following command:  test -e filename  If the file exists, the command will return a value of 0; otherwise, it will return a non-zero value. To work with directories in Bash scripts, you can use commands like cd, mkdir, rmdir, ls, and others. Script Debugging Debugging Bash scripts can be a challenging task because problems can be caused by various factors, such as syntax errors, incorrect use of variables or functions, etc. For debugging Bash scripts, you can use tools like set -x, set -v, and set -e. The set -x command allows you to display the commands before they are executed The set -v command displays the values of variables before they are used The set -e command stops the execution of the script in case of an error Conclusion Bash scripts are a powerful tool for automating tasks in UNIX-like operating systems. In this article, we covered the basic concepts and tools for writing Bash scripts, such as syntax, variables, conditional operators, loops, functions, and running scripts. We hope this guide helps you become a more productive and experienced Linux user.
14 October 2024 · 12 min to read
Python

Break, Continue, and Pass Statements in Python Loops

When working with while and for loops, there are times when you need to forcefully exit the loop, skip part of the code, or ignore specific conditions. Python uses the break, continue, and pass statements to handle these cases. Let’s explore how these statements work through examples. Break Statement The break statement in Python is used to exit a block of code prematurely. Here’s a simple example: for j in 'applefishorange': if j == 'f': break print(j) This will produce the following output: a p p l e As soon as the program encounters the letter f in the sequence, the loop breaks in Python because of the break statement. Now let’s see how it works in a while loop: x = 0 while x < 5: print(x) x += 0.5 print('Exit') The output will look like this (truncated for brevity): 0 0.5 … 4.0 4.5 Exit Once the condition is no longer met (when x becomes equal to 5), the Python program exits the loop. Now, let’s rewrite the code using the break statement: x = 0 while True: print(x) if x >= 4.5: break x += 0.5 print('Exit') The result is the same: 0 0.5 … 4.0 4.5 Exit We assigned the value 0 to x and set the condition: as long as x is True, continue printing it. The code is slightly longer, but using break is justified in situations with complex conditions or to safeguard against infinite loops. Remove two lines from the code above: x = 0 while True: print(x) x += 0.5 print('Exit') And you'll get an endless output: 0 0.5 … 100 100.5 … 1000000 1000000.5 … And the word Exit will never be printed because the loop will never end. Therefore, using break when working with number sequences helps prevent your program from getting stuck in an infinite loop. Using Break with Else Sometimes, you need to check if the loop completed successfully or was interrupted by a break statement in Python. For this, you can use the else clause. Let’s write a program that checks a word for forbidden characters: word = input('Enter a word: ') for i in word: if i == 'z': print('Loop was interrupted, the letter "z" was found') break else: print('Loop completed successfully, no forbidden letters found') print('Check completed') If the user enters "Hello!", the output will be: Loop completed successfully, no forbidden letters found Check completed But if the input contains the letter "z", the output will be: Loop was interrupted, the letter "z" was found Check completed Explanation: The input function accepts user input (the prompt "Enter a word:" is for the user; the program would work fine with word = input() alone) and assigns it to the variable word. The for loop then iterates over each element (in this case, each letter) and checks it with the condition in the if statement. Continue Statement While break interrupts the loop, the continue statement in Python is more flexible — it skips certain elements in the sequence without ending the loop. Let’s write a program that "doesn’t like" the letter "z": word = input('Enter a word: ') for i in word: if i == 'z': continue print(i) If you enter "zebra", the output will be: e b r a This happens because we set the condition where any element with the value "z" is not printed. But the Python continue statement allows the loop to finish, printing all "allowed" elements. However, there is a small issue with the code: if the user enters "Zebra" (with an uppercase Z), the program will print the entire word because we didn’t account for the letter case: Z e b r a The most obvious solution here is to add the uppercase letter in the if block like this: word = input('Enter a word: ') for i in word: if i == 'z' or i == 'Z': continue print(i) Pass Statement The pass statement in Python allows the loop to continue regardless of any conditions. It is rarely seen in final code but is useful during development as a placeholder for code that hasn’t been written yet. For example, let’s say you need to remember to add a condition for the letter "z", but you haven't written that block yet. Here, the pass placeholder keeps the program running smoothly: word = input('Enter a word: ') for i in word: if i == 'z': pass else: print('Loop completed, no forbidden letters found') print('Check completed') Now the program will run, and pass will act as a marker to remind you to add the condition later. That’s all! We hope that break, continue, and pass in Python will soon become your reliable tools for developing interesting applications. Good luck!
11 October 2024 · 4 min to read
Python

How to Reverse a String in Python

One of the top reasons for the popularity of Python is the extensive built-in capabilities it has. It offers a lot of modules and functions that enable developers to achieve specific tasks with simplicity. A very common example of these tasks is string manipulation. String manipulation is the process in which we modify a string variable by applying some type of operation like concatenation, splitting, or reordering of the characters. This manipulation can be very handy in cases like text processing, data analysis, or problem solving. In this article we’re going to cover one fundamental string manipulation operation, which is string reversal. We’ll explore different methods to reverse a string in Python and we’ll show an example for each one. We’ll also compare the efficiency between these different methods. Reverse a String Using Slicing Slicing is the process of extracting part of a sequence object (string, list, tuple, etc). We can specify the range of elements – from the start to the end – which we want to extract from the sequence. This range of elements, also called a slice, is then returned from the slicing operation and we can store it in another variable. We can apply the slicing in Python in two different ways, using the slice() function, or with the slicing [::] operator. The slice() Function A slice() function takes three arguments which are the starting element, ending element, and a step. It returns a slice object which we can later use on our sequence to extract a part of it. For example, we can slice a string with the following code: my_string="ABCDEF" my_slice=slice(2,5,1) new_string=my_string[my_slice] print(new_string) In the above code, we have the original string which is my_string. We use the slice() function with parameters 2, 5, and 1. This means that we need to extract part of the string starting from index 2 until index 5, and moving 1 element at a time.  Now let’s run this code and check the output: As we can see, our new_string contains the sliced part which is CDE. It’s important to note that the slice begins with the starting index until the element before the ending index, but it doesn’t include the ending index itself. We can also pick the slice in the opposite direction by using a negative value for the step. Meaning that we’ll start from the bigger index until the smaller one. We can achieve this with the following code: my_string="ABCDEF" my_slice=slice(5,2,-1) new_string=my_string[my_slice] print(new_string) If we run our code we should get the slice in a reversed order: In the above image the new_string contains the elements starting from index 5 until index 2 in a reversed order. Now in order to reverse the whole string, we can use the slice() function with a reverse order starting from the last index until the first index: my_string="ABCDEF" my_slice=slice(5,None,-1) new_string=my_string[my_slice] print(new_string) In the above code, we start our slice from index 5 which is the final index in my_string, until the index None, which means the starting index including the element stored in it. We should get a reversed string by running the above code: The new_string now is the reversal of the original my_string. The slicing[::] Operator The slicing [::] operator works the same as the slice() function but provides a shorter and easier syntax. Instead of creating a slice object and pass it to the original string, we can merge these in a single step with the slicing operator: my_string="ABCDEF" new_string=my_string[5:None:-1] print(new_string) In the above example, we removed the slice() function and used the slicing operator directly on the string. We use the same parameters for the starting index, ending index, and the step: We can see our string is reversed in the same way as the slice() function. We can also improve the syntax further by replacing the starting and ending index with empty value as follows: my_string="ABCDEF" new_string=my_string[::-1] print(new_string) This automatically translates to the beginning and the end of the string: Again we get our string in a reversed order with a more elegant syntax. Reverse a String Using the reversed() Function The reversed() function is a Python built-in function that accepts an iterable as a parameter and returns an iterator in a reversed order. We can then iterate over the returned object and access its elements as we need. For example, the following code will print the elements of the returned iterator after reversing a string: iterable_string="ABCDEF" my_iterator=reversed(iterable_string) for element in my_iterator: print(element) Now let’s run our code: In the above image, we have each element in our string in a reversed order. We can utilize the reversed() function to reverse a string by using it along with the join() function. The join() function is also a Python built-in function that takes an iterable object as a parameter, it concatenates the elements of this iterable and returns a string object as a result of concatenation. Because every iterator is also an iterable, we can pass the iterator returned from the reversed() function as a parameter to the join() function: iterable_string="ABCDEF" my_iterator=reversed(iterable_string) concat_string=''.join(my_iterator) print(concat_string) In the above code, we concatenate the elements of the my_iterator (which is basically the reverse of the iterable_string) using the join() function, and we save the returned string in the concat_string. The empty string ' ' in the join() function decides the separator we want to include between our concatenated elements. Since we don’t need to separate the elements by any character we provided an empty string. Let’s check the output of our code: As we can see, the join() function converted our reversed iterator object into a string. Reverse a String Using a Loop If we want to reverse a string using the basic programming structures without utilizing a built-in function, we can achieve this with traditional Python for loop. We can use the for loop to iterate over our string in the opposite direction from the last index to the first index. Through the iteration, we can pick the element at each index and concatenate it to another empty string: my_string="ABCDEF" reversed_string='' for i in range(len(my_string)-1, -1, -1): reversed_string+=my_string[i] print(reversed_string) The len() function here is used to return the number of characters in my_string, by subtracting 1 from this number we get the last index in the string. So, the expression len(my_string)-1 will be evaluated to 5. The range() function will then return a sequence of numbers starting at 5, and decremented by 1 until it reaches 0, which is specified by the -1 and -1 parameters. At each iteration, the character at the specified index will be appended to the reversed_string. Let’s run this code and check the result: We can see the reversed_string was created by concatenating the characters from my_string in the opposite direction. Reverse a String Using Recursion Recursion is the process where a function calls itself. This can be beneficial if we want to repeat the same operation multiple times until we reach a specific condition, called a base case. To reverse a string, we can create a recursive function that takes the string as a parameter and returns a call to the same function with a substring parameter removing the first character and appending it to the end. This process continues until the substring passed to the function has a length of 1. We can implement this using the following code: def reverse_string(my_string): if len(my_string) <= 1: return my_string return reverse_string(my_string[1:]) + my_string[0] ordered_string="ABCDEF" reversed_string=reverse_string(ordered_string) print(reversed_string) Now let’s run our code: And we get our reversed string after recursively calling the function which removes the first element and appends it to the end of the string. Reverse a String Using List Comprehension List comprehension provides an easy syntax to create a new list out of an existing list. We can utilize this to reverse a string in two steps, first we’ll create a new reversed list using the list comprehension, then we’ll concatenate the elements of this reversed list using the join() function: my_string="ABCDEF" reversed_list=[my_string[i] for i in range(len(my_string)-1, -1, -1)] reversed_string=''.join(reversed_list) print(reversed_string) In the above code, we’re again using the range(len(my_string)-1, -1, -1) expression as in the for loop scenario to iterate over our string in a reversed direction. However, this time instead of appending the element in the index directly to a new string, we’re creating a new list out of the elements. Once we get our reversed list, we pass it to the join() function to return a string from the concatenated elements of the list. Let’s run our code: We can see our string is reversed by creating a new reversed list and concatenating its elements. Comparing the Efficiency of Each Method Besides the difference in simplicity for each method, we also need to consider their performance in terms of the execution time. We can measure the execution time for each method by using the time() function. The time() function is part of the time module and it returns the current time in seconds. We can simply add the time() function at the beginning and at the end of the code that we want to measure, then we subtract both values. Let’s apply this to some of the previous methods and compare the results: Here we compared the slicing method with the list comprehension method, and we can see that the slicing method is more efficient by taking less execution time. Conclusion Python offers great control for programmers when it comes to string manipulation. It provides built-in modules and functions that support a wide range of use cases from text processing to data analysis. In this article, we covered a common string manipulation task which is string reversal. We explored some of the methods for reversing a string in Python including slicing, recursion, for loops, and list comprehension.
10 October 2024 · 8 min to read
C

How To Implement a Stack in C Programming

In computer science, a stack is an abstract data structure that follows the Last In, First Out (LIFO) principle. It is widely used in algorithm design and programming for tasks like evaluating expressions, managing function calls, and performing undo operations. This tutorial will guide users through implementing a stack in C using arrays, providing clear examples of common stack operations such as push, pop, and peek. By the end of this tutorial, users will understand how to efficiently manage stacks in C and apply this data structure in real-world scenarios. What is a Stack in Programming? A stack in programming is a collection of elements with two main operations: Push: Adds an element to the top of the stack. Pop: Removes the element from the top of the stack. Other useful operations include: Peek: Retrieves the top element without removing it. isFull: Checks if the stack is full (in cases of fixed-size stacks). isEmpty: Checks if the stack is empty. In this tutorial, a C implementation of the stack will be created using an array, covering the push, pop, and peek operations. Stack Data Structure Overview A stack follows a simple concept: Think of a stack like a stack of plates. You can only add (push) a plate at the top or remove (pop) the plate at the top.  The stack operates under the LIFO principle, meaning the last item added is the first one to be removed. In C, stacks can be implemented using arrays or linked lists. This tutorial will focus on using an array-based implementation. Why Use Stacks? Stacks are used in various real-world applications, including: Function call management (recursive function calls are placed on the call stack). Expression evaluation (infix, postfix, and prefix expressions). Backtracking algorithms (for example, the depth-first search algorithm). Stack Operations Push: Adds an element to the stack. Pop: Removes the topmost element. Peek: Looks at the topmost element without removing it. isFull: Checks if the stack has reached its maximum capacity. isEmpty: Checks if the stack is empty. These operations will be explained and implemented step-by-step in the sections below. Implementing a Stack Using Arrays To implement stack operations effectively, it's important to start by setting up the underlying data structure. This will ensure that the stack can handle various operations like pushing and popping elements. Defining the Stack Structure In C, a stack can be represented using an array with fixed capacity. To manage the stack, you'll need to keep track of the current top element and define the size of the stack. #include <stdio.h> #include <stdlib.h> #define MAX 5 // Stack structure definition struct Stack { int items[MAX]; // Array to store stack elements int top; // To track the top element }; // Function to initialize the stack void initStack(struct Stack* s) { s->top = -1; // Set top to -1, meaning the stack is initially empty } Implementing the Push Operation The push operation adds a new element to the top of the stack, provided the stack isn't full. // Function to push an element to the stack void push(struct Stack* s, int value) { if (s->top == MAX - 1) { printf("Stack is full. Cannot push %d\n", value); } else { s->top++; s->items[s->top] = value; printf("Pushed %d to stack\n", value); } } Implementing the Pop Operation The pop operation removes and returns the topmost element of the stack. If the stack is empty, the pop operation should notify the user. // Function to pop an element from the stack int pop(struct Stack* s) { if (s->top == -1) { printf("Stack is empty. Cannot pop.\n"); return -1; // Return -1 as an indicator of error } else { int poppedValue = s->items[s->top]; s->top--; printf("Popped %d from stack\n", poppedValue); return poppedValue; } } Implementing the Peek Operation The peek operation returns the top element without removing it. It’s useful when you want to view the topmost element without modifying the stack. // Function to peek at the top element of the stack int peek(struct Stack* s) { if (s->top == -1) { printf("Stack is empty. No top element.\n"); return -1; } else { printf("Top element is %d\n", s->items[s->top]); return s->items[s->top]; } } Checking if the Stack is Full or Empty For completeness, two utility functions, isFull and isEmpty, are often implemented to check the stack’s state. // Function to check if the stack is full int isFull(struct Stack* s) { return s->top == MAX - 1; } // Function to check if the stack is empty int isEmpty(struct Stack* s) { return s->top == -1; } Example Code for Stack Implementation Below is a complete example that demonstrates how to use the stack operations. #include <stdio.h> #include <stdlib.h> #define MAX 5 // Stack structure definition struct Stack { int items[MAX]; int top; }; // Function declarations void initStack(struct Stack* s); void push(struct Stack* s, int value); int pop(struct Stack* s); int peek(struct Stack* s); int isFull(struct Stack* s); int isEmpty(struct Stack* s); int main() { struct Stack myStack; initStack(&myStack); push(&myStack, 10); push(&myStack, 20); push(&myStack, 30); peek(&myStack); pop(&myStack); peek(&myStack); return 0; } // Function definitions void initStack(struct Stack* s) { s->top = -1; } void push(struct Stack* s, int value) { if (isFull(s)) { printf("Stack is full. Cannot push %d\n", value); } else { s->top++; s->items[s->top] = value; printf("Pushed %d to stack\n", value); } } int pop(struct Stack* s) { if (isEmpty(s)) { printf("Stack is empty. Cannot pop.\n"); return -1; } else { int poppedValue = s->items[s->top]; s->top--; printf("Popped %d from stack\n", poppedValue); return poppedValue; } } int peek(struct Stack* s) { if (isEmpty(s)) { printf("Stack is empty. No top element.\n"); return -1; } else { printf("Top element is %d\n", s->items[s->top]); return s->items[s->top]; } } int isFull(struct Stack* s) { return s->top == MAX - 1; } int isEmpty(struct Stack* s) { return s->top == -1; } Common Stack Use Cases Stacks are employed in various areas in computer programming: Function Call Management: The call stack tracks function calls and returns. Expression Evaluation: Stacks are used in parsing algorithms like converting infix to postfix expressions. Undo Operations: In many applications, such as text editors, stacks manage the undo functionality. Backtracking Algorithms: Stacks are used in depth-first search (DFS) algorithms and puzzle-solving. Conclusion In this tutorial, the stack data structure was introduced, along with a step-by-step guide to implementing a stack in C. The tutorial covered how to define a stack using arrays, perform basic operations such as push, pop, and peek, and use utility functions to check if the stack is full or empty. Stacks are essential tools in programming, and mastering their use can significantly enhance one’s ability to write efficient and maintainable code.
10 October 2024 · 6 min to read
Linux

How to Mount File Systems in Linux

File system mounting is a fundamental operation in Linux, allowing users to access and manage different file systems from various storage devices. Whether connecting a hard drive, USB drive, or network share, mounting is necessary to make these resources available to your system.  This tutorial will guide you through the process of mounting file systems in Linux, including mounting manually with the mount command, automating mounts using /etc/fstab, and troubleshooting common issues. Common File Systems in Linux Linux supports a variety of file systems, each suited for different needs. Some of the most commonly used file systems include: ext4: The default file system for many Linux distributions. NTFS: Typically used for Windows systems. FAT32/exFAT: Used for USB drives and other portable storage. XFS: Ideal for large data storage solutions. Understanding the type of file system is crucial when mounting storage devices, as the necessary options and commands may differ. Mounting a File System with the mount Command The mount command is used to manually mount file systems in Linux. The basic syntax is as follows: sudo mount [OPTIONS] <source> <mount_point> <source>: The device or file system to be mounted, such as /dev/vdc1. <mount_point>: The directory where the file system will be mounted, such as /mnt. On Hostman servers, disk names follow the format vd*, where * is replaced by a letter from a to z. The letter corresponds to the disk’s number in the system. The primary disk always contains the operating system and is named vda. The second disk, vdb, is reserved for cloud-init. So, in this guide, we will focus on working with the vdc disk.  If you are using this guide for virtual machines from another provider, make sure to verify the correct disk names beforehand. Identify the File System First, you need to identify the available disks and partitions. You can use the following command to list them: lsblk This command displays the block devices along with their mount points, helping you identify the target device. Create a Partition If you need to create a new partition, you can do so using fdisk. Replace /dev/vdc with your target disk: sudo fdisk /dev/vdc Follow the prompts to create a new partition (for instance, /dev/vdc1). You will typically use the following commands within the fdisk utility: n: to create a new partition p: to select primary Specify the partition number and size as required w: to write changes to the disk Create a File System Once the partition is created, format it with a file system. Here’s how to create an ext4 file system on the newly created partition: sudo mkfs.ext4 /dev/vdc1 Mount the File System To mount the file system, use the following command, specifying the mount options: sudo mount -o barrier=0 /dev/vdc1 /mnt/mydrive/ Verify the Mount Finally, check if the file system has been mounted successfully by using the df command: df -h This command displays all mounted file systems and their disk usage, allowing you to confirm that your new file system is correctly mounted. Unmounting a File System To unmount a file system, use the umount command followed by the mount point or device name: sudo umount /mnt/mydrive Automating Mounts with /etc/fstab Mounting file systems manually every time you boot can be tedious. Fortunately, Linux provides a way to automate the process through the /etc/fstab file. The /etc/fstab file contains information about disks and partitions that should be automatically mounted at boot. 1. Open the /etc/fstab File: Use a text editor to open the /etc/fstab file: sudo nano /etc/fstab 2. Add a New Entry: Add an entry to the file in the following format: <device> <mount_point> <file_system_type> <options> <dump> <pass>     Example: echo “/dev/vdc1 /mnt/mydrive ext4 barrier=0 0 0 1” >> /etc/fstab <device>: The partition, for example, /dev/vdc1. <mount_point>: The directory where the file system will be mounted. <file_system_type>: The type of file system, for example, ext4. <options>: Mount options, for example, defaults. <dump>: Used for backups, typically set to 0. <pass>: The file system check order during boot. 3. Test the New Entry: After saving the file, test the changes by using the mount command to mount all file systems in /etc/fstab: sudo mount -a Example /etc/fstab Entry: /dev/vdc1 /mnt/mydrive ext4 defaults 0 2 This entry mounts the ext4 partition /dev/vdc1 to /mnt/mydrive at boot. Checking Mounted File Systems To view all currently mounted file systems, use the following commands: df: This command provides information about disk usage and mounted file systems: df -h mount: Displays a list of all mounted file systems: mount | grep "^/dev" Both commands can be useful for verifying whether a file system is properly mounted and accessible. Troubleshooting File System Mounting Issues Mounting issues can arise due to various factors, such as incorrect device paths, unsupported file systems, or permission problems. Here are some common issues and troubleshooting tips: mount: wrong fs type, bad option, bad superblock This error can occur if the wrong file system type is specified. Verify the correct file system type with lsblk -f and try mounting again: sudo mount -t ext4 /dev/vdc1 /mnt/mydrive Permission Denied Ensure you have the necessary permissions to mount the device. Use sudo to gain administrative privileges: sudo mount /dev/vdc1 /mnt/mydrive Device Not Found If the device cannot be found, verify its path using lsblk or fdisk -l. The device name may change based on how the storage is connected. Automated Mounting Fails If file systems fail to mount automatically at boot, verify the /etc/fstab entry for syntax errors. Run the following to test the /etc/fstab file: sudo mount -a If the issue persists, review system logs using dmesg for more detailed error messages. Conclusion Mounting file systems in Linux is an essential task for accessing storage devices. By mastering the mount command, automating mounts with /etc/fstab, and troubleshooting common issues, users can efficiently manage their file systems. This tutorial covered all the necessary steps for mounting a file system, from basic commands to troubleshooting errors. 
08 October 2024 · 5 min to read
CSS

How to Change a CSS Background Image’s Opacity

In web design, achieving the desired visual effect often involves manipulating CSS properties. One common requirement is adjusting the opacity of a background image. Whether you’re a seasoned developer or just starting your design journey, mastering background opacity will empower you to craft stunning visuals that not only look great but also resonate with your audience. This article provides a comprehensive guide on how to achieve this, including various methods and best practices. Introduction to CSS Backgrounds CSS backgrounds are fundamental for creating visually appealing web pages. They can enhance the aesthetics of a website by adding images, colors, and patterns.  Key Components Background Color: You can pick any color to fill the background of an element (like a box or a whole page). For example, if you want a bright blue background, you’d use: background-color: blue; Background Image: Instead of just a plain color, you can use a picture as your background. This is like putting up a poster or a mural. You specify the image you want to use: background-image: url('your-image.jpg'); Background Size: This controls how the background image fits. You can make it cover the entire space or repeat like a pattern. For example: background-size: cover; /* Makes the image fill the entire space */ Background Position: This determines where the background image sits. You can center it, move it to the top, or place it wherever you like: background-position: center; Background Opacity: This controls how transparent or solid your background is. It’s like adjusting the brightness of a lamp. We’ll talk more on this in the next section. Understanding CSS Opacity Opacity is a CSS property that controls the transparency of an element. It can take a value between 0 (completely transparent) and 1 (completely opaque). When applied, this property affects both the element and its contents. Opacity refers to the transparency level of an element. It is defined using a value between 0 and 1: 0 means fully transparent (invisible). 1 means fully opaque (completely solid). Values between 0 and 1 create varying degrees of transparency. For example: .canvas { opacity: 0.2; /* 20% transparent */ } This can be useful for layering elements or softening backgrounds without completely obscuring them. Applying Opacity to an Entire Element The simplest way to change the opacity of a background image is by applying the opacity property directly to the element containing the background.  Be warned! It’s a naive approach. It’s quite limiting. Here’s how: <div class="container"> <h1>Mastering CSS Opacity</h1> <p>This text will also have reduced opacity.</p> </div> <style> .container { background-image: url('https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'); /* Set the background size and position */ background-size: cover; background-position: center; /* Set the opacity of the entire element, including the background image */ opacity: 0.6; /* Set the padding to create some space around the text */ padding: 20px; width: 500px; height: 300px; } .container h1 { color: white; font-size: 36px; } .container p { color: white; font-size: 18px; } </style> This method will set the opacity for the entire element, including any text or content within it. This can be problematic if you want text to remain fully opaque. Use an img element This method allows you to achieve a layered effect while maintaining control over the image transparency. In this example, we will include a separate <img> tag inside a container. <div class="image-container"> <img src="https://images.unsplash.com/photo-1554322662-f8dc2222f79f?q=80&w=1574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Descriptive Text" class="background-image"> <div class="content"> <h1>Make Waves and Ride the Tide</h1> <p>Escape to the Endless Horizon.</p> </div> </div> <style> .image-container { position: relative; width: 100%; height: 400px; /* Adjust height as needed */ overflow: hidden; /* Ensures no overflow */ } .background-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; /* Ensures the image covers the entire container */ opacity: 0.7; /* Adjust the opacity here */ } .content { position: relative; /* Keeps content above the image */ z-index: 1; /* Ensures this content is on top */ color: blue; text-align: center; padding: 20px; } </style> As you can see, the image opacity is 70% but the text is fully opaque. Interestingly, this approach overcomes the limitation of first method. Set Background Opacity with Pseudo-elements CSS pseudo-elements enable you to insert content before or after an element's actual content, providing a way to enhance your design with additional visual elements or text.  How It Works Layering Backgrounds: By using ::before or ::after, you can create an additional layer behind your main content. This layer can be styled with a background color or image and adjusted for opacity, providing a visually appealing backdrop. Content Insertion: The content property allows you to insert text or other elements dynamically, enhancing the design while ensuring that the main content remains unaffected. <div class="hero"> <h1>How to adjust css background image opacity</h1> </div> <style> .hero { position: relative; /* Establishes a positioning context */ text-align: center; color: black; Height: 50vh; } .hero::before { content: ""; /* Required for pseudo-elements */ position: absolute; /* Positions the background layer */ top: 0; left: 0; right: 0; bottom: 0; background-image: url('https://images.unsplash.com/photo-1705668403533-3c17914a497a?q=80&w=1506&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'); background-size: cover; /* Ensure the image covers the area */ opacity: 0.5; /* Adjusts the opacity of background css */ z-index: 0; /* Places it behind the content */ } .hero h1 { position: relative; z-index: 1; /* Text appears on top */ padding: 20px; } </style> That’s the benefit you can get using pseudo-elements. You can achieve complex designs without adding extra divs or elements to your HTML, keeping your markup minimal and organized. Explanation Positioning: The .hero class is set to relative, which creates a positioning context for the pseudo-element. The ::before pseudo-element is absolutely positioned to cover the entire .hero container. Background Layer: The ::before pseudo-element contains a background image with adjusted opacity. This creates a semi-transparent effect, allowing the background image to be visible but softened. Text Visibility: The heading (h1) is given a higher z-index to ensure it appears above the semi-transparent background, making it easy to read. Best Practices When working with CSS background opacity, keep the following best practices in  mind: Utilize ::before and ::after pseudo-elements. Avoid using opacity on elements with text or other content, as it can affect readability. If you’re working with solid colors, consider using RGBA (Red, Green, Blue, Alpha) values for transparency. This allows for fine-tuned control over color and opacity without affecting other properties. background-color: rgba(255, 0, 0, 0.5); /* Red with 50% opacity */ Use viewport units (like vh or vw) to make backgrounds responsive. This ensures that backgrounds scale appropriately on different screen sizes. Test your design in different browsers and devices to ensure com Final Thoughts Incorporating CSS background opacity effectively can transform your design, making it not only visually appealing but also functional. By leveraging transparency, you can create a polished and professional look that enhances user experience and engagement.
07 October 2024 · 7 min to read
Python

Understanding HTTP Requests: Structure, Methods & Examples

HTTP is a key to communication on the internet. Methods of HTTP protocols allow clients to send requests to the servers and servers to send responses. Every website on the World Wide Web uses HTTP requests. So, it's necessary to understand them. This article explores the concept of HTTP requests, its structure, common methods, and real-life examples. This helps in understanding the functioning of the web.  What is an HTTP Request An HTTP request is a message where a client, such as a web browser, asks the host located on the server for a specific resource. Clients use URLs in HTTP requests which show the resources they want to access from the server.  Components of an HTTP Request Every HTTP request comprises three components namely; request line, headers and message body. Request Line  A request line is the start line in an HTTP request command. It is used to initialize an action on the server. A request line would also indicate what kind of method and version of HTTP protocol the client is using. Apart from the HTTP method, a request line also consists of a URI or URL to the path or protocol.  Request line example: GET /index.html HTTP/1.1 Headers Headers are right behind the request line. They offer client’s additional information to the server. Headers include data about the host, client’s user agent, language preferences and more. Server leverages this information to identify the browser and OS version of the client. HTTP request headers are case-sensitive, followed by a colon (:) and a value.  HTTP request Headers example:  Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.9 Accept-Encoding: gzip, deflate, br Connection: keep-alive Message body The message body in an HTTP request is used to send data to the server. They are optional. So, not every HTTP request will have a message body. It depends on the HTTP request types the client uses. The HTTP requests that do have a message body, usually leverage POST to send information. Mainly, the server uses the message body to provide the requested data to the client.  Common HTTP Methods An HTTP request is a way to connect the client with the server. There can be many reasons for pursuing this connection. It might be to retrieve specific resources or delete certain information on the server. The most common HTTP request methods used daily include:  GET: To Retrieve Resources The biggest use case of an HTTP request is to ask the server for a specific set of data or resources. And that is done using the GET method. Every time a user wants to go to a website or any web page, the client browser first sends a request to retrieve the required data to load that page.  The GET in HTTP is a cacheable, safe, and idempotent method. However,, using a GET method multiple times can still impact server performance. The GET Method can only bring existing data from the server to the client. It can’t make any changes to it. So, the data or the resources would be in a read-only format.  POST: To Send Data When a client wants to retrieve any information, they use the GET method, but when providing some information to the server, the client uses the HTTP POST request. Let’s say users need to submit a form or upload a file. In this case, the client’s browser has to execute the POST method in HTTP to send the data to the server.  The message body in an HTTP request contains the data. When a client browser sends a POST request, the server processes the data. Using a POST method multiple times would result in the creation of different resources on the server.  PUT: To Update Resources Similar to the POST method, the PUT method also allows the client to add some information to the server. The only difference between both methods is that in POST, users submit new data whereas in PUT, they update the existing data.  When implementing the PUT request, the client has to specify the resource’s URL that it wants to update. The request also includes the updated representation of the resource in its message body. The server would simply replace the old representation with the new one.  The PUT method is idempotent so there is no harm in implementing multiple identical PUT requests as it would yield the same result.  DELETE: To Remove Resources As the name suggests, the DELETE method helps the client delete any specific resource from the server. Employing the DELETE request helps the client instruct the server to delete the resource mentioned in the request.  Upon the DELETE request of the client, when the server successfully deletes the specified resource, it sends back a confirmation to the client. Sending multiple identical DELETE requests would yield the same result.  What is an HTTP Response? When the server sends back a response to an HTTP request, it is called an HTTP response. The server acts upon the request it receives from the client browser. The HTTP response would then either consist of the requested resource or valuable information regarding the requested operation.  So, like an HTTP request, an HTTP response is also made up of three components with a slight difference. The response starts with a status line, and a request starts with a request line.  Status Line: As the request line does in an HTTP request, the status line in the HTTP response also indicates which version of HTTP is used along with the status code and the message specifying the outcome of the request.  Headers: Headers in the HTTP response offer additional information like the date and time of response, the type of content that is sent in the message body, details of the server and instructions on how to cache the content.  Body: The actual message or response data that the server sends to the client browser is placed in the message body. The content could be anything from XML, JSON or HTML for the web page, an image, or any other kind of requested resource. Status Codes and Their Meanings HTTP status codes represent the status of the client’s HTTP requests. They come as a part of an HTTP server response. Every status code consists of three digital numbers where the first digit of the code indicates the class or category of the response. There are five types of code groups. Status code group  Description  1xx Informational responses, continuing processing. 2xx Success responses, requests are processed, understood and accepted. 3xx Redirecting responses, suggests further action to complete the request. 4xx Error responses, show what’s wrong with the request on client-side. 5xx Error responses, state what went wrong with processing request on server-side. HTTP Headers and Their Importance HTTP headers provide additional information about requests and responses. This information is critical for communication between client and server. Headers are fundamental for web browsing and app functionality. They play an important role in the following web operations:  Host Identification Headers bear the identification of a server’s domain that is hosting the resources. It is helpful in scenarios where a server hosts multiple domains.  CachingHeaders like Expires and Cache-Control handle how browsers cache responses and intermediate proxies. It helps minimize loading time and server requests by determining how long a response needs to be stored.  Cookie ManagementHeaders like Set-Cookie and Cookie help save and send cookies respectively. They assist in tracking user behavior and maintain user sessions.  Security Headers also play a critical role in securing web applications. An Authorization header helps with user authentication whereas a Content-Security-Policy is used for mitigating XSS and other security risks.  Response ControlHeaders like Status inform whether the request was a success or a failure. It also provides the necessary details so the client can manage responses appropriately.  Practical Examples of HTTP Requests Here are a few real-life examples of how different HTTP requests are commonly used in day-to-day operations. All the examples are in Python with the use of the requests library. GET From entering a simple URL for the website to asking for a specific record from the web server, fetching data requires an HTTP GET request. Let’s say, the client wants to get the weather data of London. The implementation of GET requests in this use case would look like:  import requests response = requests.get("https://api.example.com/data", params={"param1": "value1", "param2": "value2"}) # Print the response print(response.status_code) print(response.json()) # Assuming the response is in JSON format POST When a user wants to create a new user in a hypothetical API. And wants to send the following JSON data: { "username": "newuser", "email": "[email protected]", "password": "securepassword" } The following Python code sends a POST request with the specified data: import requests url = "https://api.example.com/users" data = { "username": "newuser", "email": "[email protected]", "password": "securepassword" } # Make the POST request response = requests.post(url, json=data) if response.status_code == 201: print("User created successfully:", response.json()) else: print("Error:", response.status_code, response.text) PUT When a client wants to update the information of a user with a specific ID.  import requests url = "https://api.example.com/users/123" data = { "username": "updateduser", "email": "[email protected]" } # Make the PUT request response = requests.put(url, json=data) if response.status_code == 200: print("User updated successfully:", response.json()) else: print("Error:", response.status_code, response.text) DELETE When a client wants to delete a specific user. Here’s how it will look like in Python. import requests url = "https://api.example.com/users/123" # Make the DELETE request response = requests.delete(url) if response.status_code == 204: print("User deleted successfully.") else: print("Error:", response.status_code, response.text) Conclusion HTTP requests play a critical role in web interactions. Hence, it is essential to understand various request methods and how they work. However, the key to seamless communication lies in picking a suitable method. This also enhances the efficiency of web applications.  
04 October 2024 · 9 min to read

Answers to Your Questions

What is Hostman used for, and what services do you offer?

Hostman is a cloud platform where developers and tech teams can host their solutions: websites, e-commerce stores, web services, applications, games, and more. With Hostman, you have the freedom to choose services, reserve as many resources as you need, and manage them through a user-friendly interface.

Currently, we offer ready-to-go solutions for launching cloud servers and databases, as well as a platform for testing any applications.

 

  • Cloud Servers. Your dedicated computing resources on servers in Poland and the Netherlands. Soon, we'll also be in the USA, Singapore, Egypt, and Nigeria. We offer 25+ ready-made setups with pre-installed environments and software for analytics systems, gaming, e-commerce, streaming, and websites of any complexity.

  • Databases. Instant setup for any popular database management system (DBMS), including MySQL, PostgreSQL, MongoDB, Redis, Apache Kafka, and OpenSearch.

  • Apps. Connect your Github, Gitlab, or Bitbucket and test your websites, services, and applications. No matter the framework - React, Angular, Vue, Next.js, Ember, etc. - chances are, we support it.

Can I have confidence in Hostman to handle my sensitive data and cloud-based applications?

Your data's security is our top priority. Only you will have access to whatever you host with Hostman.

Additionally, we house our servers in Tier IV data centers, representing the pinnacle of reliability available today. Furthermore, all data centers comply with international standards: 

  • ISO: Data center design standards

  • PCI DSS: Payment data processing standards

  • GDPR: EU standards for personal data protection

What are the benefits of using Hostman as my cloud service provider?

User-Friendly. With Hostman, you're in control. Manage your services, infrastructure, and pricing structures all within an intuitive dashboard. Cloud computing has never been this convenient.

 

Great Uptime: Experience peace of mind with 99.99% SLA uptime. Your projects stay live, with no interruptions or unpleasant surprises.

 

Around-the-Clock Support. Our experts are ready to assist and consult at any hour. Encountered a hurdle that requires our intervention? Please don't hesitate to reach out. We're here to help you through every step of the process.

 

How does pricing work for your cloud services?

At Hostman, you pay only for the resources you genuinely use, down to the hour. No hidden fees, no restrictions.

Pricing starts as low as $4 per month, providing you with a single-core processor at 3.2 GHz, 1 GB of RAM, and 25 GB of persistent storage. On the higher end, we offer plans up to $75 per month, which gives you access to 8 cores, 16 GB of RAM, and 320 GB of persistent storage.

For a detailed look at all our pricing tiers, please refer to our comprehensive pricing page.

Do you provide 24/7 customer support for any issues or inquiries?

Yes, our technical specialists are available 24/7, providing continuous support via chat, email, and phone. We strive to respond to inquiries within minutes, ensuring you're never left stranded. Feel free to reach out for any issue — we're here to assist.

Can I easily scale my resources with Hostman's cloud services?

With Hostman, you can scale your servers instantly and effortlessly, allowing for configuration upsizing or downsizing, and bandwidth adjustments.

Please note: While server disk space can technically only be increased, you have the flexibility to create a new server with less disk space at any time, transfer your project, and delete the old server

What security measures do you have in place to protect my data in the cloud?

Hostman ensures 99.99% reliability per SLA, guaranteeing server downtime of no more than 52 minutes over a year. Additionally, we house our servers exclusively in Tier IV data centers, which comply with all international security standards.

 

How can I get started with Hostman's cloud services for my business?

Just sign up and select the solution that fits your needs. We have ready-made setups for almost any project: a vast marketplace for ordering servers with pre-installed software, set plans, a flexible configurator, and even resources for custom requests.

If you need any assistance, reach out to our support team. Our specialists are always happy to help, advise on the right solution, and migrate your services to the cloud — for free.

Do you have questions,
comments, or concerns?

Our professionals are available to assist you at any moment,
whether you need help or are just unsure of where to start
Email us