As a software development graduate, I have acquired a vast array of technical skills and
therefore, improved myself in programming languages, software, techniques, and writing methods.
This setup gives me a good foundation for any given environment and the ability to adapt to any situation,
build up on the required knowledge, and provide results and solutions.
Usage of Python for many school projects in which it was mostly used for backend for web applications. Python in connection with Flask and Django. This way also integration with databases.
#Showcase function / Python-Django
def login_page(request):
global wrongLogin
global sessionDict
global user
if request.method == 'GET':
print("Get method activated")
if request.method == 'POST':
wrongLogin = 'false' #set login check back to deafault
print("POST on index")
username = request.POST.get('username')
password = request.POST.get('password')
backend = database.MyBackend()
user = backend.authenticate(username=username, password=password)
print(user)
if user is not None:
login(request, user=user)
request.session.set_expiry(20)
request.session['alert'] = True
if request.session.exists(session_key=request.session.session_key):
print(request.session.session_key)
sessionDict['username'] = user.username
sessionDict['role'] = user.role.name
sessionDict['id'], sessionDict['name'] = database.get_userID_name(sessionDict['role'], sessionDict['username'])
print(sessionDict)
user.is_active=1
user.save(update_fields=["is_active"])
return redirect('/index/')
else:
wrongLogin = 'true'
return redirect('/login/')
# refers to index page and what contect is going to be displayed when post method is applied
return render(request, "login.html", {'wrongLogin': wrongLogin}) #sending message for wrong login`
Implementation of MySQL databases with stored procedures, indexes, events, triggers, functions. Experiences also with object databases and graph databases.
//Showcase function / MySQL Function for Checking Loan
DELIMITER $$
CREATE FUNCTION CheckLoan(ssnclient varchar(11))
RETURNS varchar(5)
DETERMINISTIC
BEGIN
IF EXISTS (
SELECT * FROM loans l
JOIN accounts a
on a.ID = l.account_id
JOIN account_customers ac
on ac.account_id = a.ID
JOIN clients c
on c.ID = ac.client_id
WHERE c.ssn = ssnclient)
THEN RETURN 'TRUE';
ELSE RETURN 'FALSE';
END IF;
END$$
-- SELECT CheckLoan('300-01-2000');
Creating pods based on the custom-made image of the Golang CLI app. Running CronJobs on specific app functionalities.
#Code snippet of CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: filch-permissions
spec:
schedule: "*/10 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: filch-permissions
image: filch
imagePullPolicy: Always
args:
- permissions
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: filch-secrets
key: GRAFANA_API_KEY
- name: BASE_URL
value: grafana_url
restartPolicy: OnFailure
Custom-made HTML pages for specific applications. Help use of frameworks such as Bootstrap for faster element inputs.
An essential part of the projects was the usage of Github/Git used for code sharing, versioning, branching. With Github implementation of Github Actions (CI) for code testing and deployment.
Essential knowledge used for web development. Used with backend communication and dynamic page reactions to user inputs.
//Showcase function / Simple time display
var cur_time = document.getElementById('cur_time');
function time() {
var d = new Date();
var s = d.getSeconds();
var m = d.getMinutes();
var h = d.getHours();
cur_time.textContent =
("0" + h).substr(-2) + ":" + ("0" + m).substr(-2) + ":" + ("0" + s).substr(-2);
}
setInterval(time, 1000);
Usage of Docker for development purposes. Imitating the production environment in the development phase. Running docker containers bassed on custom docker image.
FROM golang:1.19-alpine3.16 as builder
WORKDIR /app
COPY . .
RUN go build -o main main.go
#run stage
FROM alpine:3.16
WORKDIR /app
COPY --from=builder /app/main .
COPY app.env .
ENTRYPOINT [ "/app/main" ]
Editing of custom HTML pages in order to achieve a more pleasant look.
Used for creation of CLI app. usage of slices, strcuts, API calls, back-end and front-end creation. Implmentation with Docker and K8s and also with Azure Blob Storage.
//Showcase of code snippet
URL := fmt.Sprintf("%s%s", BASE_URL, "/api/folders")
fol_struct := make([]*FolderStruct, 0) //usage for array of records
GetData("GET", URL, API_KEY, &fol_struct)
//* loop throught folders and get the UID and names
for i := 0; i < len(fol_struct); i++ {
uid_slice = append(uid_slice, fol_struct[i].UID)
folder_name_slice = append(folder_name_slice, fol_struct[i].Title)
}
//* collect dashboard UIDs and names
URL = fmt.Sprintf("%s%s", BASE_URL, "/api/search?type=dash-db")
das_struct := make([]*DashboardsStruct, 0)
GetData("GET", URL, API_KEY, &das_struct)
for i := 0; i < len(das_struct); i++ {
dashboard_uids_slice = append(dashboard_uids_slice, fmt.Sprint(das_struct[i].UID))
dashboard_name_slice = append(dashboard_name_slice, das_struct[i].Title) //name slice and UID slice share the same possitiond for data
}
jsonmodel_meta := &JSONModel_meta{}
Used with Xamarin.Forms for iOS/Android application. App acted as controlling hub for remotly controlled robot. Virtual map creation and map settings.
//Showcase function / Function for map line detecting
void out_line_side(int x1, int y1, int x2, int y2)
{
bool done = false;
int result = 0;
done = false;
int x3;
int y3;
int x4;
int y4;
if (y1 < y2)
{
x3 = 1;
y3 = y1;
x4 = y1 * row_num;
y4 = y1;
}
else
{
x3 = 1;
y3 = y2;
x4 = y2 * row_num;
y4 = y2;
}
int loops = Math.Abs(y1 - y2);
for (int i = 0; i <= loops; i++)
{
if (i >= 1)
{
x3 = x3 + row_num;
y3++;
x4 = x4 + row_num;
y4++;
}
int D = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
int intersect_x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / D;
int intersect_y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / D;
foreach (Order order in order_info)
{
if (order.x == intersect_x && order.y == intersect_y)
{
Order_but[order.order].BackgroundColor = Color.Green;
result = order.order;
int max_num_in_lane; //gives last number in lane to which we black out buttons
int starting_point;
int end_point;
int starting_point_y;
if (blur_off_heading == "left") //blur to the left side
{
starting_point = RobotWay(order.x, order.y);
end_point = RobotWay(1, order.y);
if (starting_point == end_point) //when its the first button in column
{
Order_but[starting_point].BackgroundColor = Color.Transparent;
Order_but[starting_point].Text = " ";
Order_but[starting_point].BorderColor = Color.Transparent;
Order_but[starting_point].IsEnabled = false;
if (!out_of_map_buttons.Contains(Order_but[starting_point].ClassId))
{
out_of_map_buttons.Add(Order_but[starting_point].ClassId);
}
}
for (int l = starting_point; l >= end_point; l--)
{
Order_but[l].BackgroundColor = Color.Transparent;
Order_but[l].Text = " ";
Order_but[l].BorderColor = Color.Transparent;
Order_but[l].IsEnabled = false;
if (!out_of_map_buttons.Contains(Order_but[l].ClassId)) //add all out of map buttons to list of strings
{
out_of_map_buttons.Add(Order_but[l].ClassId);
}
}
}
else if (blur_off_heading == "right") //blur to the right side
{
starting_point = RobotWay(order.x, order.y);
end_point = RobotWay(row_num, order.y);
if (starting_point == end_point) //when its the first button in column
{
Order_but[starting_point].BackgroundColor = Color.Transparent;
Order_but[starting_point].Text = " ";
Order_but[starting_point].BorderColor = Color.Transparent;
Order_but[starting_point].IsEnabled = false;
if (!out_of_map_buttons.Contains(Order_but[starting_point].ClassId)) //add all out of map buttons to list of strings
{
out_of_map_buttons.Add(Order_but[starting_point].ClassId);
}
}
for (int r = starting_point; r <= end_point; r++)
{
Order_but[r].BackgroundColor = Color.Transparent;
Order_but[r].Text = " ";
Order_but[r].BorderColor = Color.Transparent;
Order_but[r].IsEnabled = false;
if (!out_of_map_buttons.Contains(Order_but[r].ClassId))
{
out_of_map_buttons.Add(Order_but[r].ClassId);
}
}
}
}
}
}
}
Used for embedded systems programming. Board pins control and sensors programming. Creation of many IoT projects.
//Showcase function / LCD displaying and weight processing
my_lcd.Set_Draw_color(WHITE);
my_lcd.Fill_Screen(WHITE);
my_lcd.Fill_Rectangle(0, 350, my_lcd.Get_Display_Width()-1, 42);
show_string("Dispensing...",CENTER,144,2,DARKGREY, BLACK,1);
Serial.println("Run pressed");
//calculations for final grams
input_grams = grams.toInt();
float together = cup_weight + input_grams;
int add_grams = 0;
Serial.print("Together:");
Serial.println(together);
delay(1000);
LoadCell.begin();
//calibrate scale for measurements
float calibrationValue;
calibrationValue = 696.0;
#if defined(ESP8266)|| defined(ESP32)
#endif
EEPROM.get(calVal_eepromAdress, calibrationValue);
long stabilizingtime = 2000;
boolean _tare = true;
LoadCell.start(stabilizingtime, _tare);
//run till desired grams are reached
while(add_grams <= input_grams)
{
if (LoadCell.update()) newDataReady = true;
if (newDataReady)
{
if (millis() > t + serialPrintInterval)
{
add_grams = LoadCell.getData();
Serial.print("Load value: ");
Serial.println(add_grams);
newDataReady = 0;
t = millis();
}
}
//motor start
if (motor == 1)
{
if (input_grams <= 6)
{
analogWrite(motorPin, 170);
Serial.println("Only half full all time.");
}
else if(input_grams >= 7)
{
percentage = input_grams * 0.8; //80% of input weight
while (add_grams <= percentage)
{
if (LoadCell.update()) newDataReady = true;
if (newDataReady)
{
if (millis() > t + serialPrintInterval)
{
add_grams = LoadCell.getData();
Serial.print("Load value: ");
Serial.println(add_grams);
newDataReady = 0;
t = millis();
}
}
analogWrite(motorPin, 255);
Serial.print("Add grams: ");
Serial.println(add_grams);
Serial.print("Percentage: ");
Serial.println(percentage);
Serial.println("80 percent full.");
}
analogWrite(motorPin, 100); //slow down to last 20 percent
Serial.println("20 percent slow.");
}
}
else if (motor == 2)
{
if (input_grams <= 6)
{
analogWrite(motorPin2, 170);
Serial.println("Only half full all time. mt2");
}
else if(input_grams >= 7)
{
percentage = input_grams * 0.8; //80% of input weight
while (add_grams <= percentage)
{
if (LoadCell.update()) newDataReady = true;
if (newDataReady)
{
if (millis() > t + serialPrintInterval)
{
add_grams = LoadCell.getData();
Serial.print("Load value: ");
Serial.println(add_grams);
newDataReady = 0;
t = millis();
}
}
analogWrite(motorPin2, 255);
Serial.print("Add grams: ");
Serial.println(add_grams);
Serial.print("Percentage: ");
Serial.println(percentage);
Serial.println("80 percent full. mt2");
}
analogWrite(motorPin2, 100); //slow down to last 20 percent
Serial.println("20 percent slow. mt2");
}
}
}
//motor stop
if (motor == 1)
{
analogWrite(motorPin, 0);
}
else
{
analogWrite(motorPin2, 0);
}
Same as for this web. Web creatiions using wordpress and add-ons to achieve fast modeling and nicer visual look. Security of webpage and FTP implementation.
Specialization on embedded system and its integration to real life world. Using low level programming in order to create programs running on microcontrollers such as Arduino, ESP8266, Raspberry Pi. Electronics lessons with focus on PCB board creations, layout and functionalities. IoT projects with implementation of databases cloud deployment.
Ocean and inland freight company. Leaders of the world wide transportation. Increasing it's power in technological sphere.
Cloud engineering intern position in one of the biggest corporates in the world had given an me enormous boost towards my learning curve in software development. Connecting with professionals in their field and having an opportunity to work side-by-side has opened my eyes how transportation company is slowly evolving to a tech-focused corporate.
In Maersk, my skill set was challenged by learning GoLang and developing in-house application workign on top of Grafana. In production whole application runs on Microsoft Azure clusters where specific app functionalities have set up CronJobs which have its own runtime schedule. This setup leads to an app performing as expected with almost no maintanance.
Powering the future of e-reading and podcasts. Enables customers to have their desired branded application with consistent maintenance.
Role of app release support at Pubfront gave me a new perspective on how an IT company works and deals with development challenges and keeps up with trends. Made me learn to be a better teammate and puts responsibilities on me in order for me to enrich my knowledge.
Main tasks which I had to solve are configurations for apps, its design changes and partially bug fixes. With this comes also code improvement and creation of scripts which take off the load from manual work.Moreover, I was responsible for testing new application features which are planned to go to live. Testing previously found bug fixes. Everything comes with appropriate documentation of actions. In the case of new customers, my task is to build a showcase application that uses its customer’s brand features such as colors, pictures, and desired functionality.
Implementing technology into shooting ranges by creating smart targets as well as remotely controlled dummy robots acting as moving targets.
Working in Trainshot as App developer helped me to gain a lot of technical skills in coding. Especially in C# and Xamarin.Forms. My task was to create a subpart of the already created app which was supposed to control the dummy robot remotely. Idea was to give users an app that is capable of creating a map on which robot is going to be moving with the option to set specific waypoints on the map. Afterward, take this virtual map and make the robot move in real life correspondingly.
I had to overtake many obstacles which helped me to become more persistent, visionary, and creative. It also learned me to look at things from a different points of view.
Roman has been helping us configure, test and deliver releases of our Whitelabel app to 15+ clients so far. I've found him to be a very quick learner; nothing has to be explained more than once. He's proven himself to be thorough and hard-working, so I've felt comfortable transferring more responsibilities to him quicker than expected. Finally, he's also an easygoing, humble and pleasant person to have around.
In Trainshot, Roman has been playing a lead role in app development for our remotely controlled robot which we have been developing for some time. He was able to adapt fast to the team and blend in. Romans workflow was flexible depending on what was prioritized. He manage to deliver what was asked of him in deadlines. It was a great experience to have him in a company.
The tasks that Roman has been working on at Maersk are of medium to high complexity, where Roman has shown good analytical skills, and the ability to keep working even though not everything was set in stone. Roman has adopted our asynchronous way of working very effectively. This includes effective written communication, making me as the receiver able to quickly know the status of things. In video/audio meetings it’s obvious that Roman respects the time of others, as he is always well prepared, and have prior to meetings send out a short agenda on what to cover. This is extremely valuable!