Posted on Leave a comment

How to Print a String and an Integer

5/5 – (1 vote)

Problem Formulation and Solution Overview

In this article, you’ll learn how to print a string and an integer together in Python.

To make it more fun, we have the following running scenario:

The Finxter Academy has decided to send its users an encouraging message using their First Name (a String) and Problems Solved (an Integer). They have provided you with five (5) fictitious users to work with and to select the most appropriate option.

First_Name Puzzles Solved
Steve 39915
Amy 31001
Peter 29675
Marcus 24150
Alice 23580

đź’¬ Question: How would we write code to print a String and an Integer?

We can accomplish this task by one of the following options:

  • Method 1: Use a print() function
  • Method 2: Use the print() function and str() method
  • Method 3: Use f-string with the print() function
  • Method 4: Use the %d, %s and %f operators
  • Method 5: Use identification numbers
  • Method 6: Use f-string conditionals
  • Bonus: Format CSV for output

Method 1: Use the print() function

This example uses the print() function to output a String and an Integer.

print('Steve', 39915)

This function offers the ability to accept various Data Types and output the results, separated by commas (,) to the terminal.

Although not the most aesthetically pleasing output, it gets the job done. The print() function at its most simplistic level!

Steve 39915
YouTube Video

Method 2: Use the print() function and str() method

This example uses the print() function and the str() method to format and output a sentence containing a String and an Integer.

print('Steve has solved ' + str(39915) + ' puzzles!')

To successfully output the contents of the print() function, the Integer must first be converted to a String. This can be done by calling the str() method and passing, in this case, 39915 as an argument.

Steve has solved 39915 puzzles!
YouTube Video

Method 3: Use f-string with print() function

This example uses the f-string inside the print() function. This method uses curly brackets ({}) to accept and display the data.

first_name = 'Steve'
solved = 39915
print(f'{first_name} has solved {solved} puzzles to date!')

Above, two (2) variables are declared: first_name and solved.

The print() function is called and passed these two (2) variables, each inside curly braces ({}). This indicates that Python should expect two (2) variables of unknown Data Types. The print() function executes and sends this output to the terminal.

Steve has solved 39915 puzzles!
YouTube Video

What if you need to print out all Finxter users? This example assumes the data is saved to separate Lists and output using a For loop.

f_name = ['Steve', 'Amy', 'Peter', 'Marcus', 'Alice']
f_solved = [39915, 31001, 29675, 24150, 23580] for i in range(len(f_name)): print(f'{f_name[i]} has solved {f_solved[i]} puzzles to date!')
Steve has solved 39915 puzzles to date!
Amy has solved 31001 puzzles to date!
Peter has solved 29675 puzzles to date!
Marcus has solved 24150 puzzles to date!
Alice has solved 23580 puzzles to date!
YouTube Video

Method 4: Use %d, %s and %f Operator

This examples uses the %d (decimal value), the %s (string value), and %f (float value) inside the print() function to output the fictitious Finxter user’s data.

f_name = ['Steve', 'Amy', 'Peter', 'Marcus', 'Alice']
f_solved = [39915, 31001, 29675, 24150, 23580]
f_avg = [99.315, 82.678, 79.563, 75.899, 71.233] i = 0
while i < len(f_name): print("%s solved %d puzzles with an average of %3.2f." % (f_name[i], f_solved[i], f_avg[i])) i += 1

Above, three (3) Lists are declared. Each List carries different information for each user (f_name, f_solved, f_avg).

The following line instantiates a while loop and a counter (i) which increments upon each iteration. This loop iterates until the final element in f_name is reached.

Inside the loop, the %s (accepts strings) is replaced with the value of f_name[i]. Then, %d (accepts integers) is replaced with the value of f_solved[i]. Finally, the %3.2f (for floats) value of is replaced with f_avg[i] having two (2) decimal places. The output displays below.

Steve solved 39915 puzzles with an average of 99.31.
Amy solved 31001 puzzles with an average of 82.68.
Peter solved 29675 puzzles with an average of 79.56.
Marcus solved 24150 puzzles with an average of 75.90.
Alice solved 23580 puzzles with an average of 71.23.

đź’ˇNote: In the %3.2f annotation, the value of three (3) indicates the width, and 2 indicates the number of decimal places. Try different widths!

YouTube Video

Method 5: Use identification numbers

This example uses field identification numbers, such as 0, 1, 2, etc., inside the print() function to identify the fields to display and in what order.

f_name = ['Steve', 'Amy', 'Peter', 'Marcus', 'Alice']
f_solved = [39915, 31001, 29675, 24150, 23580] for i in range(len(f_name)): print('{0} solved {1} puzzles!'.format(f_name[i], (format(f_solved[i], ',d'))))

Above, two (2) Lists are declared. Each List carries different information for each Finxter user (f_name, f_solved).

Then, using a For loop, the code runs through the above Lists. The numbers wrapped inside curly braces ({0}, {1}) indicate holding places for the expected data. This data appears inside the format() function ((format(f_solved[i], ',d')))) and are output to the terminal.

Steve solved 39,915 puzzles!
Amy solved 31,001 puzzles!
Peter solved 29,675 puzzles!
Marcus solved 24,150 puzzles!
Alice solved 23,580 puzzles!

đź’ˇNote: The data in f_solved is formatted to display a thousand comma (',d').

Method 6: Use f-string and a conditional

This example uses an f-string and a conditional to display the results based on a condition inside the print() function.

f_name = ['Steve', 'Amy', 'Peter', 'Marcus', 'Alice']
f_solved = [39915, 31001, 29675, 24150, 23580]
print(f'Has Alice solved more puzzles than Amy? {True if f_solved[4] > f_solved[1] else False}')

Above, two (2) Lists are declared. Each List carries different information for each Finxter user (f_name, f_solved).

Inside the print() function, the code inside the curly braces ({}) checks to see if the number of puzzles Alice has solved is greater than the number of puzzles Amy has solved. True or False returns based on the outcome and is output along with the String to the terminal.

Has Alice solved more puzzles than Amy? False

Bonus: Putting it Together!

This article used several ways to format a String and an Integer. However, let’s put this together to generate a custom email body!

The first step is to install the Pandas library. Click here for installation instructions.

import pandas as pd finxters = pd.read_csv('finxter_top5.csv') for _, row in finxters.iterrows(): user_email = row[3] e_body = f""" Hello {row[0]} {row[1]},\n The Finxter Academy wants to congratulate you on solving {row[2]:,d} puzzles. For achieving this, our Team is sending you a free copy of our latest book! Thank you for joining us. The Finxter Academy """ print(e_body.strip())

This code reads in a fictitious finxter_top5.csv file.

First_Name Last_Name Solved Email
0 Steve Hamilton 39915 steveh@acme.org
1 Amy Pullister 31001 amy.p@bminc.de
2 Peter Dunn 29675 pdunn@tsce.ca
3 Marcus Williams 24150 marwil@harpoprod.com
4 Alice Miller 23580 amiller@harvest.com

Next, a For loop is instantiated to iterate through each row of the DataFrame finxters.

đź’ˇNote: The underscore (_) character in the for loop indicates that the value is unimportant and not used, but needed.

For each loop, the user’s email address is retrieved from the row position (row[3]). This email address saves to user_email.

Next, the custom email body is formatted using the f-string and passed the user’s First Name and Last Name in the salutation ({row[0]} {row[1]}). Then, the solved variable is formatted to display commas (,) indicating thousands ({row[2]:,d}). The results are saved to e_body and, for this example, are output to the terminal.

For this example, the first record displays.

Hello Steve Hamilton,
The Finxter Academy wants to congratulate you on solving 39,915 puzzles. For achieving this, our Team is sending you a free copy of our latest book. Thank you for joining us. The Finxter Academy

đź§©A Finxter Challenge!
Combine the knowledge you learned here to create a custom emailer.
Click here for a tutorial to get you started!


Summary

These six (6) methods of printing Strings and Integers should give you enough information to select the best one for your coding requirements.

Good Luck & Happy Coding!


Programming Humor

Posted on Leave a comment

JavaScript localStorage – Simple Guide with Example

by Vincy. Last modified on August 21st, 2022.

This article is for learning how to use JavaScript localStorage to put a string or object into it. This is for storing data in the client browser and use it when the need arises.

Data storage is a critical part of programming. These are the scenarios the localStorage used for adding persistency on the client-side.

  1. To store the session and the unique identity of a guest user to manage the state of his selection.
  2. To store shopping cart selected items on the client-side.
  3. To store language preferences to display content on a multilingual site.
  4. To store user preferences to display data, time and timezone as selected on the client.

Let us see a quick example of using the JavaScript localStorage to store an object. It prepares a JSON object of an array of data and put it into the localStorage.

Quick example

var animalObject = { 'Lion': 'Wild', 'Dog': 'Domestic'
}; // flatten the animal object as a string
animalString = JSON.stringify(animalObject); //store the string into local storage
localStorage.setItem('animals', animalString);

Quick example output

Log this localStorage object into the developer’s browser console to display the following output.

Object from local storage: {Lion: 'Wild', Dog: 'Domestic'}

In a previous tutorial, we used JavaScript localStorage to create a persistent shopping cart.

javascript localstorage howto store object

What is localStorage?

The JavaScript localStorage is the global window object property. It is used to store the data to carry over page-to-page.

It is one of the storage mechanisms coming under the Web Storage API.

It can not replace the server-side solutions providing persistency. But, it is a good mechanism for non-dynamic websites.

It contains a handle to access the local storage space of the browser origin.

Properties

Web Storage API

Web Storage API provides two concepts to store the objects having data in a key: value format.

  1. window.localStorage
  2. window.sessionStorage

Both use different Storage instances and control the actions separately.

This storage object is similar to the JavaScript localStorage. But, it has an expiration time.

It is valid only on the current browser session. When closing and reloading the browser, then the sessionStorage object is elapsed.

The expiration time is the main difference between these two storage concepts.

How to set and get items in JavaScript localStorage?

This example is for learning a basic usage of the JavaScript localStorage object. It performs the following actions on the localStorage about a String item.

  1. To set an item as a key-value pair.
  2. To get the value of an item by key.
  3. To remove an item by key.
  4. To clear the entire localStorage.
  5. To get the key by item index position.

This localStorage class contains functions used to perform the above actions. This program uses these functions with appropriate parameters.

basics.html

<html>
<head>
<title>JavaScript localStorage Example and how to store a JavaScript object</title>
</head>
<body> <script> // set item in localstorage window.localStorage.setItem('king', 'Lion'); console.log("Local Storage Key-Value = " + JSON.stringify(window.localStorage) + "\n"); // get item from JavaScript localStorage window.localStorage.getItem('king'); console.log("Local Storage Value = " + window.localStorage.getItem('king') + "\n"); // to get name of key using index var indexPosition = parseInt(window.localStorage.length) -1; var KeyName = window.localStorage.key(indexPosition); console.log("Local Storage Key = " + KeyName + "\n"); // remove item from JavaScript localStorage window.localStorage.removeItem('king'); // to clear all items from localStorage window.localStorage.clear(); </script>
</body>
</html>

Output

The above program displays the following output. It is for printing the localStorage data, it’s key and value based on the appropriate function calls.

Local Storage Key-Value = {"king":"Lion"} Local Storage Value = Lion Local Storage Key = king

Store JavaScript object in HTML5 browser localStorage

This example is to store an object in the JavaScript localStorage. It proceeds with the following steps to achieve this.

  1. It builds a JSON object to have a property array.
  2. It converts the object into a string using JSON stringify.
  3. Then put the JSON string into the localStorage.

Like the above basic example, it calls the getItem() by object key to get the property mapping.

The retrieved string output from the localStorage is converted back to an object. The example outputs the converted object to the browser console.

index.html

<html>
<head>
<title>JavaScript localStorage Example and how to store a JavaScript object</title>
</head>
<body> <h1>JavaScript localStorage Example and how to store a JavaScript object</h1> <script> // Example: Store JavaScript object in HTML5 browser localStorage var animalObject = { 'Lion' : 'Wild', 'Dog' : 'Domestic', 'Tiger' : 'Wild' }; // flatten the object as a string animalString = JSON.stringify(animalObject); //store the string into local storage localStorage.setItem('animals', animalString); //retrieve the string from local storage var retrievedString = localStorage.getItem('animals'); // parse the string back to an object convertedObject = JSON.parse(retrievedString); console.log('Object from local storage: ', convertedObject); </script>
</body>
</html>

Output

Object from local storage: {Lion: 'Wild', Dog: 'Domestic', Tiger: 'Wild'}

We learned how to use JavaScript localStorage to set a String or an Object and use it later when needed.

↑ Back to Top

Posted on Leave a comment

Ethereum Classic Quickstart

5/5 – (1 vote)

This article will answer some basic questions on Ethereum Classic. Its main purpose is to give you a quick overview of the project. I’m not affiliated in any way with Ethereum Classic, so I try to be as unbiased as I can.

What is Ethereum Classic?

Ethereum Classic is an open-source proof-of-work blockchain and distributed computing platform that allows the execution of smart contracts and decentralized applications (dApps) on a public Ethereum Virtual Machine (EVM).

What is the Difference Between Ethereum Classic and Ethereum?

Ethereum is a hard fork of Ethereum Classic. These are two different Blockchain projects with different developers, features, philosophies, and dApp ecosystems.

The less popular Ethereum Classic contains the original, unmodified history of the Ethereum Blockchain, whereas the more well-known Ethereum Blockchain emerged as a hard fork that redistributed the “stolen” tokens after the DAO hack in 2016.

Most influential developers and institutions, as well as Ethereum’s founder Vitalik Buterin supported the new Ethereum blockchain and explicitly recommended miners to NOT support the Ethereum Classic Blockchain.

The main differences between the two are as follows:

  • Ethereum Classic is much smaller than Ethereum in regards to almost all metrics such as market cap, transaction volume, number of validators, total locked value, and number of dApps that run on top of the Blockchain.
  • Ethereum Classic‘s philosophy is “Code is Law”, i.e., even if there is a smart contract hack, the state of the Blockchain is never reverted. This is in contrast to Ethereum’s philosophy of “rapid change” and regular hard forks if the “Layer 0”, i.e., the people running the Blockchain agree to the changes. You could think of it as “Consensus through PoW” vs “Consensus through People”.
  • Ethereum Classic has an upper maximum supply of 210,700,000 ETC tokens, whereas Ethereum (ETH) has no max supply.
  • Ethereum Classic runs a proof of work (PoW) consensus algorithm, whereas Ethereum runs a proof of stake (PoS) consensus algorithm.
Comparison table: ETH vs ETC (source)

What is the DAO Hack?

The DAO was a decentralized autonomous organization (DAO) launched in 2016 on the Ethereum blockchain. After collecting almost 15% of all ETH through a token sale, The DAO was hacked due to a vulnerability in the smart contract.

  • Ethereum is the Blockchain that emerged when reversing the state of the chain to before the hack, i.e., rewriting history. Code is Not Law.
  • Ethereum Classic is the Blockchain that emerged from just leaving the hack unchanged, i.e., not rewriting history. Code is Law.

A great video on the DAO hack in 2016 is given here:

YouTube Video

Are There Any dApps on Ethereum Classic?

The Ethereum Classic Blockchain is Turing Complete, i.e., you can run arbitrary smart contract code on it. Thus, Ethereum Classic supports decentralized apps (dApps) that issue their own tokens and NFTs.

While there are many dApps on Ethereum Classic, the dApp ecosystem is by orders of magnitude smaller than the Ethereum dApp ecosystem due to the lack of broad developer support.

📲 Statistics: For example, DappRadar lists 3425 Ethereum dApps but not a single dApp for Ethereum Classic. On the Ethereum Classic web page itself, there are only 34 dApps listed. Now, that’s two orders of magnitude fewer dApps for Ethereum Classic when compared to Ethereum!

Figure: That’s about it regarding dApps on Ethereum Classic at the point of this writing.

How to Create a dApp for Ethereum Classic?

Programming Smart Contracts on Ethereum Classic is identical to how it is done on ETH, as ETC maintains compatibility with the Ethereum EVM. Any contract written for Ethereum can be deployed to ETC.

To create a dapp for Ethereum Classic you must program one in a smart contract programming language. Then, you must compile that dapp and install it on the blockchain from a funded account.

From the official documentation.

đź’ˇ So, you can create a decentralized application on Ethereum Classic using Solidity or any other programming language that is able to be compiled against the EVM.

YouTube Video

Does Ethereum Classic Have a Future?

Ethereum Classic has much less developer activity than many other Blockchain projects such as Ethereum or Solana. Given the strong developer network effects of bigger Blockchains, i.e., developers are more likely to go to the “meaningful” Blockchain projects which make them even more meaningful, many people are led to believe that Ethereum Classic doesn’t have a rosy future.

I agree with the network effects argument. However, when diving into the project, I discovered some interesting arguments that speak for Ethereum Classic:

  1. Proof of work smart contract blockchain
  2. Open system
  3. Permissionless
  4. Bitcoin philosophy
  5. Hedge against ETH failure

Let’s dive into each of them one by one.

Proof of work smart contract blockchain

First, Ethereum Classic will be the largest proof of work smart contract Blockchain after the “Merge”, i.e., Ethereum’s move to a proof of stake consensus algorithm. This gives Ethereum Classic a unique and robust positioning in the market for decades to come.

Open system design

Second, Ethereum Classic is an open system, whereas Ethereum is a closed system (like all PoS Blockchains). This may make Ethereum Classic more robust against corruption and capturing of the Blockchain. For example, you could argue that Ethereum is already captured by the current token holders. Ethereum Classic is an open PoW system, so the current majority of computing power doesn’t control Ethereum Classic forever. One could always add more mining devices from outside the system.

Permissionless

Third, Ethereum Classic is permissionless, whereas Ethereum is permissioned. You cannot contribute to the consensus algorithm of the Ethereum network without buying a stake from an insider, i.e., asking them for permission. If the majority of token holders are not willing to sell ETH to you, you can never start a “revolution”, i.e., taking over control from the centralized controlling entity or entities. Once a PoS chain is captured by centralized entities, it is very hard to take it over to decentralize it again. However, this is possible in a PoW system.

Bitcoin philosophy

Fourth, Ethereum Classic’s design philosophy is much closer to Bitcoin’s. Code is Law. Few changes. Decentralization over scalability. Maximum token supply and sound money properties. Proof of work security. Thus, even though the project is much smaller than Ethereum and Ethereum Classic has been subject to 51% attacks in the past, it has proven to be extremely robust organism, like Bitcoin, and many people subscribing to the Bitcoin philosophy may also subscribe to the ETC philosophy.

Hedge against ETH failure

Fifth, Ethereum Classic will be used as a “hedge” against the failure of Ethereum in the decades to come. While I believe in the philosophy of Ethereum, it is not at all guaranteed that they will make it against the powerful centralization forces (and I don’t like the fact that it’s a closed, i.e., fragile, system). To hedge against those potentially low-probability failure cases of Ethereum, one could buy some Ethereum Classic tokens (no financial advise).

Thanks for taking the time to read this article! ❤

Learn Solidity Course

Solidity is the programming language of the future.

It gives you the rare and sought-after superpower to program against the “Internet Computer”, i.e., against decentralized Blockchains such as Ethereum, Binance Smart Chain, Ethereum Classic, Tron, and Avalanche – to mention just a few Blockchain infrastructures that support Solidity.

In particular, Solidity allows you to create smart contracts, i.e., pieces of code that automatically execute on specific conditions in a completely decentralized environment. For example, smart contracts empower you to create your own decentralized autonomous organizations (DAOs) that run on Blockchains without being subject to centralized control.

NFTs, DeFi, DAOs, and Blockchain-based games are all based on smart contracts.

This course is a simple, low-friction introduction to creating your first smart contract using the Remix IDE on the Ethereum testnet – without fluff, significant upfront costs to purchase ETH, or unnecessary complexity.

Posted on Leave a comment

How to Apply a Function to Each Cell in a Pandas DataFrame?

5/5 – (1 vote)

Problem Formulation

Given the following DataFrame df:

import pandas as pd df = pd.DataFrame([{'A':1, 'B':2, 'C':2, 'D':4}, {'A':4, 'B':8, 'C':3, 'D':1}, {'A':2, 'B':7, 'C':1, 'D':2}, {'A':3, 'B':5, 'C':1, 'D':2}]) print(df) ''' A B C D
0 1 2 2 4
1 4 8 3 1
2 2 7 1 2
3 3 5 1 2 '''

đź’¬ Challenge: How to apply a function f to each cell in the DataFrame?

For example, you may want to apply a function that replaces all odd values with the value 'odd'.

import pandas as pd df = pd.DataFrame([{'A':1, 'B':2, 'C':2, 'D':4}, {'A':4, 'B':8, 'C':3, 'D':1}, {'A':2, 'B':7, 'C':1, 'D':2}, {'A':3, 'B':5, 'C':1, 'D':2}]) def f(cell): if cell%2 == 1: return 'odd' return cell # ... <Apply Function f to each cell> ... print(df) ''' A B C D
0 odd 2 2 4
1 4 8 odd odd
2 2 odd odd 2
3 odd odd odd 2 '''

Solution: DataFrame applymap()

The Pandas DataFrame df.applymap() method returns a new DataFrame where the function f is applied to each cell of the original DataFrame df. You can pass any function object as a single argument into the df.applymap() function, either defined as a lambda expression or a normal function.

Example 1: Replace Odd Values in DataFrame

Here’s an example where each cell of the DataFrame is checked against whether it is an odd value. If so, it is replaced with the string 'odd':

def f(cell): if cell%2 == 1: return 'odd' return cell df_new = df.applymap(f) print(df_new) ''' A B C D
0 odd 2 2 4
1 4 8 odd odd
2 2 odd odd 2
3 odd odd odd 2 '''

Example 2: Create Two DataFrames with Even and Odd Values Replaced

A slightly advanced example uses two lambda functions to create two new DataFrames where one has all odd and the other has all even values replaced:

import pandas as pd df = pd.DataFrame([{'A':1, 'B':2, 'C':2, 'D':4}, {'A':4, 'B':8, 'C':3, 'D':1}, {'A':2, 'B':7, 'C':1, 'D':2}, {'A':3, 'B':5, 'C':1, 'D':2}]) df_even = df.applymap(lambda x: 'odd' if x%2 else x)
df_odd = df.applymap(lambda x: x if x%2 else 'even') print(df_even) ''' A B C D
0 odd 2 2 4
1 4 8 odd odd
2 2 odd odd 2
3 odd odd odd 2 ''' print(df_odd) ''' A B C D
0 1 even even even
1 even even 3 1
2 even 7 1 even
3 3 5 1 even '''

We used the concept of a ternary operator to concisely define the replacement function using the keyword lambda to create a function object “on the fly”.

🌍 Recommended Tutorial: Understanding the Ternary Operator in Python

This tutorial idea was proposed by Finxter student Kyriakos. ❤

Posted on Leave a comment

How to Ignore Case in Strings

5/5 – (1 vote)

Problem Formulation and Solution Overview

In this article, you’ll learn how to ignore (upper/lower/title) case characters when dealing with Strings in Python.

The main reason for ignoring the case of a String is to perform accurate String comparisons or to return accurate search results.

For example, the following three (3) Strings are not identical. If compared with each other, they would return False.

when life gives you lemons, make lemonade.
WHEN LIFE GIVES YOU LEMONS, MAKE LEMONADE.
When Life Gives You Lemons, Make Lemonade.

This is because each character in the ASCII Table assigns different numeric values for each key or key combination on the keyboard.

This article outlines various ways to ignore the case of Strings.


đź’¬ Question: How would we write code to compare Strings?

We can accomplish this task by one of the following options:


Method 1: Use lower() and a lambda

This method uses lower() and a lambda to convert a List of Strings to lower case to search for an Employee.

staff = ['Andy', 'MAci', 'SteVe', 'DarCY', 'Harvey']
staff_lower = list((map(lambda x: x.lower(), staff)))
print(staff_lower)

Above declares a List of Rivers Clothing Employees. If we were searching for an Employee, such as Darcy, using this List, no results would return as Darcy and DarCY are not the same. Let’s fix this issue.

ℹ Info: A lambda function is a one-liner that, in this case, converts each List element in staff to lower case. Then, converts to a map() object and back to a List. The output saves to staff_lower and is output to the terminal.

['andy', 'maci', 'steve', 'darcy', 'harvey']

If a comparison was made now, it would find the correct Employee.

if ('Darcy'.lower() == staff_lower[3]): print('Match Found!')
Match Found!
YouTube Video

Method 2: Use upper() and List Comprehension

This method uses upper() and a list comprehension to convert a List of Strings to upper case and search for an Employee.

brands = ['ChaNnel', 'CLINique', 'DIOR', 'Lancome', 'MurAD']
brands_upper = [x.upper() for x in brands]
print(brands_upper)

Above declares a List of the Top five (5) Beauty Brands in the world. If we were searching for a Company, such as Channel, using this List, no results would return as Channel and ChaNnel are not the same. Let’s fix this issue.

A List Comprehension is called and converts each element in brands to upper case. The results are saved to brands_upper and output to the terminal.

['CHANEL', 'CLINIQUE', 'DIOR', 'LANCOME', 'MURAD']

If a comparison was made now, it would find the correct Brand.

my_fav = 'Murad'
if (my_fav.upper() == brands_upper[4]): print(f'{my_fav} Found!')
Murad Found!
YouTube Video

Method 3: Use title()

This method uses title() to convert each word in a String to upper case. Great use of this is to convert a Full Name to title case. This ensures both the First, Middle and Last Names are as expected.

full_name = 'jessica a. barker'.title()
print(full_name)

Above accepts a string, appends the title() method to the string, saves it to full_name and outputs to the terminal.

Jessica A. Barker
YouTube Video

Method 4: Use casefold() and a Dictionary

This method uses casefold() to convert a String to lower case. This method does more than lower(): it uses Unicode Case Folding Rules.

phrase = 'Nichts ist unmöglich für den Unwilligen!'
cfold = phrase.casefold()
print(cfold)

Above creates a quote in German and saves it to phrase. This ensures all characters are correctly converted to lower case, thus making a caseless match.

nichts ist unmöglich für den unwilligen!

What does this say?


Method 5: Use lower() and Dictionary Comprehension

This method uses Use lower() to convert Dictionary values into lower case using Dictionary Comprehension.

employees = {'Sandy': 'Coder', 'Kevin': 'Network Specialist', 'Amy': 'Designer'}
result = {k: v.lower() for k, v in employees.items()}
print(result)

Above creates a Dictionary containing Rivers Employees Names and associated Job Title. This saves to employees.

Next, Dictionary Comprehension is used to loop through the values in the key:value Dictionary pairs and convert the values to lower case. The output saves to result and is output to the terminal.

{'Sandy': 'coder', 'Kevin': 'network specialist', 'Amy': 'designer'}
YouTube Video

Bonus: CSV Column to title() case

In this Bonus section, a CSV file you are working with contains a column of Full Names. You want to ensure all data entered in this column is in title() case. This can be accomplished by running the following code.

Contents of finxter_users.csv file

FID Full_Name
30022145 sally jenkins
30022192 joyce hamilton
30022331 allan thompson
30022345 harry stiller
30022157 ben hawkins
import pandas as pd users = pd.read_csv('finxter_users.csv')
users['Full_Name'] = users['Full_Name'].str.title()
print(users)

Above imports the Pandas library. For installation instructions, click here.

Next, the finxter_users.csv file (contents shown above) is read and saved to the DataFrame users.

The highlighted line directly accesses all values in the users['Full_Name'] column and converts each entry to title() case. This saves back to users['Full_Name'] and is output to the terminal.

FID Full_Name
0 30022145 Sally Jenkins
1 30022192 Joyce Hamilton
2 30022331 Allan Thompson
3 30022345 Harry Stiller
4 30022157 Ben Hawkins

đź’ˇNote: Don’t forget to save the DataFrame to keep the changes.

YouTube Video

Summary

These six (6) methods of ignoring cases in Strings should give you enough information to select the best one for your coding requirements.

Programmer Humor

âť“ Question: Why do programmers always mix up Halloween and Christmas?
âť— Answer: Because Oct 31 equals Dec 25.

(If you didn’t get this, read our articles on the oct() and int() Python built-in functions!)

Posted on Leave a comment

Python – How to Convert KML to CSV?

5/5 – (1 vote)

What is KML?

ℹ Definition: The Keyhole Markup Language (KML) is a file format for displaying geographic data in Google Earth or other so-called “Earth Browsers”. Similarly to XML, KML uses a tag-based structure with nested elements and attributes.

How to Convert KML to CSV in Python?

You can convert a .kml to a .csv file in Python by using the BeautifulSoup and the csv libraries. You use the former to read the XML-structured KML file and the latter to write the CSV file row by row.

Here’s the code example inspired but modified from this GitHub repository. You can copy&paste it in the directory where your KML file resides and change the input and output filenames at the beginning to convert your own KML to a CSV in Python:

from bs4 import BeautifulSoup
import csv infile = 'my_file.kml'
outfile = 'my_file.csv' with open(infile, 'r') as f: s = BeautifulSoup(f, 'xml') with open(outfile, 'wb') as csvfile: writer = csv.writer(csvfile) for coords in s.find_all('coordinates'): # Take coordinate string from KML and break it up into [Lat,Lon,Lat,Lon...] to get CSV row space_splits = coords.string.split(" ") row = [] for split in space_splits[1:]: # Note: because of the space between <coordinates>" "-80.123, we slice [1:] comma_split = split.split(',') # lattitude row.append(comma_split[1]) # longitude row.append(comma_split[0]) writer.writerow(row)

Example Conversion

We use the following sample KML file as 'my_file.kml':

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"> <Document> <name>KML Samples</name> <open>1</open> <description>Unleash your creativity with the help of these examples!</description> <Style id="downArrowIcon"> <IconStyle> <Icon> <href>http://maps.google.com/mapfiles/kml/pal4/icon28.png</href> </Icon> </IconStyle> </Style> <Style id="globeIcon"> <IconStyle> <Icon> <href>http://maps.google.com/mapfiles/kml/pal3/icon19.png</href> </Icon> </IconStyle> <LineStyle> <width>2</width> </LineStyle> </Style> <Style id="transPurpleLineGreenPoly"> <LineStyle> <color>7fff00ff</color> <width>4</width> </LineStyle> <PolyStyle> <color>7f00ff00</color> </PolyStyle> </Style> <Style id="yellowLineGreenPoly"> <LineStyle> <color>7f00ffff</color> <width>4</width> </LineStyle> <PolyStyle> <color>7f00ff00</color> </PolyStyle> </Style> <Style id="thickBlackLine"> <LineStyle> <color>87000000</color> <width>10</width> </LineStyle> </Style> <Style id="redLineBluePoly"> <LineStyle> <color>ff0000ff</color> </LineStyle> <PolyStyle> <color>ffff0000</color> </PolyStyle> </Style> <Style id="blueLineRedPoly"> <LineStyle> <color>ffff0000</color> </LineStyle> <PolyStyle> <color>ff0000ff</color> </PolyStyle> </Style> <Style id="transRedPoly"> <LineStyle> <width>1.5</width> </LineStyle> <PolyStyle> <color>7d0000ff</color> </PolyStyle> </Style> <Style id="transBluePoly"> <LineStyle> <width>1.5</width> </LineStyle> <PolyStyle> <color>7dff0000</color> </PolyStyle> </Style> <Style id="transGreenPoly"> <LineStyle> <width>1.5</width> </LineStyle> <PolyStyle> <color>7d00ff00</color> </PolyStyle> </Style> <Style id="transYellowPoly"> <LineStyle> <width>1.5</width> </LineStyle> <PolyStyle> <color>7d00ffff</color> </PolyStyle> </Style> <Style id="noDrivingDirections"> <BalloonStyle> <text><![CDATA[ <b>$[name]</b> <br /><br /> $[description] ]]></text> </BalloonStyle> </Style> <Folder> <name>Placemarks</name> <description>These are just some of the different kinds of placemarks with which you can mark your favorite places</description> <LookAt> <longitude>-122.0839597145766</longitude> <latitude>37.42222904525232</latitude> <altitude>0</altitude> <heading>-148.4122922628044</heading> <tilt>40.5575073395506</tilt> <range>500.6566641072245</range> </LookAt> <Placemark> <name>Simple placemark</name> <description>Attached to the ground. Intelligently places itself at the height of the underlying terrain.</description> <Point> <coordinates>-122.0822035425683,37.42228990140251,0</coordinates> </Point> </Placemark> <Placemark> <name>Floating placemark</name> <visibility>0</visibility> <description>Floats a defined distance above the ground.</description> <LookAt> <longitude>-122.0839597145766</longitude> <latitude>37.42222904525232</latitude> <altitude>0</altitude> <heading>-148.4122922628044</heading> <tilt>40.5575073395506</tilt> <range>500.6566641072245</range> </LookAt> <styleUrl>#downArrowIcon</styleUrl> <Point> <altitudeMode>relativeToGround</altitudeMode> <coordinates>-122.084075,37.4220033612141,50</coordinates> </Point> </Placemark> <Placemark> <name>Extruded placemark</name> <visibility>0</visibility> <description>Tethered to the ground by a customizable &quot;tail&quot;</description> <LookAt> <longitude>-122.0845787421525</longitude> <latitude>37.42215078737763</latitude> <altitude>0</altitude> <heading>-148.4126684946234</heading> <tilt>40.55750733918048</tilt> <range>365.2646606980322</range> </LookAt> <styleUrl>#globeIcon</styleUrl> <Point> <extrude>1</extrude> <altitudeMode>relativeToGround</altitudeMode> <coordinates>-122.0857667006183,37.42156927867553,50</coordinates> </Point> </Placemark> </Folder> <Folder> <name>Styles and Markup</name> <visibility>0</visibility> <description>With KML it is easy to create rich, descriptive markup to annotate and enrich your placemarks</description> <LookAt> <longitude>-122.0845787422371</longitude> <latitude>37.42215078726837</latitude> <altitude>0</altitude> <heading>-148.4126777488172</heading> <tilt>40.55750733930874</tilt> <range>365.2646826292919</range> </LookAt> <styleUrl>#noDrivingDirections</styleUrl> <Document> <name>Highlighted Icon</name> <visibility>0</visibility> <description>Place your mouse over the icon to see it display the new icon</description> <LookAt> <longitude>-122.0856552124024</longitude> <latitude>37.4224281311035</latitude> <altitude>0</altitude> <heading>0</heading> <tilt>0</tilt> <range>265.8520424250024</range> </LookAt> <Style id="highlightPlacemark"> <IconStyle> <Icon> <href>http://maps.google.com/mapfiles/kml/paddle/red-stars.png</href> </Icon> </IconStyle> </Style> <Style id="normalPlacemark"> <IconStyle> <Icon> <href>http://maps.google.com/mapfiles/kml/paddle/wht-blank.png</href> </Icon> </IconStyle> </Style> <StyleMap id="exampleStyleMap"> <Pair> <key>normal</key> <styleUrl>#normalPlacemark</styleUrl> </Pair> <Pair> <key>highlight</key> <styleUrl>#highlightPlacemark</styleUrl> </Pair> </StyleMap> <Placemark> <name>Roll over this icon</name> <visibility>0</visibility> <styleUrl>#exampleStyleMap</styleUrl> <Point> <coordinates>-122.0856545755255,37.42243077405461,0</coordinates> </Point> </Placemark> </Document> <Placemark> <name>Descriptive HTML</name> <visibility>0</visibility> <description><![CDATA[Click on the blue link!<br><br>
Placemark descriptions can be enriched by using many standard HTML tags.<br>
For example:
<hr>
Styles:<br>
<i>Italics</i>, <b>Bold</b>, <u>Underlined</u>, <s>Strike Out</s>, subscript<sub>subscript</sub>, superscript<sup>superscript</sup>, <big>Big</big>, <small>Small</small>, <tt>Typewriter</tt>, <em>Emphasized</em>, <strong>Strong</strong>, <code>Code</code>
<hr>
Fonts:<br> <font color="red">red by name</font>, <font color="#408010">leaf green by hexadecimal RGB</font>
<br>
<font size=1>size 1</font>, <font size=2>size 2</font>, <font size=3>size 3</font>, <font size=4>size 4</font>, <font size=5>size 5</font>, <font size=6>size 6</font>, <font size=7>size 7</font>
<br>
<font face=times>Times</font>, <font face=verdana>Verdana</font>, <font face=arial>Arial</font><br>
<hr>
Links: <br>
<a href="http://earth.google.com/">Google Earth!</a>
<br> or: Check out our website at www.google.com
<hr>
Alignment:<br>
<p align=left>left</p>
<p align=center>center</p>
<p align=right>right</p>
<hr>
Ordered Lists:<br>
<ol><li>First</li><li>Second</li><li>Third</li></ol>
<ol type="a"><li>First</li><li>Second</li><li>Third</li></ol>
<ol type="A"><li>First</li><li>Second</li><li>Third</li></ol>
<hr>
Unordered Lists:<br>
<ul><li>A</li><li>B</li><li>C</li></ul>
<ul type="circle"><li>A</li><li>B</li><li>C</li></ul>
<ul type="square"><li>A</li><li>B</li><li>C</li></ul>
<hr>
Definitions:<br>
<dl>
<dt>Google:</dt><dd>The best thing since sliced bread</dd>
</dl>
<hr>
Centered:<br><center>
Time present and time past<br>
Are both perhaps present in time future,<br>
And time future contained in time past.<br>
If all time is eternally present<br>
All time is unredeemable.<br>
</center>
<hr>
Block Quote:
<br>
<blockquote>
We shall not cease from exploration<br>
And the end of all our exploring<br>
Will be to arrive where we started<br>
And know the place for the first time.<br>
<i> – T.S. Eliot</i>
</blockquote>
<br>
<hr>
Headings:<br>
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
<h3>Header 4</h4>
<h3>Header 5</h5>
<hr>
Images:<br>
<i>Remote image</i><br>
<img src="//developers.google.com/kml/documentation/images/googleSample.png"><br>
<i>Scaled image</i><br>
<img src="//developers.google.com/kml/documentation/images/googleSample.png" width=100><br>
<hr>
Simple Tables:<br>
<table border="1" padding="1">
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>a</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>
</table>
<br>
[Did you notice that double-clicking on the placemark doesn't cause the viewer to take you anywhere? This is because it is possible to directly author a "placeless placemark". If you look at the code for this example, you will see that it has neither a point coordinate nor a LookAt element.]]]></description> </Placemark> </Folder> <Folder> <name>Ground Overlays</name> <visibility>0</visibility> <description>Examples of ground overlays</description> <GroundOverlay> <name>Large-scale overlay on terrain</name> <visibility>0</visibility> <description>Overlay shows Mount Etna erupting on July 13th, 2001.</description> <LookAt> <longitude>15.02468937557116</longitude> <latitude>37.67395167941667</latitude> <altitude>0</altitude> <heading>-16.5581842842829</heading> <tilt>58.31228652890705</tilt> <range>30350.36838438907</range> </LookAt> <Icon> <href>http://developers.google.com/kml/documentation/images/etna.jpg</href> </Icon> <LatLonBox> <north>37.91904192681665</north> <south>37.46543388598137</south> <east>15.35832653742206</east> <west>14.60128369746704</west> <rotation>-0.1556640799496235</rotation> </LatLonBox> </GroundOverlay> </Folder> <Folder> <name>Screen Overlays</name> <visibility>0</visibility> <description>Screen overlays have to be authored directly in KML. These examples illustrate absolute and dynamic positioning in screen space.</description> <ScreenOverlay> <name>Simple crosshairs</name> <visibility>0</visibility> <description>This screen overlay uses fractional positioning to put the image in the exact center of the screen</description> <Icon> <href>http://developers.google.com/kml/documentation/images/crosshairs.png</href> </Icon> <overlayXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/> <screenXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/> <rotationXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/> <size x="0" y="0" xunits="pixels" yunits="pixels"/> </ScreenOverlay> <ScreenOverlay> <name>Absolute Positioning: Top left</name> <visibility>0</visibility> <Icon> <href>http://developers.google.com/kml/documentation/images/top_left.jpg</href> </Icon> <overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/> <screenXY x="0" y="1" xunits="fraction" yunits="fraction"/> <rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/> <size x="0" y="0" xunits="fraction" yunits="fraction"/> </ScreenOverlay> <ScreenOverlay> <name>Absolute Positioning: Top right</name> <visibility>0</visibility> <Icon> <href>http://developers.google.com/kml/documentation/images/top_right.jpg</href> </Icon> <overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/> <screenXY x="1" y="1" xunits="fraction" yunits="fraction"/> <rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/> <size x="0" y="0" xunits="fraction" yunits="fraction"/> </ScreenOverlay> <ScreenOverlay> <name>Absolute Positioning: Bottom left</name> <visibility>0</visibility> <Icon> <href>http://developers.google.com/kml/documentation/images/bottom_left.jpg</href> </Icon> <overlayXY x="0" y="-1" xunits="fraction" yunits="fraction"/> <screenXY x="0" y="0" xunits="fraction" yunits="fraction"/> <rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/> <size x="0" y="0" xunits="fraction" yunits="fraction"/> </ScreenOverlay> <ScreenOverlay> <name>Absolute Positioning: Bottom right</name> <visibility>0</visibility> <Icon> <href>http://developers.google.com/kml/documentation/images/bottom_right.jpg</href> </Icon> <overlayXY x="1" y="-1" xunits="fraction" yunits="fraction"/> <screenXY x="1" y="0" xunits="fraction" yunits="fraction"/> <rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/> <size x="0" y="0" xunits="fraction" yunits="fraction"/> </ScreenOverlay> <ScreenOverlay> <name>Dynamic Positioning: Top of screen</name> <visibility>0</visibility> <Icon> <href>http://developers.google.com/kml/documentation/images/dynamic_screenoverlay.jpg</href> </Icon> <overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/> <screenXY x="0" y="1" xunits="fraction" yunits="fraction"/> <rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/> <size x="1" y="0.2" xunits="fraction" yunits="fraction"/> </ScreenOverlay> <ScreenOverlay> <name>Dynamic Positioning: Right of screen</name> <visibility>0</visibility> <Icon> <href>http://developers.google.com/kml/documentation/images/dynamic_right.jpg</href> </Icon> <overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/> <screenXY x="1" y="1" xunits="fraction" yunits="fraction"/> <rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/> <size x="0" y="1" xunits="fraction" yunits="fraction"/> </ScreenOverlay> </Folder> <Folder> <name>Paths</name> <visibility>0</visibility> <description>Examples of paths. Note that the tessellate tag is by default set to 0. If you want to create tessellated lines, they must be authored (or edited) directly in KML.</description> <Placemark> <name>Tessellated</name> <visibility>0</visibility> <description><![CDATA[If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain]]></description> <LookAt> <longitude>-112.0822680013139</longitude> <latitude>36.09825589333556</latitude> <altitude>0</altitude> <heading>103.8120432044965</heading> <tilt>62.04855796276328</tilt> <range>2889.145007690472</range> </LookAt> <LineString> <tessellate>1</tessellate> <coordinates> -112.0814237830345,36.10677870477137,0 -112.0870267752693,36.0905099328766,0 </coordinates> </LineString> </Placemark> <Placemark> <name>Untessellated</name> <visibility>0</visibility> <description><![CDATA[If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point]]></description> <LookAt> <longitude>-112.0822680013139</longitude> <latitude>36.09825589333556</latitude> <altitude>0</altitude> <heading>103.8120432044965</heading> <tilt>62.04855796276328</tilt> <range>2889.145007690472</range> </LookAt> <LineString> <tessellate>0</tessellate> <coordinates> -112.080622229595,36.10673460007995,0 -112.085242575315,36.09049598612422,0 </coordinates> </LineString> </Placemark> <Placemark> <name>Absolute</name> <visibility>0</visibility> <description>Transparent purple line</description> <LookAt> <longitude>-112.2719329043177</longitude> <latitude>36.08890633450894</latitude> <altitude>0</altitude> <heading>-106.8161545998597</heading> <tilt>44.60763714063257</tilt> <range>2569.386744398339</range> </LookAt> <styleUrl>#transPurpleLineGreenPoly</styleUrl> <LineString> <tessellate>1</tessellate> <altitudeMode>absolute</altitudeMode> <coordinates> -112.265654928602,36.09447672602546,2357 -112.2660384528238,36.09342608838671,2357 -112.2668139013453,36.09251058776881,2357 -112.2677826834445,36.09189827357996,2357 -112.2688557510952,36.0913137941187,2357 -112.2694810717219,36.0903677207521,2357 -112.2695268555611,36.08932171487285,2357 -112.2690144567276,36.08850916060472,2357 -112.2681528815339,36.08753813597956,2357 -112.2670588176031,36.08682685262568,2357 -112.2657374587321,36.08646312301303,2357 </coordinates> </LineString> </Placemark> <Placemark> <name>Absolute Extruded</name> <visibility>0</visibility> <description>Transparent green wall with yellow outlines</description> <LookAt> <longitude>-112.2643334742529</longitude> <latitude>36.08563154742419</latitude> <altitude>0</altitude> <heading>-125.7518698668815</heading> <tilt>44.61038665812578</tilt> <range>4451.842204068102</range> </LookAt> <styleUrl>#yellowLineGreenPoly</styleUrl> <LineString> <extrude>1</extrude> <tessellate>1</tessellate> <altitudeMode>absolute</altitudeMode> <coordinates> -112.2550785337791,36.07954952145647,2357 -112.2549277039738,36.08117083492122,2357 -112.2552505069063,36.08260761307279,2357 -112.2564540158376,36.08395660588506,2357 -112.2580238976449,36.08511401044813,2357 -112.2595218489022,36.08584355239394,2357 -112.2608216347552,36.08612634548589,2357 -112.262073428656,36.08626019085147,2357 -112.2633204928495,36.08621519860091,2357 -112.2644963846444,36.08627897945274,2357 -112.2656969554589,36.08649599090644,2357 </coordinates> </LineString> </Placemark> <Placemark> <name>Relative</name> <visibility>0</visibility> <description>Black line (10 pixels wide), height tracks terrain</description> <LookAt> <longitude>-112.2580438551384</longitude> <latitude>36.1072674824385</latitude> <altitude>0</altitude> <heading>4.947421249553717</heading> <tilt>44.61324882043339</tilt> <range>2927.61105910266</range> </LookAt> <styleUrl>#thickBlackLine</styleUrl> <LineString> <tessellate>1</tessellate> <altitudeMode>relativeToGround</altitudeMode> <coordinates> -112.2532845153347,36.09886943729116,645 -112.2540466121145,36.09919570465255,645 -112.254734666947,36.09984998366178,645 -112.255493345654,36.10051310621746,645 -112.2563157098468,36.10108441943419,645 -112.2568033076439,36.10159722088088,645 -112.257494011321,36.10204323542867,645 -112.2584106072308,36.10229131995655,645 -112.2596588987972,36.10240001286358,645 -112.2610581199487,36.10213176873407,645 -112.2626285262793,36.10157011437219,645 </coordinates> </LineString> </Placemark> <Placemark> <name>Relative Extruded</name> <visibility>0</visibility> <description>Opaque blue walls with red outline, height tracks terrain</description> <LookAt> <longitude>-112.2683594333433</longitude> <latitude>36.09884362144909</latitude> <altitude>0</altitude> <heading>-72.24271551768405</heading> <tilt>44.60855445139561</tilt> <range>2184.193522571467</range> </LookAt> <styleUrl>#redLineBluePoly</styleUrl> <LineString> <extrude>1</extrude> <tessellate>1</tessellate> <altitudeMode>relativeToGround</altitudeMode> <coordinates> -112.2656634181359,36.09445214722695,630 -112.2652238941097,36.09520916122063,630 -112.2645079986395,36.09580763864907,630 -112.2638827428817,36.09628572284063,630 -112.2635746835406,36.09679275951239,630 -112.2635711822407,36.09740038871899,630 -112.2640296531825,36.09804913435539,630 -112.264327720538,36.09880337400301,630 -112.2642436562271,36.09963644790288,630 -112.2639148687042,36.10055381117246,630 -112.2626894973474,36.10149062823369,630 </coordinates> </LineString> </Placemark> </Folder> <Folder> <name>Polygons</name> <visibility>0</visibility> <description>Examples of polygon shapes</description> <Folder> <name>Google Campus</name> <visibility>0</visibility> <description>A collection showing how easy it is to create 3-dimensional buildings</description> <LookAt> <longitude>-122.084120030116</longitude> <latitude>37.42174011925477</latitude> <altitude>0</altitude> <heading>-34.82469740081282</heading> <tilt>53.454348562403</tilt> <range>276.7870053764046</range> </LookAt> <Placemark> <name>Building 40</name> <visibility>0</visibility> <styleUrl>#transRedPoly</styleUrl> <Polygon> <extrude>1</extrude> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -122.0848938459612,37.42257124044786,17 -122.0849580979198,37.42211922626856,17 -122.0847469573047,37.42207183952619,17 -122.0845725380962,37.42209006729676,17 -122.0845954886723,37.42215932700895,17 -122.0838521118269,37.42227278564371,17 -122.083792243335,37.42203539112084,17 -122.0835076656616,37.42209006957106,17 -122.0834709464152,37.42200987395161,17 -122.0831221085748,37.4221046494946,17 -122.0829247374572,37.42226503990386,17 -122.0829339169385,37.42231242843094,17 -122.0833837359737,37.42225046087618,17 -122.0833607854248,37.42234159228745,17 -122.0834204551642,37.42237075460644,17 -122.083659133885,37.42251292011001,17 -122.0839758438952,37.42265873093781,17 -122.0842374743331,37.42265143972521,17 -122.0845036949503,37.4226514386435,17 -122.0848020460801,37.42261133916315,17 -122.0847882750515,37.42256395055121,17 -122.0848938459612,37.42257124044786,17 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> <name>Building 41</name> <visibility>0</visibility> <styleUrl>#transBluePoly</styleUrl> <Polygon> <extrude>1</extrude> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -122.0857412771483,37.42227033155257,17 -122.0858169768481,37.42231408832346,17 -122.085852582875,37.42230337469744,17 -122.0858799945639,37.42225686138789,17 -122.0858860101409,37.4222311076138,17 -122.0858069157288,37.42220250173855,17 -122.0858379542653,37.42214027058678,17 -122.0856732640519,37.42208690214408,17 -122.0856022926407,37.42214885429042,17 -122.0855902778436,37.422128290487,17 -122.0855841672237,37.42208171967246,17 -122.0854852065741,37.42210455874995,17 -122.0855067264352,37.42214267949824,17 -122.0854430712915,37.42212783846172,17 -122.0850990714904,37.42251282407603,17 -122.0856769818632,37.42281815323651,17 -122.0860162273783,37.42244918858722,17 -122.0857260327004,37.42229239604253,17 -122.0857412771483,37.42227033155257,17 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> <name>Building 42</name> <visibility>0</visibility> <styleUrl>#transGreenPoly</styleUrl> <Polygon> <extrude>1</extrude> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -122.0857862287242,37.42136208886969,25 -122.0857312990603,37.42136935989481,25 -122.0857312992918,37.42140934910903,25 -122.0856077073679,37.42138390166565,25 -122.0855802426516,37.42137299550869,25 -122.0852186221971,37.42137299504316,25 -122.0852277765639,37.42161656508265,25 -122.0852598189347,37.42160565894403,25 -122.0852598185499,37.42168200156,25 -122.0852369311478,37.42170017860346,25 -122.0852643957828,37.42176197982575,25 -122.0853239032746,37.42176198013907,25 -122.0853559454324,37.421852864452,25 -122.0854108752463,37.42188921823734,25 -122.0854795379357,37.42189285337048,25 -122.0855436229819,37.42188921797546,25 -122.0856260178042,37.42186013499926,25 -122.085937287963,37.42186013453605,25 -122.0859428718666,37.42160898590042,25 -122.0859655469861,37.42157992759144,25 -122.0858640462341,37.42147115002957,25 -122.0858548911215,37.42140571326184,25 -122.0858091162768,37.4214057134039,25 -122.0857862287242,37.42136208886969,25 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> <name>Building 43</name> <visibility>0</visibility> <styleUrl>#transYellowPoly</styleUrl> <Polygon> <extrude>1</extrude> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -122.0844371128284,37.42177253003091,19 -122.0845118855746,37.42191111542896,19 -122.0850470999805,37.42178755121535,19 -122.0850719913391,37.42143663023161,19 -122.084916406232,37.42137237822116,19 -122.0842193868167,37.42137237801626,19 -122.08421938659,37.42147617161496,19 -122.0838086419991,37.4214613409357,19 -122.0837899728564,37.42131306410796,19 -122.0832796534698,37.42129328840593,19 -122.0832609819207,37.42139213944298,19 -122.0829373621737,37.42137236399876,19 -122.0829062425667,37.42151569778871,19 -122.0828502269665,37.42176282576465,19 -122.0829435788635,37.42176776969635,19 -122.083217411188,37.42179248552686,19 -122.0835970430103,37.4217480074456,19 -122.0839455556771,37.42169364237603,19 -122.0840077894637,37.42176283815853,19 -122.084113587521,37.42174801104392,19 -122.0840762473784,37.42171341292375,19 -122.0841447047739,37.42167881534569,19 -122.084144704223,37.42181720660197,19 -122.0842503333074,37.4218170700446,19 -122.0844371128284,37.42177253003091,19 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> </Folder> <Folder> <name>Extruded Polygon</name> <description>A simple way to model a building</description> <Placemark> <name>The Pentagon</name> <LookAt> <longitude>-77.05580139178142</longitude> <latitude>38.870832443487</latitude> <heading>59.88865561738225</heading> <tilt>48.09646074797388</tilt> <range>742.0552506670548</range> </LookAt> <Polygon> <extrude>1</extrude> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -77.05788457660967,38.87253259892824,100 -77.05465973756702,38.87291016281703,100 -77.05315536854791,38.87053267794386,100 -77.05552622493516,38.868757801256,100 -77.05844056290393,38.86996206506943,100 -77.05788457660967,38.87253259892824,100 </coordinates> </LinearRing> </outerBoundaryIs> <innerBoundaryIs> <LinearRing> <coordinates> -77.05668055019126,38.87154239798456,100 -77.05542625960818,38.87167890344077,100 -77.05485125901024,38.87076535397792,100 -77.05577677433152,38.87008686581446,100 -77.05691162017543,38.87054446963351,100 -77.05668055019126,38.87154239798456,100 </coordinates> </LinearRing> </innerBoundaryIs> </Polygon> </Placemark> </Folder> <Folder> <name>Absolute and Relative</name> <visibility>0</visibility> <description>Four structures whose roofs meet exactly. Turn on/off terrain to see the difference between relative and absolute positioning.</description> <LookAt> <longitude>-112.3348969157552</longitude> <latitude>36.14845533214919</latitude> <altitude>0</altitude> <heading>-86.91235037566909</heading> <tilt>49.30695423894192</tilt> <range>990.6761201087104</range> </LookAt> <Placemark> <name>Absolute</name> <visibility>0</visibility> <styleUrl>#transBluePoly</styleUrl> <Polygon> <tessellate>1</tessellate> <altitudeMode>absolute</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -112.3372510731295,36.14888505105317,1784 -112.3356128688403,36.14781540589019,1784 -112.3368169371048,36.14658677734382,1784 -112.3384408457543,36.14762778914076,1784 -112.3372510731295,36.14888505105317,1784 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> <name>Absolute Extruded</name> <visibility>0</visibility> <styleUrl>#transRedPoly</styleUrl> <Polygon> <extrude>1</extrude> <tessellate>1</tessellate> <altitudeMode>absolute</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -112.3396586818843,36.14637618647505,1784 -112.3380597654315,36.14531751871353,1784 -112.3368254237788,36.14659596244607,1784 -112.3384555043203,36.14762621763982,1784 -112.3396586818843,36.14637618647505,1784 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> <name>Relative</name> <visibility>0</visibility> <LookAt> <longitude>-112.3350152490417</longitude> <latitude>36.14943123077423</latitude> <altitude>0</altitude> <heading>-118.9214100848499</heading> <tilt>37.92486261093203</tilt> <range>345.5169113679813</range> </LookAt> <styleUrl>#transGreenPoly</styleUrl> <Polygon> <tessellate>1</tessellate> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -112.3349463145932,36.14988705767721,100 -112.3354019540677,36.14941108398372,100 -112.3344428289146,36.14878490381308,100 -112.3331289492913,36.14780840132443,100 -112.3317019516947,36.14680755678357,100 -112.331131440106,36.1474173426228,100 -112.332616324338,36.14845453364654,100 -112.3339876620524,36.14926570522069,100 -112.3349463145932,36.14988705767721,100 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <Placemark> <name>Relative Extruded</name> <visibility>0</visibility> <LookAt> <longitude>-112.3351587892382</longitude> <latitude>36.14979247129029</latitude> <altitude>0</altitude> <heading>-55.42811560891606</heading> <tilt>56.10280503739589</tilt> <range>401.0997279712519</range> </LookAt> <styleUrl>#transYellowPoly</styleUrl> <Polygon> <extrude>1</extrude> <tessellate>1</tessellate> <altitudeMode>relativeToGround</altitudeMode> <outerBoundaryIs> <LinearRing> <coordinates> -112.3348783983763,36.1514008468736,100 -112.3372535345629,36.14888517553886,100 -112.3356068927954,36.14781612679284,100 -112.3350034807972,36.14846469024177,100 -112.3358353861232,36.1489624162954,100 -112.3345888301373,36.15026229372507,100 -112.3337937856278,36.14978096026463,100 -112.3331798208424,36.1504472788618,100 -112.3348783983763,36.1514008468736,100 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> </Folder> </Folder> </Document>
</kml>

The following is the resulting CSV after running the above code snippet (new CSV file: 'my_file.csv'):

36.10677870477137,-112.0814237830345,36.0905099328766,-112.0870267752693
36.10673460007995,-112.080622229595,36.09049598612422,-112.085242575315
36.09447672602546,-112.265654928602,36.09342608838671,-112.2660384528238,36.09251058776881,-112.2668139013453,36.09189827357996,-112.2677826834445,36.0913137941187,-112.2688557510952,36.0903677207521,-112.2694810717219,36.08932171487285,-112.2695268555611,36.08850916060472,-112.2690144567276,36.08753813597956,-112.2681528815339,36.08682685262568,-112.2670588176031,36.08646312301303,-112.2657374587321
36.07954952145647,-112.2550785337791,36.08117083492122,-112.2549277039738,36.08260761307279,-112.2552505069063,36.08395660588506,-112.2564540158376,36.08511401044813,-112.2580238976449,36.08584355239394,-112.2595218489022,36.08612634548589,-112.2608216347552,36.08626019085147,-112.262073428656,36.08621519860091,-112.2633204928495,36.08627897945274,-112.2644963846444,36.08649599090644,-112.2656969554589
36.09886943729116,-112.2532845153347,36.09919570465255,-112.2540466121145,36.09984998366178,-112.254734666947,36.10051310621746,-112.255493345654,36.10108441943419,-112.2563157098468,36.10159722088088,-112.2568033076439,36.10204323542867,-112.257494011321,36.10229131995655,-112.2584106072308,36.10240001286358,-112.2596588987972,36.10213176873407,-112.2610581199487,36.10157011437219,-112.2626285262793
36.09445214722695,-112.2656634181359,36.09520916122063,-112.2652238941097,36.09580763864907,-112.2645079986395,36.09628572284063,-112.2638827428817,36.09679275951239,-112.2635746835406,36.09740038871899,-112.2635711822407,36.09804913435539,-112.2640296531825,36.09880337400301,-112.264327720538,36.09963644790288,-112.2642436562271,36.10055381117246,-112.2639148687042,36.10149062823369,-112.2626894973474
37.42257124044786,-122.0848938459612,37.42211922626856,-122.0849580979198,37.42207183952619,-122.0847469573047,37.42209006729676,-122.0845725380962,37.42215932700895,-122.0845954886723,37.42227278564371,-122.0838521118269,37.42203539112084,-122.083792243335,37.42209006957106,-122.0835076656616,37.42200987395161,-122.0834709464152,37.4221046494946,-122.0831221085748,37.42226503990386,-122.0829247374572,37.42231242843094,-122.0829339169385,37.42225046087618,-122.0833837359737,37.42234159228745,-122.0833607854248,37.42237075460644,-122.0834204551642,37.42251292011001,-122.083659133885,37.42265873093781,-122.0839758438952,37.42265143972521,-122.0842374743331,37.4226514386435,-122.0845036949503,37.42261133916315,-122.0848020460801,37.42256395055121,-122.0847882750515,37.42257124044786,-122.0848938459612
37.42227033155257,-122.0857412771483,37.42231408832346,-122.0858169768481,37.42230337469744,-122.085852582875,37.42225686138789,-122.0858799945639,37.4222311076138,-122.0858860101409,37.42220250173855,-122.0858069157288,37.42214027058678,-122.0858379542653,37.42208690214408,-122.0856732640519,37.42214885429042,-122.0856022926407,37.422128290487,-122.0855902778436,37.42208171967246,-122.0855841672237,37.42210455874995,-122.0854852065741,37.42214267949824,-122.0855067264352,37.42212783846172,-122.0854430712915,37.42251282407603,-122.0850990714904,37.42281815323651,-122.0856769818632,37.42244918858722,-122.0860162273783,37.42229239604253,-122.0857260327004,37.42227033155257,-122.0857412771483
37.42136208886969,-122.0857862287242,37.42136935989481,-122.0857312990603,37.42140934910903,-122.0857312992918,37.42138390166565,-122.0856077073679,37.42137299550869,-122.0855802426516,37.42137299504316,-122.0852186221971,37.42161656508265,-122.0852277765639,37.42160565894403,-122.0852598189347,37.42168200156,-122.0852598185499,37.42170017860346,-122.0852369311478,37.42176197982575,-122.0852643957828,37.42176198013907,-122.0853239032746,37.421852864452,-122.0853559454324,37.42188921823734,-122.0854108752463,37.42189285337048,-122.0854795379357,37.42188921797546,-122.0855436229819,37.42186013499926,-122.0856260178042,37.42186013453605,-122.085937287963,37.42160898590042,-122.0859428718666,37.42157992759144,-122.0859655469861,37.42147115002957,-122.0858640462341,37.42140571326184,-122.0858548911215,37.4214057134039,-122.0858091162768,37.42136208886969,-122.0857862287242
37.42177253003091,-122.0844371128284,37.42191111542896,-122.0845118855746,37.42178755121535,-122.0850470999805,37.42143663023161,-122.0850719913391,37.42137237822116,-122.084916406232,37.42137237801626,-122.0842193868167,37.42147617161496,-122.08421938659,37.4214613409357,-122.0838086419991,37.42131306410796,-122.0837899728564,37.42129328840593,-122.0832796534698,37.42139213944298,-122.0832609819207,37.42137236399876,-122.0829373621737,37.42151569778871,-122.0829062425667,37.42176282576465,-122.0828502269665,37.42176776969635,-122.0829435788635,37.42179248552686,-122.083217411188,37.4217480074456,-122.0835970430103,37.42169364237603,-122.0839455556771,37.42176283815853,-122.0840077894637,37.42174801104392,-122.084113587521,37.42171341292375,-122.0840762473784,37.42167881534569,-122.0841447047739,37.42181720660197,-122.084144704223,37.4218170700446,-122.0842503333074,37.42177253003091,-122.0844371128284
38.87253259892824,-77.05788457660967,38.87291016281703,-77.05465973756702,38.87053267794386,-77.05315536854791,38.868757801256,-77.05552622493516,38.86996206506943,-77.05844056290393,38.87253259892824,-77.05788457660967
38.87154239798456,-77.05668055019126,38.87167890344077,-77.05542625960818,38.87076535397792,-77.05485125901024,38.87008686581446,-77.05577677433152,38.87054446963351,-77.05691162017543,38.87154239798456,-77.05668055019126
36.14888505105317,-112.3372510731295,36.14781540589019,-112.3356128688403,36.14658677734382,-112.3368169371048,36.14762778914076,-112.3384408457543,36.14888505105317,-112.3372510731295
36.14637618647505,-112.3396586818843,36.14531751871353,-112.3380597654315,36.14659596244607,-112.3368254237788,36.14762621763982,-112.3384555043203,36.14637618647505,-112.3396586818843
36.14988705767721,-112.3349463145932,36.14941108398372,-112.3354019540677,36.14878490381308,-112.3344428289146,36.14780840132443,-112.3331289492913,36.14680755678357,-112.3317019516947,36.1474173426228,-112.331131440106,36.14845453364654,-112.332616324338,36.14926570522069,-112.3339876620524,36.14988705767721,-112.3349463145932
36.1514008468736,-112.3348783983763,36.14888517553886,-112.3372535345629,36.14781612679284,-112.3356068927954,36.14846469024177,-112.3350034807972,36.1489624162954,-112.3358353861232,36.15026229372507,-112.3345888301373,36.14978096026463,-112.3337937856278,36.1504472788618,-112.3331798208424,36.1514008468736,-112.3348783983763
Posted on Leave a comment

Send Email from Localhost using PHP with SMTP and PHPMailer

by Vincy. Last modified on August 17th, 2022.

Localhost is the web developer’s favorite home. Local development environment is always convenient to develop and debug scripts.

Mailing via a script with in-built PHP function. This may not work almost always in a localhost. You need to have a sendmail program and appropriate configurations.

If the PHP mail() is not working on your localhost, there is an alternate solution to sending email. You can use a SMTP server and send email from localhost and it is the popular choice for sending emails for PHP programmers.

This example shows code to use PHPMailer to send email using SMTP from localhost.

mail sending from localhost using smtp

PHP Mail sending script with SMTP

This program uses the PHPMailer library to connect SMTP to send emails. You can test this in your localhost server. You need access to a SMTP server.

Before running this code, configure the SMTP settings to set the following details.

  1. Authentication directive and security protocol.
  2. Configure SMTP credentials to authenticate and authorize mail sending script.
  3. Add From, To and Reply-To addresses using the PHPMailer object.
  4. Build email body and add subject before sending the email.

The above steps are mandatory with the PHPMailer mail sending code. Added to that, this mailing library supports many features. Some of them are,

Set the SMTP Debug = 4 in development mode to print the status details of the mail-sending script.

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception; require_once __DIR__ . '/vendor/phpmailer/src/Exception.php';
require_once __DIR__ . '/vendor/phpmailer/src/PHPMailer.php';
require_once __DIR__ . '/vendor/phpmailer/src/SMTP.php'; $mail = new PHPMailer(true); $mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = 'SET-SMTP-HOST';
$mail->SMTPAuth = true;
$mail->SMTPSecure = "ssl";
$mail->Port = 465; $mail->mailer = "smtp"; $mail->Username = 'SET-SMTP-USERNAME';
$mail->Password = 'SET-SMTP-PASSWORD'; // Sender and recipient address
$mail->SetFrom('SET-SENDER-EMAIL', 'SET-SENDER_NAME');
$mail->addAddress('ADD-RECIPIENT-EMAIL', 'ADD-RECIPIENT-NAME');
$mail->addReplyTo('ADD-REPLY-TO-EMAIL', 'ADD-REPLY-TO-NAME'); // Setting the subject and body
$mail->IsHTML(true);
$mail->Subject = "Send email from localhost using PHP";
$mail->Body = 'Hello World!'; if ($mail->send()) { echo "Email is sent successfully.";
} else { echo "Error in sending an email. Mailer Error: {$mail->ErrorInfo}";
}
?>

Google and Microsoft disabled insecure authentication

Earlier, programmers conveniently used GMail’s SMTP server for sending emails via PHP. Now, less secure APPs configuration in Google is disabled. Google and Microsoft force authentication via OAuth 2 to send email.

There is ill-informed text going around in this topic. People say that we cannot send email via Google SMTP any more. That is not the case. They have changed the authentication method.

IMPORTANT: I have written an article to help you send email using xOAuth2 via PHP. You can use this and continue to send email using Google or other email service providers who force to use OAuth.

Alternate: Enabling PHP’s built-in mail()

  1. If you do not have access to an email SMTP server.
  2. If you are not able to use xOAuth2 and Google / Microsoft’s mailing service.

In the above situations, you may try to setup your own server in localhost. Yes! that is possible and it will work.

PHP has a built-in mail function to send emails without using any third-party libraries.

The mail() function is capable of simple mail sending requirements in PHP.

In localhost, it will not work without setting the php.ini configuration. Find the following section in your php.ini file and set the sendmail path and related configuration.

php.ini mail setting

Download

↑ Back to Top

Posted on Leave a comment

Python Convert GeoJSON to CSV

5/5 – (1 vote)

What is GeoJSON?

đź’ˇ GeoJSON is an RFC standardized data format to encode geographic data structures such as Point, LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon. GeoJSON is based on the JavaScript Object Notation (JSON).

Example GeoJSON to CSV

Say, you have the following GeoJSON snippet:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-75.343, 39.984]}, "properties": { "name": "Location A", "category": "Store" } }, { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-80.24, 40.12]}, "properties": { "name": "Location B", "category": "House" } }, { "type": "Feature", "geometry": {"type": "Point", "coordinates": [ -77.2, 41.427]}, "properties": { "name": "Location C", "category": "Office" } } ] }

You want to convert it to the following CSV format:

latitude,longitude,altitude,geometry,name,category
39.984,-75.343,,Point,Location A,Store
40.12,-80.24,,Point,Location B,House
41.427,-77.2,,Point,Location C,Office

Python GeoJSON to CSV Conversion

The Python code to convert a GeoJSON to a CSV in Python uses a combination of the json and csv packages.

import json
import csv geo_filename = 'my_file.json'
csv_filename = 'my_file.csv' def feature_to_row(feature, header): l = [] for k in header: l.append(feature['properties'][k]) coords = feature['geometry']['coordinates'] assert(len(coords)==2) l.extend(coords) return l with open(geo_filename, 'r') as geo_file: with open(csv_filename, 'w', newline='') as csv_file: geojson_data = json.load(geo_file) features = geojson_data['features'] csv_writer = csv.writer(csv_file) is_header = True header = [] for feature in features: if is_header: is_header = False header = list(feature['properties'].keys()) header.extend(['px','py']) csv_writer.writerow(header) csv_writer.writerow(feature_to_row(feature, feature['properties'].keys())) 

You can either copy&paste this code and run it in the same folder as your GeoJSON (of course, after renaming the input and output filenames.

Or you can check out this excellent GitHub to get a more “scriptable” variant to be used in the command line. This code is inspired by the GitHub but simplified significantly.

Example input:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-75.343, 39.984]}, "properties": { "name": "Location A", "category": "Store" } }, { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-80.24, 40.12]}, "properties": { "name": "Location B", "category": "House" } }, { "type": "Feature", "geometry": {"type": "Point", "coordinates": [ -77.2, 41.427]}, "properties": { "name": "Location C", "category": "Office" } } ] }

Example output:

GeoJSON to CSV in QGIS

In QGIS, if you have a map like this one (source):

You can convert GEOJSON to CSV right within QGIS by clicking Export, then Save Feature As and select the Comma Separated Value [CSV] selector in the first dropdown menu.

enter image description here
(source)
enter image description here
(source)

GeoJSON to CSV Online Converter

You can easily convert specific GeoJSON snippets to CSV using the following online converter:

Posted on Leave a comment

How to Iterate over a NumPy Array

Rate this post

Problem Formulation and Solution Overview

In this article, you’ll learn how to iterate over a 1D, 2D and 3D NumPy array using Python.

When working with the NumPy library, you will encounter situations where you will need to iterate through a 1D, 2D and even a 3D array. This article will show you how to accomplish this task.


đź’¬ Question: How would we write code to iterate through a 1D, 2D or 3D NumPy array?

We can accomplish this task by one of the following options:


Preparation

Before moving forward, please ensure the NumPy library is installed. Click here if you require instructions.

Then, add the following code to the top of each script. This snippet will allow the code in this article to run error-free.

import numpy as np 

After importing the NumPy library, this library is referenced by calling the shortcode (np).


Method 1: Use a For Loop and np.array()

This method uses a For loop combined with np.array() to iterate through a 1D NumPy array. The first five (5) Atomic Numbers from the Periodic Table are generated and displayed for this example.

atomic_els = np.array(np.arange(1,6)) for el in atomic_els: print(el, end=' ')

Above, calls the np.array() function and passes it np.arange(1,6) with two (2) arguments: a start position of one (1) and stop position of five (5) or (stop-1). The result is an array of integers and saves to atomic_els.

[1 2 3 4 5]

Next, a For loop is instantiated and iterates through each element of the 1D NumPy array atomic_els.

The output is sent to the terminal on one (1) line as an additional argument was passed to the print statement (end=' '). This argument replaces the default newline character with a blank space.

1 2 3 4 5
YouTube Video

Method 2: Uses a For Loop and nditer()

This method uses a for loop combined with np.nditer() to iterate through a NumPy array. The first five (5) Atomic Numbers and Number of Neutrons data from the Periodic Table display for this example.

atomic_data = np.array([np.arange(1,6), [0, 2, 4, 5, 6]]) for dim in atomic_data: for d in dim: print(d, end=' ')

Above, calls the np.array() function and passes np.arange(1,6) as the first argument and an array of associated Number of Neutrons values as the second.

Next, an outer for loop is instantiated. This iterates through each array dimension.

Inside this loop, another for loop is instantiated. The inside loop iterates through each element of the above dimensions.

The output is sent to the terminal on one (1) line as an additional argument is passed to the print statement (end=' '). This argument replaces the default newline character with a blank space.

1 2 3 4 5 0 2 4 5 6

đź’ˇNote: The first dimension is highlighted to easily differentiate the dimensions.

YouTube Video

Method 3: Use a For Loop and itertools

This method uses a for loop and Python’s built-in itertools library to iterate through a NumPy array. The first three (3) Atomic Numbers, Phase, and Group data from the Periodic Table display for this example.

import itertools atomic_num = np.arange(1,4)
atomic_phase = ['gas', 'gas', 'solid']
atomic_group = [1, 18, 1] for (a, b, c) in itertools.zip_longest(atomic_num, atomic_phase, atomic_group, fillvalue=0): print (a, b, c)

Above, imports the itertools library to use the zip_longest() function.

Then, three (3) arrays are declared containing the relevant data for the first three (3) elements from the Periodic Table. They save respectively to atomic_num, atomic_phase, and atomic_group.

Next, a for loop is instantiated and passed three (3) arguments inside the brackets (a, b, c) which reference the arguments inside the zip_longest(atomic_num, atomic_phase, atomic_group) function.

An additional argument (fillvalue=0) is also passed. This fills in any missing values for lists of unequal lengths with the stated value.

The loop iterates until the end of the arrays are reached, outputting to the terminal for each iteration.

1 gas 1
2 gas 18
3 solid 1
YouTube Video

Method 4: Use a While Loop and Size

This method uses a while loop combined with np.size to iterate through a NumPy array. The first five (5) Atomic Numbers, Number of Neutrons, and Phase data from the Periodic Table display for this example.

atomic_names = np.array(['Hydrogen', 'Helium', 'Lithium', 'Beryllium', 'Boron'])
el_count = 0 while el_count < atomic_names.size: print(atomic_names[el_count], end=' ') el_count += 1

Above, calls the np.array() function and passes a list containing the first five (5) element names of the Periodic Table. These results save to atomic_names.

Then, a variable, el_count, is declared with a start value of zero (0). This will be a counter variable and lets the While loop know when to stop iterating.

Next, a while loop is instantiated and iterates through the elements of atomic_names. This will continue while the value of el_count remains less than the value of atomic_names.size.

The output is sent to the terminal on one (1) line as an additional argument is passed to the print statement (end=' '). This argument replaces the default newline character with a blank space.

Hydrogen Helium Lithium Beryllium Boron

Method 5: Use a For Loop and np.ndenumerate()

This method uses a For loop and np.ndenumerate() to iterate through a NumPy array. The first five (5) Element Names from the Periodic Table display for this example.

atomic_names = np.array(['Hydrogen', 'Helium', 'Lithium', 'Beryllium', 'Boron']) for idx, x in np.ndenumerate(atomic_names): print(idx, x)

Above, calls the np.array() function and passes it an array containing the first five (5) element names from the Periodic Table. The results save to atomic_names.

Next, a for loop is instantiated referencing idx which is the index of the array, and x, which is the array element’s value.

The output is sent to the terminal. Then idx displays a Tuple containing the index value of the array and then the value of x for each iteration.

(0,) Hydrogen
(1,) Helium
(2,) Lithium
(3,) Beryllium
(4,) Boron

Method 6: Use a For Loop and range()

This method uses a for loop and range()) to iterate through a 3D NumPy array.

nums = np.array([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]], [[13, 14], [15, 16], [17, 18]], [[19, 20], [21, 22], [23, 23]], [[24, 25], [26, 27], [28, 29]]]) for x in range(0, 5): for y in range(0, 3): for z in range(0, 2): print(nums[x][y][z])

Above declares a 3D NumPy array containing consecutive numbers from 1-29 inclusive. These save to nums.

Next, three (3) for loops are instantiated to loop through and output the contents of nums to the terminal one (1) number per line.

The range() function for each loop is based on the dimensions of the 3D Numpy array, for example:

  • The first loop (range(0,5) identifies the total number of tows in the array.
  • The next loop (range(0,3) identifies the number of columns in the array.
  • The final loop (range(0,2) identifies the elements in each column in the array.

Finally, the output is sent to the terminal (snippet only).

1
2
3
4
5
6
7
8
9
10
...

Bonus: Convert CSV to np.array()

This example reads in a snippet of the Periodic Table as a CSV file. This data is converted to a NumPy array and is output to the terminal.

The CSV file below contains the values of the Atomic Number, Atomic Mass, Number of Neutrons, and the Number of Electrons for the first seven (7) elements from the Periodic Table.

Contents of pt_sample.csv

1,1.007,0
2,4.002,2
3,6.941,4
4,9.012,5
5,10.811,6
6,12.011,6
7,14.007,7

To follow along, save this file as pt_sample.csv and move it into the current working directory.

Before moving forward, please ensure the Pandas library is installed. Click here if you require instructions.

import pandas as pd
import csv file_name = 'pt_sample.csv'
df_data = np.array(list(csv.reader(open(file_name, 'r'), delimiter=','))).astype("float")
print(df_data)

Above, imports the Pandas library and the CSV library. This is needed to work with DataFrames and read in the CSV file.

Then, a filename is declared and saves to file_name.

On the highlighted line, the np.array() function is called and passed the following arguments.

  • The csv.reader() function is passed as an argument and this argument passes the open() method to open the specified CSV file in read (r) mode, including the field delimiter (csv.reader(open(file_name, 'r'), delimiter=',')).
  • The contents of the CSV file converts to a list.
  • This list converts to an np.array().

The results save to df_data and output to the terminal.

[[ 1. 1.007 0. ]
[ 2. 4.002 2. ]
[ 3. 6.941 4. ]
[ 4. 9.012 5. ]
[ 5. 10.811 6. ]
[ 6. 12.011 6. ]
[ 7. 14.007 7. ]]
YouTube Video

Summary

These seven (7) methods of iterating a NumPy array should give you enough information to select the best one for your coding requirements.

Good Luck & Happy Coding!


Programmer Humor – Blockchain

“Blockchains are like grappling hooks, in that it’s extremely cool when you encounter a problem for which they’re the right solution, but it happens way too rarely in real life.” source xkcd
Posted on Leave a comment

How to Upload Files to Google Drive with JavaScript

by Vincy. Last modified on August 15th, 2022.

This article gives a working example script to learn how to upload files to Google Drive via JavaScript.

Creating a JavaScript solution to the Drive file upload process is very simple. It uses gapi library to implement this feature on the client side.

In a recently posted tutorial, we created an example code for achieving Google Drive upload in PHP.

Prerequisites

It needs two libraries loaded to achieve JavaScript via Google Drive upload.

  1. Google sign-in library for identity verification.
  2. Google API client library for JavaScript-based API access.

Added to that, create the API app and get the credentials.

  1. Enable the Google Drive API.
  2. Get the API key and Web client id from the Google developer console.

Go to the Google developer console and click “Create Credentials” to set the API key and web client id. We have seen how to get the Google API keys from the developer console in previous articles.

Steps to upload files to Google Drive with JavaScript

These are the steps to implement uploading files from an application to Google Drive using JavaScript.

  1. Authorize by proving the identity via Google sign-in API (GSI) library challenge.
  2. Get the access token.
  3. Prepare the upload request by specifying the Google drive directory target (optional).
  4. Hit Google Drive V3 endpoint to post file content and metadata via JavaScript FormData.

authorize and upload to google drive

Example code for uploading files to Drive

The below code shows the landing page interface in HTML and the JavaScript asset created for uploading the files to Google Drive.

HTML code to display controls for requesting authorization and upload

When landing on the home page, it displays an Authorize button in the UI. On clicking this button, it shows the Google sign-in overlay dialog to proceed with the authorization request.

In this step, the user must prove their identity to have access to upload to the Drive directory.

index.php

<!DOCTYPE html>
<html>
<head>
<title>Google Drive upload using JavaScript</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/form.css" />
<style>
#content { display: none;
}
</style>
</head>
<body> <!--Add HTML buttons to sign in and sign out--> <div class="phppot-container"> <h1>Google Drive upload using JavaScript</h1> <div> <div class="row"> <input type="button" id="authorize_button" onclick="handleAuthClick()" value="Authorize"> <input type="button" id="signout_button" onclick="handleSignoutClick()" value="Sign Out"> </div> </div> <div id="content" class="success message"><?php if(isset($message)) { echo $message; } ?></div> </div> <script type="text/javascript" src="./js/gapi-upload.js"></script> <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script> <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
</body>
</html>

JavaScript to handle user authorization and file upload sequence

This JavaScript code initializes the gapi and gsi on a callback of loading these Google JavaScript libraries.

It also contains the handlers to trigger API requests for the following actions.

  1. Google authorization with identity proof.
  2. Upload files with the access token.
  3. Refresh gapi upload action once authorized.
  4. Signout.

This JavaScript code requires the authorization credentials to be configured. Set the CLIENT_ID and API_KEY in this script before running this example.

In this example, it sets the Google Drive folder id to upload the file via JavaScript. This configuration is optional. If no target is needed, remove the parameter from the file meta array.

js/gapi-upload.js

// TODO: Set the below credentials
const CLIENT_ID = 'SET-YOUR-CLIENT-ID';
const API_KEY = 'SET-YOUR-API-KEY'; // Discovery URL for APIs used by the quickstart
const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'; // Set API access scope before proceeding authorization request
const SCOPES = 'https://www.googleapis.com/auth/drive.file';
let tokenClient;
let gapiInited = false;
let gisInited = false; document.getElementById('authorize_button').style.visibility = 'hidden';
document.getElementById('signout_button').style.visibility = 'hidden'; /** * Callback after api.js is loaded. */
function gapiLoaded() { gapi.load('client', initializeGapiClient);
} /** * Callback after the API client is loaded. Loads the * discovery doc to initialize the API. */
async function initializeGapiClient() { await gapi.client.init({ apiKey: API_KEY, discoveryDocs: [DISCOVERY_DOC], }); gapiInited = true; maybeEnableButtons();
} /** * Callback after Google Identity Services are loaded. */
function gisLoaded() { tokenClient = google.accounts.oauth2.initTokenClient({ client_id: CLIENT_ID, scope: SCOPES, callback: '', // defined later }); gisInited = true; maybeEnableButtons();
} /** * Enables user interaction after all libraries are loaded. */
function maybeEnableButtons() { if (gapiInited && gisInited) { document.getElementById('authorize_button').style.visibility = 'visible'; }
} /** * Sign in the user upon button click. */
function handleAuthClick() { tokenClient.callback = async (resp) => { if (resp.error !== undefined) { throw (resp); } document.getElementById('signout_button').style.visibility = 'visible'; document.getElementById('authorize_button').value = 'Refresh'; await uploadFile(); }; if (gapi.client.getToken() === null) { // Prompt the user to select a Google Account and ask for consent to share their data // when establishing a new session. tokenClient.requestAccessToken({ prompt: 'consent' }); } else { // Skip display of account chooser and consent dialog for an existing session. tokenClient.requestAccessToken({ prompt: '' }); }
} /** * Sign out the user upon button click. */
function handleSignoutClick() { const token = gapi.client.getToken(); if (token !== null) { google.accounts.oauth2.revoke(token.access_token); gapi.client.setToken(''); document.getElementById('content').style.display = 'none'; document.getElementById('content').innerHTML = ''; document.getElementById('authorize_button').value = 'Authorize'; document.getElementById('signout_button').style.visibility = 'hidden'; }
} /** * Upload file to Google Drive. */
async function uploadFile() { var fileContent = 'Hello World'; // As a sample, upload a text file. var file = new Blob([fileContent], { type: 'text/plain' }); var metadata = { 'name': 'sample-file-via-js', // Filename at Google Drive 'mimeType': 'text/plain', // mimeType at Google Drive // TODO [Optional]: Set the below credentials // Note: remove this parameter, if no target is needed 'parents': ['SET-GOOGLE-DRIVE-FOLDER-ID'], // Folder ID at Google Drive which is optional }; var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token. var form = new FormData(); form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' })); form.append('file', file); var xhr = new XMLHttpRequest(); xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id'); xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken); xhr.responseType = 'json'; xhr.onload = () => { document.getElementById('content').innerHTML = "File uploaded successfully. The Google Drive file id is <b>" + xhr.response.id + "</b>"; document.getElementById('content').style.display = 'block'; }; xhr.send(form);
}

Google Drive JavaScript Upload Response

Once authorized, the JavaScript calls the uploadFile() function to hit the Google Drive V3 API to post the file binary.

The below screenshot shows the uploaded Google Drive file id in the success message.

After sign-in, the landing page UI will display the signout option. It also shows a Refresh button to trigger upload action again in case of any issues on uploading.

file upload ack with google drive file id
Download

↑ Back to Top