#include <iostream>
#include <algorithm>
#include <string>
std::string input;
std::getline(std::cin, input);
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
25/10/2019
[C++] Convert string to lower or upper case
While playing with the Rock, Paper, Scissors game, I had to convert a given string to lower case. Turns out, C++ does not have a very straightforward way of doing so, but I found this solution works well since I am not dealing with strange locales:
[C++] Validate string contains only digits and convert it to int
While playing with the Rock, Paper, Scissors game, I had to validate the user input to check only digits where entered at a particular moment. Turns out, C++ does not have a very straightforward way of doing so, but I found this solution works well:
#include <iostream>
#include <string>
std::string input;
std::getline(std::cin, input);
if(!(input.find_first_not_of("0123456789") == std::string::npos)){
cout << "ERROR" << endl;
cin.clear();
}
int entered = stoi(input);
[C++] Good random initialization and generator
While playing with the Rock, Paper, Scissors game, I had to pick a random move from three possible values for the AI. First attempt was:
But I noticed that playing many short games (3 to 5 rounds) in quick succession would yield a fairly common pattern where the AI move would not change often enough.
So I found there is a better way to do so:
#include <ctime>
srand(time(NULL));
int move = rand() % 3;
But I noticed that playing many short games (3 to 5 rounds) in quick succession would yield a fairly common pattern where the AI move would not change often enough.
So I found there is a better way to do so:
#include <random>
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
//only 3 possible moves
std::uniform_int_distribution<> dist{0,2};
int move = dist(eng);
[C++] Rock! Paper! Scissors! Fight!
This C++ exercise implements a full game of Rock, Paper, Scissors against an AI opponent. Check the Rock! Paper! Scissors! Fight! project on GitHub.
17/10/2019
[Maven] Run HP Fortify scan during build
If you have Fortify static code analyzer (aka HP Fortify) and intend to use it with your builds, you can configure the sca-maven-plugin to perform the scan and produce a report during the build. It can also optionally upload it to your security server.
[git] Define code owners and enforce review checks
Git (both GitHub and Bitbucket) allows you to specify code owners for a particular repository. This allows you to set up checks that require an approval from any valid owner before the PR can be merged, it also is an easy place where to look up people working on the specific project.
To add code owners, simply check in a file named CODEOWNERS that includes owners in the format
filter owner
and remember that the LAST matching filter has precedence. For example:
* @someuser @someoneelse
*.java @anotheruser
means that someuser and someoneelse are requested to review any PR, while anotheruser is requested to review PRs that touch java files.
After this file is checked in, remember to also activate the PR check for your repo!
To add code owners, simply check in a file named CODEOWNERS that includes owners in the format
filter owner
and remember that the LAST matching filter has precedence. For example:
* @someuser @someoneelse
*.java @anotheruser
means that someuser and someoneelse are requested to review any PR, while anotheruser is requested to review PRs that touch java files.
After this file is checked in, remember to also activate the PR check for your repo!
[Maven] Code coverage during build
If you want to generate code coverage reports during your build, you can use an analyzer that will scan your code and your tests and give you a summary of the tested and untested lines of code.
[Maven] checkstyle during build
If you use autoformatting (and you should) for your code, you might also want to check for formatting violations as part of a build to ensure the style is consistent after every push. We will take a look at how to configure Google style, but this procedure works for any pair of files properly written.
21/09/2019
[Android] Revive MyTracks app
MyTracks was the best GPS tracking application. Lightweight, simple to use, well integrated with Google Drive, no extra crap. Until the fire nation attacked Google decided to kill it hoping you would switch to that pile of manure that is Google fit.
As valid alternatives I could only find ViewRanger or Open GPS Tracker but they are just not as good in my opinion.
The way Google killed the app, was to revoke the API keys it used. Meaning that by swapping those keys out with ones you own, everything works as expected.
Interested? Then check out the revive MyTracks project on Github
As valid alternatives I could only find ViewRanger or Open GPS Tracker but they are just not as good in my opinion.
The way Google killed the app, was to revoke the API keys it used. Meaning that by swapping those keys out with ones you own, everything works as expected.
Interested? Then check out the revive MyTracks project on Github
[Maven] Copy specific files from artifact in local directory
With Maven dependency plugin, it is possible to unpack certain content from specific artifacts in a desired directory during a certain phase:
Important parameters are:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>YOUR_ID</id>
<phase>SOME_PHASE</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>SOME_GROUP</groupId>
<artifactId>SOME_ARTIFACT</artifactId>
<version>SOME_VERSION</version>
<type>SOME_TYPE</type>
<overWrite>true</overWrite>
<outputDirectory>some/folder</outputDirectory>
<includes>some/pattern/**,and/another/pattern/**</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Important parameters are:
- artifactItem to ONLY consider that artifact instead of ALL imported ones
- type to specify the artifact type, eg: jar
- overWrite to specify whether to overwrite existing files in output folder
- outputDirectory to specify where to unpack the content
- includes to limit unpacking ONLY to specific files and folders. Multiple patterns can be added by separating with a comma
[Maven] Delete folders during specific phase
Using Maven clean plugin, it is possible to specify a clean behaviour to delete only selected folders during a certain phase:
Important parameters are:
<build>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>YOUR_ID</id>
<phase>SOME_PHASE</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>some/directory</directory>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
</build>
Important parameters are:
- excludeDefaultDirectories to avoid cleaning also the directories that a normal mvn:clean execution would
- fileset to specify only the directories to delete
[cURL] Use file content as payload
With curl, it is possible to specify a file content as payload simply with:
-d @$file
For example:
curl -X POST some_url -H some_headers -d @$file
-d @$file
For example:
curl -X POST some_url -H some_headers -d @$file
[bash] Loop over all files in folder filtering by extension
In bash, it is possible to loop over all files with a specific extension in a folder with:
for file in folder/*.extension
do
something with $file
done
Note that if directory is empty, one iteration will performed on the nonexistent *.extension file. To avoid that set the nullglob shell option for that run only as such:
shopt -s nullglob
your_script_here
shopt -u nullglob
for file in folder/*.extension
do
something with $file
done
Note that if directory is empty, one iteration will performed on the nonexistent *.extension file. To avoid that set the nullglob shell option for that run only as such:
shopt -s nullglob
your_script_here
shopt -u nullglob
[bash] Store content of file in a variable
In bash, it is possible to store the content of a file in a variable simply with:
file=/path/to/somefile.something
content="`cat $file`"
Note the special quotes used
file=/path/to/somefile.something
content="`cat $file`"
Note the special quotes used
[bash] String substitution with parameter expansion
In bash, it is possible to use parameter expansion with syntax ${expression} to perform a string replace. Here are some examples, the first value MUST be a variable.
To replace ONE occurrence of substring:
result=${string/substring/replace_with}
For example
string=grogblog
result=${string/blog/logs}
will return groglogs
To replace ALL occurrences of substring:
result=${string//substring//replace_with}
For example
string=grogbloggrogblog
result=${string//blog/logs}
will return groglogsgroglogs
Note the difference is simply the // instead of / at the beginning
To replace ONE occurrence of substring:
result=${string/substring/replace_with}
For example
string=grogblog
result=${string/blog/logs}
will return groglogs
To replace ALL occurrences of substring:
result=${string//substring//replace_with}
For example
string=grogbloggrogblog
result=${string//blog/logs}
will return groglogsgroglogs
Note the difference is simply the // instead of / at the beginning
[bash] Substring with parameter expansion
In bash it is possible to use parameter expansion with syntax ${expression}to perform a substring operation. Here are some examples, the first value MUST be a variable.
To cut out some text from the BEGINNING of the string:
result=${string#string_to_cut}
For example
string=groglogs
result=${string#grog}
will return logs
To cut out some text BEFORE the END of the string:
result=${string%cut_point*}
For example
string=grog.logs
result=${string%.*}
will return grog
They can also be chained to operate on the same variable in a sequence
To cut out some text from the BEGINNING of the string:
result=${string#string_to_cut}
For example
string=groglogs
result=${string#grog}
will return logs
To cut out some text BEFORE the END of the string:
result=${string%cut_point*}
For example
string=grog.logs
result=${string%.*}
will return grog
They can also be chained to operate on the same variable in a sequence
22/08/2019
[Spring] Schedule tasks
Scheduling execution of tasks in Spring is quite easy and requires just a couple annotations:
- Annotate the application class with @EnableScheduling
- Provide an @Component annotated class which includes the methods to be scheduled, each annotated with @Schedule
[Maven] Generate Avro sources at compile time
If you are using Apache Avro in your project, you might want to automatize the sources generation step so that at every compile, the target classes are built from the Avro schema.
In Maven, this can be done with the avro-maven-plugin with a configuration as such:
Remember that it is also possible to use avro-tools to manually generate sources from a schema.
In Maven, this can be done with the avro-maven-plugin with a configuration as such:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.blogspot.groglogs</groupId>
<artifactId>sample-avro-maven-pom</artifactId>
<version>1</version>
<dependencies>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
</dependency>
<!--
Use this for testing purposes only if you wish to manually generate the classes from Avro sources:
java -jar avro-tools.jar compile schema SCHEMA_FILE.avsc TARGET_DIRECTORY
See: https://avro.apache.org/docs/current/gettingstartedjava.html
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro-tools</artifactId>
<scope>provided</scope>
</dependency>
-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>SOURCE_DIR</sourceDirectory>
<outputDirectory>DEST_DIR</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Remember that it is also possible to use avro-tools to manually generate sources from a schema.
[Java] Date and Time utilities
Since java 8 introduced the java.time package, a lot of useful objects and methods are now available without the need to import external libraries.
Here are some operations that might come in handy when dealing with LocalDate and LocalDateTime objects:
Here are some operations that might come in handy when dealing with LocalDate and LocalDateTime objects:
- Convert String timezone (in format {Region}/{City} eg: "Europe/Rome") to ZoneOffset:
public static ZoneOffset stringToZoneOffset(final String timezone){
final ZoneId zone = ZoneId.of(timezone);
return zone.getRules().getOffset(Instant.now());
}
- Retrieve the hours offset between UTC and a given timezone:
public static int hoursOffsetFromUTC(final String timezone){
return ZoneId.of(timezone)
.getRules()
.getOffset(Instant.ofEpochMilli(1_498_329_000_000L))
.getTotalSeconds()/3600;
}
- Convert given time (in format HH:mm:ss) with specific timezone to UTC time:
public static OffsetTime timeAndTimezoneAtUTC(final String time, final String timezone){
return LocalTime.parse(time, DateTimeFormatter.ISO_LOCAL_TIME)
.atOffset(stringToZoneOffset(timezone))
.withOffsetSameInstant(ZoneOffset.UTC);
}
- Convert date to epoch seconds (if we had a LocalDateTime, we wouldn't need to use atStartOfDay):
public static Long localDateToEpoch(final LocalDate localDate){
return localDate.atStartOfDay(ZoneOffset.UTC).toEpochSecond();
}
11/08/2019
[Linux] Text handling for counting and replacing words
Here is a list of handy commands for VI and SED to count and replace text in a file. For both editors the escape character is /:
VI:
- count total words:
- count occurrences of particular word:
SED:
- copy all text from marker until end of file:
- replace all occurrences of SOURCE to TARGET with optional characters before SOURCE:
VI:
- count total words:
:%s/\i\+/&/gn
- count occurrences of particular word:
:%s/WORD/&/gn
SED:
- copy all text from marker until end of file:
sed -n -n '/MARKER/,$p' in >> out
- replace all occurrences of SOURCE to TARGET with optional characters before SOURCE:
sed -E 's/(OPTIONAL)?SOURCE/\1TARGET/g' in >> out
27/04/2019
[Spring Boot] Configure CORS
CORS (Cross-origin resource sharing) is an important security aspect of modern web applications. To prevent malicious content from being pulled into your page, usually the source(s) of the content for it are restricted to prevent external domains from serving pieces of your final page.
This functionality goes along with CSRF, X-Frame-Options, SessionPolicy and SecurityHeaders to provide a complete setup for your application.
All of this can be however very easily configured in Spring version 4+ (and therefore Spring Boot 2 as well) by providing a custom SecurityConfig (WebSecurityConfigurerAdapter) that will prevent Spring Boot from autoconfiguring the security with its own defaults.
Here is a sample implementation for Spring Boot 2 that completely disables (allows everything) CORS, it comes from this StackOverflow, slightly modified:
This functionality goes along with CSRF, X-Frame-Options, SessionPolicy and SecurityHeaders to provide a complete setup for your application.
All of this can be however very easily configured in Spring version 4+ (and therefore Spring Boot 2 as well) by providing a custom SecurityConfig (WebSecurityConfigurerAdapter) that will prevent Spring Boot from autoconfiguring the security with its own defaults.
Here is a sample implementation for Spring Boot 2 that completely disables (allows everything) CORS, it comes from this StackOverflow, slightly modified:
[Spring Boot] Upload file
In Spring Boot 2, your controller can expose a POST method to accept a file upload and return a JSON response simply as such:
And the FileUploadRequest class looks something like this:
With all the magic annotations coming from Lombok, Gradle configuration will look like this:
annotationProcessor "org.projectlombok:lombok:VERSION"
compileOnly "org.projectlombok:lombok:VERSION"
@RequestMapping(value="/upload", method=RequestMethod.POST, consumes = {"multipart/form-data"}, produces=MediaType.APPLICATION_JSON_VALUE)
@Transactional
public ResponseEntity<String> uploadFile(@ModelAttribute FileUploadRequest fileUploadRequest) {
fileUploadRequest.getFile(); //@TODO do something with your file
return new ResponseEntity<String>("{\"result\":\"success\"}", HttpStatus.OK);
}
@InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder)
throws ServletException {
binder.registerCustomEditor(byte[].class,
new ByteArrayMultipartFileEditor());
}
And the FileUploadRequest class looks something like this:
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class FileUploadRequest {
private String fileName;
private byte[] file;
}
With all the magic annotations coming from Lombok, Gradle configuration will look like this:
annotationProcessor "org.projectlombok:lombok:VERSION"
compileOnly "org.projectlombok:lombok:VERSION"
[Spring Boot] Download or display file in browser from controller
In Spring Boot 2, we can provide an endpoint that allows users to perform GET requests to download (or display) a file in their browsers as follows:
@RequestMapping("/downloadFile/{fileId}")
public ResponseEntity<byte[]> downloadFile(@PathVariable("fileId") String fileId){
File file = null; //@TODO get your file from wherever using fileId or the logic you need
byte[] fileBytes = Files.readAllBytes(file.toPath()); //@TODO for example, but you might convert file to byte[] as you wish
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF); //@TODO change accordingly!
headers.setContentDispositionFormData("attachment", file.getName()); //change to "inline" if you wish the browser to try do display it instead of downloading. WARNING: behaviour is browser dependent!
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); //prevent caching
ResponseEntity<byte[]> response = new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
return response;
}
@InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder)
throws ServletException {
binder.registerCustomEditor(byte[].class,
new ByteArrayMultipartFileEditor());
}
[Spring Boot] Send HTML email with attachment using Thymeleaf template
Thymeleaf provides a powerful and easy to use template engine that is effortlessly integrated in Spring and Spring Boot projects.
In this example we look at how to send HTML emails with attachments using a Thymeleaf template from a Spring Boot 2 project.
First of all these are the imports we need to add:
org.springframework.boot:spring-boot-starter-mail
org.springframework.boot:spring-boot-starter-thymeleaf
In this example we look at how to send HTML emails with attachments using a Thymeleaf template from a Spring Boot 2 project.
First of all these are the imports we need to add:
org.springframework.boot:spring-boot-starter-mail
org.springframework.boot:spring-boot-starter-thymeleaf
[Sheet music] Westworld - The house of the rising sun
In the TV series Westworld they did an amazing piano cover of The House of the Rising Sun, you can download it here.
18/03/2019
[Ubuntu] Install Microsoft fonts
Most of the world uses Microsoft Windows and Office, therefore it might be sometimes necessary to generate documents using Microsoft fonts, which of course are only available on Windows.
For Ubuntu, the ttf-mscorefonts-installer package contains SOME of those fonts, simply install it and you can start using them AFTER regenerating the font cache with fc-cache
[Linux] Bind special key press to ALSA control action
If using ALSA, it's possible to bind special keyboard keys to action controls with a few configuration lines.
First of all, to find the available action controls, run in a terminal: amixer scontrols
Then, find the key event we need to bind to the desired action, and add it as an event,action pair in a new configuration file under /etc/acpi/events for example:
event=button/mute MUTE 00000080 00000000 K
action=/usr/bin/amixer sset 'Master',0 toggle
event=ibm/hotkey HKEY 00000080 00001009
action=/etc/acpi/undock.sh
First of all, to find the available action controls, run in a terminal: amixer scontrols
Then, find the key event we need to bind to the desired action, and add it as an event,action pair in a new configuration file under /etc/acpi/events for example:
event=button/mute MUTE 00000080 00000000 K
action=/usr/bin/amixer sset 'Master',0 toggle
which in this case for my lapotop binds the mute button to the mute action. It is also possible to execute a script instead, for example:
action=/etc/acpi/undock.sh
which runs some actions when the laptop is undocked.
[Linux] Find which event is generated on special keypress
To determine which ACPI event is generated when a special key is pressed, simply open a terminal and run: acpi_listen
Then press any special key (media keys and such, normal keys won't generate an event) and you will see the output eg:
button/volumedown VOLDN 00000080 00000000 K
button/mute MUTE 00000080 00000000 K
button/volumeup VOLUP 00000080 00000000 K
Then press any special key (media keys and such, normal keys won't generate an event) and you will see the output eg:
button/volumedown VOLDN 00000080 00000000 K
button/mute MUTE 00000080 00000000 K
button/volumeup VOLUP 00000080 00000000 K
05/03/2019
[Ubuntu] Boot USB after error mmx64.efi not found
UEFI, great leap into the future and also great pain.
There is a funny error that can happen after creating a UEFI bootable USB to install a linux distro for example. If the installation is not completed immediately and the system is restarted, some files are left in some area of the EFI partition (I guess) and subsequent attempts to boot the exact same device will fail with an error:
Failed to open \EFI\BOOT\mmx64.efi - Not Found
Failed to load image \EFI\BOOT\mmx64.efi: Not Found
Failed to start MokManager: Not Fond
Something has gone seriously wrong: import_mok_state() failed
The easiest fix, is to simply browse the USB drive and go into the efi/boot folder, then copy the grubx64.efi file and rename it to mmx64.efi
The next boot will work again as intended. Magic of the machines
There is a funny error that can happen after creating a UEFI bootable USB to install a linux distro for example. If the installation is not completed immediately and the system is restarted, some files are left in some area of the EFI partition (I guess) and subsequent attempts to boot the exact same device will fail with an error:
Failed to open \EFI\BOOT\mmx64.efi - Not Found
Failed to load image \EFI\BOOT\mmx64.efi: Not Found
Failed to start MokManager: Not Fond
Something has gone seriously wrong: import_mok_state() failed
The easiest fix, is to simply browse the USB drive and go into the efi/boot folder, then copy the grubx64.efi file and rename it to mmx64.efi
The next boot will work again as intended. Magic of the machines
Subscribe to:
Posts (Atom)