The upcoming match between Widzew Lodz and Rakow Czestochowa is anticipated to be a thrilling encounter, with several betting markets offering intriguing odds. Based on the available data, this match is expected to be high-scoring, with an average total of 3.20 goals predicted. The teams have shown a propensity for conceding goals, with an average of 2.73 goals scored and 2.58 goals conceded per match. This suggests that both teams will likely find the back of the net during this fixture.
Widzew Lodz
LWLWL-Rakow Czestochowa
WDDLWDate: 2025-09-28Time: 10:15(FT)Venue: Stadion WidzewaScore: 0-1
Predictions:
Market | Prediction | Odd | Result |
---|---|---|---|
Home Team To Score In 1st Half | 99.00% | (0-1) | |
Over 1.5 Goals | 79.40% | (0-1) 1.30 | |
Over 4.5 Cards | 77.30% | (0-1) | |
Both Teams Not To Score In 2nd Half | 77.00% | (0-1) 0-1 2H 1.33 | |
Away Team Not To Score In 1st Half | 77.80% | (0-1) | |
Away Team To Score In 2nd Half | 75.50% | (0-1) | |
Draw In First Half | 68.00% | (0-1) | |
Last Goal 73+ Minutes | 70.40% | (0-1) 90' min 1.83 | |
Both Teams Not To Score In 1st Half | 67.90% | (0-1) 0-0 1H 1.18 | |
Goal In Last 15 Minutes | 66.40% | (0-1) | |
Goal In Last 10 Minutes | 68.20% | (0-1) | |
Over 5.5 Cards | 69.60% | (0-1) | |
Over 0.5 Goals HT | 60.70% | (0-1) 0-0 1H 1.40 | |
Home Team Not To Score In 2nd Half | 61.20% | (0-1) | |
First Goal 30+ Minutes | 58.30% | (0-1) | |
Under 2.5 Goals | 58.00% | (0-1) 1.83 | |
Both Teams Not to Score | 53.80% | (0-1) 2.05 | |
Home Team To Win | 56.00% | (0-1) 2.67 | |
Sum of Goals 2 or 3 | 50.20% | (0-1) 1.95 | |
Avg. Total Goals | 3.20% | (0-1) | |
Yellow Cards | 3.68% | (0-1) | |
Avg. Goals Scored | 2.73% | (0-1) | |
Avg. Conceded Goals | 2.58% | (0-1) | |
Red Cards | 1.50% | (0-1) |
Betting Predictions
Home Team To Score In 1st Half
The odds of 99.00 for the home team scoring in the first half indicate a strong likelihood, given Widzew Lodz’s recent form and offensive capabilities.
Over 1.5 Goals
With odds of 79.40, betting on over 1.5 goals seems a safe bet, considering both teams’ average goal-scoring rates.
Over 4.5 Cards
At odds of 77.30, expecting a high number of cards aligns with the aggressive play styles often seen in these fixtures.
Both Teams Not To Score In 2nd Half
The odds of 77.00 suggest a potential defensive adjustment or fatigue affecting both teams in the second half.
Away Team Not To Score In 1st Half
Odds of 77.80 indicate that Rakow Czestochowa might struggle to find their rhythm early in the game.
Away Team To Score In 2nd Half
With odds of 75.50, there’s a good chance Rakow will find opportunities to score once they’ve settled into the game.
Draw In First Half
The odds of 68.00 reflect a balanced first half, with both teams potentially being cautious in their approach.
Last Goal After 73 Minutes
Odds of 70.40 suggest that the decisive goal may come late in the match, adding excitement to the closing stages.
Both Teams Not To Score In First Half
At odds of 67.90, it’s possible that both teams will be wary and defensive initially.
Goal In Last 15 Minutes
Odds of 66.40 indicate that either team could score towards the end, potentially deciding the match.
Goal In Last 10 Minutes
The odds of 68.20 highlight the likelihood of a late surge from one or both teams.
Over 5.5 Cards
With odds of 69.60, expect physical play leading to numerous bookings.
Over Half A Goal By HT
Odds of 60.70 suggest that at least one goal is likely by halftime.
Home Team Not To Score In Second Half
Odds of 61.20 imply that Widzew might struggle to maintain their first-half momentum.
First Goal After First Half Hour
Odds of 58.30 indicate that scoring may take time as both teams adjust to each other’s tactics.
Under Two And A Half Goals
mattiebartman/lastfm-bot/src/lastfm-bot-redis.js
const redis = require(‘redis’);
const { promisify } = require(‘util’);
class Redis {
constructor() {
this.client = redis.createClient();
this.getAsync = promisify(this.client.get).bind(this.client);
this.setAsync = promisify(this.client.set).bind(this.client);
this.existsAsync = promisify(this.client.exists).bind(this.client);
this.quitAsync = promisify(this.client.quit).bind(this.client);
}
async get(key) {
return await this.getAsync(key);
}
async set(key, value) {
return await this.setAsync(key, value);
}
async exists(key) {
return await this.existsAsync(key);
}
async quit() {
return await this.quitAsync();
}
}
module.exports = Redis;mattiebartman/lastfm-bot/src/lastfm-bot.js
const fs = require(‘fs’);
const request = require(‘request-promise-native’);
const Redis = require(‘./lastfm-bot-redis’);
const lastFmApiKey = process.env.LASTFM_API_KEY;
const lastFmApiSecret = process.env.LASTFM_API_SECRET;
const lastFmApiUrl = ‘http://ws.audioscrobbler.com/2.0/’;
const redisHost = process.env.REDIS_HOST;
const redisPort = process.env.REDIS_PORT;
class LastFmBot {
constructor() {
if (!lastFmApiKey || !lastFmApiSecret) {
throw new Error(‘You must set LASTFM_API_KEY and LASTFM_API_SECRET environment variables’);
}
if (!redisHost || !redisPort) {
throw new Error(‘You must set REDIS_HOST and REDIS_PORT environment variables’);
}
const redisConfig = `redis://${redisHost}:${redisPort}`;
this.redisClient = new Redis(redisConfig);
}
async _getHashedValue(value) {
const hash = require(‘crypto’)
.createHash(‘md5’)
.update(value)
.digest(‘hex’);
return hash;
}
async _getHashedKey(userHash, artistName) {
const keyHash = await this._getHashedValue(`${userHash} ${artistName}`);
return keyHash;
}
async _getCacheKey(userHash, artistName) {
const keyHash = await this._getHashedKey(userHash, artistName);
const cacheKey = `${userHash}:${keyHash}`;
return cacheKey;
}
async _getArtistTopTags(artistName) {
const response = await request({
method: ‘GET’,
uri: lastFmApiUrl,
qs: {
method: ‘artist.gettoptags’,
api_key: lastFmApiKey,
artist: artistName,
format: ‘json’
},
json: true
});
const topTagsArray = response.toptags.tag.map(tag => tag.name);
const topTagsString = topTagsArray.join(‘, ‘);
return topTagsString;
}
async _getLastTopTags(cacheKey) {
const cachedData = await this.redisClient.get(cacheKey);
if (cachedData) {
return JSON.parse(cachedData);
}
return null;
}
async _setLastTopTags(cacheKey, topTags) {
await this.redisClient.set(cacheKey, JSON.stringify(topTags));
}
async _getLastTopTracks(cacheKey) {
const cachedData = await this.redisClient.get(cacheKey);
if (cachedData) {
return JSON.parse(cachedData);
}
return null;
}
async _setLastTopTracks(cacheKey, topTracks) {
await this.redisClient.set(cacheKey, JSON.stringify(topTracks));
}
async getTopTags(userHash, artistName) {
try {
const cacheKey = await this._getCacheKey(userHash, artistName);
let topTags;
if (await this.redisClient.exists(cacheKey)) {
topTags = await this._getLastTopTags(cacheKey);
} else {
topTags = await this._getArtistTopTags(artistName);
if (topTags !== null) {
await this._setLastTopTags(cacheKey, topTags);
}
}
return topTags;
} catch (error) {
console.log(error);
throw error;
} finally {
try {
await this.redisClient.quit();
} catch (error) {
console.log(error);
// don’t do anything
}
}
}
async getTopTracks(userHash, artistName) {
try {
const cacheKeyTracks = `${userHash}:tracks`;
let topTracks;
if (await this.redisClient.exists(cacheKeyTracks)) {
topTracks = await this._getLastTopTracks(cacheKeyTracks);
} else {
// we need to get a list of all artists from user’s recent tracks
// and then get all their top tracks
// but we only want artists who have played within the last month
// get recent tracks
const responseRecentTracks =
await request({
method: ‘GET’,
uri: lastFmApiUrl,
qs: {
method: ‘user.getrecenttracks’,
user: userHash,
api_key: lastFmApiKey,
limit: ‘200’,
format: ‘json’
},
json: true
});
// filter out empty entries
const recentTrackArray =
responseRecentTracks.recenttracks.track.filter(track => track.artist && track.album);
// filter out artists who haven’t played within the last month
// we use today’s date minus one month as our cut-off point
const currentDate =
new Date().toISOString().split(‘T’)[0]; // YYYY-MM-DD format
const cutoffDate =
new Date(new Date().setMonth(new Date().getMonth() -1))
.toISOString()
.split(‘T’)[0]; // YYYY-MM-DD format
const recentTrackFilteredArray =
recentTrackArray.filter(
track => track.date >= cutoffDate
);
// create array with all artist names
const artistArray =
recentTrackFilteredArray.map(
track => track.artist[‘#text’]
);
// remove duplicate artists
let uniqueArtistArray =
[…new Set(artistArray)];
// sort alphabetically by name
uniqueArtistArray.sort();
// get all their top tracks
let artistIndex;
for (artistIndex in uniqueArtistArray) {
// we need to get user hash from username as well
const responseUser =
await request({
method: ‘GET’,
uri: lastFmApiUrl,
qs: {
method: ‘user.getInfo’,
user: userHash,
api_key: lastFmApiKey,
format: ‘json’
},
json: true
});
let userHashFromUsername;
if (responseUser.user.name === userHash && responseUser.user.url && responseUser.user.url[0].resource !== null) {
userHashFromUsername =
responseUser.user.url[0].resource.split(‘/’)[4];
} else {
throw new Error(‘Invalid username’);
}
const responseArtist =
await request({
method: ‘GET’,
uri: lastFmApiUrl,
qs: {
method: ‘artist.getinfo’,
artist: uniqueArtistArray[artistIndex],
api_key: lastFmApiKey,
format: ‘json’
},
json: true
});
let artistNameFromArtistPage;
if (responseArtist.artist.name && responseArtist.artist.url && responseArtist.artist.url[0].resource !== null) {
artistNameFromArtistPage =
responseArtist.artist.url[0].resource.split(‘/’)[4];
if (artistNameFromArtistPage === uniqueArtistArray[artistIndex]) {
console.log(`getting ${artistNameFromArtistPage}’s top tracks`);
const responseArtistTopTracks =
await request({
method: ‘GET’,
uri: lastFmApiUrl,
qs: {
method: ‘artist.gettoptracks’,
artist: uniqueArtistArray[artistIndex],
api_key: lastFmApiKey,
limit:’10’,
format:’json’
},
json:true
});
if (!topTracks) {
topTracks =
[];
}
let trackNames;
if (responseArtistTopTracks.toptracks.track.length >0 ) {
trackNames =
responseArtistTopTracks.toptracks.track.map(
track => track.name);
if (!topTracks[uniqueArtistArray[artistIndex]]) {
topTracks[uniqueArtistArray[artistIndex]] =
trackNames;
} else {
console.log(`already added ${uniqueArtistArray[artistIndex]}`);
}
} else {
console.log(`${uniqueArtistArray[artistIndex]} has no tracks`);
}
} else {
throw new Error(`Invalid artist name for ${uniqueArtistArray[artistIndex]}`);
}
} else {
throw new Error(`Invalid artist name for ${uniqueArtistArray[artistIndex]}`);
}
}
if (topTracks !== null && Object.keys(topTracks).length >0 ) {
console.log(JSON.stringify(topTracks));
await this._setLastTopTracks(cacheKeyTracks,topTracks);
} else {
console.log(`No tracks found`);
}
}
return topTracks;
} catch (error) {
console.log(error);
throw error;
} finally {
try {
await this.redisClient.quit();
} catch (error) {
console.log(error);
}
}
}
}
module.exports.LastFmBot=LastFmBot;mattiebartman/lastfm-bot/README.md
# Last.fm Bot
A simple [Last.fm](https://www.last.fm/) bot.
This bot was created using [Node.js](https://nodejs.org/en/) v12.
The bot has two methods:
– `getTopTags` – returns an array of strings containing an artists’ most popular tags.
– `getTopTracks` – returns an object containing an array of strings for each artists’ most popular tracks.
## Getting started
### Install dependencies
First you’ll need to install dependencies:
npm install
### Set up environment variables
In order to use the bot you’ll need to set up some environment variables:
export LASTFM_API_KEY=your-lastfm-api-key-here # see below how to get an API key from Last.fm
export LASTFM_API_SECRET=your-lastfm-api-secret-here # see below how to get an API secret from Last.fm
export REDIS_HOST=localhost # set your Redis host here – defaults to localhost if not set
export REDIS_PORT=6379 # set your Redis port here – defaults to port number above if not set
### Getting an API key and secret from Last.fm
To obtain an API key and secret you’ll need to [create an account](https://www.last.fm/api/account/create?from=nodejsbot).
Once you’ve created your account you can go back to [the main API page](https://www.last.fm/api/account/create?from=nodejsbot), enter your username and password and click “Get my API key”.
### Run tests
You can run tests with:
npm test
## Using the bot
In order to use the bot you’ll need to create an instance:
let botInstance=new LastFmBot.LastFmBot();
### `getTopTags`
Returns an array containing strings for each tag.
Parameters:
– `userHash` – This is your Last.fm username hashed.
– `artistName` – This is the name of the band whose tags you want.
Example usage:
botInstance.getTopTags(“f8b99e8d7cbe4b90a2f4ef4a37cfc1dc”,”Coldplay”).then(tags => console.log(tags)).catch(err => console.error(err));
### `getTopTracks`
Returns an object containing arrays for each band name.
Parameters:
– `userHash` – This is your Last.fm username hashed.
Example usage:
botInstance.getTopTracks(“f8b99e8d7cbe4b90a2f4ef4a37cfc1dc”).then(tracks => console.log(tracks)).catch(err => console.error(err));
mattiebartman/lastfm-bot/test/test.js
const fs=require(‘fs’);
const chai=require(‘chai’);
const chaiAsPromised=require(‘chai-as-promised’);
chai.use(chaiAsPromised);
chai.should();
let botInstance=null;
before(async function() {
try {
botInstance=new require(‘../src/lastfm-bot’).LastFmBot.LastFmBot();
} catch (err) {
throw err;
}
});
after(async function() {
try {
await botInstance.redisClient.quit();
} catch (err) {
throw err;
}
});
describe(“Testing Last.fm Bot”, function() {
it(“should be able to create instance”, function() {
botInstance.should.be.an.instanceof(require(‘../src/lastfm-bot’).LastFmBot.LastFmBot);
});
it(“should be able to retrieve tags”, function(done) {
botInstance.getTopTags(“f8b99e8d7cbe4b90a2f4ef4a37cfc1dc”,”Coldplay”).then(tags => {
tags.should.be.an(“array”);
tags.should.be.of.length(10);
done();
}).catch(err => done(err));
});
it(“should be able retrieve tags for multiple bands”, function(done) {
botInstance.getTopTags(“f8b99e8d7cbe4b90a2f4ef4a37cfc1dc”,”Metallica”).then(tags => {
tags.should.be.an(“array”);
tags.should.be.of.length(10);
botInstance.getTopTags(“f8b99e8d7cbe4b90a2f4ef4a37cfc1dc”,”Radiohead”).then(tags => {
tags.should.be.an(“array”);
tags.should.be.of.length(10);
done();
}).catch(err => done(err));
}).catch(err => done(err));
});
it(“should be able retrieve tracks